CMake is a cross-platform compilation tool that can be written in one go and automatically generate corresponding makefiles for different platforms, reducing the time spent on hand-written makefiles and adapting to different platforms.

preface

Most of the time I used VS development on the Windows side, so I had little exposure to makefiles, CMake and other tools. I recently tried to implement a simple HTTP server from scratch, mainly in Linux, so I took this opportunity to familiarize myself with building tools like CMake.

The directory structure

Currently, there are fewer project files and a simpler directory structure is used

┣━ SRC ┃ ┣━ Cmakelists. TXT ┃ ┣━ Httprequest. CPP ┃ ┣━ Httpresponse. CPP open service ━ httpServer. CPP open service... ┣━ include ┃ ┣━ Httprequest. h ┃ ┣━ Httpresponse. h ┃ ┣━ httpServer. h ┃... ┣ ━ cmake - build - the debug ┃ ┣ ━... ┃ ┗ ━... ┣ ━ main. CPP ┣ ━ CMakeLists. TXTCopy the code

You can see that the source and header files are stored in their respective directories, the root directory uses main. CPP as the program entry, and the final build target and intermediate files are stored in a separate folder called cmake-build-debug.

CMakeLists write

In order to make the above directory structure can compile links correctly, we need to write cmakelists. TXT, and CMake can reduce the headache of link order when multiple files and multiple directories to a certain extent. In this project, there is a cmakelists. TXT file in the root directory and a CMake file in the SRC directory, which is also a feature of CMake. You can split the Makefile, compile each directory separately, and eventually link it together.

The contents of cmakelists.txt in the root directory are as follows

Cmake_minimum_required (VERSION 2.6) add_definitions(-std=c++11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -wall-wno-unused-variable-pthread ") project (Minihttpd) include_directories(include) add_subdirectory(SRC) Target_link_libraries link_directories(/usr/local/lib) add_EXECUTABLE (Minihttpd main.cpp) target_link_libraries(Minihttpd src) target_link_libraries(Minihttpd -lconfig++)Copy the code

A brief explanation of each statement follows

  • The add_definations directive can be used to manually set the open and close of certain macros and control compilation options, primarily using the c++11 standard for annotation
  • The set directive replaces the string with the preceding variable. This is actually a modification of the predefined CMAKE_CXX_FLAGS variable to set some options, primarily linking the pthread library to use multiple threads
  • The project directive is used to set the project name (including version, language and other information, which is the default).
  • The include_directories directive specifies the path to find header directories. Add the include directory to the header directory search so that files within the project can find the corresponding header file
  • The add_subdirectory directive is used to add subdirectories to the build list, and the final build is stored in the SRC variable

The next few lines are where the project needs to reference other dynamic link libraries, which is very important

  • The add_executable directive is used to specify the final build object file for the project, as well as all required source files. You can see that there is only main. CPP. Why not include other source files in SRC? The target_link_libraries directive is introduced below as a dynamically linked library. The libsrc.a file is generated in the SRC directory, and finally linked to the program entry file to implement the build.
  • The link_directories and target_link_libraries directives are used to introduce external dynamic linked libraries. Among them
    • Link_directories specifies the directory where the dynamic link library is located
    • Target_link_libraries is used to introduce the required dynamic link libraries into the project

The important thing here is the order of the statements, it must be

  1. Link_directories adds the dynamic link library directory to the search list
  2. Add_executable specifies the final build target name
  3. Target_link_libraries adds the required dynamic link libraries to the project

The wrong order here will cause links to fail, unable to find the dynamic link library, and all sorts of problems (stomped pits, sad tears)

The contents of cmakelists. TXT in the subdirectory are as follows

aux_source_directory(. srcs)
add_library(src ${srcs})
Copy the code

This is pretty simple

  • The aux_source_directory directive adds all source files in the current directory to the SRCS variable for storage
  • Add_library is built using all the source files in the SRCS variable, resulting in SRC output. Unlike ADD_executable, add_library builds a dynamic link library file as the ultimate goal, whereas add_executable builds an executable file. The dynamic link library file is also built for linking when building in the root directory

extension

After understanding the compilation of CMakeLists under multiple directories, if the source files need to be stored in multiple directories, they can also be built and linked separately in the form of dynamic link library. For multi-level directories, you can build and link them one by one.

External dynamically linked libraries that need to be referenced can also be imported through a combination of link_directories and target_link_libraries directives.

Meanwhile, ninja was used as a construction tool in this project to facilitate the construction of the project. The main methods are as follows

cd cmake-build-debug cmake -G Ninja .. // Cmake supports automatic generation of Ninja files such as Ninja. Build required by cmakelists. TXT ninja // Build in this directoryCopy the code