CMake是一个跨平台的编译自己主动配置工具,它使用一个名为CMakeLists.txt的文件来描写叙述构建过程,能够产生标准的构建文件。它能够用简单的语句来描写叙述全部平台的安装(编译过程)。它能够输出各种各样的makefile或者project文件,能測试编译器所支持的C++特性,相似UNIX下的automake。CMake并不直接建构出终于的软件,而是产生标准的建构档(如Unix的Makefile或Windows Visual C++的projects/workspaces)。然后再依一般的建构方式使用。

CMake能够编译源码、制作程式库、产生适配器(wrapper)、还能够用随意的顺序建构运行档。CMake支持in-place建构(二进档和源码在同一个文件夹树中)和out-of-place建构(二进档在别的文件夹里),因此能够非常easy从同一个源码文件夹树中建构出多个二进档。CMake也支持静态与动态程式库的建构。

CMake是一个比make更高级的编译配置工具。

CMake的组态档取名为CMakeLists.txt。

组态档是用一种建构软件专用的特殊编程语言写的CMake脚本。文件CMakeLists.txt须要手工编写,也能够通过编写脚本进行半自己主动的生成。通过编写CMakeLists.txt,能够控制生成的Makefile,从而控制编译过程。

CMake主要特点:(1)、开放源码,使用类BSD许可公布。(2)、跨平台,并可生成native编译配置文件,在Linux/Unix平台,生成makefile;在苹果平台,能够生成xcode;在windows平台,能够生成msvc的project文件;(3)、能够管理大型项目;(4)、简化编译构建过程和编译过程,CMake的工具链非常简单:cmake+make。(5)、高效率;(6)、可扩展,能够为cmake编写特定功能的模块。扩充cmake功能。

查看Ubuntu14.0464位机上是否安装了CMake及版本号号,可通过运行一下语句来验证:

$ cmake --version

若没有安装,可运行下面语句进行安装:

$ apt-get install cmake

CMakeLists.txt的语法比較简单,由命令、凝视和空格组成。当中命令是不区分大写和小写的。參数和变量是大写和小写相关的,但,推荐全部使用大写指令。

符号”#”后面的内容被觉得是凝视。命令由命令名称、小括号和參数组成。參数之间使用空格或分号进行间隔。变量使用${xxx}引用。

经常使用命令说明:

1.      aux_source_directory(<dir><variable>) :该命令会把參数<dir>中全部的源文件(不包含头文件)名称赋值给參数<variable>;

2.      find_path(<VAR> name1[path1 path2 …]):该命令在參数path*指示的文件夹中查找文件name1并将查找到的路径保存在变量VAR中(当中使用”[…]”包含的项表示可忽略项,使用”…|…”切割的项表示仅仅能选择当中一项)。

3.      find_library(${var} NAMES name1[name2 …] PATHS path1 [path2 …] PATH_SUFFIXES suffix1 [uffix2 …]):搜索一个外部的链接库文件,并将结果的全部路径保存到var变量中。

要搜索的链接库文件名称字可能是name1,name2等。搜索路径为path1, path2等;此外还能够指定路径的后缀词为suffix1,suffix2等;

4.      find_package(name):在指定的模块文件夹中搜索一个名为Find<name>.cmake(比如。FindOSG.cmake)的CMake脚本模块文件,运行当中的内容。意图搜索到指定的外部依赖库头文件和库文件位置。

5.      find_program:搜索一个外部的可运行程序;

6.      project(name):指定项目名称name。

7.      include(file):在当前文件里包含还有一个CMake脚本文件的内容,用来加载CMakeLists.txt文件,也用于加载提前定义的cmake模块。

8.      include_directories:指定头文件的搜索路径,用来向project加入多个特定的头文件搜索路径。能够多次调用以设置多个路径,相当于指定gcc的-I參数;

9.      link_directories:加入非标准的共享库搜索路径,设置外部动态链接库或静态链接库的搜素路径,相当于gcc的-L參数;

10.  link_libraries:加入链接库;

11.  add_subdirectory:用于向当前project加入存放源文件的子文件夹,并能够指定中间二进制和目标二进制文件存放的位置;

12.  add_executable:编译可运行程序,指定编译,好像也能够加入.o文件;

13.  add_definitions(-DMACRO1-DMACRO2 …):加入编译參数,加入-D预编译宏定义,能够一次加入多个;

14.  add_dependencies:定义target依赖的其他target,确保在编译本target之前。其他的target已经被构建;

15.  add_library:能够设置要生成的链接库为SHARED或者STATIC,还能够设置MODULE(插件。可动态调用,但不作为其他project的依赖);

16.  add_custom_target(name COMMANDcmd1 [COMMAND cmd2 ..]):加入一个名为name的编译文件夹,并指定一个或多个自己定义的命令cmd1,cmd2等;注意ADD_CUSTOM_COMMAND与这个命令的差别:前者是针对一个已有的子project进行自己定义编译规则的设置;后者则是建立一个新的自己定义的目标project;

17.  target_link_libraries:能够用来为target加入须要链接的共享库。指定project所用的依赖库,加入链接库,加入动态库或静态库,相当于指定-l參数;

18.  message:打印消息。在控制台或者对话框输出一行或多行调试信息;

19.  set:定义一个用户自己定义变量;

20.  set_target_properties:用来设置输出的名称,对于动态库,还能够用来指定动态库版本号和API版本号;

21.  cmake_minimum_required:设定依赖的cmake版本号。

22.  configure_file(infile outfile):将文件infile拷贝到outfile的位置,同一时候运行当中变量的自己主动配置和更替;

23.  install:安装目标project到指定的文件夹,此命令用于定义安装规则,安装的内容能够包含目标二进制、动态库、静态库以及文件、文件夹、脚本等;

24.  option(${var} “text” value):向用户提供一个可选项。提示信息为text。初始值为value,并将终于的结果传递到var变量中。

25.  enable_testing:用来控制Makefile是否构建test目标,涉及project全部文件夹;

26.  exec_program:用于在指定的文件夹运行某个程序;

27. execute_process:运行一个或多个子进程。按指定的先后顺序运行一个或多个命令;

28.  file:文件操作命令;

内置变量、环境变量:

1.      CMAKE_C_COMPILER:指定C编译器;

2.      CMAKE_CXX_COMPILER:指定C++编译器;

3.      CMAKE_C_FLAGS:指定编译C文件时的编译选项,如-g,也能够通过add_definitions加入编译选项;

4.      CMAKE_CXX_FLAGS:设置C++编译选项。

5.      CMAKE_BUILD_TYPE:build类型(Debug,Release,…),CMAKE_BUILD_TYPE=Debug;

6.      CMAKE_COMMAND:也就是CMake可运行文件本身的全路径;

7.      CMAKE_DEBUG_POSTFIX:Debug版本号生成目标的后缀,通常能够设置为”d”字符;

8.      CMAKE_GENERATOR:编译器名称。比如”UnixMakefiles”, “Visual Studio 7”等;

9.      CMAKE_INSTALL_PREFIX:project安装文件夹。全部生成和调用所需的可运行程序。库文件,头文件都会安装到该路径下,Unix/Linux下默觉得/usr/local, windows下默觉得C:\Program Files;

10.  CMAKE_MODULE_PATH:设置搜索CMakeModules模块(.cmake)的额外路径。用来定义自己的cmake模块所在的路径;

11.  CMAKE_CURRENT_SOURCE_DIR:指的是当前处理的CMakeLists.txt所在的路径。

12.  CMAKE_CURRENT_BINARY_DIR:假设是in-source编译。则跟CMAKE_CURRENT_SOURCE_DIR一致。假设是out-of-source,指的是target编译文件夹;

13.  CMAKE_CURRENT_LIST_FILE:输出调用这个变量的CMakeLists.txt的完整路径;

14.  CMAKE_CURRENT_LIST_LINE:输出这个变量所在的行;

15.  CMAKE_INCLUDE_CURRENT_DIR:自己主动加入CMAKE_CURRENT_BINARY_DIR和CMAKE_CURRENT_SOURCE_DIR到当前处理的CMakeLists.txt;

16.  CMAKE_INCLUDE_DIRECTORIES_PROJECT_EFORE:将project提供的头文件文件夹始终至于系统头文件文件夹的前面,当你定义的头文件确定跟系统发生冲突时能够提供一些帮助。

17.  EXECUTABLE_OUTPUT_PATH:指定可运行文件的存放路径。终于结果的存放文件夹;

18.  LIBRARY_OUTPUT_PATH:指定库文件存放路径,终于结果的存放文件夹;

19.  BUILD_SHARED_LIBS:指定编译成静态库还是动态库;

20.  PROJECT_BINARY_DIR(CMAKE_BINARY_DIR):假设是内部构建(in-sourcebuild),指的就是project顶层文件夹;假设是外部构建(out-of-source build)。指的是project编译发生的文件夹;

21.  PROJECT_NAME:project名称。即使用PROJECT命令设置的名称;

22.  PROJECT_SOURCE_DIR(CMAKE_SOURCE_DIR):project源码文件所在的文件夹。指的是project顶层文件夹;

23.  CYGWIN:标识当前系统是否为Cygwin;

24.  MSVC:标识当前系统是否使用MicrosoftVisual C。

25.  UNIX:标识当前系统是否为Unix系列(包含Linux、Cygwin和Apple);

26.  WIN32:标识当前系统是否为Windows及Win64;

内置变量的使用:

1.      在CMakeLists.txt中指定。使用set;

2.      cmake命令中使用,如cmake-DBUILD_SHARED_LIBS=OFF;

CMake调用环境变量的方式:使用$ENV{NAME}指令就能够调用系统的环境变量了。

如MESSAGE(STATUS “HOME dir: $ENV {HOME}”)

环境变量设置的方式是:SET(ENV{变量名} 值)

变量。以${MY_VAIRABLE}的形式表达,其储存类型为字符串类型,可是能够依据具体命令的要求自己主动转换成布尔型、整型或者浮点类型。变量能够出如今字符串中。也能够实现”内省”。变量实用户自己定义和系统内置两种,用户自己定义变量使用SET命令设置;而系统变量由系统自己主动赋值。比如${PROJECT_SOURCE_DIR}。

CMake中的条件语句:IF(expression)… ELSE(expression) … ENDIF(expression) 或者IF(expression1) …ELSEIF(expression2) … ELSE() … ENDIF() ,expression是推断条件,和C/C++相似。CMake的条件也存在”与/或/非”以及”等于/大于/小于”等几种操作符,分别用AND/OR/NOT以及EQUAL/LESS/GREATER来表示。IF控制语句。变量是直接使用变量名引用。而不须要${}.

CMake中的循环语句:FOREACH(vararg1 arg2 …) … ENDFOREACH(var) ,设置一个循环的局部变量var,每次将其赋为arg1, arg2等变量(或者变量数组)中的一个值,并运行循环中的命令段。

CMake中的宏函数能够理解为C语言的函数,它改变代码运行跳转的流程并简化了脚本程序的开发:MACRO(funcname [arg1 [arg2 …]]) … ENDMACRO(funcname) ,和函数的编写要求一样,CMake的宏函数必须制定一个函数名funcname,以及零个或多个输入參数arg1,arg2等。须要调用宏函数的时候,仅仅要直接使用funcname(arg1 arg2)的形式就能够了。

CMake第一次运行的时候,它将产生一个文件叫CMakeCache.txt。该文件能够被看作一个配置文件。它里面的内容就像传递给configure命令的參数集。

下面举例来说明CMake的具体使用方法:

总的文件夹结构为:

各个文件的内容为:

1.1 make_api.sh

#!/bin/bash

set -e

PROJ_ROOT=$PWD
BUILD_ROOT=$PROJ_ROOT
echo "build root: $BUILD_ROOT" if [ "$1" == "--no-test" ]; then
NO_TEST=1
else
NO_TEST=0
fi #mkdir的-p选项同意一次创建多层次的文件夹,而不是一次仅仅创建单独的文件夹
mkdir -p $BUILD_ROOT/build
cd $BUILD_ROOT/build
cmake -DCMAKE_CXX_FLAGS=-g -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX:PATH=$BUILD_ROOT/install $PROJ_ROOT
make -j5
make install > /dev/null mkdir -p $BUILD_ROOT/api/build
cd $BUILD_ROOT/api/build
cmake -DCMAKE_BUILD_TYPE=Release -DNO_TESTBENCH=$NO_TEST \
-DSDK_INSTALL_PATH=$BUILD_ROOT/install \
-DCMAKE_INSTALL_PREFIX:PATH=$PROJ_ROOT/api_install $PROJ_ROOT/api
make -j5
make install > /dev/null

1.2 CMakeLists.txt

#/cmake/CMakeLists.txt
PROJECT(math_sdk)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
MESSAGE("start build") ADD_SUBDIRECTORY(add_sub)
ADD_SUBDIRECTORY(mul_div)

1.3 add_sub

1.3.1 CMakeLists.txt

#/cmake/add_sub
ADD_SUBDIRECTORY(add)
ADD_SUBDIRECTORY(sub) #文件夹的安装
#INSTALL(DIRECTORY ./add/src/
# DESTINATION include/add/
# FILES_MATCHING PATTERN "*.h"
# ) #INSTALL(DIRECTORY ./sub/src/
# DESTINATION include/sub/
# FILES_MATCHING PATTERN "*.h"
# )

1.3.2 add

1.3.2.1 src

1.3.2.1.1 addOper.cpp

#include "addOper.h"

int calAdd(int a, int b)
{
return (a + b);
}

1.3.2.1.2 addOper.h

#ifndef _ADD_OPER_H_
#define _ADD_OPER_H_ int calAdd(int a, int b); #endif

1.3.2.2 CMakeLists.txt

#/cmake/add_sub/add
AUX_SOURCE_DIRECTORY(./src ADD_SRC_LIST) ADD_LIBRARY(add_oper STATIC
${ADD_SRC_LIST}
) INSTALL(DIRECTORY ./src/
DESTINATION include/add_sub/add
FILES_MATCHING PATTERN "*.h"
) INSTALL(TARGETS add_oper
DESTINATION lib
)

1.3.3 sub

1.3.3.1 src

1.3.3.1.1 subOper.cpp

#include "subOper.h"

int calSub(int a, int b)
{
return (a - b);
}

1.3.3.1.2 subOper.h

#ifndef _SUB_OPER_H_
#define _SUB_OPER_H_ int calSub(int a, int b); #endif

1.3.3.2 CMakeLists.txt

#/cmake/add_sub_sub
AUX_SOURCE_DIRECTORY(./src SUB_SRC_LIST) ADD_LIBRARY(sub_oper STATIC
${SUB_SRC_LIST}
) INSTALL(DIRECTORY ./src/
DESTINATION include/add_sub/sub
FILES_MATCHING PATTERN "*.h"
) INSTALL(TARGETS sub_oper
DESTINATION lib
)

1.4 api

1.4.1 include

1.4.1.1 mathOper.h

#ifndef _MATH_OPER_H_
#define _MATH_OPER_H_ int calAddSub(int a, int b);
int calMulDiv(int a, int b); #endif

1.4.2 sdk

1.4.2.1 CMakeLists.txt

#/cmake/api/sdk
AUX_SOURCE_DIRECTORY(. SDK_SRC_LIST) INCLUDE_DIRECTORIES(${SDK_INSTALL_PATH}/include/add_sub)
INCLUDE_DIRECTORIES(${SDK_INSTALL_PATH}/include/mul_div) ADD_LIBRARY(mathsdk SHARED ${SDK_SRC_LIST}) SET(DEP_LIBS
${SDK_INSTALL_PATH}/lib/libadd_oper.a
${SDK_INSTALL_PATH}/lib/libsub_oper.a
${SDK_INSTALL_PATH}/lib/libmul_oper.a
${SDK_INSTALL_PATH}/lib/libdiv_oper.a
) TARGET_LINK_LIBRARIES(mathsdk ${DEP_LIBS}) INSTALL(TARGETS mathsdk
DESTINATION lib
)

1.4.2.2 mathOper.cpp

#include "mathOper.h"

#include "add/addOper.h"
#include "sub/subOper.h" #include "mul/mulOper.h"
#include "div/divOper.h" int calAddSub(int a, int b)
{
int c = 0, d = 0; c = calAdd(a, b);
d = calSub(a, b); return (c + d);
} int calMulDiv(int a, int b)
{
int c = 0, d = 0; c = calMul(a, b);
d = calDiv(a, b); return (c - d);
}

1.4.3 test

1.4.3.1 CMakeLists.txt

#/cmake/api/test
AUX_SOURCE_DIRECTORY(. TEST_SRC_LIST) INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/include) ADD_EXECUTABLE(test ${TEST_SRC_LIST}) SET(DEP_LIB ${CMAKE_INSTALL_PREFIX}/lib/libmathsdk.so) TARGET_LINK_LIBRARIES(test ${DEP_LIB}) INSTALL(TARGETS test
DESTINATION bin
)

1.4.3.2 demo.cpp

#include "mathOper.h"
#include <iostream> int main()
{
int a = 10, b = 2; int c = calAddSub(a, b);
int d = calMulDiv(a, b); std::cout<<"c = "<<c<<std::endl;//c = 20
std::cout<<"d = "<<d<<std::endl;//d = 15 return 0;
}

1.4.4 CMakeLists.txt

#/cmake/api
PROJECT(math_api)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8) MESSAGE("==============start build api==============") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z defs -pthread") INCLUDE_DIRECTORIES(${SDK_INSTALL_PATH}/include/add_sub)
INCLUDE_DIRECTORIES(${SDK_INSTALL_PATH}/include/mul_div)
LINK_DIRECTORIES(${SDK_INSTALL_PATH}/lib)
INCLUDE_DIRECTORIES(include) ADD_SUBDIRECTORY(sdk) if(NOT NO_TESTBENCH)
ADD_SUBDIRECTORY(test)
endif() INSTALL(DIRECTORY ./include/
DESTINATION include
)

1.5 mul_div

1.5.1 div

1.5.1.1 src

1.5.1.1.1 divOper.cpp

#include "divOper.h"

int calDiv(int a, int b)
{
return (a / b);
}

1.5.1.1.2 divOper.h

#ifndef _DIV_OPER_H_
#define _DIV_OPER_H_ int calDiv(int a, int b); #endif

1.5.1.2 CMakeLists.txt

#/cmake/mul_div/div
AUX_SOURCE_DIRECTORY(./src DIV_SRC_LIST) ADD_LIBRARY(div_oper STATIC
${DIV_SRC_LIST}
) INSTALL(DIRECTORY ./src/
DESTINATION include/mul_div/div
FILES_MATCHING PATTERN "*.h"
) INSTALL(TARGETS div_oper
DESTINATION lib
)

1.5.2 mul

1.5.2.1 src

1.5.2.1.1 mulOper.cpp

#include "mulOper.h"

int calMul(int a, int b)
{
return (a * b);
}

1.5.2.1.2 mulOper.h

#ifndef _MUL_OPER_H_
#define _MUL_OPER_H_ int calMul(int a, int b); #endif

1.5.2.2 CMakeLists.txt

#/cmake/mul_div/mul
AUX_SOURCE_DIRECTORY(./src MUL_SRC_LIST) ADD_LIBRARY(mul_oper STATIC
${MUL_SRC_LIST}
) INSTALL(DIRECTORY ./src/
DESTINATION include/mul_div/mul
FILES_MATCHING PATTERN "*.h"
) INSTALL(TARGETS mul_oper
DESTINATION lib
)

1.5.3 CMakeLists.txt

#/cmake/mul_div
ADD_SUBDIRECTORY(mul)
ADD_SUBDIRECTORY(div)

依次运行:

$ bash ./make_api.sh --no-test
$ bash ./make_api.sh
export LD_LIBRARY_PATH=api_install/lib
$ ./api_install/bin/test

GitHubhttps://github.com/fengbingchun/Linux_Code_Test

參考文献:

1.http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/

2.http://blog.chinaunix.net/uid-28458801-id-3501768.html

3.      http://www.hahack.com/codes/cmake/

4.      

utm_source=tuicool">http://www.cnblogs.com/rickyk/p/3877238.html?utm_source=tuicool

5.      http://www.docin.com/p-728984407.html

6.http://www.doc88.com/p-7485437070242.html

7.      http://www.cmake.org/cmake/help/v3.3/index.html

最新文章

  1. sqlserver 查找某个字段在哪张表里
  2. 【Win 10应用开发】认识一下UAP项目
  3. Android进程保活
  4. 360路由器c301最新固件支持万能中继
  5. 在SQL Server 2016里使用查询存储进行性能调优
  6. TFS 2012 在IE11和Chrome (Windows 8.1) 显示英文的解决方案
  7. js的单引号,双引号,转移符
  8. python下载网页源码 写入文本
  9. JS 之BOM
  10. 验证码图片生成工具类——Captcha.java
  11. WebForm+Web.config: 超时时间已到。在操作完成之前超时时间已过或服务器未响应。
  12. IOS中用模型取代字典的好处
  13. list, tuple, dict, set的用法总结
  14. 【机器学习实验】学习Python来分类现实世界的数据
  15. windows10合并分区
  16. ubuntu批量更改文件权限
  17. Xilinx FPGA开发随笔
  18. 【C#】C#线程_混合线程的同步构造
  19. 93. Restore IP Addresses产生所有可能的ip地址
  20. java中的块

热门文章

  1. 什么是vuejs之重新认识vuejs
  2. PHP fSQL Tutorial
  3. HDU_1506_Largest Rectangle in a Histogram_dp
  4. 从Element.getElementsByTagName方法说起
  5. 日常开发需要掌握的Git命令
  6. java虚拟机(三)--HotSpot 对象
  7. 洛谷——P1972 [SDOI2009]HH的项链(线段树)
  8. 洛谷——P2054 [AHOI2005]洗牌(扩展欧几里得,逆元)
  9. 洛谷——P2018 消息传递
  10. (C/C++学习)15.C语言字符串和字符数组