1

Recently, I found that by adding -Wall and -Wextra to CFLAGS can raise the compilation warning level. And this exposes some hidden bugs.

But I do not wish to edit the warnings in the 3rd party code.

The project I used is an open source RTOS: RT-Thread

As we know, the bottom layer of scons is gcc, so I found a gcc's solution in stack-overflow.

The top solution recommends keeping the warning on, but use -isystem instead of -I to include directories of third-party projects. Then I used the scons --verbose and found that the scons used -I by default.

How to use -isystem instead of -I to include directories of third-party projects in scons?

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

2 Answers2

0

You can add flags you want passed down to the compiler to CCFLAGS (generic) - or to CFLAGS (C-specific) or CXXFLAGS (C++-specific). This can be done by appending to CCFLAGS, or by calling MergeFlags(), which understands that -isystem should be sent to CCFLAGS.

Here's a trivial sconscript file that shows this:

env = Environment()
env.MergeFlags("-isystem other/include")
env.Program("hello", "hello.c")

If the source file includes a header inc.h which exists in other/include, the build looks like this:

$ scons -Q --tree=prune
gcc -o hello.o -c -isystem other/include hello.c
gcc -o hello hello.o
+-.
  +-SConstruct
  +-hello
  | +-hello.o
  | | +-hello.c
  | | +-/bin/gcc
  | +-/bin/gcc
  +-hello.c
  +-[hello.o]

The flag is passed to gcc, so the treatment there should be correct. Notice that SCons has recorded no dependency on the header in its dependency tree - SCons looks in header directories it was told about via the contents of CPPPATH, but we didn't do that here. This actually makes the default treatment of headers given by -isystem consistent with other system headers by SCons - notice stdio.h is also not tracked as a dependency. If you want dependency tracking for headers in a 3rd-party project, you can also add the directory to CPPPATH. The directory will appear twice on the command line, but according to the gcc documentation, that's okay: "If a standard system include directory, or a directory specified with -isystem, is also specified with -I, the -I option is ignored."

So if tracking is wanted, a modified script could be:

env = Environment()
env.MergeFlags("-isystem other/include")
env.Append(CPPPATH=["other/include"])
env.Program("hello", "hello.c")

and now:

$ scons -Q --tree=prune
gcc -o hello.o -c -isystem other/include -Iother/include hello.c
gcc -o hello hello.o
+-.
  +-SConstruct
  +-hello
  | +-hello.o
  | | +-hello.c
  | | +-other/include/inc.h
  | | +-/bin/gcc
  | +-/bin/gcc
  +-hello.c
  +-[hello.o]
  +-other
    +-other/include
      +-other/include/inc.h
Mats Wichmann
  • 800
  • 6
  • 6
0

I'd had a similar problem and created a tool that adds new construction variable CPPSYSPATH (with bonus support for MSVC).

site_scons/site_tools/CppSystemPath.py:

def exists():
    return true

def generate(env):
    env.Append(CPPPATH=['$CPPSYSPATH'])
    
    env.Replace(
        SYSINCPREFIX='-isystem' if 'msvc' not in env['TOOLS'] else '/external:I',
        SYSINCSUFFIX='',
    )
    env.Replace(_CPPSYSINCFLAGS='${_concat(SYSINCPREFIX, CPPSYSPATH, SYSINCSUFFIX, __env__, RDirs)}')
    env.Append(CPPFLAGS=['$_CPPSYSINCFLAGS'])

SConstruct:

env = Environment()
env.Tool('CppSystemPath')
env.Append(CPPSYSPATH=['other/include'])

As @MatsWichmann wrote, just adding the include directories manually as -isystem works when it comes to compilation but SCons can't parse them properly and it sometimes won't rebuild files that depends on the includes after they changed.

This tool adds the path both as -I and -isystem which is interpreted correctly by SCons and by the compiler.

If you're planning to use MSVC, you also need to set a different warnings level for external headers or will default to the same as normal headers. This tool does not do that but you can use for example the code below. (It should turn off all the warnings by setting the level to 0. You can find description of all the other options here.)

if 'msvc' in env['TOOLS']:
    env.Append(CCFLAGS=['/external:W0'])
Piotr Siupa
  • 3,929
  • 2
  • 29
  • 65