6

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.

David Stone
  • 26,872
  • 14
  • 68
  • 84
  • 2
    I'd separate the two issues here. problem #1) *which* compiler is requested and #2) *where* is the requested compiler located (for that you can use sensible defaults most of the time and only let them specify it if they don't want the default clang/gcc/whatever). The two things don't have much in common, after all I can easily create a softlink to clang that's called `msvc` if I wanted to (actually never tried, but why not?) – Voo Jul 07 '12 at 18:29
  • I agree with the suggestion @Voo gave you. Edit this to narrow down to one question, and then create a new question. You have two good questions, which is why I upvoted the one you created (so far). – octopusgrabbus Jul 07 '12 at 19:50
  • @Voo if you write that up as an answer, I'll accept it, since that was the key insight that I used to solve the problem. – David Stone Jul 28 '12 at 14:06
  • If you looking for a way to force SCons to use a different compiler: https://stackoverflow.com/q/13161690/3052438 – Piotr Siupa May 14 '22 at 10:03

3 Answers3

2

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.

Torsten
  • 21,726
  • 5
  • 24
  • 31
  • Huh? OP appears to be asking how to check which compiler was chosen automatically, not how to force one. Anyway, apparently SCons doesn't quite guarantee to cleanup all the things that the default tools have set. If you want to set tools explicitly, you should not let it load the defaults. Use `env = Environment(tools=[])` instead. (It doesn't have to be an empty list but don't put other compilers on it.) Or you can use a one-liner `env = Environment(tools=['mingw'])`. I think you should, to avoid problems, also specify a linker tool, which in this case is probably `gnulink`? – Piotr Siupa May 14 '22 at 09:20
1

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.

Brady
  • 10,207
  • 2
  • 20
  • 59
0

There seems to be some confusion about what question is asked here. For what I can see, this asks how to determine which compiler was chosen by default, so I'll answer that one.

From what I found out, the official way to check the compiler is to look at the construction variable TOOLS, which contains a list of all tools / programs that SCons decided / was told to use in the given construction environment.

env = Environment()
is_gcc = 'g++' in env['TOOLS']
is_clang = 'clangxx' in env['TOOLS']

TOOLS lists only the currently used tools even if SCons can find more of them. E.g. if you have both GCC and Clang installed and SCons is able to find both, default TOOLS will still contain only GCC.

You can find the full list of predefined tools here.

Piotr Siupa
  • 3,929
  • 2
  • 29
  • 65