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 - 编译的更多相关文章

  1. linux 下cmake 编译 ,调用,调试 poco 1.6.0 小记

    上篇文章 小记了: 关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记. http://www.cnblogs.com/bleachli/p/4352 ...

  2. [C] tcharall(让所有平台支持TCHAR)v1.1。源码托管到github、添加CMake编译配置文件、使用doxygen规范注释

    作者:zyl910 v1.1版的改动如下—— 将源码上传到github. 调整目录结构. 添加CMake编译配置文件. 使用doxygen规范注释. 文件清单—— docs\ docs\images\ ...

  3. [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 ...

  4. Mysql的cmake编译与安装

    Mysql的cmake编译与安装 实验准备环境: 我的操作系统是centos6.6 编译安装MariaDB之前,我们需要准备一些需要的环境 1.开发包组套件 [root@node19 ~]# yum ...

  5. CentOS下使用cmake编译安装mysql

    一.下载安装所必需的依赖包 1.因为高版本mysql都用cmake安装,所以下载cmake wget http://www.cmake.org/files/v3.0/cmake-3.0.1.tar.g ...

  6. CentOS_5.6下使用cmake编译MySQL_5.5.11

    MySQL 最新的版本5.5.11需要cmake编译安装,估计以后的版本也会采用这种方式,网上找了一些安装方法有些地方是错的,自己整理一份 所以特地记录一下安装步骤及过程,以供参考!1 mysql 5 ...

  7. 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编译安装,估计以后的版本也会采 ...

  8. cmake编译安装mysql 5.6.12

    cmake安装mysql 5.6.12 从mysql 5.5 开始就要用cmake编译安装 下载mysql 下载地址:http://pan.baidu.com/s/1o68xxqE 一.安装mysql ...

  9. Win10 下Cmake编译配置 Opencv3.1 + Cuda7.5 + VS2013

    折腾了三天终于配置成功了,在此写下编译配置的全部步骤和遇到的很多坑. 整体介绍: OpenCV 中 CUDA 实现的函数还不是太多,使用前要在OpenCV的官网上确认以下你想要的功能是否已经实现,否则 ...

  10. Android开发学习之路--Android Studio cmake编译ffmpeg

      最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...

随机推荐

  1. [Windows] Prism 8.0 入门(上):Prism.Core

    1. Prism 简介 Prism 是一个用于构建松耦合.可维护和可测试的 XAML 应用的框架,它支持所有还活着的基于 XAML 的平台,包括 WPF.Xamarin Forms.WinUI 和 U ...

  2. moviepy音视频剪辑:追踪人脸打马赛克的三种实现方式

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 在moviepy官网的案例<Tracking and blurring someone's face>和CSDN的moviepy大神uc ...

  3. 第7章 Python类型、类、协议 第7.1节 面向对象程序设计的相关知识

    Python被视为一种面向对象的语言,在介绍Python类相关的内容前,本节对面向对象程序设计相关的概念进行简单介绍. 一.    类和对象(实例) 在面向对象的程序设计(OOP)过程中有两个重要概念 ...

  4. 开源脉冲神经网络深度学习框架——惊蛰(SpikingJelly)

    开源脉冲神经网络深度学习框架--惊蛰(SpikingJelly) 背景 近年来神经形态计算芯片发展迅速,大量高校企业团队跟进,这样的芯片运行SNN的能效比与速度都超越了传统的通用计算设备.相应的,神经 ...

  5. 实验吧 Once more

    0x1函数解析 ereg(): *用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false. 搜索字母的字符是大小写敏感的. * 此函数存在两个漏洞: ①%00截断及 ...

  6. SpringBoot之自定义拦截器

    一.自定义拦截器实现步骤 1.创建拦截器类并实现HandlerInterceptor接口 2.创建SpringMVC自定义配置类,实现WebMvcConfigurer接口中addInterceptor ...

  7. 【学习笔记】K-D tree 区域查询时间复杂度简易证明

    查询算法的流程 如果查询与当前结点的区域无交集,直接跳出. 如果查询将当前结点的区域包含,直接跳出并上传答案. 有交集但不包含,继续递归求解. K-D Tree 如何划分区域 可以借助下文图片理解. ...

  8. 题解-CF677D Vanya and Treasure

    CF677D Vanya and Treasure 有一个 \(n\times m\) 的矩阵 \(a(1\le a_{i,j}\le p)\),求从起点 \((1,1)\) 出发依次遍历值为 \(1 ...

  9. EM 算法-对鸢尾花数据进行聚类

    公号:码农充电站pro 主页:https://codeshellme.github.io 之前介绍过K 均值算法,它是一种聚类算法.今天介绍EM 算法,它也是聚类算法,但比K 均值算法更加灵活强大. ...

  10. 七、Jmeter测试元件-线程

    线程组元素是任何测试计划的起点.所有控制器和采样器必须在线程组下.其他元素(例如,侦听器)可以直接放置在测试计划下. 名称:相当于一个业务流程 继续:当取样器出错时 会继续请求: 举例:1-当一个线程 ...