当前位置:网站首页>Cmake basic use
Cmake basic use
2022-07-03 00:17:00 【JunesFour】
CMake Basic use
List of articles
1. Linux Environmental installation
install gcc Software dependency
yum install -y gcc gcc-c++ make automake # The output version is installed successfully gcc -vDownload the latest CMake
# Unzip after download tar -xvf [ Compressed package ]Go to the root directory , Run the command
./bootstrapIf the following error occurs :

Run the command :yum install -y openssl openssl-develThen run it again
./bootstrapfunction gmake
gmakeInstallation
gmake installInput
cmake -v, If the version number appears, the installation is successful :
2. Use CMake function C++ Program
2.1 Run a simple sample program
use vim Write a paragraph C++ Code :
#include <iostream>
using namespace std;
int main() {
cout << "hello world" << endl;
}
Write in the same directory CMakeLists.txt file :
PROJECT (HELLO)
SET(SRC_LIST main.cpp)
MESSAGE(STATUS "This is BINARY dir" ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir" ${HELLO_SOURCE_DIR})
ADD_EXECUTABLE (hello ${SRC_LIST})
Use CMake Generate Makefile file :
cmake .
The following files are automatically generated :

Use make Command compilation :
make

Compiled an executable 
Run the executable :
hello

3. CMake Basic grammar
Use the above CMakeLists.txt File as an example :
PROJECT (HELLO)
SET(SRC_LIST main.cpp)
MESSAGE(STATUS "This is BINARY dir" ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir" ${HELLO_SOURCE_DIR})
ADD_EXECUTABLE (hello ${SRC_LIST})
3.1 keyword
PROJECT keyword
It can be used to specify the name of the project and the supported language , All languages are supported by default .PROJECT (HELLO): Specifies the name of the project , And support all languages .PROJECT (HELLO CXX): It specifies The name of the project , And the supported language is C++.PROJECT (HELLO C CXX): Specifies the name of the project , And the supported language is C and C++.
The instruction implicitly defines two CMAKE The variable of <projectname>_ BINARY_ DIR, In this case, it is HELLO_ BINARY_ DIR.<projectname>_ SOURCE_ DIR, In this case, it is HELLO_ SOURCE DIR.MESSAGE Keyword can directly use these two variables , Currently all point to the current working directory , We will talk about external compilation later .
problem : If the project name is changed , The names of these two variables will also change .
solve : have access to CMake Two predefined variables for us : PROJECT_ BINARY_ DIR and PROJECT_SOURCE_ DIR, These two variables and HELLO_ BINARY_ DIR, HELLO_ SOURCE_ DIR It's consistent .
SET keyword
Specified variables for display .SET(SRC_ LIST main.cpp) Directive SRC_ LIST Variables contain main.cpp.
If there are more than one cpp file , It's fine too SET(SRC_LIST main.cpp t1.cpp t2.cpp).
MESSAGE keyword
Output user-defined information to the terminal
It mainly contains three kinds of information :
SEND_ ERROR, Make a mistake , The generation process was skipped .SATUS, The output prefix is-Information about .FATAL_ ERROR, Terminate all... Immediately cmake The process .
ADD_EXECUTABLE keyword
Generate executable files ADD_ EXECUTABLE(hello ${SRC_ LIST}) The instruction indicates that the generated executable file name is hello, Read variables from the source file SRC_ LIST The content in .
You can also write directly ADD_ EXECUTABLE(hello main.cpp).
So the project name HELLO And the generated executable file name hello It doesn't matter .
The above example can be simplified as :
PROJECT(HELLO)
ADD_EXECUTABLE(hello main.cpp)
3.2 Basic principles of grammar
- Variable usage
${}Method value , But in IF Variable names can be used directly in control statements . - Instructions ( Parameters 1 Parameters 2…) Parameters are enclosed in brackets , Parameters are separated by spaces or semicolons . On the surface of the above
ADD_ EXECUTABLEInstruction as an example , If there is anotherfunc.cppSource file
It's about to be written :ADD_ EXECUTABLE(hello main.cpp func.cpp)perhapsADD_ EXECUTABLE(hello main.cpp;func.cpp). - Instructions are case independent , But parameters and variables are case dependent . It is recommended to use all uppercase instructions .
SET(SRC_ LIST main.cpp)It can be written.SET(SRC_ LIST "main.cpp"), But if the source file name contains spaces , You have to put double quotes .
3.3 Internal build and external build
- Internal build : The above example is an internal build , There are many temporary documents for production , Inconvenient to clean .
- External build : Will put the generated temporary files in
buildUnder the table of contents , It will not have any impact on the source file , It is recommended to use external construction .
External build
Back to just finished writing CMakeLists.txt When you file :
Create a build Directory and access :
mkdir build
cd build
stay build Execute... In directory cmake command :
cmake ..
stay build Execute... In directory make command :
make
The generated temporary files will be in build Directory :

4. Engineering projects
- Add a subdirectory to the project
src, Used to place engineering source code . - Add a subdirectory
doc, The document used to place the projecthello.txt. - Add a text file to the project directory
COPYRIGHTREADME. - Add a
runhello.shScript , Used to callhelloBinary system . - Put the built object file into the
binsubdirectories . - take
docThe contents of the catalog andCOPYRIGHT/READMEThe installation to/usr/share/doc/cmake/.
.
├── build
├── CMakeLists.txt
├── COPYRIGHT
├── doc
│ └── hello.txt
├── README
├── runhello.sh
└── src
├── CMakeLists.txt
└── main.cpp
4.1 Generate binaries to bin Directory
There should be one under each directory CMakeLists.txt explain :
.
├── build
├── CMakeLists.txt
└── src
├── CMakeLists.txt
└── main.cpp
Outer layer CMakeLIsts.txt:
PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)
src Under the CMakeLists.txt:
ADD_EXECUTABLE(hello main.cpp)
ADD_SUBDIRECTORY Instructions
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
- This command is used to add a subdirectory for storing source files to the current project , And you can specify the location where the intermediate binary and the target binary are stored .
EXCLUDE_FROM_ALLThe function is to exclude the written directory from compilation , As in the program example.ADD_SUBDIRECTORY(src bin)
take src Add the subdirectory to the project and specify the compilation output ( Contains intermediate results of compilation ) Path is bin Catalog
If not bin The designation of the directory , So the compilation results ( Including intermediate results ) Will be stored in build/src Catalog .
Change the binary save path
SET Instruction redefines EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_ PATH Variable to specify the location of the final target binary :
SET(EXECUTABLE_OUTPUT_PATH ../../src/bin)
SET(LIBRARY_OUTPUT_PATH ../../src/lib)
Be careful : Where to change the target storage path , Where to add the above definition , So it's in src In the catalog CMakeLists.txt Write in .
Execute again after the change :
.
├── build
├── CMakeLists.txt
└── src
├── bin
│ └── hello
├── CMakeLists.txt
└── main.cpp
You can see the executable hello It's already here src/bin Under the table of contents .
4.2 Use CMake Installation
The installation files COPYRIGHT and README
In the root directory CMakeLists.txt Add to file :
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/)
FILES: file name .
DESTINATION:
1. You can write the absolute path directly .
2. You can also write relative paths , Relative path actual path is :${CMAKE_INSTALL _PREFIX}/<DESTINATION> Defined path .CMAKE_JINSTALL_PREFIX The default is in /usr/local/.cmake-DCMAKE_JNSTALL_PREFIX=/usr stay cmake When it's time to specify CMAKE_ JNSTALL_ PREFIX The path of the variable .
set up script runhello.sh
PROGRAMS: Executable installation of non target files ( Like scripts and so on ).
In the root directory CMakeLists.txt Add to file :
INSTALL(PROGRAMS runhello.sh DESTINATION bin)
explain : The actual installation is /usr/bin.
install doc In the catalog hello.txt
In the root directory CMakeLists.txt Add to file :
INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake)
DIRECTORY What's connected behind is where Source Relative path to directory .
Be careful : abc and abc/ There's a big difference
- The directory name does not start with / ending : This directory will be installed as... Under the target path abc.
- The directory name is as follows / ending : Install the contents of this directory to the target path .
install
cd build
cmake ..
make
make install

5. Construction and use of static library and dynamic library
The difference between static library and dynamic library :
- The extension of a static library is generally ".a” or ".lib"; Extension of dynamic library - - General ".so" or ".dIl".
- Static libraries are directly integrated into the target program at compile time , The compiled executable can run independently .
- The dynamic library will not be put into the connected target program at compile time , Executable files cannot be run alone .
Now let's create a static library and a dynamic library , Provide HelloFunc Function for programming other programs ,HelloFunc Output to the terminal Hello World character string .
Build instance :
.
├── build
├── CMakeLists.txt
└── lib
├── CMakeLists.txt
├── hello.cpp
└── hello.h
hello.h The content in :
#ifndef HELLO_H
#define Hello_H
void HelloFunc();
#endif
hello.cpp The content in :
#include "hello.h"
#include <iostream>
using namespace std;
void HelloFunc() {
cout << "hello world" << endl;
}
5.1 Build static library or dynamic library separately
The root directory CMakeLists.txt The content in :
PROJECT(HELLO)
ADD_SUBDIRECTORY(lib bin)
lib Under the table of contents CMakeLists.txt The content in :
SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
ADD_LIBRARY
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
- hello: It's a normal library name , The generated name will be preceded by lib, The resulting file is
libhello.so. - SHARED: Dynamic library ;STATIC: Static library .
${LIBHELLO_ SRC}: Source file .

5.2 Build static library and dynamic library at the same time
SET_TARGET_PROPERTIES
This command can be used to set the name of the output , For dynamic libraries , It can also be used to specify the dynamic library version and API edition .
Build both static and dynamic
lib Under the table of contents CMakeLists.txt The content in :
SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
After the compilation :

5.3 Version number of dynamic library
Generally, dynamic libraries have a version number Association .
libhello.so.1.2
libhello.so ->libhello.so.1
libhello.so.1->libhello.so.1.2
CMakeList.txt Insert the following :
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION Refers to the dynamic library version ,SOVERSION Refer to API edition .
5.4 Install shared libraries and header files
In this case, we will hello The shared library of is installed to <prefix>/lib Catalog , take hello.h The installation to <prefix>/include/hello Catalog .
stay lib Under the table of contents CMakeLists.txt The addition of :
# Put the file in this directory
INSTALL(FILES hello.h DESTINATION include/hello)
# Binary system 、 Static library 、 Dynamic libraries are installed with TARGETS
# ARCHIVE Specifically static libraries ,LIBRARY Specifically dynamic library ,RUNTIME The executable target binary
INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
Specify the path when installing , Put it under the system :
cmake -D CMAKE_INSTALL_PREFIX=/usr ..

5.5 Use shared libraries and header files
Build instance :
.
├── build
├── CMakeLists.txt
└── src
├── CMakeLists.txt
├── main.cpp
main.cpp The content in :
#include <hello.h>
using namespace std;
int main() {
HelloFunc();
}
In the root directory CMakeLists.txt:
PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)
src Under the CMakeLists.txt:
ADD_EXECUTABLE(hello main.cpp)
Then compile :
We can't find hello.h Error in header file :
Need to be in src Under the CMakeLists.txt add :
# It means that hello Go down the directory and find the header file
INCLUDE_DIRECTORIES(/usr/include/hello)
To compile , Also complains , Can't find HelloFunc This function :

have access to TARGET_LINK_LIBRARIES Keyword add the shared library that needs to be linked , Be sure to write in ADD_EXECUTABLE After the keyword :
TARGET_LINK_LIBRARIES (hello libhello.so)
Be careful hello Is the name of the generated binary .
So the final src Under the CMakeLists.txt The contents of the document :
INCLUDE_DIRECTORIES(/usr/include/hello)
ADD_EXECUTABLE(hello main.cpp)
TARGET_LINK_LIBRARIES (hello libhello.so)
When recompiling , The executable file can be successfully generated hello 了 , But run hello It will report an error again :

The reason is the dynamic library we generated before libhello.so Is in /usr/lib/ In the catalog , But my linux System is 64 Bit , You need to move this dynamic library to /usr/lib64/ Only in the directory can :
mv /usr/lib/libhello.so /usr/lib64/
Then it can run normally :

边栏推荐
- leetcode 650. 2 Keys Keyboard 只有两个键的键盘(中等)
- 论文的英文文献在哪找(除了知网)?
- Should you study kubernetes?
- Use of cocospods
- Question e: merged fruit -noip2004tgt2
- 国外的论文在那找?
- Bean load control
- Linux 下安装 redis
- Chinatelecom has maintained a strong momentum in the mobile phone user market, but China Mobile has opened a new track
- 67页新型智慧城市整体规划建设方案(附下载)
猜你喜欢

Maybe you read a fake Tianlong eight

Monitor container runtime tool Falco

Improvement of RTP receiving and sending PS stream tool (II)

95页智慧教育解决方案2022

How much do you know about synchronized?

CADD course learning (4) -- obtaining proteins without crystal structure (Swiss model)

Happy Lantern Festival, how many of these technical lantern riddles can you guess correctly?

Explain in detail the process of realizing Chinese text classification by CNN

Architecture: database architecture design

论文的英文文献在哪找(除了知网)?
随机推荐
来自数砖大佬的 130页 PPT 深入介绍 Apache Spark 3.2 & 3.3 新功能
MATLAB signal processing [Q & a notes-1]
Explain in detail the process of realizing Chinese text classification by CNN
教育学大佬是怎么找外文参考文献的?
MFC 获取当前时间
Open Source | Wenxin Big Model Ernie Tiny Lightweight Technology, Accurate and Fast, full Open Effect
洛谷_P1149 [NOIP2008 提高组] 火柴棒等式_枚举打表
Architecture: load balancing
Architecture: database architecture design
開源了 | 文心大模型ERNIE-Tiny輕量化技術,又准又快,效果全開
Container runtime analysis
流媒体技术优化
基于OpenCV实现口罩识别
Happy Lantern Festival, how many of these technical lantern riddles can you guess correctly?
Angled detection frame | calibrated depth feature for target detection (with implementation source code)
JDBC tutorial
What is the official website address of e-mail? Explanation of the login entry of the official website address of enterprise e-mail
哪些软件可以整篇翻译英文论文?
返回二叉树中最大的二叉搜索子树的大小
Many to one, one to many processing