一、前言
嗯。。其实到家都11点了,想起来今天还是1024,还是写篇博客庆祝一下,搬运一篇笔记过来。祝大家1024节日快乐!
二、正文
1、cmake主要用法介绍
https://blog.youkuaiyun.com/u011150681/article/details/103630938
文档: https://cmake.org/cmake/help/latest/manual/cmake.1.html#manual:cmake(1)
(1)cmake设置各种目录以及关键的全局变量
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #编译是写入INSTALL_RPATH
SET(CMAKE_INSTALL_RPATH "\${ORIGIN}/lib") #指定运行时动态库的加载路径,ORIGIN指运行文件所在目录
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/dist") #CMAKE_CURRENT_BINARY_DIR:就是当前build目录的绝对路径
CMAKE_CURRENT_SOURCE_DIR #这是当前处理的CMakeLists.txt所在的目录
CMAKE_CURRENT_LIST_DIR #(自2.8.3开始)这是当前正在处理的列表文件的目录.
2、cmake的option
CMake中的option用于控制编译流程,相当于C语言中的宏条件编译。相当于定义变量,这个变量可以作为cmake中的流程控制变量,
也可以作为cmake的命令行参数。
option(<variable> "<help_text>" [value])
//在执行cmake时,可以使用-D+选项名称,修改选项的值,如下:
$cmake .. -DTEST_OPTION=OFF
3、cmake的编译
参考:https://blog.youkuaiyun.com/weixin_44359953/article/details/119717547
一般把CMakeLists.txt文件放在工程目录下,使用时,先创建一个叫build的文件夹(这个并非必须,因为cmake命令指向CMakeLists.txt所在的目录,例如cmake . ., 表示CMakeLists.txt在当前目录的上一级目录。cmake后会生成很多编译的中间文件以及makefile文件,所以一般建议新建一个新的目录,专门用来编译),然后执行下列操作:
cd build
cmake . . //其中cmake . . 在build里生成Makefile
make //make根据生成makefile文件,编译程序,make应当在有Makefile的目录下,根据Makefile生成可执行文件。
编译后的可执行程序:
build/bin/xxxx:
decode_main:测试使用,参考readme中的第三个命令
grpc_
4、cmake中的继承关系
在cmakeLists中可以引入其他的xx.cmake文件,例如:
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
find_package(BAYES REQUIRED)
list那一行告诉cmake在哪儿去找我们的.cmake文件。之后输入我们要找的package名称。这里正如前面所说的,
我们需要把BAYES这个名字和Find<name>.cmake中的name对应起来。最后在可执行文件添加库链接的时候,
那个库的名字和FindBAYES.cmake中的find_library中定义的名字一样。
保存CMakeLists.txt之后就能正常编译了。
注意:cmakeLists.txt中通过option定义的变量,在xxx.cmake中可以直接使用。例如:onnx.cmake中直接使用父级定义的ONNX变量
5、cmake中常用的常量解释
0、MSVC : 用来区分window的宏定义。可以通过:if(MSVC)来判断是否是windows
1、CMAKE_MODULE_PATH :CMAKE_MODULE_PATH是以分号分隔的列表,供include()或 find_package()使用。初始为空,由用户设定、
2、CMAKE_PREFIX_PATH:以分号分隔的列表,供find_package(), find_program(), find_library(), find_file()和find_path()使用,初始为空,由用户设定
3、FetchContent_Declare 使用步骤:
1. 在cmake文件写入 include(FetchContent) ,具体看完整实例.
2. 使用FetchContent_Declare(三方库) 获取项目。可以是一个URL也可以是一个Git仓库。
第一个参数是第三方库的名字:
(1)url:
FetchContent_Declare(onnxruntime
URL ${ONNX_URL}
URL_HASH ${URL_HASH} # 我们设置了URL_HASH用于检查下载文件的完整性。
)
接下来就可以使用:${onnxruntime_SOURCE_DIR} ,这个是编译之后,自动生成的变量,可以直接用
(2)git:
FetchContent_Declare(json
GIT_REPOSITORY https://gitee.com/slamist/json.git #gitee加速
GIT_TAG v3.7.3)
3. 使用FetchContent_MakeAvailable(三方库) 获取我们需要库,然后引入项目。
4. 使用 target_link_libraries(项目名PRIVATE 三方库::三方库)
例如:
include(FetchContent)
FetchContent_Declare(onnxruntime
URL ${ONNX_URL}
URL_HASH ${URL_HASH}
)
FetchContent_MakeAvailable(onnxruntime)
4、target_link_libraries : 指定链接给定目标和/或其依赖项时要使用的库。命名的<目标>必须是由add_executable()或
add_library()之类的命令创建的,并且不能是ALIAS目标。
link_libraries():link_libraries 要在 add_executable 之前。 (注意,此命令已经被新版本废弃)
5、include_directories(${onnxruntime_SOURCE_DIR}/include)
include_directories
([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
将指定目录添加到编译器的头文件搜索路径之下,指定的目录被解释成当前源码路径的相对路径。
用法:
#用于头文件目录添加,注意必须是绝对路径,否则可能编译不过
INCLUDE_DIRECTORIES(~/study/cmakeStudy/demo3)
#用于库文件的目录添加,注意也必须是绝对路径,否则可能编译不过
LINK_DIRECTORIES(~/study/cmakeStudy/demo3)
#用于生成目标文件
ADD_EXECUTABLE(main ./main.cpp)
#链接静态库文件,注意此命令是放在了ADD_EXECUTABLE之后
target_link_libraries(main libsum.a)
6、file文件操作 : 参考:https://blog.youkuaiyun.com/sinat_31608641/article/details/123858610
#GLOB 会产生一个由所有匹配globbing表达式的文件组成的列表,并将其保存到变量中。相当于把所有的*.dll文件写入到ONNX_DLLS中
file(GLOB ONNX_DLLS "${onnxruntime_SOURCE_DIR}/lib/*.dll")
7、add_definitions : 功能和C/C++中的#define是一样的
option(TEST_IT_CMAKE "test" ON)
add_definitions(-DTEST_IT_CMAKE)#通过option设置一个变量,并通过add_definitions将其转换为#define TEST_IT_CMAKE
-D后面的参数就是控制程序流向。
add_definitions(-DUSE_ONNX) : 定义了USE_ONNX这个变量,在params.h文件中使用
8、ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]
这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置。
EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除。
9、add_dependencies
控制多个cmake的依赖执行顺序。比如我们想让utils先执行,openfst后执行:
add_dependencies(utils openfst) //注意utils和openfst都是子cmake文件编译的结果
10、CMAKE_BINARY_DIR,PROJECT_BINARY_DIR,_BINARY_DIR:
这三个变量内容一致,如果是内部编译,就指的是工程的顶级目录,如果是外部编译,指的就是工程编译发生的目录。
11、区分debug和release
cmake -DCMAKE__BUILD_TYPE=DEBUG(RELEASE)
12、cmake -D 和 -G
-D:-D 相当于就是定义, -D 可以理解为告诉cmake 后边我要定义一些参数了, 你每定义一个就在前边加上-D就是了
-G:指定生成器,覆盖默认的生成器。不同平台的生成器不同,例如:Unix Makefile、Ninja、Visual Studio等等
13、add_executable()相关
add_executable (<name> [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL][source1] [source2 ...])
add_executable (<name> IMPORTED [GLOBAL])
add_executable (<name> ALIAS <target>)
使用指定的源文件来生成目标可执行文件。这里的目标可执行文件分为三类:
普通可执行目标文件、
导入可执行目标文件、
别名可执行目标文件。
分别对应上面的三种命令格式。
14、cmake的add_compile_options,CMAKE_C_FLAGS和CMAKE_CXX_FLAGS
add_compile_options命令添加的编译选项是针对所有编译器的(包括c和c++编译器),
而set命令设置CMAKE_C_FLAGS或CMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器的。
15、add_test()
当在项目根目录下的CMakeLists.txt配置文件中添加:enable_testing() 之后,可以开启项目的测试功能,
注意:一定要在根目录下的CMakeLists.txt中开启,不然执行make test时会报错。
可以在项目的子CMakeLists.txt使用add_test()添加测试命令。
例如:ADD_TEST(NAME test1 COMMAND main)
16、message打印变量
SET(HELLO "Hello World")
MESSAGE( STATUS "Hello = ${HELLO}.")
6、include(ExternalProject)
(1)首先需要include来加载ExternalProject
(2)该ExternalProject_Add函数创建一个自定义目标来驱动外部项目的下载、更新/修补、配置、构建、安装和测试步骤:
#根据定义的路径创建外部项目,例如:GFLAG_ROOT是用来指定编译文件输出的路径,
#GFLAG_LIB_DIR和GFLAG_INCLUDE_DIR声明GFLAG动态库和静态库的路径
ExternalProject_Add(gflag-2.2.2
URL ${GFLAG_URL}
DOWNLOAD_NAME gflag-2.2.2.zip
PREFIX ${GFLAG_ROOT}
CONFIGURE_COMMAND ${GFLAG_CONFIGURE}
BUILD_COMMAND ${GFLAG_MAKE}
INSTALL_COMMAND ${GFLAG_INSTALL}
)
#最后通过include引用即可
include(gflag-2.2.2)
因为是笔记,所以可能会有点凌乱,见谅啦~