If you need to use a file from another directory,
it's sometimes more convenient to specify
the path to a file in another directory
from the top-level SConstruct
directory,
even when you're using that file in
a subsidiary SConscript
file in a subdirectory.
You can tell SCons to interpret a path name
as relative to the top-level SConstruct
directory,
not the local directory of the SConscript
file,
by prepending a #
(hash mark) in front of the path name:
env = Environment() env.Program('prog', ['main.c', '#lib/foo1.c', 'foo2.c'])
In this example,
the lib
directory is
directly underneath the top-level SConstruct
directory.
If the above SConscript
file is in a subdirectory
named src/prog
,
the output would look like:
% scons -Q
cc -o lib/foo1.o -c lib/foo1.c
cc -o src/prog/foo2.o -c src/prog/foo2.c
cc -o src/prog/main.o -c src/prog/main.c
cc -o src/prog/prog src/prog/main.o lib/foo1.o src/prog/foo2.o
(Notice that the lib/foo1.o
object file
is built in the same directory as its source file.
See Chapter 15, Separating Source and Build Trees: Variant Directories, below,
for information about
how to build the object file in a different subdirectory.)
A couple of notes on top-relative paths:
SCons doesn't care whether you add a slash after the #
.
Some people consider '#/lib/foo1.c'
more readable than '#lib/foo1.c'
,
but they're functionally equivalent.
The top-relative syntax is only
evaluated by SCons, the Python language itself does not
understand about it. This becomes immediately obvious
if you like to use print
for debugging,
or write a Python function that wants to evaluate a path.
You can force SCons to evaluate a top-relative path by
creating a Node object from it:
path = "#/include" print("path =", path) print("force-interpreted path =", Entry(path))
Which shows:
% scons -Q
path = #/include
force-interpreted path = include
scons: `.' is up to date.