当前位置:网站首页>C language -cmake cmakelists Txt tutorial
C language -cmake cmakelists Txt tutorial
2022-07-08 01:54:00 【Hu Anmin】
Introduce
CMakeLists.txt Official website tutorial , cmake Command configuration and other tutorials
CMakeLists.txt The file USES Cmake Command completed , Then let's learn about the commonly used commands , This is necessary , Otherwise, the static library , Dynamic library , Can't import , And project document management depends on this document , Even if your code is good , This can't be a complete project without understanding , You can only run in the compiler , Can't publish
CMake It's a cross platform compiler , Than make More advanced . The main work of its compilation is to generate CMakeLists.txt file , Then generate Makefile, Last call make To generate executable programs or dynamic libraries , The specific process is as follows :

The following tutorials are based on Clion Tools do , Clion It greatly simplifies our construction C The difficulty of , In most cases, we only need to focus on developing code , Just configure the build part at the beginning of the project , The following is how to configure , The premise is that Clion-MinGW Configure specific tutorials : http://t.csdn.cn/FnTra
introduction

cmake_minimum_required(VERSION 3.20) # Declare what you need to use cmake The minimum version of
project(example1 VERSION 1.0.0 LANGUAGES C) # Project name edition Compiled language
set(CMAKE_C_STANDARD 11) #c The version of the compiler
add_executable(example1 main.c) # Through the source file main.c Generate executable files demo.exe
When we run the compilation , stay cmake-build-debug It will appear in the directory example1.exe Executable file , Of course, if it's just learning C This default configuration is actually enough
But if it is a self-developed project , Because there are too many files , At the same time, you also need to import various external library files , Then this configuration will not work at all , In learning configuration CMakeLists.txt We need to learn first cmake Some of the syntax , because CMakeLists.txt The content is to use cmake Compiling
cmake Common grammar
Because we don't have to CMake Grammar is all finished , We simply want to package the project , So let's talk about the common syntax of packaging projects ( Don't write what you don't need )
notes
Line comments use #; Block annotation using #[[xxxxx]]. such as :
# Multi line comments follow
#[[
xxxxx
]]
Variable
Program variables
CMake Program variables in set and unset Command to set or unset variables . Scope is only in CMakeLists.txt in
The set variable can be a string , Number or list , grammar : set( Variable name A variable's value ) such as :
# Set variable
set(AUTHOR_NAME Farmer)
set(AUTHOR "Farmer Li")
set(AUTHOR Farmer\ Li)
# Set list
set(SLOGAN_ARR To be)
set(SLOGAN_ARR To;be)
set(SLOGAN_ARR "To;be")
set(NUM 30) # Saved as string, but can compare with other number string
set(FLAG ON) # Bool value
The main points are as follows :
- If the variable value to be set contains spaces , You need to use double quotation marks or use "" escape , Otherwise, double quotation marks can be omitted ;
- If multiple values are set or there is..., in the middle of the string value ";“, Save it as list, The same is true of ”;" Split string ;
- Variables can be list The command operation , A variable with a single value is equivalent to a list with only one element ;
- Reference variables :
${variable}, stayif()Condition judgment can be simplified as using only variable names . unset(variable)Delete variables
environment variable
CMake Allows setting environment variables , Environment variables take special forms $ENV{varName} obtain , adopt SET(ENV{ Variable name } " A variable's value ") Set the environment variable
Be careful : Setting environment variables only works in CMakeLists.txt It's gone after compilation , So generally, we just get environment variables , And judge whether it exists
Common variable
Variables that provide information can provide some information , Usually you just need to read variables , Without modifying the variables .
PROJECT_SOURCE_DIR Project top level directory , That's the top floor CMakeLists.txt Source directory PROJECT_BINARY_DIR work cheng BINARY_DIR , also Just yes The top layer CMakeLists.txt Source code Of BINARY_DIRCMAKE_SOURCE_DIR And PROJECT_SOURCE_DIR Equivalent CMAKE_BINARY_DIR And PROJECT_BINARY_DIR Equivalent CMAKE_CURRENT_SOURCE_DIR The path of the current source code CMAKE_CURRENT_BINARY_DIR Current source code BINARY_DIRCMAKE_MAJOR_VERSION cmake Major version number of CMAKE_MINOR_VERSION cmake Sub version number of CMAKE_VERSION cmake Version number of ( Lord + Time + The revision )PROJECT_VERSION_MAJOR Major version number of the project PROJECT_VERSION_MINOR Minor version number of the project PROJECT_VERSION Version number of the project CMAKE_PROJECT_NAME The name of the project PROJECT_NAME project name , And CMAKE_PROJECT_NAME Equivalent
Message printing
MESSAGE( Print the content )
MESSAGE( STATUS Print the content )
Execute system commands
perform shell command
execute_process(COMMAND < A word of shell command > WORKING_DIRECTORY < This sentence shell Working directory of command execution >)
If the command does not depend on a directory , If it's the overall situation, it can be used directly
execute_process(COMMAND echo "Hello")
perform shell Script
execute_process(COMMAND sh test.sh WORKING_DIRECTORY <test.sh In the directory > )
Query file
file(GLOB_RECURSE ALL_SRC
src/**.c
# module2/*.c
)
Recursively query all src All suffixes below are .c The file of , And save to ALL_SRC in (List The way )
Create directory
execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory directories creating )
Copy file
execute_process( COMMAND ${CMAKE_COMMAND} -E copy file / File list Target directory )
Copy folder
execute_process( COMMAND ${CMAKE_COMMAND} -E copy_directory Catalog / Directory listing Destination address )
list
list(LENGTH <list> <output variable>)
list(GET <list> <element index> [<element index> ...] <output variable>)
list(APPEND <list> <element> [<element> ...])
list(FIND <list> <value> <output variable>)
list(INSERT <list> <element_index> <element> [<element> ...])
list(REMOVE_ITEM <list> <value> [<value> ...])
list(REMOVE_AT <list> <index> [<index> ...])
list(REMOVE_DUPLICATES <list>)
list(REVERSE <list>)
list(SORT <list>)
Use LENGTH Option , This command will return the given list The length of .
Use GET Option , The command returns list All of them are index The elements of the index list.
Use APPEND Option , The command will be in this list Then add several elements .
Use FIND Option , The command will return list Index of the element specified in ; If not found , return -1.
Use INSERT Option , The order will be in list Insert several elements at the position specified in .
Use REMOVE_AT and REMOVE_ITEM The options will be from list Delete some elements from . The difference between them is :REMOVE_ITEM What is deleted is the specified item , and REMOVE_AT What is deleted is the item at the specified index .
Use REMOVE_DUPLICATES Option , The command will delete list Duplicate items in .
Use REVERSE Option , This command will put list The contents of are switched back and forth .
Use SORT Option , This command will align list The overall content is sorted in place .
Be careful : stay CMake in , One list It's a seal ; A set of segmented strings . Use set Command can create a list. for example ,set(var a b c d e) The command will create a list:a;b;c;d;e; and set(var “a b c d e”) The command creates only a string , Or there is only one item list. When using the command format of the specified index , If it is greater than or equal to 0 Number of numbers , It's from list The sequence number starting from the first item ,list The index of the first item of is 0. If less than or equal to -1, This index is a reverse index from the end , among -1 It means list The last item of . When using negative index , Note that they are not from 0 Start !-0 And 0 Equivalent , It points to list The first member of .
loop
foreach(var ${list})
# xxxx
endforeach()
target_link_libraries
Connection Library ( Static and dynamic ) There are several ways ,
- link_directories
- find_library
- find_path
- find_package
- target_link_libraries
Just remember the only one target_link_libraries, Universal connection , To write in add_executable after , You can talk to find_path Collocation or circulation
target_link_libraries (${PROJECT_NAME} Dynamic library / Dynamic library list ) # Connect the current project to the dynamic library , Absolute path mode
Compile the project CMakeLists.txt( Static and dynamic libraries are common )

cmake_minimum_required(VERSION 3.20)# Declare what you need to use cmake The minimum version of Be careful : Change it to your own cmake edition
project(demo1 C) # Project name and Language Be careful : The project name needs to be changed to your own
set(CMAKE_C_STANDARD 11) # Change to yourself C Compiled version of language
# Search for .h file
file(GLOB_RECURSE ALL_H
${PROJECT_SOURCE_DIR}/include_h/**.h
)
# Search for include_h All below contain .h The parent directory of
foreach(file ${ALL_H})
# Get parent directory
string(REGEX REPLACE "/$" "" CURRENT_FOLDER_ABSOLUTE ${file})
string(REGEX REPLACE "(.*/)(.*)" "\\1" CURRENT_FOLDER ${CURRENT_FOLDER_ABSOLUTE})
list(APPEND include_h ${CURRENT_FOLDER})
endforeach()
# Directory de duplication
list(REMOVE_DUPLICATES include_h)
MESSAGE("include_directories" ${include_h})
# Appoint .h Header file search path
include_directories(${include_h})
# Recursively query files
file(GLOB_RECURSE ALL_SRC
# Multiple paths can be configured
${PROJECT_SOURCE_DIR}/src/**.c # obtain src All of the following .c file
# ${PROJECT_SOURCE_DIR}/module2/*.c
)
MESSAGE("add_executable" ${ALL_SRC})
# Manually add ioc Icon , And so on
set(ICO ico/ico.o)
# Files that need to be compiled , Generate exe
add_executable(${PROJECT_NAME} ${ICO} ${ALL_SRC})
# Connect all library files under the environment variable path to the project
if(DEFINED ENV{LIBRARY_CMAKE_PATH_FILES})
file(GLOB_RECURSE ALL_library
# Multiple paths can be configured
$ENV{LIBRARY_CMAKE_PATH_FILES}/**.a # obtain lib All of the following .a file
$ENV{LIBRARY_CMAKE_PATH_FILES}/**.lib # obtain lib All of the following .lib file
$ENV{LIBRARY_CMAKE_PATH_FILES}/**.os # obtain lib All of the following .lib file
$ENV{LIBRARY_CMAKE_PATH_FILES}/**.dll # obtain lib All of the following .lib file
)
MESSAGE("target_link_libraries: " ${ALL_library})
# Linking static libraries can also link dynamic libraries
target_link_libraries (${PROJECT_NAME} ${ALL_library})
endif()
# Put the current project lib All library files (.os .dll .a .lib ) Connect to the project
file(GLOB_RECURSE ALL_library
# Multiple paths can be configured
${PROJECT_SOURCE_DIR}/lib/**.a # obtain lib All of the following .a file
${PROJECT_SOURCE_DIR}/lib/**.lib # obtain lib All of the following .lib file
${PROJECT_SOURCE_DIR}/lib/**.os # obtain lib All of the following .lib file
${PROJECT_SOURCE_DIR}/lib/**.dll # obtain lib All of the following .lib file
)
MESSAGE("target_link_libraries: " ${ALL_library})
# Linking static libraries can also link dynamic libraries
target_link_libraries (${PROJECT_NAME} ${ALL_library})
If there are library files in other places, you can set the system environment variables LIBRARY_CMAKE_PATH_FILES, To connect , By default, the current project will be added lib Download all library files
Be careful :
The file code of the static library cannot conflict with the source code ( Methods with the same name cannot exist in files with the same name ), Otherwise, an error will be reported when compiling

If you use both static and dynamic libraries , And there are files with the same name between them and methods with the same name inside , Then the default is the static library , Because the static library will copy the required code into the package when packaging , The dynamic library will only find the corresponding code in the dynamic library during operation , When calling methods, you should first find them in the current application. If they exist, you won't find them in the dynamic library
Static libraries can break points , Dynamic library cannot be interrupted ( It's all compilation )
Package static or dynamic libraries CMakeLists.txt( Universal )
Static and dynamic can use the following CMakeLists.txt, It is stated in the document , Different libraries only need to be changed 
cmake_minimum_required(VERSION 3.20) # Declare what you need to use cmake The minimum version of
project(tool C) # Project name and Language
set(CMAKE_C_STANDARD 11) # C Compiler Version
# Search all .c file
file(GLOB_RECURSE ALL_SRC
${PROJECT_SOURCE_DIR}/src/**.c
${PROJECT_SOURCE_DIR}/*.c
)
MESSAGE("add_library" ${ALL_SRC})
# Static packaging library file ( Choose... For yourself )
add_library(${PROJECT_NAME} ${ALL_SRC})
# Dynamic packaging library file ( Choose... For yourself )
# add_library(${PROJECT_NAME} SHARED ${ALL_SRC})
# Copy the library file and header file to a directory
## Create under the project root ${PROJECT_NAME} Folder
set( public_include ${PROJECT_SOURCE_DIR}/cmake-build-debug/${PROJECT_NAME})
execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory ${public_include})
## Copy header file , TripAdvisor ${PROJECT_NAME} Folder
file(GLOB_RECURSE ALL_SRC
${PROJECT_SOURCE_DIR}/src/**.h
${PROJECT_SOURCE_DIR}/**.h
)
MESSAGE("copy" ${ALL_SRC})
execute_process( COMMAND ${CMAKE_COMMAND} -E copy ${ALL_SRC} ${public_include})
Finally, after running packaging , Just put the library file and header folder , Just copy it where you need it
Invalid dynamic library import error
Static libraries are packaged into exe in
When our project uses dynamic library packaging , It doesn't work , Because the project packaged by dynamic library will find dependencies at runtime , By default, I will find exe Current directory or system PATH Path in environment variable , If there is none, then an error will be reported 
terms of settlement
If you are currently developing code locally, you can do it directly in Clion Just configure it in the environment variable of 
If you currently need to package the project , and dll Document and exe The file is not under the same level directory , Then there are two solutions :
- Then it will be relevant dll All files are copied to exe Under the same category , Then compress to zip file , After the customer downloads and unzips, double-click exe Then you can run ( Not recommended )
- Set the system variable in the environment variable of my computer PATH, Just add the absolute path of the dynamic library ( Not recommended , You can play by yourself like this )
- take dll And items into the installer , Let users download and install by themselves ( At present the mainstream )
Refresh CMakeLists.txt file
We often import some files , Or library , Found compilation errors , But in fact, there is no mistake because CMakeLists.txt( Built with cache , Need us to delete



边栏推荐
- cv2读取视频-并保存图像或视频
- 保姆级教程:Azkaban执行jar包(带测试样例及结果)
- Codeforces Round #649 (Div. 2)——A. XXXXX
- Application of slip ring in direct drive motor rotor
- Why does the updated DNS record not take effect?
- WPF custom realistic wind radar chart control
- Redisson distributed lock unlocking exception
- Sum of submatrix
- WPF 自定义 写实风 雷达图控件
- Tencent game client development interview (unity + cocos) double bombing social recruitment 6 rounds of interviews
猜你喜欢

【目标跟踪】|atom

break net

Application of slip ring in direct drive motor rotor

Usage of hydraulic rotary joint

How to fix the slip ring

云原生应用开发之 gRPC 入门

ANSI / nema- mw- 1000-2020 magnetic iron wire standard Latest original

The function of carbon brush slip ring in generator

Apache multiple component vulnerability disclosure (cve-2022-32533/cve-2022-33980/cve-2021-37839)

I don't know. The real interest rate of Huabai installment is so high
随机推荐
快手小程序担保支付php源码封装
nmap工具介紹及常用命令
用户之声 | 对于GBase 8a数据库学习的感悟
WPF custom realistic wind radar chart control
Chapter 7 behavior level modeling
很多小伙伴不太了解ORM框架的底层原理,这不,冰河带你10分钟手撸一个极简版ORM框架(赶快收藏吧)
How to fix the slip ring
Anaconda3 download address Tsinghua University open source software mirror station
鼠标事件-事件对象
QML fonts use pixelsize to adapt to the interface
Voice of users | winter goes and spring comes, waiting for flowers to bloom -- on gbase 8A learning comprehension
Version 2.0 of tapdata, the open source live data platform, has been released
metasploit
MySQL查询为什么没走索引?这篇文章带你全面解析
powerbuilder 中使用线程的方法
burpsuite
Partage d'expériences de contribution à distance
cv2读取视频-并保存图像或视频
Js中forEach map无法跳出循环问题以及forEach会不会修改原数组
[SolidWorks] modify the drawing format