Compiling C++ Programs with CMake on Linux

Compiling C++ Programs with CMake on Linux

Compiling C++ Programs with CMake on Linux

1. Compiling a Single .cpp File with g++

Use g++/gcc to compile a .cpp file and generate an executable file named .out

g++ main.cpp

1. Create the file main.cpp

#include <iostream>using namespace std;
int main(){    cout<<"hello world"<<endl;    return 0;}

2. Compile the file to generate the executable file a.out

g++ main.cpp

3. Run the executable file. After generating the a.out file, input ./a.out

./a.out

Compiling C++ Programs with CMake on Linux

2. Compiling a Single .cpp File with CMake

Create a CMakeLists.txt file, use CMake to generate the project, and use make to generate the executable file.

1. Create the file

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
# Declare the project name
project(project2)
# Declare the target executable and the source code files
add_executable(main main.cpp)

In the project2 folder, there are two files: CMakeLists.txt and main.cpp

2. Create the project with CMake

cmake .

This generates some makefile files. See the image below

Compiling C++ Programs with CMake on Linux

3. Use make to compile the project and generate the executable file

make

4. Run the executable file

./main

The process is as follows

san@ubuntu:~/project2$ cmake .
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/san/project2
san@ubuntu:~/project2$ make
Scanning dependencies of target main
[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
[100%] Linking CXX executable main
[100%] Built target main

san@ubuntu:~/project2$ ./main
hello world
san@ubuntu:~/project2$

3. Multiple .h Header Files and .cpp Source Files

In the project2 folder

san@ubuntu:~/project2$ lsCMakeLists.txt main.cpp test1.cpp test1.h test2.cpp test2.h

main.cpp

#include <iostream>
#include "test1.h"
#include "test2.h"
using namespace std;
int main(){    cout<<"hello world"<<endl;    testfunc1();    testfunc2();    return 0;}

test1.cpp

#include "test1.h"
#include <iostream>
void testfunc1()    {      std::cout<<"this is testfunc1"<<std::endl;    }

test1.h

#ifndef _TEST1_H
#define _TEST1_H
#include <iostream>
void testfunc1();
#endif /*_TEST1_H*/

Create CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(project2)
add_executable(main main.cpp test1.cpp test2.cpp)

Other steps are the same.

san@ubuntu:~/project2$ make
Scanning dependencies of target main
[ 25%] Building CXX object CMakeFiles/main.dir/main.cpp.o
[ 50%] Building CXX object CMakeFiles/main.dir/test1.cpp.o
[ 75%] Building CXX object CMakeFiles/main.dir/test2.cpp.o
[100%] Linking CXX executable main
[100%] Built target main
san@ubuntu:~/project2$ ./main
hello world
this is testfunc1
this is testfunc2
san@ubuntu:~/project2$

4. Organizing Header Files and Source Files in Different Directories

The include folder stores .h header files

The src folder stores .cpp source files

The build folder stores dependency files generated by the CMake command, such as makefile files.

The bin folder stores the generated executable files .out or main

Other files remain the same, but the CMakeLists.txt file is different.

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(project3)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
aux_source_directory(src SRC_LIST)
include_directories(include)
add_executable(main3 ${SRC_LIST})

The result is as follows:

san@ubuntu:~/cmake_learn/project3$ tree -a.
├── bin
│   └── main3
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 3.16.3
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   ├── CMakeCCompilerId.c
│   │   │   │   └── tmp
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       ├── CMakeCXXCompilerId.cpp
│   │   │       └── tmp
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeOutput.log
│   │   ├── CMakeTmp
│   │   ├── main3.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── CXX.includecache
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.internal
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── link.txt
│   │   │   ├── progress.make
│   │   │   └── src
│   │   │       ├── main.cpp.o
│   │   │       ├── test1.cpp.o
│   │   │       └── test2.cpp.o
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── progress.marks
│   │   └── TargetDirectories.txt
│   ├── cmake_install.cmake
│   └── Makefile
├── CMakeLists.txt
├── include
│   ├── test1.h
│   └── test2.h
└── src
    ├── main.cpp
    ├── test1.cpp
    └── test2.cpp
13 directories, 38 files

CMake Commands

1. Declare the minimum version of CMake

cmake_minimum_required(VERSION 3.10)

2. Set the project name

project(project2)

3. Set the directory for the executable file

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

4. Specify the directory for multiple source files (.cpp) and save it in the SRC_LIST variable

aux_source_directory(src SRC_LIST)

5. Specify the directory for multiple header files

include_directories(include)

6. Specify the executable file name and the folder containing multiple source files

add_executable(main3 ${SRC_LIST})

7. Specify the executable file name and directly specify the source files

add_executable(main main.cpp test1.cpp test2.cpp)

Leave a Comment