[about CMake, CMakeLists.txt] related knowledge and ORB_SLAM3-ROS-CMakeLists notes

Posted by tuuga on Fri, 31 Dec 2021 00:33:31 +0100

preface

Fill the abyss of your knowledge.

Everything is a variable. What the CPU needs to access memory is the address, not the variable name and function name!
Variable names and function names are just mnemonics of addresses. When the source files are compiled and linked into executable programs, they will be replaced with addresses.
An important task in the compilation and linking process is to find the addresses corresponding to these names.

1, GCC compilation process of C/C + + program

It is usually divided into four stages: preprocessing, compiling, assembling, linking, and finally generating executable programs.

1. Pretreatment

Call cpp to preprocess the source code, analyze the include and precompiled statements (macro definitions, etc.), modify the source file according to these preprocessing instructions, and generate. i file.

The preprocessing instructions provided by C/C + + mainly include:
File includes
Macro
Conditional compilation, etc.

C/C + + preprocessor only does macro replacement and text replacement.

C/C + + preprocessing does not do any syntax check, not only because it does not have the syntax check function, but also because the preprocessing command does not belong to C/C + + statements (which is why you do not add semicolons when defining macros). Syntax check is the work of the compiler.

After preprocessing, we get only the real source code.

2. Compilation

Call ccl to compile. After confirming that all instructions comply with the syntax rules through lexical analysis and syntax analysis, translate them into equivalent intermediate code representation or assembly code to generate s file.

3. Compilation

Call as to assemble, translate the assembly language code into target machine instructions and generate o documentation.

4. Link

Connect the relevant target files with each other, that is, connect the symbol referenced in one file with the definition of the symbol in another file, so that all these target files can be loaded and executed by the operating system.

5. General


The figure above shows:
Precompiled: will cpp file into i file, the gcc command used is: gcc – E, corresponding to the preprocessing command cpp

Compile: will cpp/.h file conversion to S file. The gcc command used is: gcc – s, which corresponds to the compilation command cc – s

Compilation: will s file into o file, the gcc command used is: gcc – c, corresponding to the assembly command is as

Links: will o file into an executable program. The gcc command used is gcc, and the corresponding link command is ld

2, GCC optimization level

The parameters specifying the optimization level in GCC are: - O0, - O1, - O2, - O3, - Og, - Os, - Ofast.

-Ox this parameter is only available in CMake -DCMAKE_BUILD_TYPE=release is valid because the executable generated by the debug version of the project needs debugging information and does not need to be optimized, while the release version does not need debugging information but needs to be optimized.

explain:
1) During compilation, if none of the above optimization parameters is specified, it defaults to - O0, that is, there is no optimization.

2) In the parameters - O1, - O2, - O3, as the number becomes larger, the degree of code optimization becomes higher, but in a sense, it is also at the expense of program debuggability.

3) The parameter - Og is based on - O1 and removes the optimizations that affect debugging. Therefore, this parameter can be used if the final purpose is to debug the program. However, this parameter alone is not enough. This parameter only tells the compiler that the compiled code does not affect debugging, but the generation of debugging information still depends on the - g parameter.

4) The parameter - Os is based on - O2 and removes the optimizations that will lead to the increase of the final executable program. If you want a smaller executable program, you can choose this parameter.

5) Parameter - offast adds some unconventional optimizations on the basis of - O3. These optimizations are realized by breaking some international standards (such as the implementation standards of some mathematical functions), so it is generally not recommended to use this parameter.


3, GDB common instructions

4, CMake organizes compiled files

cmake handles the relationship between files. It is a cross platform compilation tool, mainly writing cmakelists Txt file, use the cmake command to cmakelists The txt file is transformed into the Makefiles file needed by make, then g++ is called to compile the program.
CMakefiles.txt is consistent with the file used to generate Makefiles. Compile the source code with the make command to generate executable programs or shared libraries.

gcc compiles one source code file at a time
make compiles multiple source code files at once

cmake according to cmakelists Txt file generated makefile
make calls the instructions in the makefile file to compile and link

5, General process of CMake compilation and installation

cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local ..

-D is equivalent to a macro definition. In fact, it is to pass in parameters to the compiler gcc. It can be understood as telling CMake to define some parameters later. Add "- D" before each parameter defined.

CMAKE_BUILD_TYPE is often in cmakelist Txt represents the type to be compiled. If you want to debug the compiled program, you need to set CMAKE_BUILD_TYP=debugļ¼› If you want to run a compiled program just for performance, set CMAKE_BUILD_TYP=release.

CMAKE_INSTALL_PREFIX specifies the installation path of the compiled program. If it is not specified, it is the default installation path. It can be installed in any location. It is generally used when switching multiple versions of software.

CMAKE_PREFIX_PATH is the installation path of the file to be compiled.

"..." indicates the upper level directory, which means cmakelist Txt file is one level above the compilation path.

According to cmakelists Txt file, find the files that make and make install depend on, and generate the Makefile file.

make
Read the instructions from Makefile, and then compile the source code to generate static library, dynamic library, executable program, etc.

sudo make install
Read the instructions from Makefile, copy and install the compiled executable program and documents to the specified location.

6, Cmakelists Txt syntax rule summary

//Declare the minimum version of cmake required. The terminal can view the version of cmake by entering cmake -version
cmake_minimum_required( VERSION 2.8 )

//Declare cmake project name
project(slam)

//Set to use the g + + compiler, which is the usage of adding variables. set(KEY VALUE) receives two parameters to declare variables. Use ${KEY} in camke syntax to get VALUE
set( CMAKE_CXX_COMPILER "g++")

//There are two kinds of projects for setting cmake compilation mode: debug and release_ SOURCE_ The dir project root directory is cmakelists Txt absolute path
set( CMAKE_BUILD_TYPE "Release" )

//Set the storage directory where the generated executable binary files are stored
set( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

//Set the storage directory of the generated library file
set( LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

//Valuepoint CMAKE_CXX_FLAGS means: set compiler for c++ language
//Add c++11 standard support, * CPP file compilation option, - march=native specifies the cpu architecture of the target program for program optimization
//native is equivalent to self-test cpu, - march is the gcc optimization option, and the latter - O3 is used to adjust the optimization degree at compile time. The highest is - O3 and the lowest is - O0, that is, no optimization is performed
//-Ox this parameter is only available in cmake - dcmake_ BUILD_ Valid when type = release
//Because the executable generated by the debug version of the project needs debugging information and does not need to be optimized, while the release version does not need debugging information but needs to be optimized
set( CMAKE_CXX_FLAGS "-std=c++11 -march=native -O3")

//The debugging method message prints information, similar to echo/printf. It is mainly used to check the syntax errors of cmake files
set(use_test ${SOURCES_DIRECTORY}/user_accounts.cpp)
message("use_test :  ${use_test}")

//At cmakelists Txt, and specify the installation location in the compilation terminal: cmake -DCMAKE_INSTALL_PREFIX=/usr ..
set(CMAKE_INSTALL_PREFIX < install_path >)

//Add a subfolder, that is, enter the source code folder to continue the construction
add_subdirectory(${PROJECT_SOURCE_DIR}/src)

//Add dependencies to find the header file location, library file location and library file name of the library, set them as variables, and return them to cmakelists Txt used in other parts.
//cmake_ modules. The cmake file is cmakelists Txt to find a specific library. If you are prompted that no third-party dependent library is found, you can try to install or specify the path
// Find OpenCV Library
find_package( OpenCV REQUIRED )

//At cmakelists Txt trilogy using third-party libraries: find_package,include_directories,target_link_libraries
include_directories(${OpenCV_INCLUDE_DIRS})// Where can I find the first file
link_directories()// Where to find library files (. so/.lib/.ddl, etc.)
target_link_libraries( ${OpenCV_LIBRARIES})// Library files that need to be linked
message("OpenCV_INCLUDE_DIRS: \n" ${OpenCV_INCLUDE_DIRS})
message("OpenCV_LIBS: \n" ${OpenCV_LIBS})

// find_package(Eigen3 REQUIRED). If the Eigen3 library cannot be found, we will set a variable to specify the location of the header file of Eigen3
set(Eigen3_DIR /usr/lib/cmake/eigen3/Eigen3Config.cmake)
include_directories(/usr/local/include/eigen3)

// The include instruction is used to load and run CMake code from a file or module
include()

7, Orbslam3-ros-cmakelists Txt file details

cmake_minimum_required(VERSION 2.4.6)					// The minimum version of cmake required for the declaration is 2.4 six
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)	// Used to load and run CMake code from a file or module

rosbuild_init()											// initialization

IF(NOT ROS_BUILD_TYPE)									// If the compilation type is not set, it is set to Release
  SET(ROS_BUILD_TYPE Release)
ENDIF()

MESSAGE("Build type: " ${ROS_BUILD_TYPE})				// Print information, similar to echo/printf

// Valuepoint CMAKE_CXX_FLAGS means: set compiler for c++ language to establish a c + + compiler
// -Wall: it is allowed to send all useful alarm information provided by Gcc
// -O3 optimization level
// native is equivalent to self checking cpu, - march is the gcc optimization option, that is, specify the cpu architecture of the target program gcc for program optimization
// -Ox this parameter is only available in cmake - dcmake_ BUILD_ Valid when type = release
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}  -Wall  -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall  -O3 -march=native")

# Check C++11 or C++0x support 	 Determine whether the compiler supports C + + 11
include(CheckCXXCompilerFlag)							// The include instruction is used to load and run CMake code from a file or module
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)		// Flag to determine whether the compiler supports C++11
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")				// Add 'c++11' standard support
   add_definitions(-DCOMPILEDWITHC11)								// -Add the D definition flag to the compilation of the source file, and add the definition to the compiler command line of the source in the current directory and the following directories
   message(STATUS "Using flag -std=c++11.")							// Print information
elseif(COMPILER_SUPPORTS_CXX0X)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
   add_definitions(-DCOMPILEDWITHC0X)
   message(STATUS "Using flag -std=c++0x.")
else()
   message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()

// Cmake defines a series of array operations, which are used as follows
// LIST appends or deletes the value of the variable. Here, cmake is appended_ MODULE_ Value of path, cmake_ MODULE_ The value of path is the address
// ${PROJECT_SOURCE_DIR}: project source folder / root directory, which is the latest cmakelists containing PROJECT() Txt file.
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../../cmake_modules)

// Find opencv
find_package(OpenCV 3.0 QUIET)
if(NOT OpenCV_FOUND)
   find_package(OpenCV 2.4.3 QUIET)
   if(NOT OpenCV_FOUND)
      message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
   endif()
endif()

find_package(Eigen3 3.1.0 REQUIRED)		// Find Eigen3
find_package(Pangolin REQUIRED)			// Find Pangolin

include_directories(					// Directory of include d header files
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/../../../
${PROJECT_SOURCE_DIR}/../../../include
${PROJECT_SOURCE_DIR}/../../../include/CameraModels
${Pangolin_INCLUDE_DIRS}
)

set(LIBS 								// Set the path of the dependent library
${OpenCV_LIBS} 
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
${PROJECT_SOURCE_DIR}/../../../Thirdparty/DBoW2/lib/libDBoW2.so
${PROJECT_SOURCE_DIR}/../../../Thirdparty/g2o/lib/libg2o.so
${PROJECT_SOURCE_DIR}/../../../lib/libORB_SLAM3.so
-lboost_system							// -l is used to link. The linked library is "boost_system"
)

# Node for monocular camera
rosbuild_add_executable(Mono			// Generate executable
src/ros_mono.cc
)

target_link_libraries(Mono				// Library path
${LIBS}
)

# Node for monocular camera (Augmented Reality Demo)
rosbuild_add_executable(MonoAR			// Generate executable
src/AR/ros_mono_ar.cc
src/AR/ViewerAR.h
src/AR/ViewerAR.cc
)

target_link_libraries(MonoAR			// Library path
${LIBS}
)

# Node for stereo camera
rosbuild_add_executable(Stereo
src/ros_stereo.cc
)

target_link_libraries(Stereo
${LIBS}
)

# Node for RGB-D camera
rosbuild_add_executable(RGBD
src/ros_rgbd.cc
)

target_link_libraries(RGBD
${LIBS}
)

# Node for monocular-inertial camera
rosbuild_add_executable(Mono_Inertial
src/ros_mono_inertial.cc
)

target_link_libraries(Mono_Inertial
${LIBS}
)

# Node for stereo-inertial camera
rosbuild_add_executable(Stereo_Inertial
src/ros_stereo_inertial.cc
)

target_link_libraries(Stereo_Inertial
${LIBS}
)

supplement

add_definitions()

summary

Recently, cmake encountered some difficulties. I reviewed the preparation of cmake and cmakelists files directly.

Then many knowledge points come from "Xiaoqiu SLAM code practice notes", praising Yibo dalao.

Reference

  1. https://blog.csdn.net/qq_21950671/article/details/94456864 (Xiao Qiu, Quan)
  2. https://blog.csdn.net/yimingsilence/article/details/52800987 (compilation process)
  3. https://www.bilibili.com/video/BV1fy4y1b7TC?from=search&seid=10822750881263437190&spm_id_from=333.337.0.0 (station B video)
  4. http://blog.sina.com.cn/s/blog_628cc2b70102yqwj.html (CMakeLists directive)
  5. https://blog.csdn.net/wyyang2/article/details/104770144(CMAKE_PREFIX_PATH)

Topics: C C++ Autonomous vehicles