🚀write in front🚀
🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝💬本文是根据网上CSDN博客里CMake教程学习的学习笔记以及自己的总结梳理📚
前言:
本文是根据网上CSDN博客里CMake教程学习的学习笔记以及自己的总结梳理。本文大部分是对引用链接中博客的摘抄,照抄到这里的目的是为了加深对新知识学习的理解。
引用:
【C++】Cmake使用教程(看这一篇就够了)-CSDN博客
[CMake教程] CMake列表 - list_cmakelist-CSDN博客
https://zhuanlan.zhihu.com/p/690938516
https://zhuanlan.zhihu.com/p/557642088
https://zhuanlan.zhihu.com/p/688621546
正文:
介绍:
CMake是一个跨平台的开源构建系统,它用于管理软件项目的构建过程。它可以生成适合各种操作系统和编译器的构建文件。Cmake主要有以下编译步骤:
- 编写CMakeLists.txt文件
- 用cmake命令将CMakeLists.txt文件转化为make所需要的makefile文件
- 用make命令编译源码生成可执行文件或库
一般把CMakeLists.txt文件放在工程目录下,具体编译执行的命令为:
mkdir build && cd build
#cmake指令指向CMakeLists.txt所在的目录,例如,cmake .. 表示 MakeLists.txt在当前目录的上一级目录。cmake后会成成很多编译的中间文件以及makefile文件,所以新建新的build目录专门用来编译。
cmake .. #cmake .. 在build目录里生成Makefile
make #make根据生成的makefile文件,编译程序,make应当在有Makefile的目录下,根据Makefile生成可执行文件。
CMakeLists.txt常用命令及流程
编写CmakeLists.h最常用的功能就是调用其他的.h头文件和.so/.a库文件,将.cpp/.c/.cc文件编译成可执行文件或者新的库文件。
CMakeLists.txt的常用命令
- 设置project的名称
project(xxx)
会自动创建两个变量,PROJECT_SOURCE_DIR 和 PROJECT_NAME- ${PROJECT_SOURCE_DIR}:本CMakeLists.txt所在的文件夹路径
- ${PROJECT_NAME}:本CMakeLists.txt的project名称
- 获取路径下的所有 .cpp/.c/.cc 文件,并赋值给变量
aux_source_directory(路径 变量) - 给文件名/路径名/或其它字符串起别名,用${变量}获取变量的内容
set(变量 文件名/路径/...) - 添加编译选项
add_definitions(编译选项) - 打印消息
message(消息) - 编译子文件夹的CmakeLists.txt
add_subdirectory(子文件夹名称) - 将.cpp/.c/.cc文件生成.a静态库
注意,此时库文件的名称通常为libxxx.so,这里只需要写xxx即可
add_libary(库文件名称如xxx STATIC 文件) - 将.cpp/.c/.cc生成可执行文件
add_executable(可执行文件名称 文件) - 规定.h头文件路径
include_directories(路径) - 规定.so/.a库文件路径
link_directories(路径) - 对add_libary或者add_executeable生成的文件进行链接操作
注意,此时库文件名称通常为libxxx.so,在这里只需要写xxx即可
target_link_libaries(库文件/可执行文件名称 链接的库文件名称)
CMakeLists.txt的基本流程
project(xxx) #必须
add_subdirectory(子文件夹名称)#父目录必须,子目录下没有夏季目录则不需要
add_libary(库文件名称 STATIC 文件) #通常子目录(二选一)add_executable(可执行文件名称 文件) #通常父目录(二选一)
include_directories(路径)#必须link_directories(路径)#必须
target_link_libraries(库文件名称/可执行文件名称 丽娜姐的库文件名称)#必须
具体编写步骤
1.声明的cmake最低版本
cmake_minimum_required( VERSION 3.4)
2.检查C++版本,添加C++标准支持(Optional可选)
# 添加c++11标准支持 【可选】
set( CMAKE_CXX_FLAGS "-std=c++11" )
# 检查C++版本 【可选】 , Check C++11 or C++0x support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_definitions(-DCOMPILEDWITHC11)
message(STATUS "Using flag -std=c++11.")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_definitions(-DCOMPILEDWITHC0X)
message(STATUS "Using flag -std=c++0x.")
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
3. 添加工程名称(可任取)
会自动创建两个变量,PROJECT_SOURCE_DIR和PROJECT_NAME
- ${PROJECT_SOURCE_DIR}:本CMakeLists.txt所在的问价夹路径
- ${PROJECT_NAME}:本CMakeLists.txt的project名称
PROJECT(TEST)
MESSAGE(STATUS "Project: Server") #打印相关消息信息
4.设置编译模式
#设置为Release模式
SET(CMAKE_BUILD_TYPE Release)
#或者,设置为debug模式SET(CMAKE_BUILD_TYPE debug)
#打印设置的辨析模型信息
MESSAGE("Build type:" ${CMAKE_BUILD_TYPE})
4.添加子目录
如果项目包含多个子模块或子目录,可以使用 add_subdirectory()指令将它们添加到构建过程中。
add_subdirectory(submodule_dir)
5.添加头文件
- 举例使用OpenCV库
备注:这里的OpenCV包含目录为含有OpenCVConfig.cmake的路径
set(OpenCV_DIR "/usr/local/include/opencv.3.2.0/share/OpenCV")
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS}) - 如果需要添加所有包含的.h头文件
include_directories(
${PROEJCT_SOURCE_DIR}/../include/dir1
$(PROJECT_SOURCE_DIR}/../include/dir2
) - 包含第三方的头文件,举例第三方的库的名字位LIBa
#设置.h文件对应的路径
set(LIBa_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/ThirdParty/LIBa/include/)
#包含.h文件的路径
include_directories(${OpenCV_INCLUDE_DIRS}
${LIBa_INCLUDE_DIRS}
${LIBa_INLCUDE_DIRS}/LIBa)
#包含地方库的cpp文件
set(LIBz_SRCS "${PROJECT_SOURCE_DIR}/ThirdParty/LIBa/src")
6.添加源代码路径
通过设置SRC变量,将源代码路径都给SRC,如果有多个,可以直接在后面继续添加
set(SRC
${PROJECT_SOURCE_DIR}/../incldue/dir1/func1.cpp
${PROJECT_SOURCE_DIR}/../incclude/dir2/func2.cpp
${PROJECT_SOURCE_DIR}/../main.cpp
)
7.创建共享库/静态库
设置生成共享库的路径
set(CMAKE_LIBARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
#即生成的共享库在工程文件夹下的lib文件夹中
创建共享库(把工程内的cpp文件都创建成共享库文件,方便通过头文件来调用) 。这时候只需要cpp,不需要有主函数。
set(LIB_NAME main_lib)
#${LIB_NAME}是生成的库的名称,表示生成的共享库文件就叫做 lib工程名.so
#也可以专门写cmakelists来编译一个没有主函数的程序来生成共享库,控其它程序使用add_library(${LIB_NAME} STATIC ${SRC}) #SHARED生成动态库,STATIC为生成静态库
8.链接库文件
把刚刚生成的${LIB_NAME}库和所需的其它库链接起来
如果需要链接其它的动态库,-l后面写去除lib前缀和.so后缀的名称(即为LIB_NAME),以链接libphtread.so为例,-lpthread
target_link_libraryies(${LIB_NAME} pthread dl)
9.编译主函数,生成可执行文件
先设置路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
可执行文件生成 add_executable(目标文件(可执行文件) 依赖文件(.cpp))
add_executable(${PROJECT_NAME} ${SRC}}
这个可执行文件所需要的库(一般就是刚刚生成的工程的库了)
target_link_directories(${PROJECT_NAME} pthread dl {LIB_NAME})