@@ -30,67 +30,73 @@ function atmexall(varargin)
3030[fail ,varargs ]=getflag(varargs ,' -fail' );
3131force= ~miss_only ;
3232
33- atoptions= {[' -D' ,computer ]};
33+ atoptions= [varargs {[' -D' ,computer ]}] ;
3434
3535if isunix && ~ismac
3636 LIBDL= {' -ldl' };
3737else
3838 LIBDL= {};
3939end
4040
41- ompflags= {};
42- cflags= {};
41+ if isunix
42+ cflags= {' -std=c99' };
43+ compformat= ' CFLAGS="$CFLAGS %s "' ;
44+ linkformat= ' LDFLAGS="$LDFLAGS %s "' ;
45+ else
46+ cflags= {};
47+ compformat= ' COMPFLAGS="$COMPFLAGS %s "' ;
48+ linkformat= ' LINKFLAGS="$LINKFLAGS %s "' ;
49+ end
50+ cppflags= {};
4351ldflags= {};
52+
4453if openmp
4554 if ispc()
46- cflags= {' /openmp' };
55+ cflags= [cflags {' /openmp' }] ;
4756 ompflags= {};
4857 elseif ismac()
49- ompinc = select_omp();
50- cflags= {' -Xpreprocessor' , ' -fopenmp' };
51- ompflags= {ompinc ,...
52- sprintf(' -L"%s "' ,fullfile(matlabroot ,' sys' ,' os' ,computer(' arch' ))),...
53- ' -liomp5' };
58+ cflags= [cflags {' -Xpreprocessor' , ' -fopenmp' }];
59+ ompflags = select_omp();
5460 else
55- cflags= {' -fopenmp' };
61+ cflags= [cflags {' -fopenmp' }] ;
5662 ompflags= {...
5763 sprintf(' -L"%s "' ,fullfile(matlabroot ,' sys' ,' os' ,computer(' arch' ))),...
5864 ' -liomp5' };
5965 end
66+ else
67+ ompflags= {};
6068end
6169
70+ mexflags = make_flags(cflags , ldflags );
71+ mexcpp = make_flags(cppflags , ldflags );
6272if ispc()
63- ompoptions = pc_flags( ompflags , cflags , ldflags ) ;
64- map1 = pc_flags( ompflags , cflags , ldflags ) ;
73+ mapc = mexflags ;
74+ mapcpp = mexcpp ;
6575elseif ismac()
66- ompoptions= unix_flags(ompflags , cflags , ldflags );
67- map1= unix_flags(ompflags , cflags , ldflags , ' -Wl,-exported_symbols_list,' , ' trackFunctionMAC.map' );
68- map2= unix_flags(ompflags , cflags , ldflags , ' -Wl,-exported_symbols_list,' , ' passFunctionMAC.map' );
76+ mapc= make_flags(cflags , [ldflags {' -Wl,-exported_symbol,_trackFunction' }]);
77+ mapcpp= make_flags(cppflags , [ldflags {' -Wl,-exported_symbol,_trackFunction' }]);
6978else
70- ompoptions= unix_flags(ompflags , cflags , ldflags );
71- map1= unix_flags(ompflags , cflags , ldflags , ' -Wl,--version-script,' , ' mexFunctionGLNX86.map' );
79+ exportflag = sprintf(' VERSIONMAP="%s "' ,fullfile(pdir , ' mexFunctionGLNX86.mapext' ));
80+ mapc= [mexflags {exportflag , ' LINKEXPORT=""' }];
81+ mapcpp= [mexcpp {exportflag , ' LINKEXPORT=""' }];
7282end
7383
74- try
75- if ~verLessThan(' matlab' ,' 9.4' ) % >= R2018a
76- atoptions = [atoptions ,{' -R2018a' }];
77- elseif ~verLessThan(' matlab' ,' 7.11' ) % >= R2010b
78- atoptions = [atoptions ,{' -largeArrayDims' }];
79- end
80- if ~verLessThan(' matlab' ,' 8.3' ) % >= R2014a
81- atoptions = [atoptions ,{' -silent' }];
82- end
83- catch
84+ if ~verLessThan(' matlab' ,' 9.4' ) % >= R2018a
85+ atoptions = [atoptions ,{' -R2018a' }];
86+ elseif ~verLessThan(' matlab' ,' 7.11' ) % >= R2010b
87+ atoptions = [atoptions ,{' -largeArrayDims' }];
88+ end
89+ if ~verLessThan(' matlab' ,' 8.3' ) % >= R2014a
90+ atoptions = [atoptions ,{' -silent' }];
8491end
8592
8693lastwarn(' ' );
8794passinclude = [' -I' pdir ];
88- alloptions= [atoptions varargs ];
8995
9096% atpass
9197cdir= fullfile(atroot ,' attrack' ,' ' );
92- compile([alloptions , {passinclude }, LIBDL , ompoptions ], fullfile(cdir ,' atpass.c' ));
93- compile([atoptions , ompoptions ],fullfile(cdir ,' coptions.c' ))
98+ compile([atoptions , {passinclude }, LIBDL , mexflags , ompflags ], fullfile(cdir ,' atpass.c' ));
99+ compile([atoptions , mexflags , ompflags ],fullfile(cdir ,' coptions.c' ))
94100
95101[warnmess ,warnid ]=lastwarn ; % #ok<ASGLU>
96102if strcmp(warnid ,' MATLAB:mex:GccVersion_link' )
@@ -100,73 +106,65 @@ function atmexall(varargin)
100106
101107% Diffusion matrices
102108cdir= fullfile(atroot ,' atphysics' ,' Radiation' );
103- compile([alloptions , {passinclude }], fullfile(cdir ,' findmpoleraddiffmatrix.c' ));
104- compile([alloptions , {passinclude }], fullfile(cdir ,' FDW.c' ));
105- compile([alloptions , {passinclude }, LIBDL ], fullfile(cdir ,' diffusion_matrix.c' ));
109+ compile([atoptions , {passinclude }, mexflags ], fullfile(cdir ,' findmpoleraddiffmatrix.c' ));
110+ compile([atoptions , {passinclude }, mexflags ], fullfile(cdir ,' FDW.c' ));
111+ compile([atoptions , {passinclude }, LIBDL , mexflags ], fullfile(cdir ,' diffusion_matrix.c' ));
106112
107113% RDTs
108114cdir= fullfile(atroot ,' atphysics' ,' NonLinearDynamics' );
109- compile(alloptions , fullfile(cdir ,' RDTelegantAT.cpp' ));
115+ compile([ atoptions , mexcpp ] , fullfile(cdir ,' RDTelegantAT.cpp' ));
110116
111117% NAFF
112118cdir= fullfile(atroot ,' atphysics' ,' nafflib' );
113- compile(alloptions , fullfile(cdir ,' nafflib.c' ),...
114- fullfile(cdir ,' modnaff.c' ),...
115- fullfile(cdir ,' complexe.c' ));
119+ compile([ atoptions , mexflags ] , fullfile(cdir ,' nafflib.c' ),...
120+ fullfile(cdir ,' modnaff.c' ),...
121+ fullfile(cdir ,' complexe.c' ));
116122
117- % Find all files matching '*Pass.c' wildcard
118- cfiles = dir(fullfile(pdir ,' *Pass.c' ));
119- passmethods = {cfiles .name };
123+ % Passmethods
124+ cfiles = passcomp(pdir , ' *Pass.c' ,[atoptions , mapc , ompflags ]);
120125if ~c_only
121- % Find all files matching '*Pass.cc' wildcard
122- ccfiles = dir(fullfile(pdir , ' *Pass.cc' ));
123- passmethods = [passmethods ccfiles .name ];
126+ % Compile '*Pass.cc' methods
127+ ccfiles = passcomp(pdir , ' *Pass.cc' ,[atoptions , mapcpp , ompflags ]);
128+ else
129+ ccfiles= {};
124130end
125- % Eliminate invisible files
126- ok= cellfun(@(nm ) nm(1 )~=' .' ,passmethods ,' UniformOutput' ,false );
127- passmethods = passmethods(cell2mat(ok ));
131+
128132try
129- generate_passlist(pdir ,passmethods );
133+ generate_passlist(pdir ,[ cfiles ccfiles ] );
130134catch err
131135 fprintf(2 ,' \n Cannot generate the list of passmethods: %s\n\n ' , err .message );
132136end
133137
134- for i = 1 : length(passmethods )
135- PM = fullfile(pdir ,[passmethods{i }]);
136- if exist(PM ,' file' )
137- try
138- if exist(' map2' ,' var' )
139- try
140- compile([map1 , alloptions ], PM );
141- catch
142- compile([map2 , alloptions ], PM );
138+ warning(oldwarns .state ,oldwarns .identifier );
139+
140+ function meths = passcomp(pdir , pattern , compargs )
141+ meths = dir(fullfile(pdir ,pattern ));
142+ % Keep the names
143+ meths = {meths .name };
144+ % Discard hidden files
145+ meths = meths(cellfun(@(nm ) nm(1 )~=' .' ,meths ));
146+ for im= 1 : length(meths )
147+ pmeth = fullfile(pdir ,[meths{im }]);
148+ try
149+ compile(compargs , pmeth );
150+ catch errcomp
151+ if fail
152+ rethrow(err );
153+ else
154+ fprintf(2 , ' Could not compile %s :\n%s\n ' , pmeth , errcomp .message );
143155 end
144- else
145- compile([map1 , alloptions ], PM );
146- end
147- catch err
148- if fail
149- rethrow(err );
150- else
151- fprintf(2 , ' Could not compile %s :\n%s\n ' , PM , err .message );
152156 end
153157 end
154- else
155- if fail
156- error( ' AT:atmexall ' , ' %s not found \n ' , PM );
157- else
158- fprintf( 2 , ' %s not found, skip to next \n ' , PM );
158+ % Remove extension
159+ meths = cellfun(@ dpl , meths , ' UniformOutput ' , false );
160+
161+ function nm = dpl( fname )
162+ [ ~ , nm , ~ ] = fileparts( fname );
159163 end
160164 end
161- end
162165
163- warning(oldwarns .state ,oldwarns .identifier );
164166
165- function generate_passlist(pdir ,passmethods )
166- % Remove trailing '.c' or '.cc' from each passmethod using regexp
167- % Literally, replace dot plus any number of cs at the end of a
168- % passmethod with an empty string.
169- passmethodnames = cellfun(@(pass ) regexprep(pass , ' \.c*$' , ' ' ),passmethods , ' UniformOutput' , false );
167+ function generate_passlist(pdir ,passmethodnames )
170168 [fid ,msg ]=fopen(fullfile(pdir ,' passmethodlist.m' ),' wt' );
171169 if ~isempty(msg )
172170 error(msg );
@@ -179,40 +177,15 @@ function generate_passlist(pdir,passmethods)
179177 nbytes= cellfun(@(pass ) fprintf(fid ,' %s\n ' ,pass ),passmethodnames ); % #ok<NASGU>
180178 fprintf(fid ,' \n end\n ' );
181179 fclose(fid );
182- end
180+ end
183181
184- function flags = pc_flags(flags , cflags ,ldflags )
182+ function flags = make_flags(cflags , ldflags )
183+ flags = {};
185184 if ~isempty(ldflags )
186- flags= [{sprintf(' LINKFLAGS="$LINKFLAGS %s " ' ,strjoin(ldflags ))}, flags ];
185+ flags = [{sprintf(linkformat ,strjoin(ldflags ))} flags ];
187186 end
188187 if ~isempty(cflags )
189- flags= [{sprintf(' COMPFLAGS="$COMPFLAGS %s "' ,strjoin(cflags ))}, flags ];
190- end
191- end
192-
193-
194- function flags = unix_flags(flags , cflags , ldflags , exportarg , map )
195- if nargin > 3
196- mapfile= fullfile(pdir , map );
197- if verLessThan(' matlab' ,' 8.3' ) % R2008a < < R2014a
198- exp= sprintf([exportarg ' "%s "' ], mapfile );
199- def_ldflags= regexprep(mex .getCompilerConfigurations(' C' ).Details.LinkerFlags,[' \s(' exportarg ' )([^\s,]+)' ],' ' );
200- flags= [{sprintf(' LDFLAGS=%s ' ,strjoin([{def_ldflags }, ldflags , {exp }]))}, flags ];
201- ldflags = {};
202- elseif verLessThan(' matlab' ,' 9.1' ) % < R2016b
203- flags= [{sprintf(' LINKEXPORT=%s "%s "' ,exportarg ,mapfile )}, flags ];
204- else % >= R2016b
205- % Starting from R2016b, Matlab introduced a new entry point in MEX-files
206- % The "*.mapext" files defines this new entry point
207- flags= [{sprintf(' VERSIONMAP="''%s ext'' "' ,mapfile ),...
208- sprintf(' FUNCTIONMAP="''%s'' "' ,mapfile )}, flags ];
209- end
210- end
211- if ~isempty(ldflags )
212- flags = [{sprintf(' LDFLAGS="$LDFLAGS %s "' ,strjoin(ldflags ))} flags ];
213- end
214- if ~isempty(cflags )
215- flags= [{sprintf(' CFLAGS="$CFLAGS %s "' ,strjoin(cflags ))}, flags ];
188+ flags = [{sprintf(compformat ,strjoin(cflags ))} flags ];
216189 end
217190 end
218191
@@ -221,7 +194,6 @@ function compile(mexargs, varargin)
221194 target = strjoin({fullfile(fpath , fname ), mexext }, ' .' );
222195 if force || ~exist(target , ' file' ) || ...
223196 any(cellfun(@(f ) getdate(f ) > getdate(target ), varargin ))
224- % any(cellfun(@(f) dir(f).datenum > dir(target).datenum, varargin)) % Not accepted in R2016b
225197 disp([' mex ' ,strjoin([mexargs , {' -outdir' , fpath }, varargin ])]);
226198 mex(mexargs{: },' -outdir' , fpath , varargin{: });
227199 end
@@ -232,17 +204,28 @@ function compile(mexargs, varargin)
232204 end
233205 end
234206
235- function include = select_omp()
236- if exist(' /usr/local/include/omp.h' , ' file' ) % Homebrew
237- include= ' -I/usr/local/include' ;
207+ function flags = select_omp()
208+ arch= computer(' arch' );
209+ if strcmp(arch , ' maca64' )
210+ homeb= ' /opt/homebrew/opt/libomp/include' ;
211+ libdir= fullfile(matlabroot ,' bin' ,arch );
212+ libname= ' omp' ;
213+ else
214+ homeb= ' /usr/local/include' ;
215+ libdir= fullfile(matlabroot ,' sys' ,' os' ,arch );
216+ libname= ' iomp5' ;
217+ end
218+ if exist([homeb ' /omp.h' ], ' file' ) % Homebrew
219+ incdir= homeb ;
238220 elseif exist(' /opt/local/include/libomp/omp.h' , ' file' ) % MacPorts
239- include = ' -I /opt/local/include/libomp' ;
221+ incdir = ' /opt/local/include/libomp' ;
240222 else
241223 error(' AT:MissingLibrary' , strjoin({' ' , ...
242224 ' libomp.dylib must be installed with your favourite package manager:' , ' ' , ...
243225 ' Use "$ brew install libomp"' , ...
244226 ' Or "$ sudo port install libomp"' ...
245227 }, ' \n ' ));
246228 end
229+ flags= {[' -I' incdir ], sprintf(' -L"%s "' ,libdir ),[' -l' libname ]};
247230 end
248231end
0 commit comments