Chapter 28. Using SCons with other build tools

Sometimes a project needs to interact with other projects in various ways. For example, many open source projects make use of components from other open source projects, and want to use those in their released form, not recode their builds into SCons. As another example, sometimes the flexibility and power of SCons is useful for managing the overall project, but developers might like faster incremental builds when making small changes by using a different tool.

This chapter shows some techniques for interacting with other projects and tools effectively from within SCons.

28.1. Creating a Compilation Database

Tooling which wants to perform analysis and modification of source code often needs to know not only the source code itself, but also how it will be compiled, as the compilation line affects the behavior of macros, includes, etc. SCons has a record of this information once it has run, in the form of Actions associated with the sources, and can emit this information so tools can use it.

The Clang project has defined a JSON Compilation Database. This database is in common use as input into Clang tools and many IDEs and editors as well. See JSON Compilation Database Format Specification for complete information. SCons can emit a compilation database in this format by enabling the compilation_db tool and calling the CompilationDatabase builder (available since 4.0).

The compilation database can be populated with source and target files either with paths relative to the top of the build, or using absolute paths. This is controlled by COMPILATIONDB_USE_ABSPATH=(True|False) which defaults to False.

Example of absolute paths for target and source:

env = Environment(COMPILATIONDB_USE_ABSPATH=True)
env.Tool('compilation_db')
env.CompilationDatabase('compile_commands.json')
    
[
    {
        "command": "gcc -o test_main.o -c test_main.c",
        "directory": "/home/user/sandbox",
        "file": "/home/user/sandbox/test_main.c",
        "target": "/home/user/sandbox/test_main.o"
    }
]
    

Example of relative paths for target and source:

env = Environment()
env.Tool('compilation_db')
env.CompilationDatabase('compile_commands.json')
    
[
    {
        "command": "gcc -o test_main.o -c test_main.c",
        "directory": "/home/user/sandbox",
        "file": "test_main.c",
        "target": "test_main.o"
    }
]