<?xml version='1.0'?>

<!--
SPDX-FileCopyrightText: Copyright The SCons Foundation (https://scons.org)
SPDX-License-Identifier: MIT
SPDX-FileType: DOCUMENTATION

This file is processed by the bin/SConsDoc.py module.
-->

<!DOCTYPE sconsdoc [
    <!ENTITY % scons SYSTEM "../scons.mod">
    %scons;

    <!ENTITY % builders-mod SYSTEM "../generated/builders.mod">
    %builders-mod;
    <!ENTITY % functions-mod SYSTEM "../generated/functions.mod">
    %functions-mod;
    <!ENTITY % tools-mod SYSTEM "../generated/tools.mod">
    %tools-mod;
    <!ENTITY % variables-mod SYSTEM "../generated/variables.mod">
    %variables-mod;
]>

<section id="sect-parseflags"
         xmlns="http://www.scons.org/dbxsd/v1.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">
<title>Separating Compile Arguments into their Variables: the &ParseFlags; Function</title>

<para>

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

 </para>

 <para>

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

 </para>

 <para>

 &ParseFlags; returns a dictionary containing the options
 distributed into their respective &consvars;.
 Normally, this dictionary would then be passed to &f-link-MergeFlags;
 to merge the options into a &consenv;,
 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.)

 </para>

 <scons_example name="parseflags_ex1">
   <file name="SConstruct" printme="1">
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")
   </file>
   <file name="f1.c">
int main() { return 0; }
   </file>
 </scons_example>

 <scons_output example="parseflags_ex1" os="posix" suffix="1">
    <scons_output_command>scons -Q</scons_output_command>
 </scons_output>

 <para>

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

 </para>

 <scons_output example="parseflags_ex1" os="win32" suffix="2">
    <scons_output_command>scons -Q</scons_output_command>
 </scons_output>

 <para>

 Since the assumption is that the flags are used for the GCC toolchain,
 unrecognized flags are placed in &cv-link-CCFLAGS;
 so they will be used for both C and C++ compiles:

 </para>

 <scons_example name="parseflags_ex2">
   <file name="SConstruct" printme="1">
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")
   </file>
   <file name="f1.c">
void main() { return 0; }
   </file>
 </scons_example>

 <scons_output example="parseflags_ex2" suffix="1">
    <scons_output_command>scons -Q</scons_output_command>
 </scons_output>

 <para>

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

 </para>

 <scons_example name="parseflags_ex3">
   <file name="SConstruct" printme="1">
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")
   </file>
   <file name="f1.c">
void main() { return 0; }
   </file>
 </scons_example>

 <scons_output example="parseflags_ex3" suffix="1">
    <scons_output_command>scons -Q</scons_output_command>
 </scons_output>

 <para>

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

 </para>

 <scons_example name="parseflags_ex4">
   <file name="SConstruct" printme="1">
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")
   </file>
   <file name="f1.c">
void main() { return 0; }
   </file>
 </scons_example>

 <scons_output example="parseflags_ex4" suffix="1">
    <scons_output_command>scons -Q</scons_output_command>
 </scons_output>

 <para>

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

 </para>

</section>
