[c + + compilation] makefile and CMake

Posted by webspinner on Fri, 24 Dec 2021 22:12:38 +0100

Brief introduction

We usually use makefile files to organize large-scale C/C + + or projects with multiple C/C + + files. Some people think that makefile is inconvenient, so they invented CMake.

CMake generates a makefile file from the file containing the CMake instruction. The name of the file containing the CMake instruction is generally cmakelists Txt, using CMake is a common way to organize and manage C/C + + projects in actual development, and it is also applicable to most C/C + + open source projects.

For some open source projects under Linux, cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist. Cmakelist Txt file, then execute CMake command to generate makefile rule file, and then execute make command to compile the project with gcc/g + +. There are also some open source projects. After executing the configure command, the makefile rule file will be generated directly, and then the make command will be executed to compile the project using gcc/g + +.

CMakeList. An example of TXT is as follows:

cmake_minimum_required(VERSION 2.6)

project (FLAMGINGO_SERVER)

#CMAKE_CXX_FLAGS specifies the g + + compilation options
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -g -Wall -o0 -Wno-unused-variable -pthread")

link_directories(
	${PROJECT_SOURCE_DIR}/lib
	/usr/lib64/mysql/
)

set(net_srcs
base/AsyncLog.cpp
base/ConfigFileReader.cpp
base/Platform.cpp

net/Acceptor.cpp
net/BytesBuffer.cpp
net/Channel.cpp
)

set(mysqlapi_srcs
mysqlapi/DatabaseMysql.cpp
mysqlapi/Field.cpp
mysqlapi/QueryResult.cpp
)

set(chatserver_srcs
chatserversrc/main.cpp
chatserversrc/ChatServer.cpp
chatserversrc/ChatSession.cpp
)

set(fileserver_srcs
fileserversrc/main.cpp
fileserversrc/FileServer.cpp
fileserversrc/FileSession.cpp	
)

set(imgserver_srcs
imgserversrc/main.cpp
fileserversrc/FileServer.cpp
fileserbersrc/FileSession.cpp
)

add_executable(chatserver ${net_srcs} ${chatserver_srcs} ${mysqlapi_srcs})
#It is useless to include only the library directory. You must also use TARGET_LINK_LIBRARIES links the library
#Specify other libraries on which the generated binary depends
TARGET_LINK_LIBRARIES(chatserver mysqlclient)

add_executable(fileserver ${net_srcs} ${fileserver_srcs})
#Specify other libraries on which the generated binary depends
TARGET_LINK_LIBRARIES(fileserver)

add_executable(imgserver ${net_srcs} ${imgserver_srcs})
#Specify other libraries on which the generated binary depends
TARGET_LINK_LIBRARIES(imgserver)

Example 2:

PROJECT(TRADE)

#Specify source directory
AUX_SOURCE_DIRECTORY(./ SRC_LIST)

#EXECUTABLE_OUTPUT_PATH specifies the path to the output binary file
SET(EXECUTABLE_OUTPUT_PATH ../bin)

ADD_DEFINITIONS(-g -o0 -W -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO -DAC_HAS_WARNING -DAC_HAS_ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL -DHAVE_CXX_STDHEADERS -Wno-deprecated ${CMAKE_CXX_FLAGS})

#Specify the include directory
INCLUDE_DIRECTORIES(
./
/usr/local/include/commonlib/json2
/usr/local/include/commonlib/mysql
)

LINK_DIRECTORIES(
./
/usr/local/lib/commonlib
)

ADD_EXECUTABLE(trade ${SRC_LIST})

#Specify other libraries on which the generated binary depends
TARGET_LINK_LIBRARIES(trade pthread netutil json2 mysqlclient dbapi)

The following is an analysis of some contents in the above code:

  1. CMake in the first line_ minimum_ The required directive specifies that the cmakelist.xml file is supported The CMake minimum version number of the txt file.
  2. The project directive specifies the name of the project. Note that the project name is not the final binary program name. Multiple binary program names can be generated under a project.
  3. Set defines and sets various variables. The first name after the set bracket is the name of the defined variable, followed by the value of the variable. For example, the above file defines CMAKE_CXX_FLAGS,net_srcs,mysqlapi_srcs,chatserver_srcs,fileserver_srcs,imgserver_srcs has six variables. These variables can then be referenced using ${variable name}. These variables can be built-in variables, such as CMAKE_CXX_FLAGS specifies the g + + compilation option, EXECUTABLE_OUTPUT_PATH specifies the binary file path of the output. It can also be a custom variable, such as chatserver_srcs,fileserver_srcs et al.
  4. CMake using aux_ SOURCE_ The directory directive specifies the source directory and uses include_ The directories directive specifies the include directory, using link_directories specifies the lib directory.
  5. The name of the dynamic library or static library generated by CMake using the instruction. The format is as follows:
add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 .. sourceN)

For example:

add_library(hello hello1.cpp hello2.cpp)

We don't need to write all libhello So or libhello a. Just fill in the hello, and CMake will automatically generate libhello X. There are three types:
a) SHARED: dynamic library (extension. so)
b) STATIC: static library (extension. a)
c) MODULE: valid in systems using dyld. If dyld is not supported, it will be treated as SHARED.

EXCLUDE_ FROM_ The all parameter means that the library will not be built by default unless there are other component dependencies or built manually.

The following command will generate a libkafkawrapper So file, and libapple The generation of so file depends on librdkafka so,librdkafka++.so,libcrypto.so,libssl.so these four libraries:

add_library(libkafkawrapper SHARED ${kafka_wrapper_srcs})
TARGET_LINK_LIBRARIES(kafkawrapper rdkafka rdkafka++ crypto ssl)
  1. TARGET_LINK_LIBRARIES specifies other libraries on which the generated binary depends.

Finally, after writing cmakelist Txt file, enter cmakelist Txt file, execute the following commands in sequence to generate the final binary file:

#Generating makefile using cmake
cmake .
#Execute the make command, compile the source file described by the makefile file with gcc/g + +, and finally generate the final binary file
make

CMakeList.txt also supports recursive execution. First execute CMakeList.txt of the parent directory Txt file, and then execute CMakeList.txt in the subdirectory Txt file.

For Linux programs that can be compiled with CMake (that is, CMakeList.txt file is provided), we can use CMake to generate Visual Studio project files on Windows.

Introduction to CMake

CMake is a cross platform open source project management tool. What CMake does is actually tell the compiler how to compile the linked source code. Similarly, the makefile file is written directly, but the biggest disadvantage of makefile is that it cannot cross platform. Once the environment is changed, it will be rewritten. Therefore, we can use CMake to write CMakeLists file to solve this problem.

Check if CMake is installed

First, check whether CMake is installed. Enter cmake --version in the terminal to check. If it is not installed, you can use sudo apt get install camke (Ubuntu) or break install CMake (MacOS). windows can directly download it from the official website to install CMake.

Common instructions

#cmake minimum version requirements
cmake_minimum_required(VERSION xxx)

#Set the name of this item
project(xxx) 

#Generate executable target, followed by the list of source files on which the executable depends.
add_executable(target target_source_codes) 

# Set a name var_name, and assign VaR to this variable_ value
SET(var_name var_value)

# Specifying Compilers 
# CMAKE_ C_ FLAGS_ Debug -- C compiler
# CMAKE_ CXX_ FLAGS_ Debug -- C + + compiler
# -std=c++11 use C++11
# -g: Only the compiler generates debugging information when compiling.
# -Wall: generate all warning messages. The following are specific options that can be used separately
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  -std=c++11   -g  -wall  ")
add_definitions(${CMAKE_CXX_FLAGS})

#Specify the compilation type, debug or release
# debug will generate relevant debugging information, which can be performed using GDB
# release does not generate debugging information. When debugging is not possible, check whether it is set to debug
set(CMAKE_BUILD_TYPE Debug)

# Print message
MESSAGE("MSG") 

#Given variable var_name is assigned to var_value and comment are the comments of this variable. They have the same effect as SET and are used to SET the default value for a variable
option(var_name "comment" var_value) 

# Add the include path, that is, the header file path
include_directories(xxx) 

# Call cmakelists.xxx subdirectory Txt execution
add_subdirectory(xxx) 

# Add xxx parameter to compiler
add_compile_options(xxx)

# Add a library directory to the compiler,
link_directories(xxx)

# Generate library files. SHARED represents dynamic library, STATIC represents STATIC library, and the last parameter represents the source file list of this library
add_library(lib_name SHARED or STATIC lib_source_code) 

# Add dependent library to target
target_link_libraries(target_name lib_name ...)

Simple application

The following figure shows the general project file format. include stores header files, src stores source code files, and build stores temporary compiled files.

Assuming that the project folder is called Test, we can add CMakeLists Txt files are placed in the Test folder, that is, the same level directory of src and include. The following is a simple CMakeLists file format.

# Minimum specified CMake version
cmake_minimum_required(VERSION 3.0)

# Fill in your project name in brackets
PROJECT(Test)

# Header file path
INCLUDE_DIRECTORIES(include)
INCLUDE_DIRECTORIES(/usr/local/include/)

# Find all cpp files under src, and then save the results into the specified variable name (here is DIR_SRCS)
AUX_SOURCE_DIRECTORY(src DIR_SRCS)

# Specify the language requirements. The following command is c++ 11
SET(CMAKE_CXX_STANDARD 11)

# Generate an executable file, and the generated test is the executable file
add_executable(test ${DIR_SRCS})

Because many intermediate files will be generated during this process, we use the cmake command in the build folder, so that these files can be placed in the build folder, and then make can run:

cd build
cmake ..
make
./test

Topics: C++ Linux Visual Studio