Repository navigation
Expand file tree
/
Copy pathbuilder.m
More file actions
129 lines (129 loc) · 5.38 KB
/
Copy pathbuilder.m
File metadata and controls
129 lines (129 loc) · 5.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
%=============================================================================
% Generated by ngen. Makes this module a first-class nmm local module so it can
% be installed, packaged and published (nmm install / package / publish).
%=============================================================================
% LICENCE_BLOCK_BEGIN
% SPDX-License-Identifier: LGPL-3.0-or-later
% LICENCE_BLOCK_END
%=============================================================================
% (Re)generates the loader and the help, and compiles the native gateway
% (libnls<Module>_builtin) in place. The build is driven entirely by Nelson's
% own dynamic_link helpers - dlgetnelsonincludes / dlgetnelsonlibraries provide
% the Nelson C++ SDK include and import-library set, dlgeneratemake writes the
% CMakeLists and dlmake compiles it - so no CMakeLists is maintained by hand and
% no third-party path is ever hard-coded here. It depends on Nelson only and
% does NOT require the ngen module to be loaded.
%
% The build runs once, on demand. It is skipped when there is nothing to
% compile yet (a fresh scaffold has no gateway sources), when the gateway is
% already built (an install carries the prebuilt library in builtin/, so nmm
% never recompiles at install time), or when no build toolchain is available.
% Delete the library (or use ngen.build) to force a rebuild.
%=============================================================================
NGEN_MODULE_DIR = fileparts(nfilename('fullpath'));
tessera_build_native_gateway('tessera', NGEN_MODULE_DIR);
nmm_build_loader('tessera', NGEN_MODULE_DIR);
nmm_build_help('tessera', NGEN_MODULE_DIR);
clear('NGEN_MODULE_DIR');
%=============================================================================
function tessera_build_native_gateway(moduleName, moduleDir)
moduleDir = strrep(moduleDir, '\', '/');
capName = [upper(moduleName(1)), moduleName(2:end)];
gatewayLib = [moduleDir, '/builtin/libnls', capName, '_builtin', getdynlibext()];
sources = tessera_native_sources(moduleDir);
if isempty(sources)
disp(['[', moduleName, '] no native sources; skipping native gateway build.']);
return;
end
inputs = tessera_native_inputs(moduleDir);
if isfile(gatewayLib) && tessera_gateway_is_current(gatewayLib, inputs)
disp(['[', moduleName, '] native gateway already built: ', gatewayLib]);
return;
end
if isfile(gatewayLib)
disp(['[', moduleName, '] native gateway is older than its sources; rebuilding.']);
end
if ~havecompiler()
disp(['[', moduleName, '] no build toolchain; skipping native gateway build.']);
return;
end
% Nelson SDK includes/libraries + the module's own headers. Only existing
% directories are added: dlgeneratemake rejects a non-existent include path,
% so a module without a src/include (or builtin/include) still configures.
includes = dlgetnelsonincludes();
for extraInc = {[moduleDir, '/src/include'], [moduleDir, '/builtin/include']}
if isdir(extraInc{1})
includes{end + 1, 1} = extraInc{1};
end
end
libraries = dlgetnelsonlibraries();
% Export macros follow Nelson's naming convention NLS<MODULE>_[BUILTIN_]EXPORTS.
upperName = upper(moduleName);
defines = {['NLS', upperName, '_EXPORTS'], ['NLS', upperName, '_BUILTIN_EXPORTS']};
buildDir = [moduleDir, '/build'];
if ~isdir(buildDir)
mkdir(buildDir);
end
disp(['[', moduleName, '] generating build files (dlgeneratemake)...']);
[ok, msg] = dlgeneratemake(buildDir, ['libnls', capName, '_builtin'], ...
sources, includes, defines, libraries, 'Release');
if ~ok
disp(msg);
error('Nelson:dlgeneratemake:failed', 'dlgeneratemake failed.');
end
disp(['[', moduleName, '] building native gateway (dlmake)...']);
[ok, msg] = dlmake(buildDir);
if ~ok
disp(msg);
error('Nelson:dlmake:failed', 'dlmake failed.');
end
built = [buildDir, '/libnls', capName, '_builtin', getdynlibext()];
if isfile(built)
copyfile(built, gatewayLib, 'f');
disp(['[', moduleName, '] native gateway ready: ', gatewayLib]);
else
disp(['[', moduleName, '] no gateway library produced: ', built]);
end
end
%=============================================================================
function sources = tessera_native_sources(moduleDir)
sources = {};
for sub = {'/src/cpp/', '/builtin/cpp/'}
for ext = {'*.cpp', '*.c'}
entries = dir([moduleDir, sub{1}, ext{1}]);
for k = 1:numel(entries)
sources{end + 1, 1} = [moduleDir, sub{1}, entries(k).name]; %#ok<AGROW>
end
end
end
end
%=============================================================================
function inputs = tessera_native_inputs(moduleDir)
inputs = tessera_native_sources(moduleDir);
for sub = {'/src/include/', '/builtin/include/'}
for ext = {'*.hpp', '*.h'}
entries = dir([moduleDir, sub{1}, ext{1}]);
for k = 1:numel(entries)
inputs{end + 1, 1} = [moduleDir, sub{1}, entries(k).name]; %#ok<AGROW>
end
end
end
end
%=============================================================================
function tf = tessera_gateway_is_current(gatewayLib, inputs)
tf = false;
info = dir(gatewayLib);
if isempty(info)
return;
end
gatewayTime = info.datenum;
tf = true;
for k = 1:numel(inputs)
sourceInfo = dir(inputs{k});
if ~isempty(sourceInfo) && sourceInfo.datenum > gatewayTime
tf = false;
return;
end
end
end
%=============================================================================