当前位置:网站首页>Cmake notes
Cmake notes
2022-07-23 14:48:00 【Chaoying.】
I didn't write this blog post myself , yes B Stand on one CMake Supporting materials for the introductory tutorial , Personally, I think this tutorial is very suitable for me to use g++ Introduction to Xiaobai , Put a link here Liu Beisi : Detailed introduction from zero CMake, I strongly recommend that you want to learn CMake Go and have a look . There is a tutorial at the end of the article Up Lord's reward QR code , Not my own , Those with strength can support this Up Lord
CMake
explain
cmake What is the definition of ?----- Advanced compilation configuration tool
When multiple people develop a project in different languages or compilers , Finally, output an executable file or shared library (dll,so wait ) Then the artifact appeared -----CMake!
All operations are compiled CMakeLists.txt To complete — Simple
Officer, Fang's website is www.cmake.org, You can get more information about cmake Information about
Study CMake Purpose , Handling large for the future C/C++/JAVA Project preparation
CMake install
1、 Most of linux The system has been installed CMake
2、Windows Or some not installed linux System , Go to http://www.cmake.org/HTML/Download.html You can download and install
CMake One HelloWord
1、 Step one , Write a HelloWord
#main.cpp
#include <iostream>
int main(){
std::cout << "hello word" << std::endl;
}
2、 Step two , Write CMakeLists.txt
#CMakeLists.txt
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、 Step three 、 Use cmake, Generate makefile file
cmake .
Output :
[[email protected] cmake]# cmake .
CMake Warning (dev) in CMakeLists.txt:
Syntax Warning in cmake code at
/root/cmake/CMakeLists.txt:7:37
Argument not separated from preceding token by whitespace.
This warning is for project developers. Use -Wno-dev to suppress it.
-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- This is BINARY dir /root/cmake
-- This is SOURCE dir /root/cmake
-- Configuring done
-- Generating done
-- Build files have been written to: /root/cmake
These files are generated in the directory -CMakeFiles, CMakeCache.txt, cmake_install.cmake Wait for the documents , And generated Makefile.
Now we need to ignore the role of these documents , You can ignore it later . The key is , It automatically generates Makefile.
4、 Use make Command compilation
[email protected] cmake]# make
Scanning dependencies of target hello
[100%] Building CXX object CMakeFiles/hello.dir/main.cpp.o
Linking CXX executable hello
[100%] Built target hello
5、 And you end up with Hello Executable program of
CMake One HelloWord- The grammar of
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 — Suggest
PROJECT (HELLO CXX) 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++
This assignment implicitly defines two CMAKE The variable of
_BINARY_DIR, In this case, it is HELLO_BINARY_DIR
_SOURCE_DIR, In this case, it is HELLO_SOURCE_DIR
MESSAGE Keyword can directly use 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 : Two more predefined variables are defined :PROJECT_BINARY_DIR and PROJECT_SOURCE_DIR, These two variables and HELLO_BINARY_DIR,HELLO_SOURCE_DIR It's consistent . So it doesn't matter to change the project name
SET keyword
Of the specified variable used to display
SET(SRC_LIST main.cpp) SRC_LIST Variables contain main.cpp
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 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)
The above example can be simplified as
PROJECT(HELLO)
ADD_EXECUTABLE(hello main.cpp)
Be careful : Project name HELLO And the generated executable hello It doesn't matter
Basic principles of grammar
Variable usage ${} Method value , But in IF The variable name is used directly in the control statement
Instructions ( Parameters 1 Parameters 2…) Parameters are enclosed in brackets , Parameters are separated by spaces or semicolons . On the surface of the above ADD_EXECUTABLE Instruction as an example , If there is another func.cpp Source file
It's about to be written :ADD_EXECUTABLE(hello main.cpp func.cpp) perhaps ADD_EXECUTABLE(hello main.cpp;func.cpp)
Instructions are case independent , Parameters and variables are case dependent . but , It is recommended that you use all uppercase commands
Grammar notes
- SET(SRC_LIST main.cpp) It can be written. SET(SRC_LIST “main.cpp”), If the source file name contains spaces , You have to put double quotes
- ADD_EXECUTABLE(hello main) Suffix OK no , He will automatically find .c and .cpp, It's better not to write like this , There may be these two files main.cpp and main
Internal build and external build
- The above example is an internal build , He produces a lot of temporary documents , Inconvenient to clean
- External build , Will put the generated temporary files in build Under the table of contents , It will not have any impact on the source file. It is strongly built by external methods
Examples of external construction methods
// Example directory ,CMakeLists.txt Consistent with the above example
[[email protected] cmake]# pwd
/root/cmake
[[email protected] cmake]# ll
total 8
-rw-r--r--. 1 root root 198 Dec 28 20:59 CMakeLists.txt
-rw-r--r--. 1 root root 76 Dec 28 00:18 main.cpp
1、 Build a build Catalog , It can be anywhere , It is suggested that the current directory
2、 Get into build, function cmake … Of course … Represents the directory above , You can write CMakeLists.txt The absolute path , The production documents are in build The directory
3、 stay build Under the table of contents , function make To build the project
Notice the two variables built externally
1、HELLO_SOURCE_DIR Or engineering path
2、HELLO_BINARY_DIR Compile path That is to say /root/cmake/bulid
Give Way Hello World It looks more like a project
- Add a subdirectory to the project src, Used to place engineering source code
- Add a subdirectory doc, The document used to place the project hello.txt
- Add a text file to the project directory COPYRIGHT, README
- Add a runhello.sh Script , Used to call hello Binary system
- Put the built object file into the bin subdirectories
- take doc Catalog and COPYRIGHT/README The installation to /usr/share/doc/cmake/
Put the target file in the... Of the build directory bin subdirectories
There should be one under each directory CMakeLists.txt explain
[[email protected] cmake]# tree
.
├── 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_ALL The 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 ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
reflection : Load which CMakeLists.txt among
Where to change the target storage path , Where to add the above definition , So it should be src Under the CMakeLists.txt The write
install
- One is to compile the code directly make install install
- One is to specify when packing Directory installation .
- Simply specify the directory like this :make install DESTDIR=/tmp/test
- A little more complicated, you can specify the directory like this :./configure –prefix=/usr
How to install HelloWord
Use CMAKE A new instruction :INSTALL
INSTALL The installation of can include : Binary system 、 Dynamic library 、 Static libraries and files 、 Catalog 、 Script etc.
Use CMAKE A new variable :CMAKE_INSTALL_PREFIX
// Tree structure
[[email protected] cmake]# tree
.
├── build
├── CMakeLists.txt
├── COPYRIGHT
├── doc
│ └── hello.txt
├── README
├── runhello.sh
└── src
├── CMakeLists.txt
└── main.cpp
3 directories, 7 files
The installation files COPYRIGHT and README
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/)
FILES: file
DESTINATION:
1、 Write absolute path
2、 You can write relative paths , Relative path actual path is :${CMAKE_INSTALL_PREFIX}/<DESTINATION Defined path >
CMAKE_INSTALL_PREFIX The default is in /usr/local/
cmake -DCMAKE_INSTALL_PREFIX=/usr stay cmake When it's time to specify CMAKE_INSTALL_PREFIX The path of the variable
set up script runhello.sh
PROGRAMS: Executable installation of non target files ( Like scripts and so on )
INSTALL(PROGRAMS runhello.sh DESTINATION bin)
explain : The actual installation is /usr/bin
install doc Medium hello.txt
One 、 It is through doc Directory establishment CMakeLists.txt , adopt install Under the file
Two 、 It's directly in the project directory through
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
The directory name is as follows / ending : Install the contents of this directory to the target path
setup script
cmake …
make
make install
Construction of static library and dynamic library
Mission :
1, Build a static library and a dynamic library , Provide HelloFunc Functions are used by other programs ,HelloFunc Output to the terminal Hello World character string .
2, Install header files and shared libraries .
The difference between static library and dynamic library
- The extension of a static library is generally “.a” or “.lib”; The extension of the dynamic library is generally “.so” or “.dll”.
- 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 .
Some functions are needed in many places , In order to save storage space, only one copy is enough , Call and execute when necessary , So you can use dynamic library , But some function codes only need one or a few programs , Therefore, you can directly compile it when compiling , At this point, you should use the static library . In short, whether it is compiled into a static library or a dynamic library mainly depends on whether this part of the code will be used in many places
Build instance
[[email protected] cmake2]# tree
.
├── 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>
void HelloFunc(){
std::cout << "Hello World" << std::endl;
}
In the project cmake Content
PROJECT(HELLO)
ADD_SUBDIRECTORY(lib bin)
lib in 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
Build both static and dynamic libraries
// If in this way , Only one dynamic library will be built , Will not build static libraries , Although the suffix of the static library is .a
ADD_LIBRARY(hello SHARED ${
LIBHELLO_SRC})
ADD_LIBRARY(hello STATIC ${
LIBHELLO_SRC})
// Modify the name of the static library , This is OK , But we often want their names to be the same , Just different suffixes
ADD_LIBRARY(hello SHARED ${
LIBHELLO_SRC})
ADD_LIBRARY(hello_static STATIC ${
LIBHELLO_SRC})
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 libraries
SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello_static STATIC ${
LIBHELLO_SRC})
// Yes hello_static Your duplicate name is hello
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
//cmake Building a new target when , Will try to clean up other libraries using this name , because , In the build libhello.so when , It's going to clean up libhello.a
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 PROPERTIES CLEAN_DIRECT_OUTPUT 1)
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
CMakeLists.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 .
Install shared libraries and header files
In this case, we will hello The shared library of is installed to /lib Catalog ,
take hello.h The installation to /include/hello Catalog
// 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)
Be careful :
During installation , Specify the path , Put it under the system
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
Use external shared libraries and header files
preparation , Create a new directory to use external shared libraries and header files
[[email protected]-R4CM-srv cmake3]# tree
.
├── build
├── CMakeLists.txt
└── src
├── CMakeLists.txt
└── main.cpp
main.cpp
#include <hello.h>
int main(){
HelloFunc();
}
solve :make The problem that the following header file cannot be found
PS:include <hello/hello.h> such include Yes. , In doing so , There's nothing to say
keyword :INCLUDE_DIRECTORIES This command can be used to add multiple specific header search paths to a project , The paths are separated by spaces
stay CMakeLists.txt Add header file search path to
INCLUDE_DIRECTORIES(/usr/include/hello)
thank :
Net friend :zcc720 Reminder
solve : Find the referenced function problem
Error message :undefined reference to `HelloFunc()’
keyword :LINK_DIRECTORIES Add non-standard search paths for shared libraries
Specify the path where the third-party library is located ,LINK_DIRECTORIES(/home/myproject/libs)
keyword :TARGET_LINK_LIBRARIES Add shared libraries that need to be linked
TARGET_LINK_LIBRARIES When , Just give the name of the dynamic link library .
stay CMakeLists.txt Insert linked shared library in , Mainly inserted in executable Behind
see main Link status of
[[email protected]-R4CM-srv bin]# ldd main
linux-vdso.so.1 => (0x00007ffedfda4000)
libhello.so => /lib64/libhello.so (0x00007f41c0d8f000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f41c0874000)
libm.so.6 => /lib64/libm.so.6 (0x00007f41c0572000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f41c035c000)
libc.so.6 => /lib64/libc.so.6 (0x00007f41bff8e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f41c0b7c000)
Link static libraries
TARGET_LINK_LIBRARIES(main libhello.a)
Special environment variables CMAKE_INCLUDE_PATH and CMAKE_LIBRARY_PATH
Be careful : These two are environment variables, not cmake Variable , Can be in linux Of bash Set in
We used the absolute path in the above example INCLUDE_DIRECTORIES(/usr/include/hello) To indicate include The location of the path
There's another way we can use it , Using environment variables export CMAKE_INCLUDE_PATH=/usr/include/hello
Add : production debug Version method :
cmake … -DCMAKE_BUILD_TYPE=debug
Ben ⼈ All videos and notes are free to share with ⼤ Family , Making videos and notes costs ⼤ The time cost of quantity
I have ⽼ Mother and child ⼦ To support , Please audience ⽼ Men have economic reality ⼒ A little reward ⼀ Next ⼩ brother , But don't force , Again ⼀ Thanks again .
Your reward , It will make me more ⼤ The movement of ⼒, Make better videos , thank ⼤ Family ⽀ a

边栏推荐
- 可以进行2D或3D三角剖分的一些库
- mysql唯一索引无重复值报错重复
- uni-app知识点和项目上遇到的问题和解决办法的记录
- 工作小记:一次抓包
- [array & String & Macro exercise]
- Quick introduction to PKI system
- QT document reading notes audio example analysis
- 【测试平台开发】十七、接口编辑页面实现下拉级联选择,绑定接口所属模块...
- Sword finger offer 46. translate numbers into strings
- Qu'est - ce que le codage par titre?
猜你喜欢
随机推荐
基于nextcloud构建个人网盘
【软件测试】盘一盘工作中遇到的 MQ 异常测试
Canvas from getting started to persuading friends to give up (graphic version)
第4章 集合运算
mysql唯一索引无重复值报错重复
websocket通用化封装设计与实现
【测试平台开发】23. 接口断言功能-保存接口断言和编辑回显
Can bus quick understanding
Authing 支持 Zadig 啦!云原生用户统一认证快速对接
Solve a series of problems in using Bert encoder
koa框架的使用
转自玉溪信息公开:mRNA新冠疫苗、九洲马破伤风免疫球蛋白等产品有望年内上市。
右键新建txt,新建文本文件不见了,通过添加注册表就可以解决,找来找去办法解决不了的终极办法
About flex layout justify content: the last solution to the misalignment of space around and why it is solved like this is a discussion
JS texture style pie chart plug-in
[pyqt5 installation and use]
Some libraries that can perform 2D or 3D triangulation
云呐|公司固定资产如何管理?公司固定资产如何管理比较好?
Quanzhi f1c100s/f1c200s learning notes (13) -- lvgl transplantation
Ffmpeg 1 - Overview / installation






![Looking for peak [Abstract dichotomy exercise]](/img/99/122e79784f0f07120680d2cbcf89da.png)


