|
23 | 23 | plan("clean") = matlab.buildtool.tasks.CleanTask; |
24 | 24 | end |
25 | 25 |
|
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 | 26 | if ~isMATLABReleaseOlderThan("R2024a") |
32 | 27 | plan("check") = matlab.buildtool.tasks.CodeIssuesTask(pkg_name, IncludeSubfolders=true, ... |
33 | 28 | WarningThreshold=0, Results="CodeIssues.sarif"); |
|
42 | 37 | % dummy task to allow "buildtool mex" to build all MEX targets |
43 | 38 | plan("mex") = matlab.buildtool.Task(); |
44 | 39 | mex_deps = string.empty; |
| 40 | +else |
| 41 | + td = plan.RootFolder + "/test"; |
| 42 | + |
| 43 | + plan("exe:c") = matlab.buildtool.Task(Inputs=td+"/stdout_stderr_c.c", ... |
| 44 | + Outputs=td+"/stdout_stderr_c.exe", Actions=@build_exe); |
| 45 | + |
| 46 | + plan("exe:cpp") = matlab.buildtool.Task(Inputs=td+"/stdin_cpp.cpp",... |
| 47 | + Outputs=td+"/stdin_cpp.exe", Actions=@build_exe); |
| 48 | + |
| 49 | + plan("exe:fortran") = matlab.buildtool.Task(Inputs=[td + "/stdout_stderr_fortran.f90", td + "/stdin_fortran.f90"],... |
| 50 | + Outputs=[td+"/stdout_stderr_fortran.exe", td+"/stdin_fortran.exe"], Actions=@build_exe); |
| 51 | + |
| 52 | + plan("test").Dependencies = "exe"; |
45 | 53 | end |
46 | 54 |
|
47 | 55 | for s = get_mex_sources() |
|
51 | 59 | % name of MEX target function is name of first source file |
52 | 60 | if isMATLABReleaseOlderThan("R2024b") |
53 | 61 | 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()); |
| 62 | + plan(mex_name) = matlab.buildtool.Task(Inputs=src, Outputs=fullfile(bindir, name + "." + mexext()), ... |
| 63 | + Actions=@(context) legacy_mex(context, compiler_opt, linker_opt)); |
59 | 64 | mex_deps(end+1) = mex_name; %#ok<AGROW> |
60 | 65 | else |
61 | 66 | plan("mex:" + name) = matlab.buildtool.tasks.MexTask(src, bindir, ... |
@@ -96,112 +101,89 @@ function publishTask(context) |
96 | 101 | end |
97 | 102 |
|
98 | 103 |
|
99 | | -function subprocess_build_c(context) |
| 104 | +function build_exe(context) |
100 | 105 |
|
101 | | -td = context.Plan.RootFolder + "/test"; |
102 | | -src = td + "/stdout_stderr_c.c"; |
| 106 | +for i = 1:length(context.Task.Inputs) |
| 107 | + src = context.Task.Inputs(i); |
| 108 | + exe = context.Task.Outputs(i).paths; |
| 109 | + exe = exe(1); |
103 | 110 |
|
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 |
| 111 | + [~,~,ext] = fileparts(src.paths); |
| 112 | + switch ext |
| 113 | + case ".c", lang = "c"; |
| 114 | + case ".cpp", lang = "c++"; |
| 115 | + case ".f90", lang = "fortran"; |
| 116 | + otherwise, error("unknown code suffix " + ext) |
109 | 117 | end |
110 | 118 |
|
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 |
| 119 | + [comp, shell, outFlag] = get_build_cmd(lang); |
| 120 | + if isempty(comp), return, end |
120 | 121 |
|
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"]; |
128 | | - |
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 |
| 122 | + cmd = join([comp, src.paths, outFlag + exe]); |
| 123 | + if ~isempty(shell) |
| 124 | + cmd = join([shell, "&&", cmd]); |
134 | 125 | end |
135 | 126 |
|
136 | | - cmd = get_build_cmd("c++", s); |
137 | | - if isempty(cmd), return, end |
138 | | - cmd = cmd + exe; |
139 | 127 | disp(cmd) |
140 | | - [r, m] = system(cmd); |
141 | | - if r ~= 0 |
142 | | - disp("failed to build TestSubprocess " + exe + " " + m) |
143 | | - end |
| 128 | + system(cmd); |
144 | 129 | end |
145 | 130 |
|
146 | 131 | end |
147 | 132 |
|
148 | 133 |
|
149 | | -function subprocess_build_fortran(context) |
| 134 | +function [comp, shell] = get_compiler(lang) |
150 | 135 |
|
151 | | -td = context.Plan.RootFolder + "/test"; |
152 | | -src = [td + "/stdout_stderr_fortran.f90", td + "/stdin_fortran.f90"]; |
| 136 | +lang = lower(lang); |
153 | 137 |
|
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 |
| 138 | +co = mex.getCompilerConfigurations(lang); |
| 139 | + |
| 140 | +if isempty(co) |
| 141 | + switch lang |
| 142 | + case "fortran" |
| 143 | + comp = getenv("FC"); |
| 144 | + if isempty(comp) |
| 145 | + error("set FC environment variable to the Fortran compiler path, or do 'mex -setup fortran'") |
| 146 | + end |
| 147 | + case "c++" |
| 148 | + comp = getenv("CXX"); |
| 149 | + if isempty(comp) |
| 150 | + error("set CXX environment variable to the C++ compiler path, or do 'mex -setup c++") |
| 151 | + end |
| 152 | + case "c" |
| 153 | + comp = getenv("CC"); |
| 154 | + if isempty(comp) |
| 155 | + error("set CC environment variable to the C compiler path, or do 'mex -setup c'") |
| 156 | + end |
| 157 | + otherwise, error("language not known " + lang) |
159 | 158 | end |
| 159 | +else |
| 160 | + comp = co.Details.CompilerExecutable; |
| 161 | + disp(lang + " compiler: " + co.Name + " " + co.Version + " " + comp) |
| 162 | +end |
160 | 163 |
|
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) |
| 164 | + |
| 165 | +shell = string.empty; |
| 166 | +if ispc |
| 167 | + disp("Shell: " + co.Details.CommandLineShell) |
| 168 | + if contains(co.Name, "Visual Studio") |
| 169 | + shell = join([strcat('"',string(co.Details.CommandLineShell),'"'), ... |
| 170 | + co.Details.CommandLineShellArg], " "); |
168 | 171 | end |
169 | 172 | end |
170 | 173 |
|
171 | 174 | end |
172 | 175 |
|
173 | 176 |
|
174 | | -function cmd = get_build_cmd(lang, src) |
| 177 | +function [comp, shell, outFlag] = get_build_cmd(lang) |
175 | 178 |
|
176 | | -cmd = string.empty; |
| 179 | +outFlag = "-o"; |
177 | 180 |
|
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 |
| 181 | +[comp, shell] = get_compiler(lang); |
191 | 182 |
|
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], " "); |
| 183 | +if ~isempty(shell) |
198 | 184 | outFlag = "/Fo" + tempdir + " /link /out:"; |
199 | 185 | end |
200 | 186 |
|
201 | | -cmd = join([comp, src, outFlag]); |
202 | | -if ~isempty(shell) |
203 | | - cmd = join([shell, "&&", cmd]); |
204 | | -end |
205 | 187 |
|
206 | 188 | end |
207 | 189 |
|
|
0 commit comments