Article directory
1 Introduction
Official website address:
https://cmake.org
CMake is a cross-platform installation (compilation) tool, which can describe the installation (compilation process) of all platforms with simple sentences. It can output various makefiles or project files, and can test the C++ features supported by the compiler, similar to automake under UNIX. It's just that the configuration file of CMake is named CMakeLists.txt.
2. Download cmake
(1) Official website download address one
https://cmake.org/download/
(2) Official website download address 2
https://cmake.org/files/
(3) GitHub download address:
https://github.com/Kitware/CMake/releases
Under the ubuntu system, only the following command is required:
# ubuntu
sudo apt install cmake
CMake provides a variety of versions, including but not limited to "RC version" (Release Candidate) and "stable version" (Latest Release). Switch to the directory where the system stores the source code, and then use the curl command to download the binary distribution compressed package of CMake through this link:
cd /usr/local/src
curl -LO https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz
# or
yum install -y wget
wget -c https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz
# wget -c https://cmake.org/files/v3.26/cmake-3.26.0-rc1-linux-x86_64.tar.gz
3. Install cmake
After the CMake binary distribution compressed package is downloaded, run the following two commands to decompress the compressed package, move the obtained folder to the local program directory of the system, and rename the folder to cmake (ie /usr/local/cmake ):
tar -xvf cmake-3.26.0-rc1-linux-x86_64.tar.gz
# tar zxvf cmake-3.22.2-linux-x86_64.tar.gz
mv cmake-3.26.0-rc1-linux-x86_64 /usr/local/cmake
View the path after installation:
ls /usr/local/cmake
If you are installing CMake for the first time according to the steps in this article, for the convenience of running CMake related commands later, please run the following two commands to add the CMake executable file directory to the system environment variable PATH:
echo 'export PATH="/usr/local/cmake/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
View ~/.bashrc:
vi ~/.bashrc
#在最后添加export PATH=/usr/local/cmake/bin:$PATH
Check the version of cmake:
cmake --verison
4. Test cmake
4.1 Single source file
main.c:
#include <stdio.h>
int main(void)
{
printf("Hello World\n");
return 0;
}
Then write CMakeLists.txt in the same directory as main.c:
cmake_minimum_required (VERSION 2.8)
project (demo)
add_executable(main main.c)
Excuting an order:
cmake .
Let's take a look at the files in the directory again. The Makefile was successfully generated, and there are some files automatically generated when cmake runs:
View Makefile:
vi Makefile
Enter the make command to compile:
make
ls
./main
#make clean
4.2 Multiple source files in the same directory
Install the tree command to view the hierarchical relationship of folders:
ubuntu:sudo apt-get install tree
centos:yum -y install tree
tree ./
Modify CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (demo)
add_executable(main main.c anotherTest.c)
Excuting an order:
cmake .
ls
make
./main
If there are multiple source files in the same directory. cmake provides a command to store all source files in a specified directory in a variable, this command is aux_source_directory(dir var). The first parameter dir is the specified directory, and the second parameter var is the variable used to store the list of source files.
Modify CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (demo)
aux_source_directory(. SRC_LIST)
add_executable(main ${SRC_LIST})
Use aux_source_directory to store the source file storage list in the current directory into the variable SRC_LIST, and then call SRC_LIST in add_executable (note the way of calling the variable).
aux_source_directory() also has disadvantages. It will add all the source files in the specified directory, and may add some files we don’t need. At this time, we can use the set command to create new variables to store the required source files, as follows:
cmake_minimum_required (VERSION 2.8)
project (demo)
set( SRC_LIST
./main.c
./anotherTest.c)
add_executable(main ${SRC_LIST})
4.3 Multiple source files in different directories
Modify CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (demo)
include_directories (test1 test2)
aux_source_directory (test1 SRC_LIST)
aux_source_directory (test2 SRC_LIST1)
add_executable (main main.c ${SRC_LIST} ${SRC_LIST1})
4.4 Standard Organizational Structure
Generally, the source files are put in the src directory, the header files are put in the include file, the generated object files are put in the build directory, and the final output elf file is put in the bin directory, so that the whole structure is clearer.
Modify CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (demo)
add_subdirectory (src)
Here, the source files are stored in the src directory. When cmake is executed, it will enter the src directory to find the CMakeLists.txt in the src directory, so create a CMakeLists.txt in the src directory: add CMakeLists.txt
:
aux_source_directory (. SRC_LIST)
include_directories (../include)
add_executable (main ${SRC_LIST})
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
There is a new command set here, which is used to define variables. EXECUTABLE_OUT_PATH and PROJECT_SOURCE_DIR are predefined variables that come with CMake. Their meanings are as follows.
EXECUTABLE_OUTPUT_PATH: The storage location of the target binary executable file
PROJECT_SOURCE_DIR: The root directory of the project
Create a new build folder and enter:
mkdir build
cd build
cmake ..
make
ls
../bin/main
You can also use only one CMakeLists.txt, and change the content of the outermost CMakeLists.txt as follows:
cmake_minimum_required (VERSION 2.8)
project (demo)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
aux_source_directory (src SRC_LIST)
include_directories (include)
add_executable (main ${SRC_LIST})
4.5 Compilation of dynamic library and static library
Sometimes it is necessary to compile dynamic libraries and static libraries, and then wait for other programs to use them. The test project folder is as follows:
- The Windows example is as follows:
The content of CMakeLists.txt is as follows:
cmake_minimum_required (VERSION 2.8)
project (myrand)
# find *.cpp *.c
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/getRandomAPI.cpp)
# find *.h
include_directories (${PROJECT_SOURCE_DIR}/include)
########################################
# create lib and dll
add_library (myrand_shared SHARED ${SRC_LIST})
add_library (myrand_static STATIC ${SRC_LIST})
set_target_properties (myrand_shared PROPERTIES OUTPUT_NAME "myrand")
set_target_properties (myrand_static PROPERTIES OUTPUT_NAME "myrand_s")
set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
########################################
# create exe
add_compile_options(-std=c++11 -Wall)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_executable (myrand_test ${SRC_LIST})
命令解释如下:
(1)add_library: 生成动态库或静态库(第1个参数指定库的名字;第2个参数决定是动态还是静态,如果没有就默认静态;第3个参数指定生成库的源文件)
(2)set_target_properties: 设置最终生成的库的名称,还有其它功能,如设置库的版本号等等
(3)LIBRARY_OUTPUT_PATH: 库文件的默认输出路径,这里设置为工程目录下的lib目录
Run cmake in the build directory, and store the generated library files (.dll, .lib) in the lib folder, and put the exe in the bin folder. Execute the command as follows:
cd C:\Users\tomcat\Desktop\test_cmake
mkdir build
cd build
cmake ..
Open the build folder as follows:
Compile myrand.sln through the command line, as follows.
# release x64(默认)
cd C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE
.\devenv.com C:\Users\tomcat\Desktop\test_cmake\build\myrand.sln /Build
# or debug x64
.\devenv.com F:\00Projects\test.sln /Build "Debug|64"
# or debug win32
.\devenv.com F:\00Projects\test.sln /Build "Debug|Win32"
The running results are as follows:
the running result folder is as follows:
4.6 Linking the library
Add a main.cpp in the src directory and call the library file generated in the above section.
cmake_minimum_required (VERSION 2.8)
project (myrand_test)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.cpp)
# find *.h
include_directories (${PROJECT_SOURCE_DIR}/include)
find_library(TEST_LIB NAMES myrand HINTS ${PROJECT_SOURCE_DIR}/lib/debug)
add_executable (test ${SRC_LIST})
target_link_libraries (test ${TEST_LIB})
Excuting an order:
cmake ..
4.7 Add compilation options
Add some compilation options, such as -Wall, -std=c++11, etc., and you can use add_compile_options to operate.
cmake_minimum_required (VERSION 2.8)
project (test)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_compile_options(-std=c++11 -Wall)
add_executable(test main.cpp)
4.8 Add control options
Sometimes only compile some specified source code, you can use the cmake option command:
1、本来要生成多个bin或库文件,现在只想生成部分指定的bin或库文件
2、对于同一个bin文件,只想编译其中部分代码(使用宏来控制)
The content of CMakeLists.txt is as follows:
cmake_minimum_required(VERSION 3.0)
project(test)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.cpp)
set (SRC_LIST2 ${PROJECT_SOURCE_DIR}/src/main2.cpp)
option(USE_TEST_1 "use test 1" OFF)
option(USE_TEST_2 "use test 2" OFF)
option(USE_TEST_3 "use test 3" OFF)
if (USE_TEST_1)
add_definitions(-DTEST_1)
endif()
if (USE_TEST_2)
add_definitions(-DTEST_2)
endif()
if (USE_TEST_3)
add_definitions(-DTEST_3)
endif()
add_executable(main ${SRC_LIST})
if (USE_PROJECT2)
add_executable(main2 ${SRC_LIST2})
else()
message(STATUS "No project main2")
endif()
main.cpp:
#include <windows.h>
#include <iostream>
int main()
{
#ifdef TEST_1
printf("getRandom_1\n");
#endif
#ifdef TEST_2
printf("getRandom_2\n");
#endif
#ifdef TEST_3
printf("getRandom_3\n");
#endif
system("pause");
return 0;
}
cmake .. -DTEST_3=ON -DTEST_2=OFF -DUSE_PROJECT2=OFF
cmake .. -DTEST_3=ON && make
5. Build a minimal project
5.1 Create a new code file
Edit the code file: tutorial.cpp
- tutorial.cpp
// tutorial.cpp
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " number" << std::endl;
return 1;
}
// convert input to double
const double inputValue = atof(argv[1]);
// calculate square root
const double outputValue = sqrt(inputValue);
std::cout << "(爱看书的小沐)The square root of " << inputValue
<< " is " << outputValue
<< std::endl;
return 0;
}
5.2 Create a new CMakeLists.txt
Create a new file in the same folder: CMakeLists.txt.
- CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
# set the project name
project(Tutorial)
# add the executable
add_executable(Tutorial tutorial.cpp)
cmake_minimum_required: specifies the minimum version number of CMake,
project: specifies the project name,
add_executable: is used to generate an executable file, and needs to specify the name of the generated executable file and related source files.
Now start building, compiling and running the above code example.
5.3 Building the project
In the current project working folder, create a build directory build. Next, enter the build directory and run CMake to configure the project and generate the build system.
mkdir build
cd build
cmake ..
- Command execution status:
- The generated files and folders are as follows:
5.4 Compile the project
Then invoke that build system to actually compile/link the project:
cmake --build .
- The generated files and folders are as follows:
5.5 Running the project
.\debug\Tutorial.exe 3.14
The result of the operation is as follows:
5.6 Modify related files
Edit the code file: CMakeLists.txt
- CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
## set the project name
# project(Tutorial)
project(Tutorial VERSION 1.2.3)
string(TIMESTAMP COMPILE_TIME %Y%m%d-%H%M%S)
configure_file(TutorialConfig.h.in TutorialConfig.h)
# set(SRC_LIST a.cpp b.cpp c.cpp)
SET(SRC_LIST tutorial.cpp)
## add the executable
# add_executable(Tutorial tutorial.cpp)
# add_executable(${PROJECT_NAME} tutorial.cpp)
# add_executable(${PROJECT_NAME} a.cpp b.cpp c.cpp)
add_executable(${
PROJECT_NAME} ${
SRC_LIST})
target_include_directories(${
PROJECT_NAME} PUBLIC
${
PROJECT_BINARY_DIR} )
New file: TutorialConfig.h.in
- TutorialConfig.h.in
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define Tutorial_VERSION_PATCH @PROJECT_VERSION_PATCH@
#define TIMESTAMP @COMPILE_TIME@
Edit the code file: tutorial.cpp
- tutorial.cpp
// tutorial.cpp
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
#include "TutorialConfig.h"
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
<< Tutorial_VERSION_MINOR << std::endl;
std::cout << "Usage: " << argv[0] << " number" << std::endl;
return 1;
}
// convert input to double
const double inputValue = atof(argv[1]);
// calculate square root
const double outputValue = sqrt(inputValue);
std::cout << "(爱看书的小沐)The square root of " << inputValue
<< " is " << outputValue
<< std::endl;
return 0;
}
Execute the following command:
cmake --build .
.\debug\Tutorial.exe
Make file: TutorialConfig.h
TutorialConfig.h:
epilogue
如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;
╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地
//(ㄒoㄒ)// ,就在评论处留言,作者继续改进;
o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;
(✿◡‿◡)
感谢各位大佬童鞋们的支持!
(´▽´)ノ (´▽´)! ! !