CMake的使用

CMake

打印变量信息

message("XXX : ${XXX}")

设置debug和release版本

C语言版

set(CMAKE_BUILD_TYPE "Debug") #当前是debug版本
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0") #debug版本的编译选项
set(CMAKE_C_FLAGS_Release "${CMAKE_C_FLAGS_Release} -O3") #release版本的编译选项

一些常用的编译选项:

  • -g:启动调试
  • -O0:不优化代码
  • -O3:3级优化代码
  • -Wall:打开一些很有用的警告选项,建议编译时加此选项
  • -Wextra:打印一些额外的警告信息

查找库

该命令用于查找库(动态库或者静态库),当构建依赖于第三方库/系统库,可以使用该命令来查找并使用库;

find_library (<VAR> name [path1 path2 ...])

基本参数的解析:

  • <var>用于存储该命令执行的结果,也就是找到的库的全路径(包含库名):
     1. <var>可以是普通变量(需要指定NO_CACHE选项),也可以是缓存条目(意味着会存放在CMakeCache.txt中,不删除该文件或者用set重新设置该变量,其存储的值不会再刷新);
     2. 当库能被找到,<var>会被存放正常的库路径,当库未被找到,<var>中存放的值为"<var>-NOTFOUND"。只要<var>中的值不是"<var>-NOTFOUND",那么即使多次调用find_library<var>也不会再刷新;
  • name用于指定待查找的库名称,库名称可以使用全称,例如libmymath.a(优先会当成全名搜索);也可以不带前缀(例如前缀lib)和后缀(例如Linux中的.so.aMac中的.dylib等),直接使用mymath
  • path用于指定库的查找的路径;

库的搜索路径:搜索路径和附加搜索路径。
默认搜索路径包含cmake定义的以CMAKE开头的一些变量(例如CMAKE_LIBRARY_ARCHITECTURECMAKE_PREFIX_PATHCMAKE_LIBRARY_PATHCMAKE_FRAMEWORK_PATH)、标准的系统环境变量(例如系统环境变量LIBPATH定义的路径)、系统的默认的库安装路径(例如/usr/usr/lib等)
附加搜索路径find_library命令中通过HINTSPATHS指定的路径;

举个例子:-lrt -lpthread

find_library(LIBRT rt)
if(LIBRT)
    target_link_libraries(targetname ${LIBRT})
endif()

find_library(LIBPTHREAD pthread)
if(LIBPTHREAD)
    target_link_libraries(targetname ${LIBPTHREAD})
endif()

设置头文件路径

include_directories(lvgl_src/lvgl/)

设置文件保存路径

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) #可执行二进制的输出路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) #库的输出路径

获取指定目录下的所有符合条件的文件名列表

下面语句将会把./src目录下所有符合*.cpp结尾的文件存入USER_LIBS_PATH变量中

file(GLOB USER_LIBS_PATH "./src/*.cpp")

GLOB命令主要用于匹配规则在指定的目录内匹配到所需要的文件


如果我们不但在当前目录需要引入,还需要在当前目录子目录引入了,这里就直接使用GLOB_RECURSE

file(GLOB_RECURSE USER_LIBS_PATH "./src/*.cpp")

GLOB_RECURSE命令不仅可以遍历当前路径,还可以遍历路径下面的所有子目录

使用指定的源文件来生成目标可执行文件

add_executable(${CMAKE_PROJECT_NAME} 源文件1 源文件2)

find_package

当编译一个需要使用第三方库的软件时,需要知道:

  • 去哪找头文件
  • 去哪找库文件
  • 需要链接的库文件的名字

比如需要一个第三方库 curl,那么我们的CMakeLists.txt需要指定头文件目录,和库文件,类似:

include_directiories(/usr/include/curl) 	  #库路径
target_link_libraries(myprogram path/curl.so) #库文件名字

还可以换一种方法,借助 find_package 命令:

find_package(CURL REQUIRED)
include_directories(${CURL_INCLUDE_DIR})
target_link_libraries(curltest ${CURL_LIBRARY})

我们可以在官方文档中查看到哪些库官方已经为我们定义好了,我们可以直接使用find_package函数进行引用

add_library

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [source1] [source2 ...])

添加名为name的库,库的源文件可指定,也可用target_sources()后续指定。库的类型是STATIC(静态库)/SHARED(动态库)/MODULE(模块库)之一。

add_library(<name> ALIAS <target>)

为给定library添加一个别名,后续可使用<name>来替代<target>。使用有如下限制:

  1. <target>不能是ALIAS
  2. 可用于判断target是否存在、链接。
  3. ALIAS的library不能修改属性,不能调用set_property(), set_target_properties()target_link_libraries()等方法
  4. 不能用于install()

子模块

.
├── CMakeLists1.txt
├── src
	├── CMakeLists2.txt
	└── ui
    	├── ui.c
    	└── ui.h

CMakeLists1.txt

add_subdirectory(src) #添加子模块

target_link_libraries(main PRIVATE sub::src) #连接子模块的库

CMakeLists2.txt

cmake_minimum_required(VERSION 3.10)

project(src) #可有可无

file(GLOB_RECURSE SOURCES ./*.c) #获取所有的.c文件
add_library(src ${SOURCES}) #将源码链接成子模块
add_library(sub::src ALIAS src) #取别名

常用环境变量

  • CMAKE_PROJECT_NAME:工程名字,由project命令设置。
  • PROJECT_BINARY_DIR:如果是 in source 编译,指得就是工程顶层目录,如果是 out-of-source 编译,指的是工程编译发生的目录。
cmake_minimum_required(VERSION 3.16) #cmake最低要求版本
project(XXXXXX) #工程名

set(CMAKE_BUILD_TYPE "Debug") #当前是debug版本
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0") #debug版本的编译选项
set(CMAKE_C_FLAGS_Release "${CMAKE_C_FLAGS_Release} -O3") #release版本的编译选项

add_executable(${CMAKE_PROJECT_NAME} main.c thpool.c)

find_package(Threads)
target_link_libraries(${CMAKE_PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})
posted @ 2022-06-13 11:50  木丨易  阅读(245)  评论(0)    收藏  举报