@@ -30,67 +30,73 @@ function atmexall(varargin)
30
30
[fail ,varargs ]=getflag(varargs ,' -fail' );
31
31
force= ~miss_only ;
32
32
33
- atoptions= {[' -D' ,computer ]};
33
+ atoptions= [varargs {[' -D' ,computer ]}] ;
34
34
35
35
if isunix && ~ismac
36
36
LIBDL= {' -ldl' };
37
37
else
38
38
LIBDL= {};
39
39
end
40
40
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= {};
43
51
ldflags= {};
52
+
44
53
if openmp
45
54
if ispc()
46
- cflags= {' /openmp' };
55
+ cflags= [cflags {' /openmp' }] ;
47
56
ompflags= {};
48
57
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();
54
60
else
55
- cflags= {' -fopenmp' };
61
+ cflags= [cflags {' -fopenmp' }] ;
56
62
ompflags= {...
57
63
sprintf(' -L"%s "' ,fullfile(matlabroot ,' sys' ,' os' ,computer(' arch' ))),...
58
64
' -liomp5' };
59
65
end
66
+ else
67
+ ompflags= {};
60
68
end
61
69
70
+ mexflags = make_flags(cflags , ldflags );
71
+ mexcpp = make_flags(cppflags , ldflags );
62
72
if ispc()
63
- ompoptions = pc_flags( ompflags , cflags , ldflags ) ;
64
- map1 = pc_flags( ompflags , cflags , ldflags ) ;
73
+ mapc = mexflags ;
74
+ mapcpp = mexcpp ;
65
75
elseif 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' }]);
69
78
else
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=""' }];
72
82
end
73
83
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' }];
84
91
end
85
92
86
93
lastwarn(' ' );
87
94
passinclude = [' -I' pdir ];
88
- alloptions= [atoptions varargs ];
89
95
90
96
% atpass
91
97
cdir= 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' ))
94
100
95
101
[warnmess ,warnid ]=lastwarn ; % #ok<ASGLU>
96
102
if strcmp(warnid ,' MATLAB:mex:GccVersion_link' )
@@ -100,73 +106,65 @@ function atmexall(varargin)
100
106
101
107
% Diffusion matrices
102
108
cdir= 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' ));
106
112
107
113
% RDTs
108
114
cdir= fullfile(atroot ,' atphysics' ,' NonLinearDynamics' );
109
- compile(alloptions , fullfile(cdir ,' RDTelegantAT.cpp' ));
115
+ compile([ atoptions , mexcpp ] , fullfile(cdir ,' RDTelegantAT.cpp' ));
110
116
111
117
% NAFF
112
118
cdir= 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' ));
116
122
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 ]);
120
125
if ~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= {};
124
130
end
125
- % Eliminate invisible files
126
- ok= cellfun(@(nm ) nm(1 )~=' .' ,passmethods ,' UniformOutput' ,false );
127
- passmethods = passmethods(cell2mat(ok ));
131
+
128
132
try
129
- generate_passlist(pdir ,passmethods );
133
+ generate_passlist(pdir ,[ cfiles ccfiles ] );
130
134
catch err
131
135
fprintf(2 ,' \n Cannot generate the list of passmethods: %s\n\n ' , err .message );
132
136
end
133
137
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 );
143
155
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 );
152
156
end
153
157
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 );
159
163
end
160
164
end
161
- end
162
165
163
- warning(oldwarns .state ,oldwarns .identifier );
164
166
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 )
170
168
[fid ,msg ]=fopen(fullfile(pdir ,' passmethodlist.m' ),' wt' );
171
169
if ~isempty(msg )
172
170
error(msg );
@@ -179,40 +177,15 @@ function generate_passlist(pdir,passmethods)
179
177
nbytes= cellfun(@(pass ) fprintf(fid ,' %s\n ' ,pass ),passmethodnames ); % #ok<NASGU>
180
178
fprintf(fid ,' \n end\n ' );
181
179
fclose(fid );
182
- end
180
+ end
183
181
184
- function flags = pc_flags(flags , cflags ,ldflags )
182
+ function flags = make_flags(cflags , ldflags )
183
+ flags = {};
185
184
if ~isempty(ldflags )
186
- flags= [{sprintf(' LINKFLAGS="$LINKFLAGS %s " ' ,strjoin(ldflags ))}, flags ];
185
+ flags = [{sprintf(linkformat ,strjoin(ldflags ))} flags ];
187
186
end
188
187
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 ];
216
189
end
217
190
end
218
191
@@ -221,7 +194,6 @@ function compile(mexargs, varargin)
221
194
target = strjoin({fullfile(fpath , fname ), mexext }, ' .' );
222
195
if force || ~exist(target , ' file' ) || ...
223
196
any(cellfun(@(f ) getdate(f ) > getdate(target ), varargin ))
224
- % any(cellfun(@(f) dir(f).datenum > dir(target).datenum, varargin)) % Not accepted in R2016b
225
197
disp([' mex ' ,strjoin([mexargs , {' -outdir' , fpath }, varargin ])]);
226
198
mex(mexargs{: },' -outdir' , fpath , varargin{: });
227
199
end
@@ -232,17 +204,30 @@ function compile(mexargs, varargin)
232
204
end
233
205
end
234
206
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 ;
238
220
elseif exist(' /opt/local/include/libomp/omp.h' , ' file' ) % MacPorts
239
- include= ' -I/opt/local/include/libomp' ;
221
+ incdir= ' /opt/local/include/libomp' ;
222
+ libdir= ' /opt/local/lib' ;
223
+ libname= ' omp' ;
240
224
else
241
225
error(' AT:MissingLibrary' , strjoin({' ' , ...
242
226
' libomp.dylib must be installed with your favourite package manager:' , ' ' , ...
243
227
' Use "$ brew install libomp"' , ...
244
228
' Or "$ sudo port install libomp"' ...
245
229
}, ' \n ' ));
246
230
end
231
+ flags= {[' -I' incdir ], sprintf(' -L"%s "' ,libdir ),[' -l' libname ]};
247
232
end
248
233
end
0 commit comments