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,29 @@ 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 ).paths;
109+ exe = exe(1 );
135110
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 )
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 )
143117 end
144- end
145118
146- end
119+ [comp , shell , outFlag ] = get_build_cmd(lang );
120+ if isempty(comp ), return , end
147121
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
122+ cmd = join([comp , src .paths , outFlag + exe ]);
123+ if ~isempty(shell )
124+ cmd = join([shell , " &&" , cmd ]);
159125 end
160126
161- cmd = get_build_cmd(" Fortran" , s );
162- if isempty(cmd ), return , end
163- cmd = cmd + exe ;
164127 disp(cmd )
165128 [r , m ] = system(cmd );
166129 if r ~= 0
@@ -171,38 +134,56 @@ function subprocess_build_fortran(context)
171134end
172135
173136
174- function cmd = get_build_cmd (lang , src )
137+ function [ comp , shell ] = get_compiler (lang )
175138
176- cmd = string . empty ;
139+ lang = lower( lang ) ;
177140
178141co = mex .getCompilerConfigurations(lang );
142+
179143if 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
144+ switch lang
145+ case " fortran"
146+ comp = getenv(" FC" );
147+ if isempty(comp )
148+ disp(" set FC environment variable to the Fortran compiler path, or do 'mex -setup fortran'" )
149+ end
150+ case " c++"
151+ comp = getenv(" CXX" );
152+ if isempty(comp )
153+ disp(" set CXX environment variable to the C++ compiler path, or do 'mex -setup c++" )
154+ end
155+ case " c"
156+ comp = getenv(" CC" );
157+ if isempty(comp )
158+ disp(" set CC environment variable to the C compiler path, or do 'mex -setup c'" )
159+ end
160+ otherwise , error(" language not known " + lang )
185161 end
186- disp(lang + " compiler not found" )
187- return
188162else
189163 comp = co .Details .CompilerExecutable ;
190164end
191165
192- outFlag = " -o" ;
193- shell = string .empty ;
194- msvcLike = ispc && (contains(co .Name , " Visual Studio" ));
195- if msvcLike
166+ if ispc && contains(co .Name , " Visual Studio" )
196167 shell = join([strcat(' "' ,string(co .Details .CommandLineShell ),' "' ), ...
197168 co .Details .CommandLineShellArg ], " " );
198- outFlag = " /Fo" + tempdir + " /link /out:" ;
169+ else
170+ shell = string .empty ;
171+ end
172+
199173end
200174
201- cmd = join([comp , src , outFlag ]);
175+
176+ function [comp , shell , outFlag ] = get_build_cmd(lang )
177+
178+ outFlag = " -o" ;
179+
180+ [comp , shell ] = get_compiler(lang );
181+
202182if ~isempty(shell )
203- cmd = join([ shell , " && " , cmd ]) ;
183+ outFlag = " /Fo " + tempdir + " /link /out: " ;
204184end
205185
186+
206187end
207188
208189
0 commit comments