cmake - 编译
cmake在编译期间会使用到的命令总结:
1、指定编译器并同时设置编译选项
set(CMAKE_CXX_COMPILER "clang++" ) # 显示指定使用的C++编译器
set(CMAKE_CXX_FLAGS "-std=c++11") # c++11
set(CMAKE_CXX_FLAGS "-g") # 调试信息
set(CMAKE_CXX_FLAGS "-Wall") # 开启所有警告
set(CMAKE_CXX_FLAGS_DEBUG "-O0" ) # 调试包不优化
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG " ) # release包优化
CMAKE_CXX_FLAGS设置的编译选项只会对g++有效,其他编译器不生效
当然我们也可以通过add_compile_options()设置,但是通过add_compile_options会对所有编译器生效,如:
add_compile_options(-std=c++11)
在编译C代码时就会产生告警信息
2、编译库文件
1、cmake可以通过add_library利用源文件生成动态和静态库文件,指令如下:
add_library(libxxx1 SHARED xxx.cpp xxxx.cpp) ##命令根据xxx.cpp和xxxx.cpp生成动态库文件libxxx1.so
add_library(libxxx2 STATIC xxx.cpp xxxx.cpp) ##命令根据xxx.cpp和xxxx.cpp生成静态库文件libxxx1.a
add_library(libxxx3 MODULE xxx.cpp xxxx.cpp) ##命令根据xxx.cpp和xxxx.cpp生成中间文件libxxx3,该文件不会被加载到其他地方使用
库文件生成后,我们需要对其属性进行设置,如重置库文件的名称,设置库文件的版本号等,这些需要通过set_target_properties命令实现:
1、将静态库hello_static更名为hello
set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello")
2、cmake在构建一个新的target时,会尝试清理掉其它使用这个名字的库,所以在构建libxxx.a时,就会清理掉libxxx.so,所以为了避免这种情况,我们需要如下指令
set_target_properties(xxx PROPERTIES CLEAN_DIRECT_OUTPUT 1)
set_target_properties(xxx_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
3、有时候我们需要增加动态库的版本号
set_target_properties(hello PROPERTIES VERSION 1.2 SOVERSION 1) ## VERSION指代动态库版本,SOVERSION指代API版本
2、当然我们也可以使用外部现成的库文件,指令如下
add_library(libxxx4 <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED)
IMPORTED 表明此库在工程之外,是target_link_libraries的方便形式。外部库的详细信息通过set_target_properties
设置以IMPORTED_开头的属性来完成,其中最重要的就是 IMPORTED_LOCATION 属性,它指定外部库的位置。
add_library(libxxx4 STATIC IMPORTED)
set_target_properties(libxxx4 PROPERTIES IMPORTED_LOCATION /path/to/libboost_system.a) ##libxxx4其实就是libboost_system.a
target_link_libraries(wang libxxx4)
其实上述3条命令等价于
target_link_libraries(wang /path/to/libboost_system.a)
注意:add_library除了可以生产库文件之外,还可以生成目标文件,但不打包成lib命令如下:
add_library(objlib OBJECT <src>...)
这种库只编译源文件生成目标文件,但是不把这些目标文件打包进一个lib。当其他的库或者目标文件要使用这些目标文件的时候,会以这样的形式来添加,objlib是这个库的名字
add_library(... $<TARGET_OBJECTS:objlib> ...)
add_executable(... $<TARGET_OBJECTS:objlib> ...)
寻找外部依赖库find_package()
在一个大型项目中,免不了需要导入很多外部依赖库,比如一个项目需要使用到伯克利数据库项目,我们需要知道头文件的位置,库文件的位置以及库文件的名称,此时我们就需要find_package命令
find_package命令就是寻找该库的头文件位置、库文件位置以及库文件名称,并将其设置为变量提供给CMakelists使用。以上述伯克利数据库项目为例,
find_package(DBMS)
include_directories(${DBMS_INCLUDE_DIR})
target_link_libraries(main ${DBMS_LIBRARY})
find_package(DBMS)会去 ${CMAKE_MODULE_PATH}指定的所有路径下寻找名字为FindDBMS.cmake的文件,并执行相应的代码,通常FindDBMS.cmake会输出如下几个变量
通常FindCURL.cmake文件会提供以下几个变量:
<name>_FOUND => 表明是否查找到
<name>_INCLUDE_DIR 或 <name>_INCLUDES => 表示头文件位置
<name>_LIBRARY 或 <name>_LIBRARIES 或 <name>_LIBS => 表示库文件路径+名称
<name>_DEFINITIONS
编写FindDBMS.cmake
FindDBMS.cmake主要使用如下两个函数find_path/find_library,其中find_path输出头文件的位置信息,find_library输出库文件的位置信息
find_path原型如下:
查找路径HINTS/PATH/PATH_SUFFIXES下,是否有文件名为name1的文件,如果有则将HINTS/PATH/PATH_SUFFIXES的内容存储在中,否则中存储_NOTFOUND
find_path(<VAR>
name | NAMES name1 [name2 ...]
[HINTS path1 [path2 ... ENV var]]
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
举例如下:
find_path(dbms_path
NAMES db_xxx.h
PATHS /home/dongfang/cmake_example/find_path
DOC "this is a test for find_path"
)
查找路径PATH(/home/dongfang/cmake_example/find_path)下是否有db_xxx.h文件,如果有则将"/home/dongfang/cmake_example/find_path"存储在变量dbms_path中
find_library原型如下:
查找路径HINTS/PATH/PATH_SUFFIXES下,是否有文件名为name1的文件,如果有则将HINTS/PATH/PATH_SUFFIXES的内容存储在中,否则中存储_NOTFOUND
find_library(
<VAR>
name | NAMES name1 [name2 ...]
[HINTS path1 [path2 ... ENV var]]
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
举例如下:
find_library(dbms_library
NAMES libDBMS.so
PATHS /home/dongfang/cmake_example/find_path
DOC "this is a test for find_path"
)
查找路径PATH(/home/dongfang/cmake_example/find_path)下是否有libDBMS.so文件,如果有则将"/home/dongfang/cmake_example/find_path"存储在变量dbms_library中
在经过查找头文件和库文件路径之后,我们需要对下游负责,明确告知下游头文件路径和库文件路径是否准确找到,可使用如下命令:
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DBMS dbms_path dbms_library) //如果dbms_path或者dbms_library无值,直接对下游报错
安装
不管是库文件还是目标文件,编出来之后,都需要将其放到一定的位置,方便其他目标文件使用,此时就需要install命令
install(TARGETS xylib
CONFIGURATIONS DEBUG
RUNTIME DESTINATION bin ##可执行文件安装路径
LIBRARY DESTINATION lib ##动态库安装路径
ARCHIVE DESTINATION libstatic ##静态库安装路径
)
cmake - 编译的更多相关文章
- linux 下cmake 编译 ,调用,调试 poco 1.6.0 小记
上篇文章 小记了: 关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记. http://www.cnblogs.com/bleachli/p/4352 ...
- [C] tcharall(让所有平台支持TCHAR)v1.1。源码托管到github、添加CMake编译配置文件、使用doxygen规范注释
作者:zyl910 v1.1版的改动如下—— 将源码上传到github. 调整目录结构. 添加CMake编译配置文件. 使用doxygen规范注释. 文件清单—— docs\ docs\images\ ...
- [C] c99int(让VC等编译器自动兼容C99的整数类型)V1.02。源码托管到github、添加CMake编译配置文件、使用doxygen规范注释
新版本—— http://www.cnblogs.com/zyl910/p/zlstdint_v100.html[C] zlstdint(让VC.TC等编译器自动兼容C99的整数类型)V1.0.支持T ...
- Mysql的cmake编译与安装
Mysql的cmake编译与安装 实验准备环境: 我的操作系统是centos6.6 编译安装MariaDB之前,我们需要准备一些需要的环境 1.开发包组套件 [root@node19 ~]# yum ...
- CentOS下使用cmake编译安装mysql
一.下载安装所必需的依赖包 1.因为高版本mysql都用cmake安装,所以下载cmake wget http://www.cmake.org/files/v3.0/cmake-3.0.1.tar.g ...
- CentOS_5.6下使用cmake编译MySQL_5.5.11
MySQL 最新的版本5.5.11需要cmake编译安装,估计以后的版本也会采用这种方式,网上找了一些安装方法有些地方是错的,自己整理一份 所以特地记录一下安装步骤及过程,以供参考!1 mysql 5 ...
- CentOS_5.6下使用cmake编译MySQL_5.5.11教程
注:资料来自网络 Centos 5.6编译安装mysql 5.5.11 2011年06月24日 星期五 05:33 MySQL 最新的版本5.5.11需要cmake编译安装,估计以后的版本也会采 ...
- cmake编译安装mysql 5.6.12
cmake安装mysql 5.6.12 从mysql 5.5 开始就要用cmake编译安装 下载mysql 下载地址:http://pan.baidu.com/s/1o68xxqE 一.安装mysql ...
- Win10 下Cmake编译配置 Opencv3.1 + Cuda7.5 + VS2013
折腾了三天终于配置成功了,在此写下编译配置的全部步骤和遇到的很多坑. 整体介绍: OpenCV 中 CUDA 实现的函数还不是太多,使用前要在OpenCV的官网上确认以下你想要的功能是否已经实现,否则 ...
- Android开发学习之路--Android Studio cmake编译ffmpeg
最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...
随机推荐
- 洛谷P3901 数列找不同(莫队水题)
重温下手感,判断区间是否全是不同的数字有两种做法,一个长度为len的区间不同的数字,参见HH的项链,一种是区间众数,参见蒲公英,是水题没错了.明天搞数据库,然后继续自己的gre和训练计划 #inclu ...
- 第5.2节 Python的函数参数收集
函数的参数使用除了常规的位置参数和关键字参数外,还支持可变个数的函数参数,这种支持可变个数的参数方法称为参数收集,对应的参数称为收集参数. 一.参数收集的定义 Python的函数支持可变不定数量的参数 ...
- Pentaho Report Designer 入门教程(一)
PentahoReport Designer 入门教程 采用Pentaho Report Designer5.1版本,也是最新的版本. 一. 安装和介绍 介绍部分内容略,首先安装jdk,并 ...
- (四)一个bug的生命周期
Bug的属性 Bug重现环境 这个应该是我们重现BUG的一个前提,如果没有这个前提,我们可能会无法重现问题,或者根本就无从下手. • 操作系统 这个是一般软件运行的一大前提,基本上所有的软件都依赖于操 ...
- 安装centos出现的问题
1.配置好之后,点击完成,如果出现"无法创建新虚拟机,无法打开配置文件,D:/... ,拒绝访问" 的错误时: 关闭虚拟机,重新以管理员身份打开.
- C#实例化对象的三种方式及性能对比
前言 做项目过程中有个需求要实例化两万个对象并添加到List中,这个过程大概需要1min才能加载完(传参较多),于是开启了代码优化之旅,再此记录. 首先想到的是可能实例化比较耗时,于是开始对每种实例化 ...
- solidity 合约单元测试报错 org.fisco.bcos.web3j.protocol.exceptions.TransactionException: Transaction has failed with status: 0x16. Gas used: 1163650. (not-enough gas?)
org.fisco.bcos.web3j.protocol.exceptions.TransactionException: Transaction has failed with status: 0 ...
- 第一章、Docker 简介
笔记内容来自:第一本Docker书 [澳] James Turnbull 著 李兆海 刘斌 巨震 Docker 是一个能够把开发的应用程序自动部署到容器的开源引擎.(由Docker 公司,前dot ...
- Ionic学习记录
1.跨域问题 浏览器中的运行 当你运行 ionic serve 时发生了什么呢? 启动了一个本地 web 服务器 你的浏览器打开并定位到本地服务器地址 这让你看着你的应用加载到你电脑上一个浏览器里,地 ...
- CSS知识点记录
1.浏览器style中显示的样式 这里面的样式,是行内样式或者是使用js添加的样式