2323 plan(" clean" ) = matlab .buildtool .tasks .CleanTask ;
2424end
2525
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-
3126if ~isMATLABReleaseOlderThan(" R2024a" )
3227 plan(" check" ) = matlab .buildtool .tasks .CodeIssuesTask(pkg_name , IncludeSubfolders= true , ...
3328 WarningThreshold= 0 , Results= " CodeIssues.sarif" );
4237 % dummy task to allow "buildtool mex" to build all MEX targets
4338 plan(" mex" ) = matlab .buildtool .Task();
4439 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" ;
4553end
4654
4755for s = get_mex_sources()
5159 % name of MEX target function is name of first source file
5260 if isMATLABReleaseOlderThan(" R2024b" )
5361 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 ));
5964 mex_deps(end + 1 ) = mex_name ; % #ok<AGROW>
6065 else
6166 plan(" mex:" + name ) = matlab .buildtool .tasks .MexTask(src , bindir , ...
@@ -96,71 +101,24 @@ function publishTask(context)
96101end
97102
98103
99- function subprocess_build_c(context )
100-
101- td = context .Plan .RootFolder + " /test" ;
102- src = td + " /stdout_stderr_c.c" ;
103-
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
109- end
110-
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 )
104+ function build_exe(context )
125105
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
134- end
106+ for i = 1 : length(context .Task .Inputs )
107+ src = context .Task .Inputs(i );
108+ exe = context .Task .Outputs(i );
135109
136- cmd = get_build_cmd(" c++" , s );
137- if isempty(cmd ), return , end
138- cmd = cmd + exe ;
139- disp(cmd )
140- [r , m ] = system(cmd );
141- if r ~= 0
142- disp(" failed to build TestSubprocess " + exe + " " + m )
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 )
143116 end
144- end
145117
146- end
147-
148-
149- function subprocess_build_fortran(context )
150-
151- td = context .Plan .RootFolder + " /test" ;
152- src = [td + " /stdout_stderr_fortran.f90" , td + " /stdin_fortran.f90" ];
153-
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
159- end
118+ [comp , outFlag ] = get_build_cmd(lang );
119+ if isempty(comp ), return , end
160120
161- cmd = get_build_cmd(" Fortran" , s );
162- if isempty(cmd ), return , end
163- cmd = cmd + exe ;
121+ cmd = join([comp , src .paths , outFlag + exe .paths ]);
164122 disp(cmd )
165123 [r , m ] = system(cmd );
166124 if r ~= 0
@@ -171,38 +129,58 @@ function subprocess_build_fortran(context)
171129end
172130
173131
174- function cmd = get_build_cmd (lang , src )
132+ function [ comp , shell ] = get_compiler (lang )
175133
176- cmd = string . empty ;
134+ lang = lower( lang ) ;
177135
178136co = mex .getCompilerConfigurations(lang );
137+
179138if 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
139+ switch lang
140+ case " fortran"
141+ comp = getenv(" FC" );
142+ if isempty(comp )
143+ disp(" set FC environment variable to the Fortran compiler path, or do 'mex -setup fortran'" )
144+ end
145+ case " c++"
146+ comp = getenv(" CXX" );
147+ if isempty(comp )
148+ disp(" set CXX environment variable to the C++ compiler path, or do 'mex -setup c++" )
149+ end
150+ case " c"
151+ comp = getenv(" CC" );
152+ if isempty(comp )
153+ disp(" set CC environment variable to the C compiler path, or do 'mex -setup c'" )
154+ end
155+ otherwise , error(" language not known " + lang )
185156 end
186- disp(lang + " compiler not found" )
187- return
188157else
189158 comp = co .Details .CompilerExecutable ;
190159end
191160
192- outFlag = " -o" ;
193- shell = string .empty ;
194- msvcLike = ispc && (contains(co .Name , " Visual Studio" ));
195- if msvcLike
161+ if ispc && contains(co .Name , " Visual Studio" )
196162 shell = join([strcat(' "' ,string(co .Details .CommandLineShell ),' "' ), ...
197163 co .Details .CommandLineShellArg ], " " );
198- outFlag = " /Fo" + tempdir + " /link /out:" ;
164+ else
165+ shell = string .empty ;
199166end
200167
201- cmd = join([comp , src , outFlag ]);
168+ end
169+
170+
171+ function [comp , outFlag ] = get_build_cmd(lang )
172+
173+ outFlag = " -o" ;
174+
175+ [comp , shell ] = get_compiler(lang );
176+ if isempty(comp ), return , end
177+
202178if ~isempty(shell )
203- cmd = join([shell , " &&" , cmd ]);
179+ comp = join([shell , " &&" , comp ]);
204180end
205181
182+ outFlag = " /Fo" + tempdir + " /link /out:" ;
183+
206184end
207185
208186
0 commit comments