当前位置:网站首页>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 :

边栏推荐
- zhvoice
- CADD course learning (4) -- obtaining proteins without crystal structure (Swiss model)
- Is the multitasking loss in pytoch added up or backward separately?
- Sourcetree details
- What is the official website address of e-mail? Explanation of the login entry of the official website address of enterprise e-mail
- leetcode 650. 2 Keys Keyboard 只有两个键的键盘(中等)
- cocospods 的使用
- 来自数砖大佬的 130页 PPT 深入介绍 Apache Spark 3.2 & 3.3 新功能
- In February 2022, the ranking list of domestic databases: oceanbase regained its popularity with "three consecutive increases", and gaussdb is expected to achieve the largest increase this month
- Top Devops tool chain inventory
猜你喜欢

What are the recommended thesis translation software?
![MATLAB signal processing [Q & a notes-1]](/img/53/ae081820fe81ce28e1f04914678a6f.png)
MATLAB signal processing [Q & a notes-1]

Create an interactive experience of popular games, and learn about the real-time voice of paileyun unity

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

直击产业落地!飞桨重磅推出业界首个模型选型工具

Bean load control

Master the development of facial expression recognition based on deep learning (based on paddlepaddle)

Chinatelecom has maintained a strong momentum in the mobile phone user market, but China Mobile has opened a new track

List of major chip Enterprises

Maybe you read a fake Tianlong eight
随机推荐
How much do you know about synchronized?
Interpretation of new plug-ins | how to enhance authentication capability with forward auth
What website can you find English literature on?
接口自动化覆盖率统计——Jacoco使用
Open source | Wenxin big model Ernie tiny lightweight technology, which is accurate and fast, and the effect is fully open
maya渔屋建模
cocospods 的使用
Chinatelecom has maintained a strong momentum in the mobile phone user market, but China Mobile has opened a new track
[shutter] shutter photo wall (center component | wrap component | clickrrect component | stack component | positioned component | button combination component)
leetcode 650. 2 Keys Keyboard 只有两个键的键盘(中等)
Leetcode DP three step problem
英文论文有具体的格式吗?
MFC file operation
Returns the maximum distance between two nodes of a binary tree
洛谷_P2010 [NOIP2016 普及组] 回文日期_折半枚举
Angled detection frame | calibrated depth feature for target detection (with implementation source code)
Xcode real machine debugging
[OJ] intersection of two arrays (set, hash mapping...)
yolov5train. py
TypeError: Cannot read properties of undefined (reading ***)