8.3. Separating Compile Arguments into their Variables: the `ParseFlags` Function
Prev | Chapter 8. Automatically Putting Command-line Options into their Construction Variables | Next

## 8.3. Separating Compile Arguments into their Variables: the `ParseFlags` Function

SCons has a bewildering array of construction variables for different types of options when building programs. Sometimes you may not know exactly which variable should be used for a particular option.

SCons construction environments have a `ParseFlags` method that takes a set of typical command-line options and distributes them into the appropriate construction variables Historically, it was created to support the `ParseConfig` method, so it focuses on options used by the GNU Compiler Collection (GCC) for the C and C++ toolchains.

`ParseFlags` returns a dictionary containing the options distributed into their respective construction variables. Normally, this dictionary would then be passed to `MergeFlags` to merge the options into a construction environment, but the dictionary can be edited if desired to provide additional functionality. (Note that if the flags are not going to be edited, calling `MergeFlags` with the options directly will avoid an additional step.)

    env = Environment()
    d = env.ParseFlags("-I/opt/include -L/opt/lib -lfoo")
    for k, v in sorted(d.items()):
        if v:
            print(k, v)
    env.MergeFlags(d)
    env.Program("f1.c")

    % scons -Q
    CPPPATH ['/opt/include']
    LIBPATH ['/opt/lib']
    LIBS ['foo']
    cc -o f1.o -c -I/opt/include f1.c
    cc -o f1 f1.o -L/opt/lib -lfoo

Note that if the options are limited to generic types like those above, they will be correctly translated for other platform types:

    C:\>scons -Q
    CPPPATH ['/opt/include']
    LIBPATH ['/opt/lib']
    LIBS ['foo']
    cl /Fof1.obj /c f1.c /nologo /I\opt\include
    link /nologo /OUT:f1.exe /LIBPATH:\opt\lib foo.lib f1.obj
    embedManifestExeCheck(target, source, env)

Since the assumption is that the flags are used for the GCC toolchain, unrecognized flags are placed in `$CCFLAGS` so they will be used for both C and C++ compiles:

    env = Environment()
    d = env.ParseFlags("-whatever")
    for k, v in sorted(d.items()):
        if v:
            print(k, v)
    env.MergeFlags(d)
    env.Program("f1.c")

    % scons -Q
    CCFLAGS -whatever
    cc -o f1.o -c -whatever f1.c
    cc -o f1 f1.o

`ParseFlags` will also accept a (recursive) list of strings as input; the list is flattened before the strings are processed:

    env = Environment()
    d = env.ParseFlags(["-I/opt/include", ["-L/opt/lib", "-lfoo"]])
    for k, v in sorted(d.items()):
        if v:
            print(k, v)
    env.MergeFlags(d)
    env.Program("f1.c")

    % scons -Q
    CPPPATH ['/opt/include']
    LIBPATH ['/opt/lib']
    LIBS ['foo']
    cc -o f1.o -c -I/opt/include f1.c
    cc -o f1 f1.o -L/opt/lib -lfoo

If a string begins with an exclamation mark (`!`), the string is passed to the shell for execution. The output of the command is then parsed:

    env = Environment()
    d = env.ParseFlags(["!echo -I/opt/include", "!echo -L/opt/lib", "-lfoo"])
    for k, v in sorted(d.items()):
        if v:
            print(k, v)
    env.MergeFlags(d)
    env.Program("f1.c")

    % scons -Q
    CPPPATH ['/opt/include']
    LIBPATH ['/opt/lib']
    LIBS ['foo']
    cc -o f1.o -c -I/opt/include f1.c
    cc -o f1 f1.o -L/opt/lib -lfoo

`ParseFlags` is regularly updated for new options; consult the man page for details about those currently recognized.

Prev | Up | Next
8.2. Merging Options While Creating Environment: the `parse_flags` Parameter | Home | 8.4. Finding Installed Library Information: the `ParseConfig` Function