@@ -197,6 +197,182 @@ def test_user_options(self):
197
197
198
198
tmp .cleanup ()
199
199
200
+ def test_user_alias (self ):
201
+ """Check that we import user-defined aliases"""
202
+ tmp = tempfile .TemporaryDirectory ()
203
+ path = Path (tmp .name )
204
+ os .chdir (tmp .name )
205
+ os .mkdir (".cbi" )
206
+ with open (path / ".cbi" / "config" , mode = "w" ) as f :
207
+ f .write ('[compiler."c++"]\n ' )
208
+ f .write ('alias_of = "clang"\n ' )
209
+ config ._load_compilers ()
210
+
211
+ parser = ArgumentParser ("c++" )
212
+ passes = parser .parse_args (["-fopenmp" , "test.cpp" ])
213
+
214
+ self .assertEqual (len (passes ), 1 )
215
+ self .assertCountEqual (passes [0 ].defines , ["_OPENMP" ])
216
+
217
+ tmp .cleanup ()
218
+
219
+ def test_nested_aliases (self ):
220
+ """Check that we handle user-defined aliases to aliases"""
221
+ tmp = tempfile .TemporaryDirectory ()
222
+ path = Path (tmp .name )
223
+ os .chdir (tmp .name )
224
+ os .mkdir (".cbi" )
225
+ with open (path / ".cbi" / "config" , mode = "w" ) as f :
226
+ f .write ('[compiler."c++"]\n ' )
227
+ f .write ('alias_of = "g++"\n ' )
228
+ config ._load_compilers ()
229
+
230
+ parser = ArgumentParser ("c++" )
231
+ passes = parser .parse_args (["-fopenmp" , "test.cpp" ])
232
+
233
+ self .assertEqual (len (passes ), 1 )
234
+ self .assertCountEqual (passes [0 ].defines , ["_OPENMP" ])
235
+
236
+ tmp .cleanup ()
237
+
238
+ def test_alias_loops (self ):
239
+ """Check that we identify and complain about alias loops"""
240
+ tmp = tempfile .TemporaryDirectory ()
241
+ path = Path (tmp .name )
242
+ os .chdir (tmp .name )
243
+ os .mkdir (".cbi" )
244
+ with open (path / ".cbi" / "config" , mode = "w" ) as f :
245
+ f .write ("[compiler.foo]\n " )
246
+ f .write ('alias_of = "bar"\n ' )
247
+ f .write ("[compiler.bar]\n " )
248
+ f .write ('alias_of = "foo"\n ' )
249
+ config ._load_compilers ()
250
+
251
+ logging .disable (logging .NOTSET )
252
+ with self .assertLogs ("codebasin" , level = logging .ERROR ):
253
+ _ = ArgumentParser ("foo" )
254
+ logging .disable ()
255
+
256
+ tmp .cleanup ()
257
+
258
+ def test_user_parser (self ):
259
+ """Check that we import user-defined parser"""
260
+ tmp = tempfile .TemporaryDirectory ()
261
+ path = Path (tmp .name )
262
+ os .chdir (tmp .name )
263
+ os .mkdir (".cbi" )
264
+ with open (path / ".cbi" / "config" , mode = "w" ) as f :
265
+ f .write ('[[compiler."c++".parser]]\n ' )
266
+ f .write ('flags = ["-fasdf"]\n ' )
267
+ f .write ('action = "append_const"\n ' )
268
+ f .write ('dest = "passes"\n ' )
269
+ f .write ('const = "asdf-pass"\n ' )
270
+ f .write ('[[compiler."c++".modes]]\n ' )
271
+ f .write ('name = "asdf-mode"\n ' )
272
+ f .write ('defines = ["ASDF"]\n ' )
273
+ f .write ('[[compiler."c++".passes]]\n ' )
274
+ f .write ('name = "asdf-pass"\n ' )
275
+ f .write ('modes = ["asdf-mode"]\n ' )
276
+
277
+ config ._load_compilers ()
278
+
279
+ parser = ArgumentParser ("c++" )
280
+ passes = parser .parse_args (["-fasdf" , "test.cpp" ])
281
+
282
+ self .assertEqual (len (passes ), 2 )
283
+ pass_names = {p .pass_name for p in passes }
284
+ self .assertCountEqual (pass_names , {"default" , "asdf-pass" })
285
+
286
+ for p in passes :
287
+ if p .pass_name == "default" :
288
+ expected = []
289
+ elif p .pass_name == "asdf-pass" :
290
+ expected = ["ASDF" ]
291
+ self .assertCountEqual (p .defines , expected )
292
+
293
+ tmp .cleanup ()
294
+
295
+ def test_user_overrides (self ):
296
+ """Check that we can merge user-defined overrides"""
297
+ tmp = tempfile .TemporaryDirectory ()
298
+ path = Path (tmp .name )
299
+ os .chdir (tmp .name )
300
+ os .mkdir (".cbi" )
301
+ with open (path / ".cbi" / "config" , mode = "w" ) as f :
302
+ f .write ('[[compiler."g++".parser]]\n ' )
303
+ f .write ('flags = ["-fopenmp"]\n ' )
304
+ f .write ('action = "append_const"\n ' )
305
+ f .write ('dest = "passes"\n ' )
306
+ f .write ('const = "new-openmp-pass"\n ' )
307
+ f .write ("\n " )
308
+ f .write ('[[compiler."g++".passes]]\n ' )
309
+ f .write ('name = "new-openmp-pass"\n ' )
310
+ f .write ('modes = ["new-openmp-mode"]\n ' )
311
+ f .write ("\n " )
312
+ f .write ('[[compiler."g++".modes]]\n ' )
313
+ f .write ('name = "new-openmp-mode"\n ' )
314
+ f .write ('defines = ["_NEW_OPENMP"]\n ' )
315
+ f .write ("\n " )
316
+ f .write ('[compiler."g++"]\n ' )
317
+ f .write ('options = ["-D", "EXTRA_DEFINE"]\n ' )
318
+ f .write ("\n " )
319
+ f .write ("[[compiler.clang.modes]]\n " )
320
+ f .write ('name = "openmp"\n ' )
321
+ f .write ("defines = []\n " )
322
+ f .write ("\n " )
323
+ f .write ("[[compiler.icx.passes]]\n " )
324
+ f .write ('name = "sycl-spir64"\n ' )
325
+ f .write ("defines = []\n " )
326
+ f .write ("\n " )
327
+ f .write ("[compiler.nvcc]\n " )
328
+ f .write ('alias_of = "unknown"\n ' )
329
+
330
+ # Verify that the correct warnings are generated when loading the file.
331
+ logging .disable (logging .NOTSET )
332
+ with self .assertLogs ("codebasin" , level = logging .WARNING ) as cm :
333
+ config ._load_compilers ()
334
+ logging .disable ()
335
+
336
+ self .assertEqual (
337
+ cm .output ,
338
+ [
339
+ "WARNING:codebasin.config:definition of g++ in .cbi/config overrides alias." ,
340
+ "WARNING:codebasin.config:compiler mode 'openmp' redefined" ,
341
+ "WARNING:codebasin.config:compiler pass 'sycl-spir64' redefined" ,
342
+ "WARNING:codebasin.config:nvcc redefined as alias of unknown." ,
343
+ ],
344
+ )
345
+
346
+ # Verify that user-defined overrides affect passes, etc.
347
+ parser = ArgumentParser ("g++" )
348
+ argv = ["-fopenmp" ]
349
+ passes = parser .parse_args (argv )
350
+
351
+ pass_names = {p .pass_name for p in passes }
352
+ self .assertCountEqual (pass_names , {"default" , "new-openmp-pass" })
353
+
354
+ for p in passes :
355
+ if p .pass_name == "default" :
356
+ expected = ["EXTRA_DEFINE" ]
357
+ else :
358
+ expected = ["EXTRA_DEFINE" , "_NEW_OPENMP" ]
359
+ self .assertCountEqual (p .defines , expected )
360
+
361
+ # Verify that invalid aliases are identified.
362
+ logging .disable (logging .NOTSET )
363
+ with self .assertLogs ("codebasin" , level = logging .ERROR ) as cm :
364
+ _ = ArgumentParser ("nvcc" )
365
+ logging .disable ()
366
+
367
+ self .assertEqual (
368
+ cm .output ,
369
+ [
370
+ "ERROR:codebasin.config:Compiler 'nvcc' aliases unrecognized 'unknown'." ,
371
+ ],
372
+ )
373
+
374
+ tmp .cleanup ()
375
+
200
376
201
377
if __name__ == "__main__" :
202
378
unittest .main ()
0 commit comments