Basic Path Setup

If we restructure our project thus:

.
├── SConstruct
├── src
│   └── main.c
└── support
    ├── message.c
    └── message.h

We need to change two build parameters:

Source files

Changing our SConstruct to find the files is simply a matter of adding the directory path, e.g.

sources=['src/main.c', 'support/message.c']
Program(target = exe, source = sources)

But the build will fail, e.g.:

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o src/main.o -c src/main.c
src/main.c:1:10: fatal error: 'message.h' file not found
#include "message.h"
         ^~~~~~~~~~~
1 error generated.
scons: *** [src/main.o] Error 1

as the build system cannot message.h in the default search path.

Search path Include

The construction variable CPPPATH is a list of directories that the C preprocessor will search for include directories. We can simple add our required directory to the variable.

However, to do this, it is best to create an Environment variable (the benefit of this will become more obvious later, but for now just accept this).

We do this by adding the line:

env = Environment()

to the head of the SConstruct file.

Next we can append the required search path for our needed header file:

env.Append(CPPPATH = ["support"])

Finally, we modify the build step to use the context of the environment:

env.Program(target = exe, source = sources)

So our complete SConstruct looks thus:

env = Environment()

env.Append(CPPPATH = ["support"])

exe = 'hello'
sources = ['src/main.c', 'support/message.c']
env.Program(target = exe, source = sources)

When we build:

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o src/main.o -c -Isupport src/main.c
gcc -o support/message.o -c -Isupport support/message.c
gcc -o hello src/main.o support/message.o
scons: done building targets.

we can see the -Isupport added to the compilation step.

When more than one include directory is needed, simply create a comma separated list, e.g.

env.Append(CPPPATH = ["support", "dir1", "dir2", ])

or:

project_includes = ["support", "dir1", "dir2"]
env.Append(CPPPATH = project_includes)

or even:

project_includes = [
    "support", 
    "dir1", 
    "dir2"
]
env.Append(CPPPATH = project_includes)

depending on your persuasion!

Relative vs Absolute paths

A worthwhile practice is to force scons to look-up a directory relative to the root of the source tree by using # at the start of the path, e.g.

project_includes = [
    "#/support", 
    "#/dir1", 
    "#/dir2"
]
env.Append(CPPPATH = project_includes)

Again, the benefit of this approach will become apparent later.

Source file lookup alternative

earlier we discussed using with the Glob pattern matching or the explicit list model. Of course we could combine the two, e.g.

sources = ['src/main.c']
sources += Glob('support/*.c')
env.Program(target = exe, source = sources)

results matching ""

    No results matching ""