Compiler Flags
Once we have an environment object, configuring settings for the build becomes relatively simple.
Consider wanting to follow good practice by turning on the basic warnings for GCC, e.g.
- All warnings
-Wall
which of course is not all warnings - Extra warnings
-Wextra
For setting general C/C++ compiler options, there is a construction variable call CCFLAGS
. Adding this our environment in the SConstruct
file adds these flags, e.g.:
# CCFLAGS : general C and C++ flags
env.Append( CCFLAGS = [
'-Wall',
'-Wextra',
] )
Now when we build we'll see the extra flags added:
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o src/main.o -c -Wall -Wextra -Isupport -Idir1 -Idir2 src/main.c
gcc -o support/message.o -c -Wall -Wextra -Isupport -Idir1 -Idir2 support/message.c
scons: done building targets.
Preprocessor Flags
For any pre-processor directives (i.e. the -D option for the compiler), then you can set the CPPDEFINES
variable.
For example, suppose we wanted the print the string out a set number of times:
#include "message.h"
#ifndef COUNT
#define COUNT 1
#endif
int main(void)
{
for(int i = 0; i < COUNT; ++i){
print_message("Hello world");
}
return 0;
}
If we wanted to set this value at the command line, we would use the following directive:
-DCOUNT=5
To achive this with scons, simple append to the variable CPPDEFINES
, e.g.
# set COUNT=5
env.Append( CPPDEFINES = [ ('COUNT',5) ] )
Now when we build, we see the approriate flag being set:
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o src/main.o -c -Wall -Wextra -DCOUNT=5 -Isupport src/main.c
gcc -o support/message.o -c -Wall -Wextra -DCOUNT=5 -Isupport support/message.c
g++ -o hello src/main.o support/message.o
scons: done building targets.
Now when we execute hello
:
$ ./hello
Hello world
Hello world
Hello world
Hello world
Hello world
If only the directive is required and a value is not specifically needed, e.g.
int main(void)
{
#ifdef LOGGING
puts("loggin on");
#endif
for(int i = 0; i < COUNT; ++i){
print_message("Hello world");
}
return 0;
}
then is can be set thus:
env.Append( CPPDEFINES = [ 'LOGGING' ] )
Note: It is not considered good practice to use the compiler flags, e.g.
# CCFLAGS : general C and C++ flags
env.Append( CCFLAGS = [
'-Wall',
'-Wextra',
'-DLOGGING'
] )
to set the pre-processor directives.
Separating out flags
One useful benefit of being a Python based build is there is a lot of flexibility. For example, all the flags don't have to be set in one place, e.g.:
# CCFLAGS : general C and C++ flags
env.Append( CCFLAGS = ['-Wall',] )
env.Append( CCFLAGS = ['-Wextra',] )
This can be especially useful in an embedded build where you want to split the more generic flags (-Wall
, -Wextra
, etc.) and any cross-compiler specific flags (e.g. -mcpu=cortex-m4
)
C Compiler Specific Flags
When working with both C and C++ projects, then it is good practice to separate out the common complier flags from those that are either C or C++ specific (e.g. C or C++ standard).
The specific C compiler (C only; not C++) flags are set using CFLAGS
For example:
# for C
env.Append(CFLAGS = ['-std=c99',])
C++ Compiler Specific Flags
The specific C++ flag variable is CXXFLAGS.
For example, if we change our struture so that the main is a C++ file:
.
├── README.md
├── SConstruct
├── src
│ └── main.cpp
└── support
├── message.c
└── message.h
and change main.cpp
to:
extern "C" {
#include "message.h"
}
int main(void)
{
print_message("Hello world");
return 0;
}
Now we can add the following lines to the SConstruct
file:
# CXXFLAGS : for C++ specific flags
env.Append(CXXFLAGS = ['-std=c++14',])
When we build, we can see that message.c
is compiler using the $CPPLAGS
whereas main.cpp
is compiled with both $CPPFLAGS
and the $CXXFLAGS
.
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o src/main.o -c -std=c++14 -fno-threadsafe-statics -Wall -Wextra -Isupport src/main.cpp
gcc -o support/message.o -c -Wall -Wextra -Isupport support/message.c
g++ -o hello src/main.o support/message.o
scons: done building targets.