Search code examples
c++windowsclangclang++scons

SCons uses Visual Studio flags with Clang


I'm trying to use SCons with Clang on Windows. When I do SCons attempts to use Visual Studio flags with Clang.

scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
clang++ /Fomain.obj /c main.cc -static /nologo /Iinclude
clang++: error: no such file or directory: '/Fomain.obj'
clang++: error: no such file or directory: '/c'
clang++: error: no such file or directory: '/nologo'
clang++: error: no such file or directory: '/Iinclude'
clang++: error: unable to make temporary file: no such file or directory
scons: *** [main.obj] Error 1
scons: building terminated because of errors.

Running scons -n I get:

clang++ /Fomain.obj /c main.cc -static /nologo /Iinclude
link /OUT:test.exe /LIBPATH:lib main.obj

What I want are these commands which work on Windows and Linux:

clang++ -o main.o -c -static -Iinclude main.cc
clang++ -o test main.o -Llib

My build script:

import os
from os.path import join, dirname
import shutil

LIBS=[]
LIBPATH=['./lib']

CXXFLAGS='-static'
LINKFLAGS = ''

env = Environment(
    CC='clang',
    CXX='clang++',
    CPPPATH=['./include'],
    ENV = {'PATH' : os.environ['PATH']},
    LIBS=LIBS,
    LIBPATH=LIBPATH,
    CXXFLAGS=CXXFLAGS,
    LINKFLAGS=LINKFLAGS
)

source = ['main.cc']
env.Program('test', source)

Solution

  • Visual Studio is the preferred toolchain in Windows. SCons chooses it by default unless told otherwise. Variables CC and CXX do not override that. They only change the executables that will be called in the build commands. Every other setting is still configured for Visual Studio.

    What you're looking for is called a "tool" in SCons. They are complete configurations for specific tools that can be loaded into SCons.

    If you not define your own list of tools, a default one is loaded, which includes the C++ compiler chosen by SCons.

    To change this setting, istead of CC and CXX, pass a variable TOOLS to the created environment, with the list of all tools required to use Clang (['clang', 'clang++', 'gnulink']):

    import os
    from os.path import join, dirname
    import shutil
    
    LIBS=[]
    LIBPATH=['./lib']
    
    CXXFLAGS='-static'
    LINKFLAGS = ''
    
    env = Environment(
        TOOLS=['clang', 'clang++', 'gnulink'],
        CPPPATH=['./include'],
        ENV = {'PATH' : os.environ['PATH']},
        LIBS=LIBS,
        LIBPATH=LIBPATH,
        CXXFLAGS=CXXFLAGS,
        LINKFLAGS=LINKFLAGS
    )
    
    source = ['main.cc']
    env.Program('test', source)
    

    This will set not only executable names but also everything else, like the format of options.

    Be aware that after this change the build script will fail if there is no Clang found on the machine. It won't default to Visual Studio.