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
、.a
,Mac
中的.dylib
等),直接使用mymath
;path
用于指定库的查找的路径;
库的搜索路径:搜索路径和附加搜索路径。
默认搜索路径包含cmake
定义的以CMAKE
开头的一些变量(例如CMAKE_LIBRARY_ARCHITECTURE
、CMAKE_PREFIX_PATH
、CMAKE_LIBRARY_PATH
、CMAKE_FRAMEWORK_PATH
)、标准的系统环境变量(例如系统环境变量LIB
和PATH
定义的路径)、系统的默认的库安装路径(例如/usr
、/usr/lib
等)
附加搜索路径即find_library
命令中通过HINTS
或PATHS
指定的路径;
举个例子:-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>
。使用有如下限制:
<target>
不能是ALIAS
- 可用于判断target是否存在、链接。
ALIAS
的library不能
修改属性,不能调用set_property()
,set_target_properties()
和target_link_libraries()
等方法不能
用于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})