Scons copy header files to build directory

I'm trying to copy a number of headers files from my source directories to an 'includes' directory inside my build directory using scons. My target is a static library and I want to distribute it together with its relevant headers. The expected end result:

build
|-- objects -> .o output files for constructing libmclib.a
|-- includes
|   |-- foo.h
|   `-- bar.h
`-- libmclib.a

My SConstruct:

#!python
target = 'mock'

env = Environment(LINKCOM = "$LINK -o $TARGET $SOURCES $LINKFLAGS $CCFLAGS")
Export('env', 'target')

build_base = 'build'
SConscript('SConscript', variant_dir=build_base, duplicate=0)

# remove build directory
if GetOption('clean'):
    import subprocess
    subprocess.call(['rm', '-rf', build_base])

My SConscript:

#!python
Import('env')

# ...
# other stuff to build 'mclib_target'
# ...

def copy_header_files(target, source, env):
    Mkdir(target)
    header_files = []
    for d in env['CPPPATH']:
        header_files += Glob(d + "/*.h")
    for f in header_files:
        Copy(target, f)

# copy all relevant header files
env.Command("includes", mclib_target, copy_header_files)

Scons does call 'copy_header_files' with arguments '["build/includes"], ["build/libmclib.a"]', but for some reason 'Mkdir' doesn't create the includes directory. Also 'Copy' seems to do nothing. If I however call Mkdir like this:

env.Command("includes", mclib_target, [Mkdir('$TARGET')])

it seems to work well. How to fix/work around this? I'm also quite new to Scons so any alternative for doing this task are welcome. I'm using scons 2.5.0.


You probably want to use " Install() " instead of " Copy() ". Also the Mkdir() shouldn't be necessary, SCons creates all intermediate folders for its targets automatically.

Finally, allow me some comments about your general approach: I'd rather not mix "building" with "installing/preparing for packaging". The " variant_dir " option is there to help you with building several "variants" (release, optimized, debug, ARM-specific,...) from the same source files (let's say you have a folder named "src"). By passing the name of the current "build" directory into your "src" SConscript you're embedding variant-specific knowledge into your local build description, meaning that you'll have to touch it with every variant that you add. Instead, you should move the " Install/Package " steps into the top-level SConstruct...where you have global knowledge about which variants get built. From there you can copy (= Install) the final files to a separate subfolder, eg distribution , and archive that one instead.

For a simple example of how to handle variants right in SCons, check out the repo https://bitbucket.org/dirkbaechle/scons_talks and there the " pyconde_2013/examples/exvar " folder.


The Mkdir and Copy operations that you are using are Action factories for use in Command definitions, described in Platform-Independent File System Manipulation:

SCons provides a number of platform-independent functions, called factories, that perform common file system manipulations like copying, moving or deleting files and directories, or making directories. These functions are factories because they don't perform the action at the time they're called, they each return an Action object that can be executed at the appropriate time.

I have always had problems trying to use these functions within my own action functions. Perhaps I am missing something, but I don't think these functions can be used outside of the immediate list of operations in the Command builder.

Instead I use the platform-independent functions in python for creating directories and copying files, such as os.makedirs and shutil.copy .

链接地址: http://www.djcxy.com/p/67922.html

上一篇: 目标取决于未来的未知目标

下一篇: Scons复制头文件以构建目录