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. moviepy音视频开发:audio_normalize调整剪辑音量大小到正常

    ☞ ░ 前往老猿Python博文目录 ░ 概述 audio_normalize函数用于将一个剪辑的音量大小调整到正常,调整的思路就是将剪辑中音频帧数据的最大值取出来,当其值小于1时,表示剪辑的音量偏小 ...

  2. Python接口测试-使用requests模块发送post请求

    本篇主要记录下使用python的requests模块发送post请求的实现代码. #coding=utf-8 import unittest import requests class PostTes ...

  3. LeetCode初级算法之数组:217 存在重复元素

    存在重复元素 题目地址:https://leetcode-cn.com/problems/contains-duplicate/ 给定一个整数数组,判断是否存在重复元素.如果任意一值在数组中出现至少两 ...

  4. KM 算法

    KM 算法 可能需要先去学学匈牙利算法等二分图相关知识. 模板题-洛谷P6577 [模板]二分图最大权完美匹配 给 \(n\) 和 \(m\) 与边 \(u_i,v_i,w_i(1\le i\le m ...

  5. 三、Zookeeper简介

    一.简介 zookeeper 主要使用场景:分布式系统的分布式协同服务.协同工作就是通过某种方式,让着节点的信息能够同步和共享,依赖于进程间的通信.通信方式有俩种. 通过网络进行信息共享 现实工作中, ...

  6. STL—— 容器(vector)begin() 与 rbegin() , end() 与 rend()

    1. Vector 迭代器首地址与尾地址 begin() 和 end() 在代码中可以将迭代器用作参数的位置可以使用  begin() 和 end() 获取地址,如下代码: 1 #include &l ...

  7. Jmeter(4)断言

    Jmeter添加断言,检查测试中得到的响应数据是否符合预期.以下介绍下响应断言,JSON断言 一.响应断言 1.创建测试计划: 添加线程组->添加取样器->添加察看结果树,运行后可查看接口 ...

  8. Linux系统的目录及作用

    Linux与Windows命令的区别  Linux的目录结构 / :Linux系统的根目录 通常不会在这里存储文件 /bin :二进制目录,存放用户级的命令/boot: 启动目录,存放的是启动文件 L ...

  9. IIS应用程序池配置详解及优化

    参数说明 1.常规 属性名称 属性详解 NET CLR 版本 配置应用程序池,以加载特定版本的 .NET CLR.选定的 CLR版本应与应用程序所使用的相应版本的 .NET Framework 对应. ...

  10. do while 后面要加分号,你大爷的

    do { //do something } while (0) TSfree(url); 这个TSFree 正好是个宏,然后编译就提示错误: error: expected ';' before '_ ...