6/9
4.2. Compilation tools
Typing by hand all compiler calls and arguments can become tedious when dealing with large projects.
Different tools have been developed to ease this process.
We can notably separate low level build tools storing compiler calls
And higher level tools used to generate build tools files such as Makefile or ninja files.
Example on single file project
Consider the following file
#include <iostream>
int main()
{
std::cout << "Hello world" << std::endl;
return 0;
}
In command line
$ g++ main.cpp -g -Wall -Wextra -O2 -std=c++14 -o pgm
The executable is created, and you can run it using
$ ./pgm
With Make
Create the file Makefile
[ Makefile ]
CXXFLAGS = -g -Wall -Wextra -O2 -std=c++14
CXX = g++
all: pgm
pgm: main.cpp
${CXX} $^ -o pgm ${CXXFLAGS}
clean:
rm -f pgm
You can compile and execute the program using
$ make
$ ./pgm
With CMake
Create the file CMakeLists.txt
[ CMakeLists.txt ]
cmake_minimum_required(VERSION 2.8)
project(pgm)
set(CMAKE_CXX_FLAGS "-O2 -g -std=c++14 -Wall -Wextra")
add_executable(pgm main.cpp)
CMakeLists.txt is a configuration file for CMake. CMake will generate several temporary files. It is usually a good idea to execute CMake in a separated directory in order to avoid poluting the src directory.
# Create temporary build directory
$ mkdir build
$ cd build
# Call CMake on the CMakeLists.txt
$ cmake ..
# A Makefile should have been created
$ make
# It is usually a good idea to execute the pgm from the original directory
$ cd ..
$ build/pgm
With Meson
Create the file meson.build
[ meson.build ]
project('pgm', 'cpp')
cxxflags = ['-O2','-g','-std=c++14','-Wall','-Wextra']
add_global_arguments(cxxflags, language : 'cpp')
executable('pgm', 'main.cpp')
# Call Meson to generate build file in a directory called build
$ meson build
# Compile using ninja
$ cd build
$ ninja
# It is usually a good idea to execute the pgm from the original directory
$ cd ..
$ build/pgm
Example on multiple files project
Consider the following files that we will consider to be in /src directory
[ source ]
[ src/main.cpp ]
#include "f1.hpp"
int main()
{
f1();
return 0;
}
[ src/f1.hpp ]
#pragma once
void f1();
[ src/f1.cpp ]
#include <iostream>
void f1()
{
std::cout<<"Function f1"<<std::endl;
}
In command line
$ g++ -c src/main.cpp -g -Wall -Wextra -O2 -std=c++14
$ g++ -c src/f1.cpp -g -Wall -Wextra -O2 -std=c++14
$ g++ main.o f1.o -o pgm
$ ./pgm
With Make
[ Makefile ]
CXXFLAGS = -g -Wall -Wextra -O2 -std=c++14
CXX = g++
all: pgm
pgm: src/main.o src/f1.o
${CXX} $^ -o pgm
src/main.o: src/main.cpp src/f1.hpp
src/f1.o: src/f1.cpp
clean:
rm -f pgm src/*.o
$ make
$ ./pgm
With CMake
[ CMakeLists.txt ]
cmake_minimum_required(VERSION 2.8)
project(pgm)
set(CMAKE_CXX_FLAGS "-O2 -g -std=c++14 -Wall -Wextra")
file(
GLOB_RECURSE
source_files
src/*.[ch]pp
)
add_executable(pgm ${source_files})
-
Note that the file inclusion is very generic and include recursively all files ending by .cpp and .hpp.
$ mkdir build
$ cd build
$ cmake ..
$ make
$ cd ..
$ build/pgm
With Meson
[ meson.build ]
project('pgm', 'cpp')
cxxflags = ['-O2','-g','-std=c++14','-Wall','-Wextra']
add_global_arguments(cxxflags, language : 'cpp')
src = ['src/main.cpp','src/f1.cpp']
executable('pgm', sources : src)
$ meson build
$ cd build
$ ninja
$ cd ..
$ build/pgm