1 简单的可执行文件生成工程

1.1 源文件

  main.cpp

#include <stdio.h>

int main(int argc, char *argv[])
{
printf("Hello CMake!/n"); return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

1.2 CMakeLists.txt文件

  CMakeLists.txt

# 版本限定
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
# 项目名称
PROJECT(Test1)
# 添加源文件列表变量
SET(SRC_LIST main.cpp)
# 打印编译目录和项目目录路径
MESSAGE(STATUS "This is BINARY dir " ${PROJECT_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir " ${PROJECT_SOURCE_DIR})
# 生成可执行文件
ADD_EXECUTABLE(HelloCMake ${SRC_LIST})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2 只单独生成静态库和动态库

2.1 工程目录

.
├── build
├── CMakeLists.txt
├── include
│ └── mymath.h
└── src
└── mymath.c
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.2 工程文件

  mymath.h

#ifndef _MYMATH_H_
#define _MYMATH_h_ int add(int a, int b);
int sub(int a, int b); #endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  mymath.c

#include "mymath.h"

int add(int a, int b)
{
return a + b;
} int sub(int a, int b)
{
return a - b;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.3 CMakeLists.txt

# 版本限定
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
# 项目名称
PROJECT(Test2)
# 设置编译器选项:O3优化,显示所有警告
SET(CMAKE_C_FLAGS "$ENV{CFLAGS} -O3 -Wall")
# 定义头文件的路径变量
SET(INCLUDE_PATH ${PROJECT_SOURCE_DIR}/include)
MESSAGE(STATUS "Include Path, ${INCLUDE_PATH}")
# 定义源文件路径变量
SET(SOURCE_PATH ${PROJECT_SOURCE_DIR}/src)
MESSAGE(STATUS "Source Path , ${SOURCE_PATH}")
# 包含头文件路径
INCLUDE_DIRECTORIES(${INCLUDE_PATH})
# 添加源文件路径下所有源文件存放到变量中(*.c && *.cpp),当然也可以手动一个个文件添加进来
AUX_SOURCE_DIRECTORY(${SOURCE_PATH} SRC_LIST)
# 设置动态库输出路径
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
MESSAGE(STATUS "Library Output Path, " ${PROJECT_BINARY_DIR/lib})
# 生成动态库(libmymath.so)
ADD_LIBRARY(mymath SHARED ${SRC_LIST})
# 生成静态库(libmymath.a,target名字只能有一个,所以不能与动态库的名字一样)
ADD_LIBRARY(mymath_static STATIC ${SRC_LIST})
# 但是可以通过下面的命令更改静态库target生成的库名,这样就和动态库的名字一样的了
SET_TARGET_PROPERTIES(mymath_static PROPERTIES OUTPUT_NAME "mymath")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

3 外链接动态库和静态库生成可执行文件

3.1 工程目录

.
├── build
├── CMakeLists.txt
├── include
│ └── mymath.h
├── libs
│ ├── libmymath.a
│ └── libmymath.so
└── src
└── main.c
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.2 工程文件

  mymath.h

#ifndef _MYMATH_H_
#define _MYMATH_h_ int add(int a, int b);
int sub(int a, int b); #endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  main.c(注意:因为编译的动/静态库是采用的C语言,所以只能写为main.c,而不是main.cpp,否则在链接的时候出问题,当然比较好的做法就是在生成库的时候加入extern "C"关键字,增加兼容性)

#include <stdio.h>

#include "mymath.h"

int main()
{
printf("Hello CMake!\n");
printf("1 + 5 = %d\n", add(1, 5)); return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3.3 CMakeLists.txt

# 版本限定
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
# 项目名称
PROJECT(Test3)
# 设置编译器选项:O3优化,显示所有警告
SET(CMAKE_C_FLAGS "$ENV{CFLAGS} -O3 -Wall")
# 定义头文件的路径变量
SET(INCLUDE_PATH ${PROJECT_SOURCE_DIR}/include)
MESSAGE(STATUS "Include Path, ${INCLUDE_PATH}")
# 定义库文件路径
SET(LIB_PATH ${PROJECT_SOURCE_DIR}/libs)
MESSAGE(STATUS "Libs Path, ${LIB_PATH}")
# 定义源文件路径变量
SET(SOURCE_PATH ${PROJECT_SOURCE_DIR}/src)
MESSAGE(STATUS "Source Path , ${SOURCE_PATH}")
# 包含头文件搜索路径
INCLUDE_DIRECTORIES(${INCLUDE_PATH})
# 包含库搜索路径
LINK_DIRECTORIES(${LIB_PATH})
# 定义待链接库名字
# 链接静态库
SET(LIBS_LIST libmymath.a)
# 链接动态库
#SET(LIBS_LIST libmymath.so)
# 添加源文件路径下所有源文件存放到变量中(*.c && *.cpp)
AUX_SOURCE_DIRECTORY(${SOURCE_PATH} SRC_LIST)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
# 设置生成可执行文件的名称
SET(EXECUTABLE_FILE_NAME mymath.exe)
# 生成可执行文件
ADD_EXECUTABLE(${EXECUTABLE_FILE_NAME} ${SRC_LIST})
# 设置可执行文件链接的库名称
TARGET_LINK_LIBRARIES(${EXECUTABLE_FILE_NAME} ${LIBS_LIST})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

4 CMake常用系统变量

# 编译目录路径,下面三个变量均是同样的值
CMAKE_BINARY_DIR
PROJECT_BINARY_DIR
<projectname>_BINARY_DIR
# 工程顶层路径,三个均是同样的值
CMAKE_SOURCE_DIR
PROJECT_SOURCE_DIR
<projectname>_SOURCE_DIR
# 当前CMakeLists.txt的路径,如果子目录下有CMakeLists.txt,那么该值与CMAKE_SOURCE_DIR不一样
CMAKE_CURRENT_SOURCE_DIR
# 当前CMakeLists.txt的目标文件输出路径,意义同上
CMAKE_CURRRENT_BINARY_DIR
ADD_SUBDIRECTORY(src "更改为子目录新的目标文件输出路径")
# 设置目标文件的存放路径
EXECUTABLE_OUTPUT_PATH
# 设置库文件的存放路径
LIBRARY_OUTPUT_PATH
# 设置工程名
PROJECT_NAME
# 主版本号,比如2.4.6中的2,通过SET命令来设置
CMAKE_MAJOR_VERSION,CMAKE
# 次版本号,比如2.4.6中的4
CMAKE_MINOR_VERSION,CMAKE
# 补丁等级,比如2.4.6 中的6
CMAKE_PATCH_VERSION,CMAKE
# 系统名称,比如Linux-2.6.22
CMAKE_SYSTEM
# 不包含版本的系统名,比如Linux
CMAKE_SYSTEM_NAME
# 系统版本,比如2.6.22
CMAKE_SYSTEM_VERSION
# 处理器名称,比如i686
CMAKE_SYSTEM_PROCESSOR
# 在所有的类UNIX平台为TRUE,包括OS X和cygwin
UNIX
# 在所有的win32平台为TRUE,包括cygwin
WIN32
# 动/静态库生成全局控制
BUILD_SHARED_LIBS
# C编译器选项(ADD_DEFINITIONS也可以添加选项)
CMAKE_C_FLAGS/CMAKE_C_FLAGS_DEBUG/CMAKE_C_FLAGS_RELEASE
SET(CMAKE_C_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
# C++编译器选项
CMAKE_CXX_FLAGS/CMAKE_CXX_FLAGS_DEBUG/CMAKE_CXX_FLAGS_RELEASE
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -lpthread -lm")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

5 CMake常用的指令说明

  add_definitions(-DXXX1 -DXXX2 ...) 
  remove_definitions(-DXXX1 -DXXX2 ...)

# 添加/移出宏定义
  • 1
  • 1

  aux_source_directory(dir variable)

# 作用是发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表。如将当前文件夹中所有源文件放入一个变量中:
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

# 添加编译所需的头文件
INCLUDE_DIRECTORIES(${XXX_INCLUDE_PATH} ${Other_INCLUDE_PATH} ${PROJECT_INCLUDE_PATH})
  • 1
  • 2
  • 1
  • 2

  link_directories(directory1 directory2 ...)

# 添加库搜索文件夹
LINK_DIRECTORIES(${XX1_LIB_PATH} ${XX2_LIB_PATH})
  • 1
  • 2
  • 1
  • 2

  target_link_libraries(<target> [item1 [item2 [...]]] [[debug|optimized|general] <item>] ...)

# 指明可执行文件或者库文件需要连接的链接库(静态or动态)
add_library(A STATIC a.c)
add_library(B STATIC b.c)
target_link_libraries(A B)
target_link_libraries(B A)
add_executable(main main.c)
target_link_libraries(main A)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED [GLOBAL])

# 参数 name 为欲生成的库名称,默认不加修饰为静态库,但是最后会受BUILD_SHARED_LIBS全局变量的影响,此变量默认为OFF,生成库文件是,不需要加前缀lib
add_library(calc calc.c)
add_library(mylib ${mylib_sources})
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  get_filename_component(<VAR> <FileName> <COMP> [CACHE])

# 获取一个完整名的特定部分
# 获取PROJECT_SOURCE_DIR路径中去除项目名称的路径部分
# 保存到变量WORKSPACE_DIR中(当cmake版本低于2.8.11时,component的值取PATH与大于2.8.11版本中的DIRECTORY的效果是一样的)
# <= 2.8.11
get_filename_component(WORKSPACE_DIR ${PROJECT_SOURCE_DIR} PATH)
# > 2.8.11
get_filename_component(WORKSPACE_DIR ${PROJECT_SOURCE_DIR} DIRECTORY)
# 各component说明如下
DIRECTORY = Directory without file name
NAME = File name without directory
EXT = File name longest extension (.b.c from d/a.b.c)
NAME_WE = File name without directory or longest extension
ABSOLUTE = Full path to file
REALPATH = Full path to existing file with symlinks resolved
PATH = Legacy alias for DIRECTORY (use for CMake <= 2.8.11)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

参考资料和扩展阅读

CMake和Vistual Studio

DLL动态库导出

https://cmake.org/cmake/help/v2.8.12/cmake.html

http://blog.csdn.net/freeape/article/details/52567087

cmake常用工程示例大集合的更多相关文章

  1. (转)Android之常用功能方法大集合

    这些,都是Andorid中比较常用的方法和功能,在网上搜集整理一下记录之,以备不时之需.由于经过多次转载,源文作者不确凿,在此申明,敬请见谅.不得不赞,非常实用. 1.判断sd卡是否存在 boolea ...

  2. Android 常用代码大集合 [转]

    [Android]调用字符串资源的几种方法   字符串资源的定义 文件路径:res/values/strings.xml 字符串资源定义示例: <?xml version="1.0&q ...

  3. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

  4. cmake 常用变量和常用环境变量查表手册---整理 .

    一,cmake 变量引用的方式: 前面我们已经提到了,使用${}进行变量的引用.在 IF 等语句中,是直接使用变量名而不通过${}取值 二,cmake 自定义变量的方式: 主要有隐式定义和显式定义两种 ...

  5. cmake 常用变量和常用环境变量查表手册

    cmake 常用变量和常用环境变量查表手册 一,cmake 变量引用的方式: 前面我们已经提到了,使用${}进行变量的引用.在 IF 等语句中,是直接使用变量名而不通过${}取值 二,cmake 自定 ...

  6. 干货100+ 最超全的web开发工具和资源大集合

    干货100+ 最超全的web开发工具和资源大集合   作为Web开发者,这是好的时代,也是坏的时代.Web开发技术也在不断变化.虽然很令人兴奋,但是这也意味着Web开发人员需要要积极主动的学习新技术和 ...

  7. CMake学习笔记四-CMake常用命令

    CMake常用命令 PROJECT PROJECT(projectname [CXX] [C] [Java]) 指定工程名称,并可指定工程支持的语言.支持语言列表可忽略,默认支持所有语言 SET ...

  8. java8-lambda常用语法示例

    常用语法示例: public static void main(String[] args) { List<OrderInfo> orderInfoList = Lists.newArra ...

  9. Lambda表达式常用代码示例

    Lambda表达式常用代码示例 2017-10-24 目录 1 Lambda表达式是什么2 Lambda表达式语法3 函数式接口是什么  3.1 常用函数式接口4 Lambdas和Streams结合使 ...

随机推荐

  1. TensorFlow 学习(九)—— 初始化函数(概率分布函数 api、常数生成函数)

    在 TensorFlow 中,一个变量的值在被使用之前,其初始化过程需要被明确地调用. 1. 随机数生成函数 tensorflow 下的概率分布函数,一般用于对变量进行初始化,这里的变量显然是指神经网 ...

  2. Android中使用achartengine生成图表

    今天在做项目的时候用到了图表功能,记录下来 achartengine是google的一个开源项目,可以在https://code.google.com/p/achartengine/ 下载技术文档,j ...

  3. 《node.js开发指南》第五章与新版Node变化太大的一些问题

    1.在win下,命令行工具express -h无效,因为4.x版本的express需要安装express-generator才可以使用express命令,npm install -g express- ...

  4. wxWidgets初学者导引(2)——下载、安装wxWidgets

    wxWidgets初学者导引全目录   PDF版及附件下载 1 前言2 下载.安装wxWidgets3 wxWidgets应用程序初体验4 wxWidgets学习资料及利用方法指导5 用wxSmith ...

  5. spring集成Quartz时区问题造成任务晚执行八小时

    项目中在Spring中集成了Quartz,配置的每日凌晨执行的定时任务都是到了八点多才执行,经过一番查找,可能是时区问题造成的. 一种解决办法是在JVM启动参数中增加 --Duser.timezone ...

  6. 下面介绍一个 yii2.0 的 Rbac 权限设置,闲话少说,直接上代码,

    1.首先我们要在组件里面配置一下 Rbac ,如下所示(common/config/main-local.php或者main.php).  'authManager' => [  'class' ...

  7. RabbitMQ及其.NET客户端——几个小例子

    一.简单生产者-消费者(使用direct交换器) 1.生产者 var factory = new ConnectionFactory();//实例化一个工厂 factory.HostName = &q ...

  8. 取消Jquery mobile自动省略的文本

    在使用jquery moblie做移动客户端app时,listview控件下的列表文本不能完全显示,只能显示一行,超过字数jquery mobile会自动用省略号代替.很是纠结啊. 最后在一个岛国网站 ...

  9. delphi的bpl、dcp 、dcu文件意义(BPL相当于C++中的DLL,DCP相当于C++中的Lib,编译时需要)

    BPL  英文全称 Borland Package library ,是一种特殊的DLL文件,用于代码重用和减少可执行文件.编译bpl时,仅需要添加相应功能的pas文件,如果有窗体,则需要添加dfm文 ...

  10. 李开复:VC看不上你的五个原因

    [编者按]:此文是李开复先生发表于其LinkedIn主页上的一篇文章,简单列举了五条与VC接触常忽略的经验.如果你是一位正准备和VC谈判取得资金上帮助的创业者,那么应该避免企业家常常犯下的五条错误. ...