CMake multi-file compilation

When learning the 3d-related source code in ceres-solver before, I found that the understanding and application of CMakeLists.txt writing and processing in CMake multi-file project compilation is still relatively vague. Here I sort out how to use the number of different folders.

Reference article:

CMake uses detailed explanation 2 (multi-file compilation)_Liu Kai's blog-CSDN blog_cmake multi-file compilation

1. Under the same folder, multiple cpp files

The tree looks like this:

.
└── test1
    ├── add.cpp
    ├── add.hpp
    ├── CMakeLists.txt
    └── main.cpp

The source code is:

//add.h
#include "iostream"

using namespace std;

int add1(int a, int b);

//add.cpp
#include "add.hpp"

int add1(int i, int j)
{
    return i + j;
}

//main.cpp
#include "add.hpp"

int main()
{
    cout << add1(1, 10) << endl;
    return 0;
}

CMakeLists.txt looks like this:

cmake_minimum_required(VERSION 2.8)
project(add)

add_executable(add1 main.cpp add.cpp)

2. There are too many cpp files in the same folder

If there are more than 5 cpp files in the folder, it is inconvenient to type one by one, you can enter the command in CMakeLists.txt:

aux_source_directory

aux_source_directory(<dir> <variable>)

1 uses aux_source_directory as follows:

cmake_minimum_required(VERSION 2.8)
project(add)
aux_source_directory(. ALL_SRCS)
add_executable(add1 ${ALL_SRCS})

Compilation can also pass.

CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 2.8.12 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.


-- Configuring done
-- Generating done
-- Build files have been written to: /home/hhh/test-folder/cmake-test/test1/build
Consolidate compiler generated dependencies of target add1
[ 33%] Building CXX object CMakeFiles/add1.dir/main.cpp.o
[ 66%] Linking CXX executable add1
[100%] Built target add1

3. Under different folders

The tree looks like this:

.
├── add
│   ├── add.cpp
│   ├── add.hpp
│   └── CMakeLists.txt
├── CMakeLists.txt
└── main.cpp

All the source codes are as follows:

//   add/add.hpp
#include <iostream>
using namespace std;

int add1(int i, int j);

//   add/add.cpp
#include "add.hpp"

int add1(int i, int j)
{
    return i + j;
}

//   main.cpp
#include "add/add.hpp"

int main()
{
    cout << add1(10, 1) << endl;
    return 0;
}

The outermost CMakeLists.txt file:

cmake_minimum_required(VERSION 2.8)
project(add1)

aux_source_directory(. ALL_SRCS)
add_subdirectory(add)
add_executable(add1 ${ALL_SRCS})
target_link_libraries(add1 add2)

analyze:

add_subdirectory(add)

Yes will indicate that this project contains a subdirectory add, so the CMakeLists.txt file and source code in the add directory will also be processed.

After compiling and running, under the build folder, an add folder will appear:

it's inside:

It is the static library of the add folder.

target_link_libraries(add1 add2)

Indicates that the executable add1 needs to be linked against a link library named add2.

Then add the CMakeLists.txt file in the folder:

aux_source_directory(. LIB_SRCSSSSS)
add_library(add2 ${LIB_SRCSSSSS})
add_library(add2 ${LIB_SRCSSSSS})

It is to generate a static library from the work in the current directory, and the library name is add2.

Here is another command:

include_directories()

This article is written in great detail:

include_directories and find_package_Tianxi Blog-CSDN Blog_include_directories

4. Another form

The tree is as follows:

.
├── add
│   └── add.h
├── CMakeLists.txt
└── main
    ├── add.cpp
    └── main.cpp

Reference article:

cmake builds a multi-directory project

Modify the tree according to this article:

.
├── add
│   ├── add.h
│   └── CMakeLists.txt
├── CMakeLists.txt
└── main
    ├── add.cpp
    └── main.cpp

Then there were a lot of interesting mistakes. After a series of attempts, I found that I could not write the CMakeLists.txt file in the .h file, so I had to modify it like this:

.
├── add
│   └── add.h
├── CMakeLists.txt
└── main
    ├── add.cpp
    ├── CMakeLists.txt
    └── main.cpp

The CMakeLists.txt in the main folder should be written like this:

include_directories(../add)
add_library(add2 add.cpp)

The main function is to read the content of the add.h header file and add the static library of add2.

The outermost CMakeLists.txt file should be written like this:

cmake_minimum_required(VERSION 2.8)
project(main)


set(DIR_SRCS ./main/main.cpp)
add_subdirectory(main)
add_executable(add1 ${DIR_SRCS})
target_link_libraries(add1 add2)

The set command directly points to the final main.cpp file, and then adds the main folder to the cmake compilation path to generate the add1 executable file and link the add2 library to add1.

The focus is on the content of main.cpp:

#include "../add/add.h"

int main()
{
    cout << add1(1, 12222);
    return 0;
}

Header files must use relative addresses to compile and pass.

5. Compile the 3d-pose project file in ceres-slover again

Reference article:

cmake--Multi-level directory project

tree:

.
├── common
│   └── read_g2o.h
└── pose_graph_3d
    ├── CMakeLists.txt
    ├── plot_results.py
    ├── pose_graph_3d.cc
    ├── pose_graph_3d_error_term.h
    ├── README.md
    └── types.h

Then here's the content of the CMakeLists.txt file:

cmake_minimum_required(VERSION 2.8)
project(addd)
include_directories(../common)

find_package(Ceres REQUIRED)
include_directories(${CERES_INCLUDE_DIRS})

aux_source_directory(. ALL_SRCS)
add_executable(pose3d ${ALL_SRCS} )

target_link_libraries(pose3d  ${CERES_LIBRARIES})

target_include_directories( pose3d
 PUBLIC ../common
)

Because this inside pose_graph_3d.cc uses read_g2o.h in the common folder. So to use include_directories() and target_include_directories(), PUBLIC must be ordered to add it. If the library is generated, you can write a CMakeLists.txt in common to generate the library, and then add the library to the CMakeLists.txt file. .

After that, the compilation passed. Pay attention to the reference format of read_g2o.h in pose_graph_3d.cc.

Tags: C++ Ubuntu cmake programming language

Posted by slawrence10 on Mon, 23 Jan 2023 16:12:23 +0530