网站规划建设与管理维护大学论文,在哪个网站开发外贸业务,房产网站建设公司,上海中学初中部一、CmakeList介绍#xff1a;
cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。它会通过写的语句自动生成一个MakeFile,从而实现高效编译
二、CmakeList的常用指令
1.指定…一、CmakeList介绍
cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。它会通过写的语句自动生成一个MakeFile,从而实现高效编译
二、CmakeList的常用指令
1.指定 cmake 的最小版本可选 cmake_minimum_required(VERSION 2.8) 这条语句规定了执行这个cmake的版本不能低于2.8否则会报错要求升级cmake版本
2.设置项目名称可选 project(HELLO) 这个命令不是强制性的但最好都加上。它会引入两个变量 HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR同时cmake 自动定义了两个等价的变量 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR
3.添加生成的二进制文件 add_executable(name source…) 参数解释 1name为需要生成的可执行文件名也就是例如gcc demo.c -o demo-o生成的demo就是这里的参数name生成后就可以在可执行文件目录执行./demo运行 2第二个参数source为源文件也就是.c或者.cpp文件这个参数可以有多个实现多个源文件一起编译
知道了上面三个指令我们就可以写一个简单的CmakeList文件啦先写一个小demo试试水~
在当前目录下有一个function的文件夹里面存放着一个叫fun.cpp的文件文件中有一个add的函数实现的是对输入的两数相加并返回。function文件夹外面存放着CmakeList.txt与我们的主函数demo.cpp。 现在编写CmakeList.txt
cmake_minimum_required(VERSION 2.8)
project(HELLO)
add_executable(hello ./demo.cpp function/fun.cpp)接着在CmakeList.txt所在的目录下执行
cmake .
就会生成几个文件以及文件夹其中的MakeFile就是我们需要的 接着执行
make
就可以看到目录下出现了我们需要的可执行文件hello运行./hello 可以看到成功打印出了结果15
4. 收集指定目录下的源码文件
很多时候我们构建一个二进制文件的时候可能有几十或上百个.c或.cpp源码参与编译如果我们在add_executable后一个个指定效率非常低下这时候就可以使用aux_source_directory aux_source_directory(dir variable) 5.生成库文件 add_library(library_name [STATIC | SHARED | MODULE] EXCLUDE_FROM_ALL source_files) library_name为要生成库的名称例如生成一个名为libadd.so的动态库时填add就行lib与后面的.so会自动生成 STATIC表示生成静态库SHARED表示生成动态库MODULE表示生成一个模块这是可选参数但是最好根据需要生成的库类型都加上 使用 EXCLUDE_FROM_ALL 选项时库目标将不会被自动构建而是需要通过其他目标或手动指令进行显式构建。这个选项通常用于一些可选的或测试相关的库它们不需要作为构建过程的一部分但可以在需要时手动构建。这个也是可选参数 source_files为生成库的源文件
6. 指定连接库
这里有两种方式第一种为link_directories与link_libraries搭配使用还有一种是find_library与target_link_libraries搭配更加推荐使用第二种因为可读性更好可以让我们更好的了解代码的依赖关系并且可以确保在构建过程中只链接指定的库文件
第一种方式 link_directories(directory1 directory2 …) 添加库的查找路径 其中directory1、directory2等是你要添加的附加库文件目录。 需要注意的是link_directories默认路径在当前目录下也就是说如果不提供绝对路径的话只能在当前目录的子目录下找 link_libraries(library1 library2 …) 设置需要链接的文件 其中library1、library2等参数是要链接的库文件名。 link_libraries可以把库链接到后续所有的目标中库名以libpthread为例可以写libpthread.so、pthread,都可以识别
第二种方式推荐使用 find_library(LIBRARY_PATH mylibrar PATHS /path/to/library/directory1 /path/to/library/directory2) LIBRARY_PATH为一个变量find_library会把找到的库存到这个变量中。可以供下面target_link_libraries使用 mylibrar为需要查找的库名称 PATHS为开始的字段不是必须的它可以指定除当前目录下的其他路径后面跟的都是需要查找的路径 target_link_libraries(target [item1] [item2] …) 其中 target 是要链接库文件的目标例如可执行文件、静态库等[item1]、[item2] 等是要链接到目标的库文件或目标。 item1的设置方式
可以是写死的库例如库名为libadd.so可以写成target_link_libraries(demo add)使用set设置变量的方式set(LIBRARY_PATH /path/to/library)item1使用${LIBRARY_PATH}代替add_library(my_library STATIC my_library.cpp) 这种方式会生成一个新的库供使用使用find_library设置的变量来链接
7.添加编译宏
很多时候我们的代码中存在类似#ifdef XXX 这样的编译宏可以决定代码编译出不同功能或架构的代码例如gcc编译时为gcc demo.c -DDEBUG,这时候如果代码中存在DEBUG这样的宏就会编译被ARM宏包着的那段代码,设置宏与库一样也有两种方式 第一种add_definitions add_definitions(-DXXX) -D为必须的XXX为需要设置的宏这样设置会让下面所有构建的目标都带上这个宏参与编译同样不推荐使用
第二种target_compile_definitions 推荐使用 target_compile_definitions(target DEFINE1 DEFINE2 …) target 是要添加宏定义的目标例如可执行文件、静态库等 scope 是定义的作用范围例如 PUBLIC、PRIVATE 或 INTERFACE DEFINE1、DEFINE2 等是要添加的宏定义。 需要注意的是target_compile_definitions需要写在已经构建的目标后例如target是demo这个可执行文件那么在target前需要首先调用add_executable在有demo这个目标后再再调用target_compile_definitions否则会出现构建报错
8. 检查软件包 find_package( [version] # 指定要查找的库或者模块版本号可选 [EXACT] # 要求version完全匹配 [QUIET] # 无论找到与否都不产生任何提示性消息 [REQUIRED] # 要求必须找到 xxx.cmake找不到就提示报错 [[COMPONENTS] [components…]] 查找 Package 中的指定模块COMPONENTS 跟的是一个列表只要列表中任意一个模块没有被找到则认为整个 Package 没有被找到即 PackageName_FOUND 为 false如果存在REQUIRED选项则可以省略COMPONENTS关键字 [OPTIONAL_COMPONENTS [components…]] [MODULE] # 仅使用模块模式 [CONFIG|NO_MODULE] # 仅使用配置模式两种写法是等效的 [GLOBAL] [NO_POLICY_SCOPE] [BYPASS_PROVIDER] ) find_package 一般都内置了一些变量 _FOUND可以判断是否找到对应的包或者模块 _INCLUDE_DIR表示头文件目录前提是包被找到才会被自动设置 _LIBRARIES表示库文件
以opencv为例
# 检索OpenCV库
find_package(OpenCV REQUIRED)add_executable(main src/main.cpp)
if(OpenCV_FOUND)# 引入头文件目录include_directories(${OpenCV_INCLUDE_DIRS})# 链接库文件target_link_libraries(main ${OpenCV_LIBRARIES})
else(OpenCV_FOUND)message(FATAL_ERROR OpenCV library not found)
endif()9.添加头文件搜索路径 include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 …]) AFTER|BEFORE: 指定添加的搜索路径的位置默认是 AFTER即添加到已有的搜索路径之后。可以使用 BEFORE 将搜索路径添加到已有的搜索路径之前。 SYSTEM: 表示目录是系统目录编译器会忽略其中的头文件的警告。可以不加 dir1 [dir2 …]: 要添加到搜索路径的目录列表。
10.构建带有层级目录的工程
如果我们想编译一个二进制文件而这个二进制文件需要链接一个动态库这个动态库也是需要实时编译出来给二进制使用的这时候我们就可以使用add_subdirectory、add_dependencies来建构 add_subdirectory(subdirectory_path binary_output_path) subdirectory_path为子目录的路径指定要添加的子目录的路径。 binary_output_path为二进制输出目录指定生成的二进制文件库或可执行文件的输出路径。 当我们执行cmake 时它会进入指定的子目录中执行该子目录下的 CMakeLists.txt 文件并将生成的二进制文件输出到指定的二进制输出目录。 add_dependencies(target_name dependency_target_name) target_name为目标名称指定当前目标的名称。 dependency_target_name为依赖目标名称指定当前目标所依赖的目标的名称。 当运行 cmake 构建项目时如果当前目标依赖于另一个目标则会先构建所依赖的目标然后再构建当前目标。这可以确保在构建当前目标之前其所依赖的目标已经被正确地构建完成。 下面是示例 这是主目录与子目录的CMakeList内容
主目录cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(DEMO)include_directories(./include)# 添加可执行文件目标
add_executable(demo ./demo.c)# 将 demo 目标与 lib 目标链接
target_link_libraries(demo add)add_subdirectory(lib ./lib/)
add_dependencies(demo add)子目录cat lib/CMakeLists.txt
cmake_minimum_required(VERSION 2.8project)
project(ADD)
add_library(add SHARED add.c)
下面是目录结构
.
├── CMakeLists.txt
├── demo.c
├── include
│ └── add.h
└── lib├── add.c└── CMakeLists.txt
10:30 上午 cmake cat demo.c
#include stdio.h
#include add.hint main()
{printf(%d\n,add(1,2));return 0;
}10:31 上午 cmake cat lib/add.c
int add(int a,int b)
{return ab;
}
在主目录下执行cmake. make发现lib下生成了libadd.so并且主目录下生成了我们需要的demo可执行文件运行结果为3
11.设置二进制的生成路径
当我们执行add_executable后通常需要把二进制放到指定的目录这时候就可以通过install来实现相当于操作了make install install([Target | File | Directory | Script] my_executable DESTINATION you_path) 目标Target可以使用构建生成的目标名称作为第一个参数。 文件File可以使用文件路径作为第一个参数。 目录Directory可以使用目录路径作为第一个参数。 脚本Script可以使用脚本文件路径作为第一个参数。
示例 install(TARGETS my_executable DESTINATION bin)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.md DESTINATION share) 示例中my_executable 是一个已经定义的可执行目标它将被安装到 bin 目录中。同时项目根目录下的 README.md 文件将被安装到 share 目录中。