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:
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.