Sorting out the core knowledge points of cmake

Written in the front: mainly refer to the classic pdf tutorial cmake practice. Here, I mainly summarize and add some details encountered in the process of practice

  1. The function of cmakelists is to automatically generate makefile s. If there are cmakelists, the compilation process is as follows:
    This is typical_ Source method, that is, external search, and then generate files to the current specified folder to avoid a large number of files interfering with the code directory.
    In clion, you don't need to consider out_source, it will automatically put the makefile s generated by cmakelists in the root directory into a cmake build debug folder
    Note: the instruction of cmakelists is case independent, but the parameter and variable names are case dependent. Some people recommend capitalization, but I think it's more comfortable for commands to be lowercase and variables and parameters to be uppercase.
mkdir build
cd build
cmake ..       //Or cmake The two points here indicate that cmakelists are found in the upper folder to generate makefile s and related files
make           //Execute makefile
make install   //(optional) installation

make clean     // Clean up works
  1. The debugging of cmake is very simple: after writing, print the corresponding output through message() for verification, and then you can see the output in the cmake tab of clion.
    Note: it is not seen in the terminal terminal, nor in the message tab. Instead, it is displayed in the cmake tab.

  2. Under a large project, there can be independent small projects, and each independent small project corresponds to an independent cmakelist:

  • Create a small project folder and generate small projects cmakelists, CPP H file
  • Right click any cmakelists to see one of the two options: if it is the current cmakelists, you will see the reload cmakelists option.
    If it is not the current cmakelists, you will see the load cmakelists option. After clicking it, you will switch to the corresponding sub project of the cmakelists and can run independently.
  1. project() to create a project: use the project(name) instruction
    After the command, you will get name_ BINARY_ Dir (points to the compilation path, such as the build folder) and name_ SOURCE_ Dir (point to project path)
    Get project at the same time_ BINARY_ Dir and project_ SOURCE_ The two dir variables are the same as the first two variables, so in order to change the project name in the future, do not change cmakelists, and use the latter two variables as much as possible.
  1. set() sets variables, reference variables, and common system variables
set(tensorRT_path "/usr/tensorRT/")   // This is to create the variable tensorRT_path
file(GLOB Sources *.cpp)              // This is also the creation of the variable Sources
${tensorRT_path}                      // This is a reference variable  
if tensorRT_path                      // Note that ${} is not required only when variables are referenced after if

// Common system variables
${PROJECT_SOURCE_DIR}     // Point to the project path, that is, the src path. If not, it is the project path
${PROJECT_BINSARY_DIR}    // Point to the compilation path, that is, the build folder. If not, it is the same as the project path by default

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINSARY_DIR}/bin)   // Modify common system variable path EXECUTABLE_OUTPUT_PATH, that is, the output path of the executable file
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)       // Modify common system variable path LIBRARY_OUTPUT_PATH, that is, the output path of the library file
set(CMAKE_INSTALL_PREFFIX=/usr)                          // Modify the default prefix path of cmake installation. The default is / usr/local, that is, the default is / usr/local for this user, and can be changed to / usr for all users 
  1. add_difinitions() is used to add compilation options, which is essentially the - D option of the cmake instruction
  • If you want to add relevant features of c++11, such as nullptr, add this sentence and put it in add_ Before executable():
add_definitions(-std=c++11)
  1. If you want to place a single src subfolder cpp and h file, you need to add this sentence to the cmakelists in the root path, and add additional cmakelists files in the src folder.
    Refer to Teris source code. At this time, cmakelists in the home directory is mainly used to contain src folders, and executable files are not generated, while cmakelists in src will generate executable files.
add_subdirectory(src)
  1. include_ When adding the header file path to directories(), you need to add this sentence: note that if you are not sure about the path address, you can use locate XXX at the terminal H search the folder where the header file is located. The function of this sentence is equivalent to the function of - I in g + +.
  • There are two statements that can add header file paths. One is include_directories(), which needs to be placed before generating executable files.
    The other is target_include_directories(), which needs to be placed after generating the executable file.
include_directories(./common)

target_include_directories(main ./common)
  1. link_libraries() add so dynamic library file path, you need to add this sentence:
  • The default is found in the actual measurement The so path has only one / usr/lib, that is, the library file. If it is in this path, you do not need to manually link it.
    However, if it is not under this path or in a folder under this path, you need to manually link, that is, add a link_libraries(“lib_path.so”)
  • There are two statements that can implement link library files. One is link_libraries(path) this specifies the path of the library file before generating the executable file (it must be placed in front of add_executable()).
    Another statement can also implement the link library file, that is, target_link_libraries(main path) this is the link after the target executable is generated (it must be placed after add_executable())
    The difference between the two is that when defining the linked file, the function can be realized before or after the generation of the executable file.
  • Another way to implement the link library file is to add the path of the library file to CMAKE_INCLUDE_PATH, and then use find_path() instruction.
    But note: add to CMAKE_INCLUDE_PATH does not mean that he will provide the path to the compiler, or he needs to use find himself_ Path found the header file.
    The advantage of this method is that as long as it is added to the path, all find_ All instructions can be used
export CMAKE_INCLUDE_PATH=/usr/local/include/test   
find_path(myHeader hello.h)         // Find the header file and assign it to the variable myHeader
include_directories(${myHeader})    // Include the path
  • The third way to realize the link library file is to use find_package() to find the modules supported by cmake or customized modules to obtain the corresponding header file and library file path.
    This method refers to find_ Use of package().
  1. find_library() and find_path() looks for library files and header files
  • To find a library file, you need to provide the library file name and use find_ Library (VaR name hits path_suffixes suff1 suff2), that is, search the library file named name (the actual name is libname.so), and store it in var,
    It can take multiple key parameters, among which the hits key parameter represents the search path and PATH_SUFFIXES stands for path suffix
find_library(_NVINFER_LIB nvinfer HINTS ${TRT_LIB} PATH_SUFFIXES lib lib64)
  • To find the header file, you need to provide the header file name and use find_path()
  1. cmake advanced instruction find_package: is another method to find header files and library files. It is a common method for third-party libraries (such as CUDA/opencv).
  • If you want to use find_package() finds the header file and link library file path of the third-party library:
    Note: find is used_ The order in which the cmake modules of the package() command are searched is: first in the variable ${CMAKE_MODULE_PATH}, and then in / usr/shared/cmake/Modules /.
find_package(CUDA REQUIRED)           # Find the cmake module of a third-party library. For example, CUDA represents findcuda Cmake this module
find_package(OpenCV REQUIRED)         # Multiple libraries are searched separately, and then uniformly added to include_directories and links_ Libraries 
target_include_directories(tensorrt PUBLIC ${CUDA_INCLUDE_DIRS} ${TENSORRT_INCLUDE_DIR})
target_link_libraries(tensorrt ${CUDA_LIBRARIES} ${TENSORRT_LIBRARY} ${CUDA_CUBLAS_LIBRARIES} ${CUDA_cudart_static_LIBRARY} ${OpenCV_LIBS})
  • If you want to view all the module s and contents supported by cmake, go to the following path:
/usr/shared/cmake/Modules/    # All findxxxx in this path Cmake files are all cmake module files (most of them start with Find, and some don't)
  • If you want to define a cmake module for the library you write, it is essentially to find the header file and library file path yourself, and then put them into some variables.
    And cmake uniformly specifies the writing method of these variables: name_FOUND, name_INCLUDE_DIR, name_LIBRARY.
    Thus, as long as you know the module keyword (generally uppercase) of some libraries, and then run find_ Package (keyword), and then you can get two variables: keyword_ INCLUDE_DIR, keyword_ LIBRARY, so you can use include_directories(), link_libraries() is set.
#The following is a named findtest Cmake module: the keyword is TEST
# Find your own installed header file (test.h): to avoid different prefix path settings during installation, look for two default paths for storing header files at the same time, one is all user path and the other is login user path.
find_path(TEST_INCLUDE_DIR test.h /usr/include/mytest      # Means to find test H file. If it is found, assign the path to the variable TEST_INCLUDE_DIR
        /usr/local/include/mytest)              
# Find the dynamic library you installed (libmytest.so): in order to avoid different prefix path settings during installation, you can search in both paths at the same time
find_library(TEST_LIBRARY NAMES mytest PATH /usr/lib       #NAMES is a keyword, which means to find the header file named mytest (actual name libmytest.so). PATH is also a keyword, which means to find in the next two paths
        usr/local/lib)                         

if(TEST_INCLUDE_DIR AND TEST_LIBRARY)      # Set flag if found
    set(TEST_FOUND TRUE)
endif(TEST_INCLUDE_DIR AND TEST_LIBRARY)
  • Visible: if you know the file path of the header file library, you can directly use target_include_directories() and target_link_libraries().
    If you don't know the file path of the header file library, there are two other methods, one is find_package() is equivalent to assigning a value to a variable and then using target_include_directories() and target_link_libraries() can be set.
    The other uses find_library() and
  1. message() outputs a message:
  • The output type can be selected: status (output information prefixed with -), send_ Error, fatal_ Error (terminate cmake procedure)
message(STATUS "messages")  
  1. file() operations on files and folders: such as searching for files, opening files, and writing files
  • If you want to automatically search all supporting files, consider the automatic search command
file(GLOB Sources *.cpp)
file(GLOB Includes *.h)
add_executable(Cars ${Sources} ${Includes})
  • If you want to create a folder path:
file(MAKE_DIRECTORY ${xxx})   # Create a path folder
  1. add_library() if you want to generate a dynamic or static link library, use add_library
  • You can choose to generate SHARED dynamic library or STATIC static library
  • Note: the library name does not need to be prefixed with lib. The system will automatically add lib before the given library name
// Create dynamic library
add_library(algorithms SHARED ${src_path})  // Create a dynamic link library: the library name is libalgorithms and shared is so dynamic link library, src_path is cpp file path
// Create static library
set_target_properties(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)         // Set not to clear the dynamic library with the same name hello so
set_target_properties(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)  // Set not to clear the static library with the same name hello a
set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello")    // Set the output name of the static library to hello, so that it can be realized even if it has the same name as the dynamic library

  1. install() if you want to install the generated header and library files:
  • There are three kinds of target files that can be generated: RUNTIME is an executable file, LIBRARY is a dynamic LIBRARY, and ARCHIVE is a static LIBRARY
  • The installation path can be specified and followed by the keyword DESTINATION. Note that the path starting with / is an absolute path. If it does not start with a slash, it is based on cmake by default_ INSTALL_ Prefix, i.e. {CMAKE_INSTALL_PREFIX} / relative path
  • Note that if you want to install in clion, you also need to manually enter the project cmake build debug folder and execute sudo make install. Otherwise, clion will not automatically install for you.
// Install header file
install(FILES hello.h DESTINATION include/hello)  //Install header file
// Install the bin/lib library file or header file
${CMAKE_INSTALL_PREFIX}                     // This path can be used in the cmake command through - D CMAKE_INSTALL_PREFIX=/usr to set to absolute path
install(TARGETS myrun mylib mystaticlib     // Indicates that there are three target files, corresponding to the following three lines
        RUNTIME DESTINATION bin             // The target file type is RUNTIME, that is, the executable file, which is stored
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION libstatic)      // Install header and library files
install(TARGETS test test_static            // Also install the dynamic library test So and static library test_static.a
        LIBRARY DESTINATION lib             // The dynamic library installation path is a relative path / lib
        ARCHIVE DESTINATION lib)            //
// Install sh header file:
install(PROGRAMS runhello.sh DESTINATION bin)// Install sh file

Keywords: C++ cmake Ubuntu IDE

Added by blen on Tue, 11 Jan 2022 12:18:29 +0200