简体   繁体   中英

How to determine which compiler was requested

My project uses SCons to manage the build process. I want to support multiple compilers, so I decided to use AddOption so the user can specify which compiler to use on the command line (with the default being whatever their current compiler is).

AddOption('--compiler', dest = 'compiler', type = 'string', action = 'store', default = DefaultEnvironment()['CXX'], help = 'Name of the compiler to use.')

I want to be able to have built-in compiler settings for various compilers (including things such as maximum warning levels for that particular compiler). This is what my first attempt at a solution currently looks like:

if is_compiler('g++'):
    from build_scripts.gcc.std import cxx_std
    from build_scripts.gcc.warnings import warnings, warnings_debug, warnings_optimized
    from build_scripts.gcc.optimizations import optimizations, preprocessor_optimizations, linker_optimizations
elif is_compiler('clang++'):
    from build_scripts.clang.std import cxx_std
    from build_scripts.clang.warnings import warnings, warnings_debug, warnings_optimized
    from build_scripts.clang.optimizations import optimizations, preprocessor_optimizations, linker_optimizations

However, I'm not sure what to make the is_compiler() function look like. My first thought was to directly compare the compiler name (such as 'clang++') against what the user passes in. However, this immediately failed when I tried to use scons --compiler=~/data/llvm-3.1-obj/Release+Asserts/bin/clang++ .

So I thought I'd get a little smarter and use this function

cxx = GetOption('compiler')
def is_compiler (compiler):
    return cxx[-len(compiler):] == compiler

This only looks at the end of the compiler string, so that it ignores directories. Unfortunately, 'clang++' ends in 'g++', so my compiler was seen to be g++ instead of clang++.

My next thought was to do a backward search and look for the first occurrence of a path separator ('\\' or '/'), but then I realized that this won't work for people who have multiple compiler versions. Someone compiling with 'g++-4.7' will not register as being g++.

So, is there some simple way to determine which compiler was requested?

Currently, only g++ and clang++ are supported (and only their most recently released versions) due to their c++11 support, so a solution that only works for those two would be good enough for now. However, my ultimate goal is to support at least g++, clang++, icc, and msvc++ (once they support the required c++11 features), so more general solutions are preferred.

Compiler just are part of build process. Also you need linker tool and may be other additional programs. In Scons it's named - Tool. List of tools supported from box you can see in man page , search by statement: SCons supports the following tool specifications out of the box: ... Tool set necessary scons environment variables, it's documented here .

Scons automatically detects compiler in OS and have some priority to choose one of them, of course autodetect will work properly if PATH variable set to necessary dirs. For example of you have msvc and mingw on windows, scons choose msvc tool. For force using tool use Tool('name')(env). For example:

env = Environment()
Tool('mingw')(env)

Now env force using mingw.

So, clang is one of tool which currently not supported from box by scons. You need to implement it, or set env vars such CC, CXX which using scons for generate build commands.

You could just simply use the Python os.path.basename() or os.path.split() functions, as specified here .

You could do what people suggested in the comments by splitting this question into 2 different issues, but I think it could be a good idea to be able to specify the path with the compiler, since you could have 2 versions of g++ installed, and if the user only specifies g++, they may not get the expected version.

This question led to the development of a SCons project that can handle this:

https://bitbucket.org/davidstone/scons-template/

The relevant code is in build_scripts/compiler_settings.py . The SCons options are set up in the SConstruct file with the following lines:

AddOption('--compiler', dest = 'compiler', type = 'string', action = 'store', help = 'Name of the compiler to use.')
AddOption('--compiler-command', dest = 'compiler_command', type = 'string', action = 'store', help = 'Command to launch the compiler.')

The user can specify 0, 1, or 2 command-line options.

If you don't specify anything ( scons ), then it builds with the compiler from the DefaultEnvironment.

You can optionally specify the name of the compiler ( scons --compiler=g++ ). My script then assumes that the command used to compile is the same as the name.

You can also optionally specify the command to compile ( scons --compiler-command=~/llvm-3.1-obj/Release+Asserts/bin/clang++ ). My script then assumes that the name of the compiler you are using is name of the executable (everything after the final directory separator, as determined by by os.path.basename ).

You can specify both. This allows you to handle strange situations: scons --compiler-command=/path/to/executable/that/is/not/clang++ --compiler=g++

It uses the name to determine which warnings / optimizations to turn on. I have even added a bit of normalization to the name, so that g++, gcc, and GcC are all treated as the same thing, as far as the compiler name is concerned.

It still has a lot of work left in it, such as support for more compilers, better support for mingw compilers, and detection of compiler versions to allow better handling of flags that are available only in version xyz+. It would also be nice if I could do something like scons --compiler-command=/path/to/gcc-4.7.1 and have it detect that the compiler is gcc without me having to explicitly tell it.

However, it has solved the initial problem I set out to fix. Much of the credit for this has to go to Voo in the comments for putting me on the right track.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM