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开发学习之路– ...
随机推荐
- day6(短信验证接口)
1.注册容联云账号 1.1注册账号 https://www.yuntongxun.com/user/login 1.2登录即可看到开发者账号信息 1.3 添加测试账号 2.使用容联云发送代码测试 ' ...
- Python中判断一个中文是否中文数字的方法
Python内置功能非常强大,在字符串内置函数中提供了一个判断字符串是否全数字的方法,而且这个方法不只是简单判断阿拉伯数字,包括中文数字和全角的阿拉伯数字都认识,这个函数就是字符串的isnumeric ...
- PyQt(Python+Qt)学习随笔:Qt Designer中部件与国际化有关的设置translatable、 disambiguation和comment含义
在Qt Designer的部件的多个属性中,如toolTip.whatsThis.accessibleName.accessibleDescription.text等都有国际化属性设置,国际化属性有三 ...
- 事后Postmortem会议
会议图片 一.设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我的软件是要建立一个失物招领网站,是一个为校园里的失误招领工作提供便利的平台.我们对 ...
- linux 下指定配置文件安装mongodb
下载 官网下载地址:https://www.mongodb.com/try/download/community,并上传linux 服务器 二.mongon目录结构下 /data/mongo . lo ...
- NameSilo的DDNS动态域名解析
用Java写的,一个实时检测IP变化并更新DNS状态的工具,适用于在NameSilo购买的域名,如果你的域名是在其他商家购买的,修改为你自己的api就行.代码我放github了,地址: https:/ ...
- 学生证申请Idea
1.地址:https://www.jetbrains.com/shop/eform/students2.英语不好的一键翻译,说明:三五天下来3.上图:
- C++异常之七 标准库里的异常类
标准库里的异常类 C++标准提供了一组标准异常类,这些类以基类 Exception 开始,标准程序库抛出的所有异常,都派生于该基类,这些类构成如图所示的异常类的派生继承关系,该基类提供一个成员函数 w ...
- HTTP/2做错了什么?刚刚辉煌2年就要被弃用了!?
GitHub 19k Star 的Java工程师成神之路,不来了解一下吗! GitHub 19k Star 的Java工程师成神之路,真的不来了解一下吗! GitHub 19k Star 的Java工 ...
- 双端口RAM和多模块存储器
目录 双端口RAM 存取周期 双端口RAM 多模块存储器 普通存储器 单体多字存储器 多体并行的存储器 高位交叉编址的多体存储器 低位交叉编址的多提存储器 为什么要这么弄? 高位 低位 流水线(考试常 ...