当前位置:网站首页>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
边栏推荐
- Codeforces Round #643 (Div. 2)——B. Young Explorers
- Usage of hydraulic rotary joint
- regular expression
- Remote Sensing投稿经验分享
- 不算不知道,花呗分期的真实利率居然这么高
- CV2 read video - and save image or video
- Tapdata 的 2.0 版 ,开源的 Live Data Platform 现已发布
- How to realize batch control? MES system gives you the answer
- Uniapp one click Copy function effect demo (finishing)
- Tapdata 的 2.0 版 ,開源的 Live Data Platform 現已發布
猜你喜欢
【SolidWorks】修改工程图格式
Sum of submatrix
[target tracking] |dimp: learning discriminative model prediction for tracking
The foreach map in JS cannot jump out of the loop problem and whether foreach will modify the original array
ArrayList源码深度剖析,从最基本的扩容原理,到魔幻的迭代器和fast-fail机制,你想要的这都有!!!
How to make enterprise recruitment QR code?
Remote Sensing投稿經驗分享
为什么更新了 DNS 记录不生效?
如何制作企业招聘二维码?
进程和线程的退出
随机推荐
[error] error loading H5 weight attributeerror: 'STR' object has no attribute 'decode‘
What kind of MES system is a good system
Nacos microservice gateway component +swagger2 interface generation
快手小程序担保支付php源码封装
滑环使用如何固定
Give some suggestions to friends who are just getting started or preparing to change careers as network engineers
Codeforces Round #649 (Div. 2)——A. XXXXX
ANSI / NEMA- MW- 1000-2020 磁铁线标准。. 最新原版
MySQL数据库(2)
Reading notes of Clickhouse principle analysis and Application Practice (7)
Is it necessary for project managers to take NPDP? I'll tell you the answer
PB9.0 insert OLE control error repair tool
From starfish OS' continued deflationary consumption of SFO, the value of SFO in the long run
SQLite3 data storage location created by Android
云原生应用开发之 gRPC 入门
如何制作企业招聘二维码?
ArrayList源码深度剖析,从最基本的扩容原理,到魔幻的迭代器和fast-fail机制,你想要的这都有!!!
Version 2.0 de tapdata, Open Source Live Data Platform est maintenant disponible
Nmap tool introduction and common commands
生态 | 湖仓一体的优选:GBase 8a MPP + XEOS