In the following lines you find tips help you start with building C++ programs using SCons project construction tool under Linux.
SCons package can be installed with
sudo apt install scons
command
SCons is super easy to start with you need to know only three thinks. The first one, scons
command to start a building process (from project root directory), scons -c
command for project clean-up and that SCons build file is called SConstruct
. The most simplest SConstruct
file can looks like this
Program('main.cpp')
Yes, that is all! I've told it is super easy. SCons will take main.cpp
source file and create main
executable from it. We are now ready to build something, go to basic/
directory and execute scons
by
cd basic
scons
commands to see SCons in action. The main
output should looks like this
./main
done!
don't forget to test
scons -c
command to clean-up the sample directory
Let's say we want to force building against C++17 standard and also turn on all compiler warnings. To do that, we can adjust compiler options with Environment
variable this way
cpp17 = Environment(CCFLAGS=['-std=c++17', '-Wall'])
cpp17.Program('main.cpp')
go to
environment/
directory and runscons
to buildmain
executable to see SCons with modified environment in action
There is not only CCFLAGS
construction variable there but many others like
CCFLAGS
general options passed to the c and c++ compilersCPPPATH
the list of directories that the c preprocessor will search for include directories.LIBS
list of libraries that will be linkedLIBPATH
the list of directories that will be searched for libraries (use#
to indicate absolute pathLIBPATH='#/libs'
)CPPDEFINES
c/c++ preprocessor definitions
full list of construction variables can be found there
tip: we don't need to remember all that construction variable names, there is a shortcut there we can use
parse_flags
argument this wayEnvironment(parse_flags='-std=c++17 -Wall -g -O0')
advanced tip: building with clang instead of gcc can be done by setting
CXX
construction variable toCXX='clang++'
In some cases there are more source files there like in 3dmath sample (we have main.cpp
and vectors.cpp
source files there) we can use Python's list instead of single string in a Program()
builder like this
Program(['main.cpp', 'vector.cpp'])
We can makes our lives even easier with Glob(PATTERN)
helper function and build all cpp files in a directory with
Program('3dmath', Glob('*.cpp'))
'3dmath'
is explicitly used there as a name for program executable, feel free to change it
tip: to speed up whole building process on multicore machines we can call SCons with
-jN
option like thisscons -j4
, whereN
represents number of parallel jobs
Let's render a triangle with OpenGL ES2 and GLFW libraries, like in triangle sample. We need to create SConstruct
with OpenGL ES2 and GLFW library dependencies to get our sample working.
In Linux there is almighty pkg-config there to help us with the task.
before we can continue we need to install GLFW, OpenGL ES2 libraries and pkg-config itself with
sudo apt install libglfw3-dev libgles2 pkg-config
command
Build environment can parse pkg-config output with ParseConfig()
function this way
cpp17.ParseConfig('pkg-config --cflags --libs glfw3 glesv2')
tip: we can use
pkg-config --list-all | grep -i LIBRARY
command to search for GLFW and OpenGL ES2 libraries, under Ubuntu 20.04 LTS they are there as glfw3 and glesv2
Now the last think needed to be done is to tell GLFW library we want render with OpenGL ES2 (not OpenGL). It can be done with GLFW_INCLUDE_ES2
define so we need to change CPPDEFINES
construction variable for our environment. Final SConstruct
file will looks like this
cpp17 = Environment(
CCFLAGS=['-std=c++17', '-Wall', '-O0', '-g'],
CPPDEFINES=['GLFW_INCLUDE_ES2'])
cpp17.ParseConfig('pkg-config --cflags --libs glfw3 glesv2')
cpp17.Program('triangle.cpp')
We are done, go to triangle/
directory and run scons
from konsole to see it is working.
see OGRE starter or cube rain repositories for more SCons samples
It is a good practise to group domain specific code into a library like in a physics sample. I've moved sample physics engine from great Game Physics Cookbook into a phys/
directory and want to use it from my project as a static library. In SCons it is super easy to do that with StaticLibrary()
builder and Glob()
function, like this
cpp17 = Environment(
CXX='clang++', CCFLAGS=['-std=c++17', '-Wall'])
cpp17.ParseConfig('pkg-config --cflags --libs glfw3 gl')
phys = cpp17.StaticLibrary('phys', Glob('phys/*.cpp'))
cpp17.Program('physics', ['main.cpp', phys])
We need to use clang there, because physics library use non-standard C++ language feature not supported by GCC. Install clang with
sudo apt install clang
command.
tip: there are also builders for shared libraries
SharedLibrary()
and object filesObject()
Sometimes it can be handy to provide install command so project can be automatically installed to proper destination without too much effort from user side. In SCons install process can be done with Install()
builder and Alias()
function this way
target_dir = '/opt/foo'
cpp.Install(target_dir, main)
cpp.Alias('install', target_dir)
see full SConstruct file version
Now we can type scons install
to install main
executable to /opt/foo
directory.
tip: in case you don't have write access to
/opt
directory, use--install-sandbox
option to prefix target directory likescons --install-sandbox=/home/adam install
to installmain
executable to/home/adam/opt/foo
instead of/opt/foo
directory
Maybe, you are asking yourself whether uninstall is also possible? Yes, it is! We've got uninstall for free, we can type scons -c install
which will uninstall main
executable from /opt/foo
directory.
Adam Hlavatovic