|
9 | 9 |
|
10 | 10 | addpath(plan.RootFolder)
|
11 | 11 |
|
| 12 | +%% Self-test setup |
12 | 13 | if isMATLABReleaseOlderThan("R2023b")
|
13 | 14 | plan("test") = matlab.buildtool.Task(Actions=@legacy_test);
|
14 | 15 | elseif isMATLABReleaseOlderThan("R2024a")
|
|
19 | 20 | plan("test") = matlab.buildtool.tasks.TestTask("test", Strict=false, TestResults="TestResults.xml");
|
20 | 21 | end
|
21 | 22 |
|
| 23 | +td = plan.RootFolder + "/test"; |
| 24 | +srcs = [td+"/stdout_stderr_c.c", td+"/stdin_cpp.cpp", td+"/printenv.cpp"]; |
| 25 | +exes = [td+"/stdout_stderr_c.exe", td+"/stdin_cpp.exe", td+"/printenv.exe"]; |
| 26 | +if ~isempty(get_compiler("fortran")) |
| 27 | + srcs = [srcs, td + "/stdout_stderr_fortran.f90", td + "/stdin_fortran.f90"]; |
| 28 | + exes = [exes, td+"/stdout_stderr_fortran.exe", td+"/stdin_fortran.exe"]; |
| 29 | +end |
| 30 | +plan("exe") = matlab.buildtool.Task(Inputs=srcs, Outputs=exes, Actions=@build_exe); |
| 31 | +plan("test").Dependencies = "exe"; |
| 32 | + |
22 | 33 | if ~isMATLABReleaseOlderThan("R2023b")
|
23 | 34 | plan("clean") = matlab.buildtool.tasks.CleanTask;
|
24 | 35 | end
|
25 | 36 |
|
26 |
| -plan("build_c") = matlab.buildtool.Task(Actions=@subprocess_build_c); |
27 |
| -plan("build_cpp") = matlab.buildtool.Task(Actions=@subprocess_build_cpp); |
28 |
| -plan("build_fortran") = matlab.buildtool.Task(Actions=@subprocess_build_fortran); |
29 |
| -plan("test").Dependencies = ["build_c", "build_cpp", "build_fortran"]; |
30 |
| - |
31 | 37 | if ~isMATLABReleaseOlderThan("R2024a")
|
32 | 38 | plan("check") = matlab.buildtool.tasks.CodeIssuesTask(pkg_name, IncludeSubfolders=true, ...
|
33 | 39 | WarningThreshold=0, Results="CodeIssues.sarif");
|
34 |
| - plan("coverage") = matlab.buildtool.tasks.TestTask(Description="code coverage", Dependencies="clean", SourceFiles="test", Strict=false, CodeCoverageResults="code-coverage.xml"); |
| 40 | + |
| 41 | + plan("coverage") = matlab.buildtool.tasks.TestTask(Description="code coverage", Dependencies="clean", SourceFiles="test", Strict=false, CodeCoverageResults="code-coverage.xml"); |
35 | 42 | end
|
36 | 43 |
|
37 | 44 | %% MexTask
|
|
51 | 58 | % name of MEX target function is name of first source file
|
52 | 59 | if isMATLABReleaseOlderThan("R2024b")
|
53 | 60 | mex_name = "mex_" + name;
|
54 |
| - % specifying .Inputs and .Outputs enables incremental builds |
55 |
| - % https://www.mathworks.com/help/matlab/matlab_prog/improve-performance-with-incremental-builds.html |
56 |
| - plan(mex_name) = matlab.buildtool.Task(Actions=@(context) legacy_mex(context, compiler_opt, linker_opt)); |
57 |
| - plan(mex_name).Inputs = src; |
58 |
| - plan(mex_name).Outputs = fullfile(bindir, name + "." + mexext()); |
| 61 | + plan(mex_name) = matlab.buildtool.Task(Inputs=src, Outputs=fullfile(bindir, name + "." + mexext()), ... |
| 62 | + Actions=@(context) legacy_mex(context, compiler_opt, linker_opt)); |
59 | 63 | mex_deps(end+1) = mex_name; %#ok<AGROW>
|
60 | 64 | else
|
61 | 65 | plan("mex:" + name) = matlab.buildtool.tasks.MexTask(src, bindir, ...
|
@@ -96,112 +100,89 @@ function publishTask(context)
|
96 | 100 | end
|
97 | 101 |
|
98 | 102 |
|
99 |
| -function subprocess_build_c(context) |
| 103 | +function build_exe(context) |
100 | 104 |
|
101 |
| -td = context.Plan.RootFolder + "/test"; |
102 |
| -src = td + "/stdout_stderr_c.c"; |
| 105 | +for i = 1:length(context.Task.Inputs) |
| 106 | + src = context.Task.Inputs(i); |
| 107 | + exe = context.Task.Outputs(i).paths; |
| 108 | + exe = exe(1); |
103 | 109 |
|
104 |
| -for s = src |
105 |
| - [~, n] = fileparts(s); |
106 |
| - exe = fullfile(td, n + ".exe"); |
107 |
| - if stdlib.get_modtime(s) < stdlib.get_modtime(exe) |
108 |
| - continue |
| 110 | + [~,~,ext] = fileparts(src.paths); |
| 111 | + switch ext |
| 112 | + case ".c", lang = "c"; |
| 113 | + case ".cpp", lang = "c++"; |
| 114 | + case ".f90", lang = "fortran"; |
| 115 | + otherwise, error("unknown code suffix " + ext) |
109 | 116 | end
|
110 | 117 |
|
111 |
| - cmd = get_build_cmd("c++", s); |
112 |
| - if isempty(cmd), return, end |
113 |
| - cmd = cmd + exe; |
114 |
| - disp(cmd) |
115 |
| - [r, m] = system(cmd); |
116 |
| - if r ~= 0 |
117 |
| - disp("failed to build TestSubprocess " + exe + " " + m) |
118 |
| - end |
119 |
| -end |
120 |
| - |
121 |
| -end |
122 |
| - |
123 |
| - |
124 |
| -function subprocess_build_cpp(context) |
125 |
| - |
126 |
| -td = context.Plan.RootFolder + "/test"; |
127 |
| -src = [td + "/sleep.cpp", td + "/stdin_cpp.cpp"]; |
| 118 | + [comp, shell, outFlag] = get_build_cmd(lang); |
| 119 | + if isempty(comp), return, end |
128 | 120 |
|
129 |
| -for s = src |
130 |
| - [~, n] = fileparts(s); |
131 |
| - exe = fullfile(td, n + ".exe"); |
132 |
| - if stdlib.get_modtime(s) < stdlib.get_modtime(exe) |
133 |
| - continue |
| 121 | + cmd = join([comp, src.paths, outFlag + exe]); |
| 122 | + if ~isempty(shell) |
| 123 | + cmd = join([shell, "&&", cmd]); |
134 | 124 | end
|
135 | 125 |
|
136 |
| - cmd = get_build_cmd("c++", s); |
137 |
| - if isempty(cmd), return, end |
138 |
| - cmd = cmd + exe; |
139 | 126 | disp(cmd)
|
140 |
| - [r, m] = system(cmd); |
141 |
| - if r ~= 0 |
142 |
| - disp("failed to build TestSubprocess " + exe + " " + m) |
143 |
| - end |
| 127 | + system(cmd); |
144 | 128 | end
|
145 | 129 |
|
146 | 130 | end
|
147 | 131 |
|
148 | 132 |
|
149 |
| -function subprocess_build_fortran(context) |
| 133 | +function [comp, shell] = get_compiler(lang) |
150 | 134 |
|
151 |
| -td = context.Plan.RootFolder + "/test"; |
152 |
| -src = [td + "/stdout_stderr_fortran.f90", td + "/stdin_fortran.f90"]; |
| 135 | +lang = lower(lang); |
153 | 136 |
|
154 |
| -for s = src |
155 |
| - [~, n] = fileparts(s); |
156 |
| - exe = fullfile(td, n + ".exe"); |
157 |
| - if stdlib.get_modtime(s) < stdlib.get_modtime(exe) |
158 |
| - continue |
| 137 | +co = mex.getCompilerConfigurations(lang); |
| 138 | + |
| 139 | +if isempty(co) |
| 140 | + switch lang |
| 141 | + case "fortran" |
| 142 | + comp = getenv("FC"); |
| 143 | + if isempty(comp) |
| 144 | + disp("set FC environment variable to the Fortran compiler path, or do 'mex -setup fortran'") |
| 145 | + end |
| 146 | + case "c++" |
| 147 | + comp = getenv("CXX"); |
| 148 | + if isempty(comp) |
| 149 | + disp("set CXX environment variable to the C++ compiler path, or do 'mex -setup c++") |
| 150 | + end |
| 151 | + case "c" |
| 152 | + comp = getenv("CC"); |
| 153 | + if isempty(comp) |
| 154 | + disp("set CC environment variable to the C compiler path, or do 'mex -setup c'") |
| 155 | + end |
| 156 | + otherwise, error("language not known " + lang) |
159 | 157 | end
|
| 158 | +else |
| 159 | + comp = co.Details.CompilerExecutable; |
| 160 | + disp(lang + " compiler: " + co.ShortName + " " + co.Name + " " + co.Version + " " + comp) |
| 161 | +end |
160 | 162 |
|
161 |
| - cmd = get_build_cmd("Fortran", s); |
162 |
| - if isempty(cmd), return, end |
163 |
| - cmd = cmd + exe; |
164 |
| - disp(cmd) |
165 |
| - [r, m] = system(cmd); |
166 |
| - if r ~= 0 |
167 |
| - disp("failed to build TestSubprocess " + exe + " " + m) |
| 163 | + |
| 164 | +shell = string.empty; |
| 165 | +if ispc |
| 166 | + disp("Shell: " + co.Details.CommandLineShell) |
| 167 | + if any(startsWith(co.ShortName, ["INTEL", "MSVC"])) |
| 168 | + shell = join([strcat('"',string(co.Details.CommandLineShell),'"'), ... |
| 169 | + co.Details.CommandLineShellArg], " "); |
168 | 170 | end
|
169 | 171 | end
|
170 | 172 |
|
171 | 173 | end
|
172 | 174 |
|
173 | 175 |
|
174 |
| -function cmd = get_build_cmd(lang, src) |
| 176 | +function [comp, shell, outFlag] = get_build_cmd(lang) |
175 | 177 |
|
176 |
| -cmd = string.empty; |
| 178 | +outFlag = "-o"; |
177 | 179 |
|
178 |
| -co = mex.getCompilerConfigurations(lang); |
179 |
| -if isempty(co) |
180 |
| - if lang == "Fortran" |
181 |
| - fc = getenv("FC"); |
182 |
| - if isempty(fc) |
183 |
| - disp("set FC environment variable to the Fortran compiler executable, or do 'mex -setup fortran' to configure the Fortran compiler") |
184 |
| - end |
185 |
| - end |
186 |
| - disp(lang + " compiler not found") |
187 |
| - return |
188 |
| -else |
189 |
| - comp = co.Details.CompilerExecutable; |
190 |
| -end |
| 180 | +[comp, shell] = get_compiler(lang); |
191 | 181 |
|
192 |
| -outFlag = "-o"; |
193 |
| -shell = string.empty; |
194 |
| -msvcLike = ispc && (contains(co.Name, "Visual Studio")); |
195 |
| -if msvcLike |
196 |
| - shell = join([strcat('"',string(co.Details.CommandLineShell),'"'), ... |
197 |
| - co.Details.CommandLineShellArg], " "); |
| 182 | +if ~isempty(shell) |
198 | 183 | outFlag = "/Fo" + tempdir + " /link /out:";
|
199 | 184 | end
|
200 | 185 |
|
201 |
| -cmd = join([comp, src, outFlag]); |
202 |
| -if ~isempty(shell) |
203 |
| - cmd = join([shell, "&&", cmd]); |
204 |
| -end |
205 | 186 |
|
206 | 187 | end
|
207 | 188 |
|
|
0 commit comments