CMake从入门到精通

合集下载

CC++从零开始的cmake教程

CC++从零开始的cmake教程

CC++从零开始的cmake教程C/C++从零开始的CMake教程如果你有过在linux系统上源码安装某款软件的经历,那么肯定对这三部曲⼀点都不会陌⽣——配置(configure)、编译(make)、安装(make install)。

⼏乎每次都是机器⼈般的操作,这背后其实是make(准确地说应该是GNU Make)在默默为你⼲了不少活。

1.编译hello.c——单⼀源⽂件的编译//hello.c#include <stdio.h>int main(){puts("hello, world!");return 0;}为了编译⽣成对应的可执⾏⽂件,你可能会使⽤下⾯的命令:$ cc -o hello hello.c$ ./hellohello, world!但是,如果使⽤make(前提是你的操作系统已经安装了GCC和GNU Make),会显得更清爽⼀些。

$ make hellocc hello.c -o hello$ ./hellohello, world!1.1编写Makefile什么?你连“make hello”都懒得写?看完这部分,你的“妄念”应该就能实现了,到时候你只需要慢悠悠地打出4个字母——”make”,然后按下回车键,⽐图形界⾯IDE还要⽅便(⾄少你不⽤到处去找那个该死的“运⾏”按钮在哪。

这时候你只要在hello.c的同⼀个⽬录下新建⼀个⽂件Makefile作为make命令的配置⽂件即可。

它的内容很简单:hello:1.2设定编译器什么?你不想使⽤默认的cc,⽽想使⽤gcc来编译程序?那还不简单,只⽤在Makefile⽂件中把CC变量的值赋为gcc就可以了。

CC := gcchello:如果你这时候想运⾏make试下效果,请注意:make根本就不会重新编译⽣成hello。

为什么啊?因为make很“懒”,因为它检测到hello.c和上⼀次编译时⼀模⼀样,再重新编译⽣成的可执⾏⽂件肯定也⼀样啊,那就没有运⾏的必要了,直接返回结果了。

超详细的cmake入门教程

超详细的cmake入门教程

超详细的cmake⼊门教程什么是cmake你或许听过好⼏种 Make ⼯具,例如 GNU Make ,QT 的 qmake ,微软的 MSnmake,BSD Make(pmake),Makepp,等等。

这些 Make ⼯具遵循着不同的规范和标准,所执⾏的 Makefile 格式也千差万别。

这样就带来了⼀个严峻的问题:如果软件想跨平台,必须要保证能够在不同平台编译。

⽽如果使⽤上⾯的 Make ⼯具,就得为每⼀种标准写⼀次 Makefile ,这将是⼀件让⼈抓狂的⼯作。

CMake CMake附图 1 CMake就是针对上⾯问题所设计的⼯具:它⾸先允许开发者编写⼀种平台⽆关的 CMakeList.txt ⽂件来定制整个编译流程,然后再根据⽬标⽤户的平台进⼀步⽣成所需的本地化 Makefile 和⼯程⽂件,如 Unix 的 Makefile 或Windows 的 Visual Studio ⼯程。

从⽽做到“Write once, run everywhere”。

显然,CMake 是⼀个⽐上述⼏种 make 更⾼级的编译配置⼯具。

⼀些使⽤ CMake 作为项⽬架构系统的知名开源项⽬有 VTK、ITK、KDE、OpenCV、OSG 等。

在 linux 平台下使⽤ CMake ⽣成 Makefile 并编译的流程如下:1. 编写 CMake 配置⽂件 CMakeLists.txt 。

2. 执⾏命令 cmake PATH 或者 ccmake PATH ⽣成 Makefile。

其中, PATH 是 CMakeLists.txt 所在的⽬录。

(ccmake 和cmake 的区别在于前者提供了⼀个交互式的界⾯)3. 使⽤ make 命令进⾏编译。

⼊门案例:单个源⽂件本节对应的源代码所在⽬录:Demo1。

对于简单的项⽬,只需要写⼏⾏代码就可以了。

例如,假设现在我们的项⽬中只有⼀个源⽂件 ,该程序的⽤途是计算⼀个数的指数幂。

CMake快速入门教程:实战

CMake快速入门教程:实战

CMake快速入门教程:实战~/workspace/CRNode├─ src│ ├─ rpc│ │ ├─ CRMasterCaller.h│ │ ├─ │ │ ├─ CRNode.h│ │ ├─ │ │ ├─ Schd_constants.h│ │ ├─ Schd_│ │ ├─ CRMaster.h│ │ ├─ │ │ ├─ CRNode_server.skeleton.h│ │ ├─ CRNode_│ │ ├─ Schd_types.h│ │ └─ Schd_│ ├─ task│ │ ├─ TaskExecutor.h│ │ ├─ │ │ ├─ TaskMonitor.h│ │ └─ │ ├─ util│ │ ├─ Const.h│ │ ├─ │ │ ├─ Globals.h│ │ ├─ │ │ ├─ Properties.h│ │ ├─ │ │ ├─ utils.h│ │ └─ │ ├─ │ └─ CMakeLists.txt├─ doc│ └─ crnode.txt├─ COPYRIGHT├─ README├─ crnode.sh└─ CMakeLists.txt其中,src存放源代码文件和一个CMakeLists.txt文件,CMakeLists文件的编写我们稍候介绍;doc目录中存放项目的帮助文档,该文档以及COPYRIGHT和README一起安装到/usr/share/doc/crnode目录中;COPYRIGHT文件存放项目的版权信息,README存放一些说明性文字;crnode.sh存放CRNode的启动命令;CMakeLists.txt文件稍候介绍。

除此之外,项目还依赖两个外部库:Facebook开发的thrift库,其头文件存放在/usr/include/thrift目录中;log4cpp库,其头文件存放再/usr/include下。

2. CMakeLists.txt文件本工程中使用了两个CMakeLists.txt文件,分别项目的根目录(即~/workspace/CRNode目录,下同)和src目录中(参考以上目录结构)。

CMake手册详解:(一)开始篇

CMake手册详解:(一)开始篇

CMake手册详解:(一)开始篇前言CMake是目前比较流行的跨平台构建工具,接触过跨平台项目的小伙伴应该都对他很熟悉。

为了能更好的学习CMake,我打算从CMake官网的开发手册入手,系统的学习 CMake。

CMake的版本也在不停更新,有些新的命令和变量会随着版本更新添加进来,这是后事了,暂且不管;现在锁定CMake 2.8.12作为手册翻译的版本。

(因为目前ubuntu系统的最新版本CMake就是这版),下面就进入正题:手册开始部分命令名称cmake - 跨平台Makefile生成工具。

用法cmake [选项] <源码路径>cmake [选项] <现有构建路径>描述cmake可执行程序是CMake的命令行界面。

它可以用脚本对工程进行配置。

工程配置设置可以在命令行中使用-D选项指定。

使用-i 选项,cmake将通过提示交互式地完成该设置。

CMake是一个跨平台的构建系统生成工具。

它使用平台无关的CMake清单文件CMakeLists.txt,指定工程的构建过程;源码树的每个路径下都有这个文件。

CMake产生一个适用于具体平台的构建系统,用户使用这个系统构建自己的工程。

选项-C [initial-cache]: 预加载一个脚本填充缓存文件。

当cmake在一个空的构建树上第一次运行时,它会创建一个CMakeCache.txt文件,然后向其中写入可定制的项目设置数据。

-C 选项可以用来指定一个文件,在第一次解析这个工程的cmake清单文件时,从这个文件加载缓存的条目(cache entries)信息。

被加载的缓存条目比项目默认的值有更高的优先权。

参数中给定的那个文件应该是一个CMake脚本,其中包含有使用CACHE选项的SET命令;而不是一个缓存格式的文件。

-D [var]:[type]=[value]: 创建一个CMake的缓存条目。

当cmake第一次运行于一个空的构建数时,它会创建一个CMakeCache.txt文件,并且使用可定制的工程设置来填充这个文件。

c++cmake及包管理工具conan简单入门

c++cmake及包管理工具conan简单入门

c++cmake及包管理⼯具conan简单⼊门cmake是⼀个跨平台的c/c++⼯程管理⼯具,可以通过cmake轻松管理我们的项⽬conan是⼀个包管理⼯具,能够⾃动帮助我们下载及管理依赖,可以配合cmake使⽤这是⼀个⼊门教程,想深⼊了解的我在后⾯放了⼏个链接可以去学习1 cmake1.1 下载cmake1.2 cmake的主要命令cmake -B [target][target] 表⽰我们希望cmake⽣成⽂件存放的⽬录,⼀般命名为build,我们也可以进⼊到build⽂件夹下使⽤cmake ..将cmake⽣成的⽂件存放到当前⽬录这个命令作⽤是⾃动帮我们⽣成makefile⽂件注意事项:build ⽂件的上⼀级⽬录中要有CMakeLists.txt⽂件,即cmake的描述⽂件cmake --build [target]开始编译,[target]是上⼀步存放cmake⽣成⽂件的⽬录,如果我们在该⽬录中使⽤cmake --build .即可1.3 cmake描述⽂件CMakeLists.txt初体验(1)声明需要的cmake的最低版本: 这⾏必须在描述⽂件的第⼀⾏,这⾥我设置的最低版本是3.16cmake_minimum_required(VERSION 3.16)(2) 添加项⽬名: 这⾥我把项⽬名称设置为cmakeproject(cmake)(3) 添加可执⾏⽂件名:这⾥我设置的可执⾏⽂件名是cmake,他依赖的⽂件是main.cpp,在编译完成后回⽣成cmake.out或cmake.exe⽂件add_executable(cmake main.cpp)以上三⾏代码就简单定义好⼀个cmake描述⽂件了,这三⾏也是⼀个camke描述⽂件必不可少的1.4 cmake描述⽂件再探上⼀节介绍了cmake的简单使⽤,我们的⼯程不会只有⼀个⽂件,也不会只有⼀个⽂件夹,否则也不会使⽤cmake来帮助我们管理,接下来介绍cmake的更多⽤法(1) 设置c++版本:指定c++最低编译版本,这⾥我设置的是14set(CMAKE_CXX_STANDARD 14)(2) 指定⼯程的版本号及语⾔:使⽤1.3节第(2)步的命令我们可以为⼯程设置版本号和指定语⾔,这⾥设置的版本号是1.0.0,语⾔CXX表⽰c++,我们可以设置4个字段的版本信息,通过使⽤配置⽂件⽣成头⽂件在我们的项⽬中使⽤版本信息, 4个字段见附录project(cmake VERSION 1.0.0 LANGUAGES CXX)(3) ⽣成静态链接库:有时候我们的⽂件可能分散在多个⽂件夹中,这时我们就可以通过⽣成静态库的⽅式将他们链接并⽣成可执⾏⽂件,我们需要在⼦⽂件中同样包含CMakeLists.txt⽂件,然后添加add_library(libmyHeap STATIC ${CMAKE_CURRENT_SOURCE_DIR}/MyHeap.cpp) # 当前库⽂件target_include_directories(libmyHeap PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # 头⽂件这⾥通过add_library()指定⽣成库,libmyHeap是库的名字,STATIC 指定⽣成的静态库,${CMAKE_CURRENT_SOURCE_DIR}/MyHeap.cpp指定我们⽣成库依赖源⽂件的路径${CMAKE_CURRENT_SOURCE_DIR}表⽰当前CMakeLists.txt所在的⽂件路径target_include_directories()指定⽣成库依赖的头⽂件libmyHeap是⽣成静态库的名字PUBLIC表⽰当前静态库的依赖可以被上层cmake发现,同时该库也依赖该头⽂件,当然还有其它设置,作为⼊门不做介绍${CMAKE_CURRENT_SOURCE_DIR}表⽰当前CMakeLists.txt所在的⽂件路径通过这两句命令即可⽣成⼀个静态库,要想能被可执⾏程序链接到,我们只需在顶层CMakeLists.txt⽂件中添加add_subdirectory(myHeap) # 添加⼦⽬录搜索路径以及target_link_libraries(cmake libmyHeap)⾸先,第⼀句add_subdirectory()指定底层CMakeLists.txt的路径,这样我们的顶层CMakeLists.txt就能找到并编译target_link_libraries()第⼀个参数指定target即我们的项⽬名,第⼆个参数指定要链接的库名由于我们在上⾯设置⽣成静态库时设置可见属性为PUNLIC 因此这⾥不需要指定头⽂件路径,cmake就可以通过底层CMakeLists.txt 找到我们需要的头⽂件,这也是现代cmake的做法以上就是cmake的基本使⽤,我们可以把⽂件放在不同⽂件夹,并通过⽣成静态库的⽅式将各个⽂件链接起来,这⾥列出总的CMakeLists.txt⽂件顶层CMakeLists.txtcmake_minimum_required(VERSION 3.16) # 设置cmake最低版本project(cmake VERSION 1.0.0 LANGUAGES CXX) # 设置⽂件名及版本信息set(CMAKE_CXX_STANDARD 14) # 设置c++版本add_subdirectory(myHeap) # 添加⼦⽬录搜索路径,这⾥值myHeap路径add_executable(cmake main.cpp) # 添加可执⾏⽂件target_link_libraries(cmake libmyHeap) # 链接库名称底层CMakeLists.txtadd_library(libmyHeap STATIC ${CMAKE_CURRENT_SOURCE_DIR}/MyHeap.cpp) # 当前库⽂件target_include_directories(libmyHeap PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # 头⽂件⽂件结构Ok,上⾯就列出了cmake的简单使⽤,有时候我们写项⽬的时候需要使⽤别⼈写的库,这个时候⼀般会下载源码在本地编译或者下载对应版本的编译后的⽂件,但是我们使⽤的库还可能包含别⼈的库,别⼈的库可能还使⽤了别别⼈写的库,这样⼀个个下载编译太过⿇烦,⽽且有些库还存在多次引⼊的可能,因此我们需要⼀个⼯具帮助我们管理包和依赖,这⾥介绍conan2 conanconan是⼀个c++包管理⼯具,⼀⾏代码就能将我们需要的包下载到本地并进⾏编译注意:⽬前已知在windows + gcc存在bug,导致编译失败,我也不知什么原因,stackoverflow上有⼀个提问,说是由于兼容性问题,这⾥我是直接在linux平台使⽤2.1 下载conan下载很简单,直接通过pip下载pip install conan稍等⽚刻,就下载好了,这个时候如果我们输⼊conan --version可能会找不到命令,这是因为环境变量没有添加,添加环境变量⽹上教程很多2.2 添加conan配置⽂件conanfile.txt这⾥包含两项,第⼀项是要下载的库和版本号,第⼆项是指定⽣成的管理格式,这⾥我们选择cmake以使⽤poco库为例,我们只需在conanfile.txt中写[requires]poco/1.11.1[generators]cmake这⾥我们怎么知道所使⽤的库有哪些版本呢?可以使⽤命令conan search poco -r conancenter获取,其中-r conancenter指定我们需要在conan中央仓库搜索,否则默认本地搜索,要添加其它库,直接在[requires]下添加库名和版本号,然后重新安装就好了2.3 安装库我们以及创建好好conan配置⽂件,下⼀步,进⼊build⽂件夹(这个⽂件夹就是我们存放cmake⽣成⽂件的地⽅哦),然后⼀⾏命令conan install .即可静静等待下载安装完成了,注意事项: 这个时候可能需要我们指定⼀些配置信息,配置信息在~/.conan/profiles/default⽂件⾥,配置信息需要添加的内容在~/.conan/settings.yml⽂件⾥,对于gcc,需要配置compiler.libcxx=libstdc++11否则以旧版本安装,这⾥列出我的配置⽂件供参考[settings]os=Linuxos_build=Linuxarch=x86_64arch_build=x86_64build_type=Releasecompiler=gcccompiler.libcxx=libstdc++11compiler.version=9[options][build_requires][env]在这插⼀条刚刚吃完饭准备把build⽂件夹的缓存删了,然后测试⼀下看看写的对不对,准备输rm -rf build/* 结果输成了rm -rf /*,好家伙.....⾃闭中...2.4 在cmake中配置只需要在顶层CMakeLists.txt⽂件中添加include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)conan_basic_setup()${CMAKE_BINARY_DIR}表⽰当前build⽂件夹路径, 然后在mian.cpp⾥引⽤头⽂件即可2.5 使⽤现在我么可以使⽤cmake编译我们我们的⼯程了进⼊到build⽂件夹下,输⼊cmake ..等待⽣成makefile⽂件完成后,输⼊cmake build .等待编译成功了附录附录1:cmake变量常⽤变量PROJECT_SOURCE_DIR:⼯程的根⽬录,顶层CMakeLists.txt所在的⽬录PROJECT_BINARY_DIR:cmake⽣成⽂件保存的⽬录,通常为build⽬录PROJECT_NAME:项⽬名CMAKE_CURRENT_SOURCE_DIR:当前CMakeLists.txt所在的路径EXECUTABLE_OUTPUT_PATH:重新定义⽬标⼆进制可执⾏⽂件的存放位置LIBRARY_OUTPUT_PATH:重新定义⽬标链接库⽂件的存放位置使⽤格式 ${value}附录2: 版本号字段PROJECT-NAME:当前项⽬名PROJECT-NAME_VERSION_MAJOR:第⼀个字段PROJECT-NAME_VERSION_MINOR:第⼆个字段PROJECT-NAME_VERSION_PATCH:第三个字段PROJECT-NAME_VERSION_TWEAK:第四个字段附录3:更进⼀步的学习链接1. 知乎: 很酷的程序员 cmke2. CSDN: weixin_39773239 cmake3. B站:IPADS cmake4. B站: bennyhuo不是算命的 conan5. cmake官⽅⽂档。

Cmake学习手册

Cmake学习手册

Cmake学习笔记1、一个比较典型的例子共享库和静态库的cmake典型实例# This is a typical library CMakeList.txt# Modify the corresponding places to adapt to own setting# Write by jfbai.cmake_minimum_required (VERSION 2.8)# Add Include, Library path hereinclude_directories(/usr/local/include)link_directories(/usr/local/lib)# Set library source setset(LIB_SRC xxx.cpp xxx.cpp)# Generate shared libraryadd_library(xxx_shared SHARED ${LIB_SRC})set_target_properties(xxx_shared PROPERTIES OUTPUT_NAME "xxx")set_target_properties(xxx_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1) set_target_properties(xxx_shared PROPERTIES VERSION 1.2 SOVERSION 1) target_link_libraries(xxx_shared xx1.so xx2.so xx1.a xx2.a)get_target_property(OUTPUT_VALUE xxx_shared OUTPUT_NAME)message(STATUS "Shared library outname:" ${OUTPUT_VALUE})# Generate static libraryadd_library(xx_static STATIC ${LIBLM_SRC})set_target_properties(xx_static PROPERTIES OUTPUT_NAME "xxx")set_target_properties(xx_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) target_link_libraries(xx_static xx1.so xx2.so xx1.a xx2.a)get_target_property(OUTPUT_VALUE xx_static OUTPUT_NAME)message(STATUS "Static library outname:" ${OUTPUT_VALUE})# Set library install pathinstall(TARGETS xxx_shared xxx_staticLIBRARY DESTINATION libARCHIVE DESTINATION lib)可执行程序的cmake典型实例# This is a typical executable CMakeList.txt# Modify the corresponding places to adapt to own setting# Write by jfbai.cmake_minimum_required(VERSION 2.8)# Add Include, Library path hereinclude_directories(~/projects/Linux_Project/include)link_directories(~/projects/Test_lib/build/libLM/lib)# Set executable source setset(ALL_SRC libLMTest.cpp)# Generate executable fileadd_executable(libLM_Test ${ALL_SRC})target_link_libraries(libLM_Test libLM.so)总规划的cmake典型实例# This is a typical executable CMakeList.txt# Modify the corresponding places to adapt to own setting# Write by jfbai.cmake_minimum_required(VERSION 2.8)# Set cmake list hereadd_subdirectory(libLM)add_subdirectory(libLM_Test)2、总体说明首先,cmake是自动生成makefile的工具,它和make工具是互补的,而不是竞争的关系;有点类似automake 的作用。

cmake手册

cmake手册

cmake手册概述CMake是一个开源的、跨平台的构建工具。

它使用简单的配置文件和命令来生成建构系统文件(如makefile或Visual Studio解决方案),从而实现自动化构建过程。

本文将详细介绍CMake的基本使用方法和常见功能。

安装要使用CMake,首先需要将其安装在计算机上。

以下是安装CMake的一般步骤:1.在CMake的官方网站上下载适合您操作系统的安装包。

2.运行安装包,按照提示完成安装过程。

3.验证CMake是否成功安装,可以在终端(Linux或macOS)或命令提示符(Windows)中运行cmake --version命令,如果输出了CMake的版本信息,则表示安装成功。

CMakeLists.txt文件CMake使用CMakeLists.txt文件来定义项目的构建规则。

每个项目都需要一个CMakeLists.txt文件,其中包含了项目所需的信息和配置。

以下是一个简单的CMakeLists.txt文件示例:cmake_minimum_required(VERSION 3.12) # 指定CMake的最低版本要求project(MyProject) # 定义项目名称add_executable(MyExecutable main.cpp) # 添加一个可执行文件target_link_libraries(MyExecutable MyLibrary) # 链接一个库文件基本命令CMake提供了一系列命令来定义项目的构建规则。

以下是一些常用的CMake命令:add_executableadd_executable命令用于添加一个可执行文件到项目中。

它接受一个参数,即可执行文件的名称及相关的源文件。

add_executable(MyExecutable main.cpp) # 添加一个可执行文件MyExecutable,包括main.cpp源文件add_libraryadd_library命令用于添加一个库文件到项目中。

CMake基础教程

CMake基础教程

CMake基础教程如果需要配置和检查我们⼯程中的所有依赖,那么可以选⽤CMake⼯具;但是,这并不是必须的,因为我们可以使⽤其他的⼯具或者是IDE(⽐如Makefiles或者Visual Studio)来配置我们的⼯程。

然⽽,CMake是最好移植的⽅式来配置多平台的C++项⽬。

1. 基本⽤法 CMake使⽤名称为CMakeLists.txt的⽂件,其中定义了编译和依赖处理等过程。

对于⼀个基本的项⽬⽽⾔,从⼀个源码⽂件构建⼀个可执⾏程序只需要中CMakeLists.txt⽂件中添加两⾏代码即可。

⽂件内容像下⾯这样:cmake_minimum_required (VERSION 2.6)project (CMakeTest)add_executable (${PROJECT_NAME} main.cpp) ⽂件的第⼀⾏定义了所需的CMake版本的最⼩值,这⼀⾏是强制添加在CMakeLists.txt⽂件中,其拥有指定了从第⼆⾏开始可以使⽤的给定版本所定义的cmake函数;第⼆⾏的project函数⽤于定义⼯程名(这⾥为CMakeTest),这个名字被保存在⼀个名为PROJECT_NAME的变量中。

最后⼀⾏,在main.cpp⽂件中创建⼀个可执⾏命令(add_executable()),它的名字和⼯程名称(${PROJECT_NAME})相同,然后将源代码编译到名称为CMakeTest的可执⾏⽂件中,也就是将可执⾏⽂件名设置为与⼯程名相同。

${}表达式允许访问环境中定义的任何变量,因此,我们可以使⽤${PROJECT_NAME}变量作为⼀个可执⾏程序的输出名。

假设这⾥的main.cpp⽂件是⼀个简单的Hello World程序,代码如下:#include <iostream>using namespace std;int main(int argc, char *argv[]){cout << "Hello World! " << argc << argv[0] << endl;return0;}将这两个⽂件放置在同⼀⽬录下,然后依次执⾏如下命令:cmake .make这样,我们就可以在当前⽬录下⾯看到⼀个名称为CMakeTest的可执⾏⽂件了。

CMake词法和语法

CMake词法和语法

词法和语法在开始本节的学习之前,我们先总结一下之前所了解到的CMake基本词法和命令。

CMake命令通常使用如下的格式:1. COMMAND( ARG1 ARG2 … )复制代码命令关键字之后使用括号来包含所有的参数;各个参数之间使用空格或者换行符分隔;而参数通常有以下几种形式:变量,以${MY_VAIRABLE}的形式表达,其储存类型为字符串类型,但是可以根据具体命令的要求自动转换为布尔型、整型或者浮点类型。

变量可以出现在字符串中,也可以实现“内省”。

变量有用户自定义和系统内置两种,用户自定义变量使用SET命令设置;而系统变量由系统自动赋值,例如${PROJECT_SOURCE_DIR}。

枚举量,例如ADD_LIBRARY可以设置要生成的链接库为SHARED或者STATIC,还可以设置为MODULE(插件,可动态调用,但不作为其他工程的依赖),除此之外的赋值都是不能被识别的。

值,也就是任意的字符串内容,它可以用来指示要编译的源代码文件名,也可以表达一段文字提示信息,或者表达特定的功能。

值可以使用引号进行标识,多数情况下也可以不用。

前文中我们已经了解到的命令列举如下,此外这里还简要地介绍了另一些可能在各类CMake 工程中遇到的命令及其语法格式。

CMake部分命令的语法歌是十分复杂,这里仅仅介绍它的某一种实现形式,建议读者阅读CMake的帮助文档以获取更多信息。

括号中为该命令的一个或多个参数项,其中使用“[…]”包含的项表示可忽略项,使用“…|…”分隔的项表示只能选择其中一项。

ADD_CUSTOM_COMMAND(TARGET namePRE_BUILD|PRE_LINK|POST_BUILDCOMMAND cmd1 [COMMAND cmd2 …] ):为目标工程name添加一个或多个新的自定义的编译规则cmd1,cmd2等,执行时机可以选择编译前,链接前或者编译后。

它的作用相当于Visual Studio工程的“Custom Build Step”属性。

CMake之初级教程

CMake之初级教程

CMake之初级教程(VTK)的过程中所产生的衍生品。

后来经过发展,最终形成体系,在2001年成为一个独立的开放源代码项目。

其*****是,可以通过访问*****来获得更多关于cmake 的信息,而且目前官方的英文文档比以前有了很大的改进,可以作为实践中的参考手册。

cmake的流行离不开KDE4的选择。

KDE开发者在使用autotools近10年之后,终于决定为KDE4项目选择一个新的工程构建工具。

之所以如此,用KDE开发者们自己话来说,就是:只有少数几个“编译专家”能够掌握KDE现在的构建体系。

在经历了unsermake,scons 以及cmake的选型和尝试之后,KDE4最终决定使用cmake作为自己的构建系统。

在迁移过程中,进展一场的顺利,并获得了cmake开发者的支持。

所以,目前的KDE4开发版本已经完全使用cmake来进行构建。

随着cmake 在KDE4项目中的成功,越来越多的项目正在使用cmake作为其构建工具,这也使得cmake正在成为一个主流的构建体系。

一、为何要使用项目构建工具?为何要使用cmake和autotools之类的项目构建工具?我想,这恐怕是刚刚接触软件项目的人最应该问的问题之一了。

“Hello, world!“这个最经典的程序相信我们每个人都写过。

无论在什么平台下,编译和运行这个程序都仅需要非常简单的操作。

但事实上,hello,world最多只能算是一个实例程序,根本算不上一个真正的软件项目。

任何一个软件项目,除了写代码之外,还有一个更为重要的任务,就是如何组织和管理这些代码,使项目代码层次结构清晰易读,这对以后的维护工作大有裨益。

使想一下,如果把一个像KDE4那么大的项目像hello world那样,把全部代码都放到一个main.cpp 文件中,那将会是多么恐怖的一件事情。

别说KDE4,就是我们随便一个几千行代码的小项目,也不会有人干这种蠢事。

决定代码的组织方式及其编译方式,也是程序设计的一部分。

cmake学习笔记

cmake学习笔记

cmake学习笔记最近接触到⼀些⼯程上的代码,都是⽤cmake来编译的,每次看着CMakeLists.txt 就各种懵逼,决定从0 开始学习1 setset(var hello)message(${var})输出hello其实并不是单单输出hello,还有很多其他信息,会⽣成很多⽂件files2 CMAKE_C(XX)_FLAGS变量 CMAKE_C_FLAGS 存放的内容会被传给 C 编译器,作⽤在所有的编译组态上。

如果希望只针对特定⼀种组态有效,可以设定 CMAKE_C_FLAGS_<编译组态>,例如 CMAKE_C_FLAGS_RELEASE、CMAKE_C_FLAGS_DEBUG。

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native -Wno-reorder")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native -Wno-reorder")编译选项为-Wall O3的优化其他内部变量:•CMAKE_C_COMPILER:指定C编译器•CMAKE_CXX_COMPILER:•CMAKE_C_FLAGS:编译C⽂件时的选项,如-g;也可以通过add_definitions添加编译选项•EXECUTABLE_OUTPUT_PATH:可执⾏⽂件的存放路径•LIBRARY_OUTPUT_PATH:库⽂件路径•CMAKE_BUILD_TYPE::build 类型(Debug, Release, ...),•CMAKE_BUILD_TYPE=Debug•BUILD_SHARED_LIBS:Switch between shared and static libraries内置变量的使⽤:•在CMakeLists.txt中指定,使⽤set•cmake命令中使⽤,如cmake -DBUILD_SHARED_LIBS=OFF3 CHECK_CXX_COMPILER_FLAG检查CXX编译器是否⽀持给定的flag必须先include(CheckCXXCompilerFlag)include(CheckCXXCompilerFlag)CHECK_CXX_COMPILER_FLAG(<flag> <var>)e.g.CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)CHECK_CXX_COMPILER_FLAG("-std=c++0x"COMPILER_SUPPORTS_CXX0X)if(COMPILER_SUPPORTS_CXX11)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")add_definitions(-DCOMPILEDWITHC11)message(STATUS "Using flag -std=c++11.")elseif(COMPILER_SUPPORTS_CXX0X)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")add_definitions(-DCOMPILEDWITHC0X)message(STATUS "Using flag -std=c++0x.")else()message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")endif()上⾯的代码很直接就是在检查当前编译器是否⽀持c++11CHECK_CXX_COMPILER_FLAG 赋值给的var是个bool型4 add_definitions添加编译参数add_definitions(-DDEBUG)将在gcc命令⾏添加DEBUG 宏定义,那么你就可以在你的源⽂件⾥⾯对DEBUG宏来操作5 ENV语法:$ENV(VAR)# 读取环境变量 VAR,也可⽤set对其赋值eg:IF(DEFINED ENV{ARM_ARCHITECTURE})#如果是arm的机器6 listList 操作list(LENGTH <list> <output variable>)list(GET <list> <element index> [<element index> ...]<output variable>)list(APPEND <list> [<element> ...])list(FIND <list> <value> <output variable>)list(INSERT <list> <element_index> <element> [<element> ...])list(REMOVE_ITEM <list> <value> [<value> ...])list(REMOVE_AT <list> <index> [<index> ...])list(REMOVE_DUPLICATES <list>)list(REVERSE <list>)list(SORT <list>)APPEND 追加元素,懂了吧,这些都是list的操作7 CMAKE_MODULE_PATHcmake 进⾏搜索的modules的list,它是⼀个list8 find_package这个有点复杂,还是直接看官⽅⽂档还有这个9 include_directories增加头⽂件的搜索路径,相当于指定gcc的-I参数include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])10 add_libraryadd_library(<name> [STATIC | SHARED | MODULE][EXCLUDE_FROM_ALL]source1 [source2 ...])增加库的⽬录11 target_link_librariestarget_link_libraries(<target> [item1 [item2 [...]]][[debug|optimized|general] <item>] ...)指令 target_link_libraries()⽤于指定 target 所需要链接的库,还可以有不同的选项。

Cmake简单教程

Cmake简单教程

Cmake简单教程变量赋set(VAR a b c) VAR为变量名 a b c 为变量的值用空格分隔变量使用${VAR}例如: set (Foo a b c)command (${Foo}) 相当于 command (a b c)流程控制语句1. ifif(var)some_command(...)endif(var)2. foreach and whileset(VAR a b c)foreach (f ${VAR})message(${f})endforeach(f)3. macro and function//定义宏macro (hello MESSAGE)message($ {MESSAGE})endmacro (hello)//调用hello("hello world")//定义函数function(hello MESSAGE)message(${MESSAGE})endfunction(hello)//function与macro的区别: function create a local scope for variables. // macros user the global scope.正则表达式^ 匹配行或字符串的开始$ 匹配行或字符串的结尾. 匹配除了新行外的任意单个字符[] 匹配括号内的任意字符[^] 匹配不在括号内的任意字符[-] 匹配在"-"两端范围中的字符* 匹配 0个或多个之前的表达式+ 匹配 1个或多个之前的表达式? 匹配 0个或1个之前的表达式() 保存一个匹配表达式用于之后的替换常用命令ADD_SUBDIRECTORY添加一个子目录INCLUDE从给出的文件中读取CMake listfile代码INCLUDE(file1 [OPTIONAL])INCLUDE(module [OPTIONAL])file中的命令会立即处理如果使用module代替file1 cmake将会在CMAKE_MODULE_PATH中寻找名为<modulename>.cmake的文件INCLUDE_DIRECTORIES 添加include目录到build中INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2)LINK_DIRECTORIES指定搜索库的目录LINK_DIRECTORIES(directory1 directory2 ...)指定链接程序搜索库的路径PROJECT设置项目名PROJECT (projectname [CXX] [C] [JAVA])该命令会生成两个变量projectname_BINARY_DIR与projectname_SOURCE_DIR 后面的选项为项目支持的语言默认全部支持SET给一个CMAKE变量赋值SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])模块(module)FindPkgConfig CMake 的pkg-config模块<PREFIX> 自定义的前缀pkg_check_modules(<PREFIX> [REQUIRED] <MODULE> [<MODULE>]*) 检测所有给出的modules设置'REQUIRED'参数后如果MODULE没有找到会发生错误该命令会设置以下几个变量PKG_CONFIG_FOUND 如果pkg-config可以运行在系统中为TRUE PKG_CONFIG_EXECUTABLE pkg-config程序的路径<PREFIX>_FOUND 如果module存在设置为1下列生成的变量有两组值一种使用<PREFIX>作为前缀另一种使用<PREFIX>_STATIC作为前缀 (在调用pkgconfig时使用--static选项)<XPREFIX> = <PREFIX> 普通情况下<XPREFIX> = <PREFIX>_STATIC 为static链接的情况下<XPREFIX>_LIBRARIES 库<XPREFIX>_LIBRARY_DIRS 库的路径<XPREFIX>_LDFLAGS 所有需要的链接选项<XPREFIX>_LDFLAGS_OTHERS 所有其他的链接选项<XPREFIX>_INCLUDE_DIRS '-I' 预处理选项<XPREFIX>_CFLAGS 所有需要的cflags(C编译器的选项)<XPREFIX>_CFLAGS_OTHERS 其他的编译选项。

关于cmake的书

关于cmake的书

关于cmake的书
关于CMake的书籍有很多,以下是其中一些推荐:
* 《Professional CMake: A Practical Guide》这本书从头开始学习CMake,内容跟随CMake版本更新,可以学习到CMake比较新的版本。

它从浅到深,循序渐进,适合初学者阅读。

内容非常全面,适合深入学习。

不过,它的篇幅较长,需要花不少的时间阅读。

* 《Modern CMake for C++》这本书也适合零基础学习。

虽然内容介绍不如前面一本详细,但它有结合C或C++介绍的内容,也值得一读。

* 《CMake——入门到精通》这本书从CMake的基本概念和用法入手,逐步深入介绍了CMake的各种功能和高级用法。

它从安装和配置开始讲起,然后讲解了CMake项目的基本结构。

接着详细讲解了如何编写CMakeLists.txt文件来描述项目的构建过程,包括如何定义源文件、头文件和链接库,如何设置编译选项和链接选项,以及如何生成不同平台和编译器下的构建配置。

在介绍完基本使用后,着重讲解了CMake的高级功能和技巧,比如跨平台开发、自定义构建规则、配置项目的安装和打包,以及模块化管理等等。

同时,书中还提供了大量的示例代码和实用技巧,帮助读者更好地理解和应用CMake。

以上书籍都是关于CMake的优秀教材,读者可以根据自己的需求和兴趣选择适合自己的书籍进行阅读和学习。

CMake从入门到精通

CMake从入门到精通

例子一一个经典的C程序,如何用cmake来进行构建程序呢?//main.c#include <stdio.h>int main(){printf("Hello World!/n");return 0;}编写一个CMakeList.txt 文件(可看做cmake的工程文件):project(HELLO)set(SRC_LIST main.c)add_executable(hello ${SRC_LIST})然后,建立一个任意目录(比如本目录下创建一个build子目录),在该build目录下调用cmake 注意:为了简单起见,我们从一开始就采用cmake的out-of-source 方式来构建(即生成中间产物与源代码分离),并始终坚持这种方法,这也就是此处为什么单独创建一个目录,然后在该目录下执行cmake 的原因cmake .. -G"NMake Makefiles"nmake或者cmake .. -G"MinGW Makefiles"make即可生成可执行程序hello(.exe)目录结构+|+--- main.c+--- CMakeList.txt|/--+ build/|+--- hello.execmake 真的不太好用哈,使用cmake的过程,本身也就是一个编程的过程,只有多练才行。

我们先看看:前面提到的这些都是什么呢?CMakeList.txt第一行project不是强制性的,但最好始终都加上。

这一行会引入两个变量∙HELLO_BINARY_DIR 和HELLO_SOURCE_DIR同时,cmake自动定义了两个等价的变量∙PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR因为是out-of-source方式构建,所以我们要时刻区分这两个变量对应的目录可以通过message来输出变量的值message(${PROJECT_SOURCE_DIR})set命令用来设置变量add_exectuable告诉工程生成一个可执行文件。

CMake使用教程

CMake使用教程

CMake使用教程CMake是一个比make更高级的编译配置工具,它可以根据不同平台、不同的编译器,生成相应的Makefile或者vcproj项目。

通过编写CMakeLists.txt,可以控制生成的Makefile,从而控制编译过程。

CMake自动生成的Makefile不仅可以通过make命令构建项目生成目标文件,还支持安装(make install)、测试安装的程序是否能正确执行(make test,或者ctest)、生成当前平台的安装包(make package)、生成源码包(make package_source)、产生Dashboard显示数据并上传等高级功能,只要在CMakeLists.txt中简单配置,就可以完成很多复杂的功能,包括写测试用例。

如果有嵌套目录,子目录下可以有自己的CMakeLists.txt。

总之,CMake是一个非常强大的编译自动配置工具,支持各种平台,KDE也是用它编译的,感兴趣的可以试用一下。

准备活动:(1)安装cmake。

下载地址:/cmake/resources/software.html根据自己的需要下载相应的包即可,Windows下可以下载zip压缩的绿色版本,还可以下载源代码。

(2)运行cmake的方法。

(GUI、命令行)/cmake/help/runningcmake.html CMake使用步骤:运行GUI的cmake界面:cmake-2.8.1-win32-x86/bin/cmake-gui.exe执行Configure:运行之后,生成了如下文件:生成Makefile:执行Generate之后生成如下文件:运行make进行编译:编译完成后,在build目录生成Tutorial.exe,运行Tutorial.exe 25就可以看到运行结果:运行make install安装程序:运行make test进行测试:通过cmake tutorial学习CMake配置方法/cmake/help/cmake_tutorial.html可以在源代码的Tests/Turorial目录中找到这个手册对应的代码。

cmake 教程

cmake 教程

cmake 教程CMake是一个开源的跨平台构建工具,用于管理和构建软件项目。

它使用简单的语法来描述构建过程,并生成相应的构建配置文件(如Makefile或Visual Studio项目文件),从而使构建过程变得自动化、可靠和可重复。

使用CMake构建项目的基本步骤如下:1. 创建CMakeLists.txt文件:在项目根目录下创建一个名为CMakeLists.txt的文件。

这个文件将用来描述项目的构建过程。

2. 设置CMake的最低版本:在CMakeLists.txt文件的开头,可以使用cmake_minimum_required命令设置CMake的最低版本号,以确保项目可以在支持所需功能的CMake版本上正确构建。

3. 定义项目名称:使用project命令来定义项目的名称。

这将在构建过程中用于生成构建配置文件和项目标识。

4. 添加源代码文件:使用add_executable或add_library命令来添加源代码文件和头文件。

这些命令将源代码文件和头文件关联到项目中,以便在构建过程中进行编译和链接。

5. 添加依赖库:如果项目需要依赖其他库文件,可以使用find_package命令来查找这些库。

然后使用target_link_libraries 命令将这些库链接到项目中。

6. 设置编译选项:使用set命令来设置编译选项,例如编译器选项、预处理器宏等。

可以使用target_compile_options命令为单个目标设置编译选项。

7. 指定安装目标:如果需要将项目安装到特定的位置,可以使用install命令来指定需要安装的目标文件和目标路径。

8. 生成构建配置文件:在项目根目录下创建一个build文件夹,然后在该文件夹中执行cmake命令。

CMake将根据CMakeLists.txt文件生成相应的构建配置文件。

9. 执行构建:进入build文件夹,执行make命令(对于Unix/Linux系统)或打开生成的Visual Studio项目文件(对于Windows系统)来执行构建过程。

cmake教程

cmake教程

cmake教程cmake是一个开源的跨平台构建工具,它可以自动生成Makefile或Visual Studio的解决方案文件,从而实现项目的编译和构建。

本教程将介绍cmake的基本用法和常见的用法示例。

1. 安装cmakecmake可以在官方网站上下载并安装,在安装完成后,可以使用命令行中的cmake命令进行操作。

2. 创建一个基本的C++项目首先,创建一个空的文件夹作为项目的根目录。

在此目录下,创建一个C++源文件(例如main.cpp),并添加一些基本的C++代码。

3. 创建CMakeLists.txt文件在项目根目录下,创建一个名为CMakeLists.txt的文件。

这个文件将包含cmake的构建指令。

4. 编写CMakeLists.txt打开CMakeLists.txt文件,并编写cmake的构建指令。

以下是一个简单的示例:```# 设置项目的名称project(MyProject)# 指定要编译的源文件add_executable(MyProject main.cpp)```这段代码指定了项目的名称为MyProject,并将main.cpp作为需要编译的源文件。

你可以根据需要修改项目名称和源文件的路径。

5. 构建项目在命令行中,进入到项目根目录,并执行以下命令进行构建:```cmake .make```第一个命令将会生成Makefile,第二个命令将会使用Makefile 进行项目的编译和构建。

6. 运行项目在构建成功后,可以通过以下命令运行项目:```./MyProject```如果一切正常,你将会看到程序输出的结果。

以上仅是cmake的基本使用方法,它还有很多更高级的特性和用法,比如添加依赖库、选择构建类型等等。

你可以通过查阅相关的文档和官方网站来学习更多关于cmake的知识。

cmake新手入门教程

cmake新手入门教程

cmake新⼿⼊门教程linux 环境使⽤ cmake 编译⼤型项⽬1.⼀个简单的实例使⽤ cmake 编译⼤型项⽬⾮常⽅便,做个简单的记录。

建⽴⼀个⽬录 win,这⾥⾯是⼯程⽂件。

win 的⽬录如下:win\-- CMakeLists.txt|-- build.sh|-- libs 外部库|-- src|-- CMakeLists.txt|-- common 公⽤头⽂件|-- win98 win98⼯程| |-- CMakeLists.txt| |-- | |-- win98.h| \-- ||-- win2000 win2000⼯程|-- CMakeLists.txt|-- |-- win2000.h\-- win、src、win98、win2000 四个⽬录下都有⼀个 CMakeLists.txt ⽂件,该⽂件是必须的,cmake 根据这个⽂件来⽣成 Makefile。

win98 的CMakeLists.txt 内容如下add_executable(win98)假设 win2000 加⼊了新的⽹络功能,链接时需要⽤到 network 这个库⽂件,那么需要在 CMakeLists.txt 中指明add_executable(robot)target_link_libraries(win2000 network)src ⽬录下的 CMakeLists.txt 需要把它下属需要编译的⽬录都指定add_subdirectory(win98)add_subdirectory(win2000)在 win ⽬录下的 CMakeLists.txt ⽂件内容复杂⼀点,下⾯是个简单的例⼦# 指定版本和项⽬名称cmake_minimum_required(VERSION 2.6)project(windows CXX)# 指定源码⽬录add_subdirectory(src)在 win ⽬录下运⾏cmake . 后⾯有个点make整个⼯程编译完成,在 win98 和 win2000 下⾯就可以得到执⾏⽂件。

cmake基本入门(编译可执行文件和动态库)

cmake基本入门(编译可执行文件和动态库)

cmake基本⼊门(编译可执⾏⽂件和动态库)编译可执⾏⽂件单⽂件cmake_minimum_required(VERSION 3.4.2)project(single) # 定义项⽬名称add_executable(single ) # 添加可执⾏⽂件 如下#include <stdio.h>#include <stdlib.h>double power(double base, int exponent){int result = base;int i;if (exponent == 0) {return1;}for(i = 1; i < exponent; ++i){result = result * base;}return result;}int main(int argc, char *argv[]){if (argc < 3){printf("Usage: %s base exponent \n", argv[0]);return1;}double base = atof(argv[1]);int exponent = atoi(argv[2]);double result = power(base, exponent);printf("%g ^ %d is %g\n", base, exponent, result);return0;}View Code执⾏以下命令mkdir build && cd build && cmake .. && make结果如下,就是这么简单,不过对于单⽂件,没有直接gcc或者g++来的直接├── CMakeLists.txt├── build│├── CMakeCache.txt│├── CMakeFiles│├── Makefile│├── cmake_install.cmake│└── single└── 单⽬录多⽂件我们把⾥⾯的power函数的拆分到头⽂件和cc⽂件,修改CMakeLists.txt如下cmake_minimum_required(VERSION 3.4.2)project(single)aux_source_directory(. DIR_SRCS) # 遍历⽬录的所有⽂件,赋值给Dir_SRCSadd_executable(single ${DIR_SRCS})还是⼀样执⾏以下命令mkdir build && cd build && cmake .. && make这个时候cmake⽐传统的gcc和g++要好⼀点了├── CMakeLists.txt├── ├── MathFunctions.h├── build│├── CMakeCache.txt│├── CMakeFiles│├── Makefile│├── cmake_install.cmake│└── single└── 多⽬录多⽂件我们再折腾⼀下,把power函数相关的放⼊⼀个math⽂件夹,⽬录结构如下├── CMakeLists.txt├── └── math├── └── MathFunctions.h同时修改CMakeLists.txt加⼊math⽬录cmake_minimum_required (VERSION 2.8)project (many)set(CMAKE_MACOSX_RPATH 1)aux_source_directory(. DIR_SRCS)aux_source_directory(./math MATH)list(APPEND DIR_SRCS ${MATH})add_executable(many ${DIR_SRCS})最后执⾏以下命令即可mkdir build && cd build && cmake .. && make多⽬录+⼦⽬录.a⽂件我们稍作修改⼀下,我们想让math先编译成.a⽂件,这样math的⽤途可以更⼴注意⽬录结构中,math⽂件夹⾥多了⼀个CMakeLists.txt⽂件,这意味着math⽂件夹可以独⽴编译├── CMakeLists.txt├── └── math├── CMakeLists.txt├── └── MathFunctions.h我们看下math的CMakeLists⽂件,很简单,不同的是⽣成了⼀个静态库aux_source_directory(. DIR_LIB_SRCS)# ⽣成链接库add_library (math STATIC ${DIR_LIB_SRCS})主⽬录的CMakeLists⽂件也有⼩⼩的变动cmake_minimum_required (VERSION 2.8)project (many)set(CMAKE_MACOSX_RPATH 1)aux_source_directory(. DIR_SRCS)# 添加 math ⼦⽬录add_subdirectory(./math math)add_executable(many ${DIR_SRCS})target_link_libraries(many math)最后的⽬录结构如下(省略了⼀些重复的⽬录⽂件),可以看到math⽬录下⾯⽣成了⼀个.a⽂件├── CMakeLists.txt├── build│├── many│└── math│└── libmath.a├── └── math├── CMakeLists.txt├── └── MathFunctions.h最后看下这四种⽅式⽣成的可执⾏⽂件是否都能正常⼯作$ cd ../../single_file/build/$ ./single 232 ^3 is 8$ cd ../../single_dir_many_file/build/$ ./single 232 ^3 is 8$ cd ../../many_dir_many_file/build/$ ./many 232 ^3 is 8$ cd ../../many_dir_many_file_a/build/$ ./many 232 ^3 is 8⽣成动态库也是很简单的,改动CMakeLists⽂件的⼀⾏即可cmake_minimum_required (VERSION 2.8)project (many)set(CMAKE_MACOSX_RPATH 1)aux_source_directory(. DIR_SRCS)# 添加 math ⼦⽬录add_subdirectory(./math math)# 就是下⾯这⼀⾏add_library(many SHARED ${DIR_SRCS})target_link_libraries(many math)在mac上⾯⽣成的动态库不是.so后缀,⽽是.dylib后缀(相同的代码在Linux上⽣成的应该是so)├── CMakeLists.txt├── build│├── libmany.dylib│└── math├── └── math├── CMakeLists.txt├── └── MathFunctions.hmac上⽣成so动态库如果是mac开发给Android或者Linux系统⽤,⾃然就有⽣成so动态库的需求,以Android为例,修改CMakeLists如下(碰到的⼤坑:set 命令要放在project命令前⾯,否则可能不⽣效,因为命令⾏可以但CmakeLists不⾏所以发现了这个⼤坑)cmake_minimum_required (VERSION 2.8)set(CMAKE_SYSTEM_NAME Android)# 如果没有配置相关环境变量,可以参考下⾯的设置# set(CMAKE_ANDROID_NDK "/Users/qiweijie/Tools/android-ndk-r15c")# set(CMAKE_TOOLCHAIN_FILE "/Users/qiweijie/Tools/android-ndk-r15c/build/cmake/android.toolchain.cmake")# set(ANDROID_TOOLCHAIN clang)# set(ANDROID_NATIVE_API_LEVEL 14)# set(ANDROID_ABI "armeabi-v7a")# set(CMAKE_BUILD_TYPE Release)# set(CMAKE_CROSSCOMPILING "TRUE")# set(CMAKE_CXX_STANDARD 11) #c++标准project (many)aux_source_directory(. DIR_SRCS)# 添加 math ⼦⽬录add_subdirectory(./math math)add_library(many SHARED ${DIR_SRCS}) target_link_libraries(many math)done。

CMake使用教程

CMake使用教程

CMake使用教程CMake简介CMake是一个跨平台的、开源的构建工具。

cmake是makefile的上层工具,它们的目的正是为了产生可移植的makefile,并简化自己动手写makefile时的巨大工作量.目前很多开源的项目都可以通过CMake工具来轻松构建工程,例如博客之前分享的openHMD、hidapi、OSVR-Core等等,代码的分享者提供源代码和相应的Cmake配置文件,使用者就可以非常方便的在自己的电脑上构建相应的工程,进行开发和调试。

CMake链接CMake官网CMakeWikiCMake3.7 DocumentCMake教程官方英文教程,黑体部分是本人在操作过程中,觉得需要额外提示的地方,整理翻译如下:第一步:一个简单的起点最简单的工程就是将一些源文件编译为可执行程序。

对于简单工程来说,只需要在CMakeList.txt添加2行内容即可。

这就是我们这个教程的起点,CMakeLists.txt文件内容如下:cmake_minimum_required (VERSION 2.6)project (Tutorial)add_executable(Tutorial tutorial.cxx)注意:CMake文件是不区分大小写的,这个例子中CMakeLists.txt文件中都使用小写字母。

源文件”tutorial.cxx”用来计算一个数的平方根,它的第一个版本非常简单,如下所示:// A simple program that computes the square root of a number#include <stdio.h>#include <stdlib.h>#include <math.h>int main (int argc, char *argv[]){if (argc < 2){fprintf(stdout,"Usage: %s number\n",argv[0]);return 1;}double inputValue = atof(argv[1]);double outputValue = sqrt(inputValue);fprintf(stdout,"The square root of %g is %g\n",inputValue, outputValue);return 0;}添加版本号和配置头文件我们添加的第一个特性就是为我们的可执行程序和工程提供一个版本号.你可以在源代码中写入版本号,然而在CMakeLists.txt中提供(版本号)更灵活.修改CMakeLists.txt增加一个版本号,内容如下:cmake_minimum_required (VERSION 2.6)project (Tutorial)# The version number.set (Tutorial_VERSION_MAJOR 1)set (Tutorial_VERSION_MINOR 0)# configure a header file to pass some of the CMake settings# to the source codeconfigure_file ("${PROJECT_SOURCE_DIR}/TutorialConfig.h.in""${PROJECT_BINARY_DIR}/TutorialConfig.h")# add the binary tree to the search path for include files# so that we will find TutorialConfig.hinclude_directories("${PROJECT_BINARY_DIR}")# add the executableadd_executable(Tutorial tutorial.cxx)因为配置文件将会被写入到二进制树当中,我们需要把这个目录添加到头文件路径当中。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

例子一一个经典的C程序,如何用cmake来进行构建程序呢?//main.c#include <stdio.h>int main(){printf("Hello World!/n");return 0;}编写一个CMakeList.txt 文件(可看做cmake的工程文件):project(HELLO)set(SRC_LIST main.c)add_executable(hello ${SRC_LIST})然后,建立一个任意目录(比如本目录下创建一个build子目录),在该build目录下调用cmake 注意:为了简单起见,我们从一开始就采用cmake的out-of-source 方式来构建(即生成中间产物与源代码分离),并始终坚持这种方法,这也就是此处为什么单独创建一个目录,然后在该目录下执行cmake 的原因cmake .. -G"NMake Makefiles"nmake或者cmake .. -G"MinGW Makefiles"make即可生成可执行程序hello(.exe)目录结构+|+--- main.c+--- CMakeList.txt|/--+ build/|+--- hello.execmake 真的不太好用哈,使用cmake的过程,本身也就是一个编程的过程,只有多练才行。

我们先看看:前面提到的这些都是什么呢?CMakeList.txt第一行project不是强制性的,但最好始终都加上。

这一行会引入两个变量∙HELLO_BINARY_DIR 和HELLO_SOURCE_DIR同时,cmake自动定义了两个等价的变量∙PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR因为是out-of-source方式构建,所以我们要时刻区分这两个变量对应的目录可以通过message来输出变量的值message(${PROJECT_SOURCE_DIR})set命令用来设置变量add_exectuable告诉工程生成一个可执行文件。

add_library则告诉生成一个库文件。

∙注意:CMakeList.txt 文件中,命令名字是不区分大小写的,而参数和变量是大小写相关的。

cmake命令cmake 命令后跟一个路径(..),用来指出CMakeList.txt 所在的位置。

由于系统中可能有多套构建环境,我们可以通过-G来制定生成哪种工程文件,通过 cmake -h 可得到详细信息。

要显示执行构建过程中详细的信息(比如为了得到更详细的出错信息),可以在CMakeList.txt 内加入:∙SET( CMAKE_VERBOSE_MAKEFILE on )或者执行make时∙$ make VERBOSE=1或者∙$ export VERBOSE=1∙$ make例子二一个源文件的例子一似乎没什么意思,拆成3个文件再试试看:∙hello.h 头文件#ifndef DBZHANG_HELLO_#define DBZHANG_HELLO_void hello(const char* name);#endif //DBZHANG_HELLO_∙hello.c#include <stdio.h>#include "hello.h"void hello(const char * name){printf ("Hello %s!/n", name);}∙main.c#include "hello.h"int main(){hello("World");return 0;}∙然后准备好CMakeList.txt 文件project(HELLO)set(SRC_LIST main.c hello.c)add_executable(hello ${SRC_LIST})执行cmake的过程同上,目录结构+|+--- main.c+--- hello.h+--- hello.c+--- CMakeList.txt|/--+ build/|+--- hello.exe例子很简单,没什么可说的。

例子三接前面的例子,我们将hello.c 生成一个库,然后再使用会怎么样?改写一下前面的CMakeList.txt文件试试:project(HELLO)set(LIB_SRC hello.c)set(APP_SRC main.c)add_library(libhello ${LIB_SRC})add_executable(hello ${APP_SRC})target_link_libraries(hello libhello)和前面相比,我们添加了一个新的目标libhello,并将其链接进hello程序然后想前面一样,运行cmake,得到+|+--- main.c+--- hello.h+--- hello.c+--- CMakeList.txt|/--+ build/|+--- hello.exe+--- libhello.lib里面有一点不爽,对不?∙因为我的可执行程序(add_executable)占据了hello 这个名字,所以add_library 就不能使用这个名字了∙然后,我们去了个libhello 的名字,这将导致生成的库为libhello.lib(或liblibhello.a),很不爽∙想生成hello.lib(或libhello.a) 怎么办?添加一行set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")就可以了例子四在前面,我们成功地使用了库,可是源代码放在同一个路径下,还是不太正规,怎么办呢?分开放呗我们期待是这样一种结构+|+--- CMakeList.txt+--+ src/| || +--- main.c| /--- CMakeList.txt|+--+ libhello/| || +--- hello.h| +--- hello.c| /--- CMakeList.txt|/--+ build/哇,现在需要3个CMakeList.txt 文件了,每个源文件目录都需要一个,还好,每一个都不是太复杂∙顶层的CMakeList.txt 文件project(HELLO)add_subdirectory(src)add_subdirectory(libhello)∙src 中的CMakeList.txt 文件include_directories(${PROJECT_SOURCE_DIR}/libhello)set(APP_SRC main.c)add_executable(hello ${APP_SRC})target_link_libraries(hello libhello)∙libhello 中的CMakeList.txt 文件set(LIB_SRC hello.c)add_library(libhello ${LIB_SRC})set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")恩,和前面一样,建立一个build目录,在其内运行cmake,然后可以得到∙build/src/hello.exe∙build/libhello/hello.lib回头看看,这次多了点什么,顶层的CMakeList.txt 文件中使用add_subdirectory 告诉cmake去子目录寻找新的CMakeList.txt 子文件在src 的CMakeList.txt 文件中,新增加了include_directories,用来指明头文件所在的路径。

例子五前面还是有一点不爽:如果想让可执行文件在bin 目录,库文件在lib 目录怎么办?就像下面显示的一样:+ build/|+--+ bin/| || /--- hello.exe|/--+ lib/|/--- hello.lib∙一种办法:修改顶级的CMakeList.txt 文件project(HELLO)add_subdirectory(src bin)add_subdirectory(libhello lib)不是build中的目录默认和源代码中结构一样么,我们可以指定其对应的目录在build中的名字。

这样一来:build/src 就成了build/bin 了,可是除了hello.exe,中间产物也进来了。

还不是我们最想要的。

∙另一种方法:不修改顶级的文件,修改其他两个文件src/CMakeList.txt 文件include_directories(${PROJECT_SOURCE_DIR}/libhello)#link_directories(${PROJECT_BINARY_DIR}/lib)set(APP_SRC main.c)set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)add_executable(hello ${APP_SRC})target_link_libraries(hello libhello)libhello/CMakeList.txt 文件set(LIB_SRC hello.c)add_library(libhello ${LIB_SRC})set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")例子六在例子三至五中,我们始终用的静态库,那么用动态库应该更酷一点吧。

试着写一下如果不考虑windows下,这个例子应该是很简单的,只需要在上个例子的libhello/CMakeList.txt 文件中的add_library命令中加入一个SHARED参数:add_library(libhello SHARED ${LIB_SRC})可是,我们既然用cmake了,还是兼顾不同的平台吧,于是,事情有点复杂:∙修改hello.h 文件#ifndef DBZHANG_HELLO_#define DBZHANG_HELLO_#if defined _WIN32#if LIBHELLO_BUILD#define LIBHELLO_API __declspec(dllexport)#else#define LIBHELLO_API __declspec(dllimport)#endif#else#define LIBHELLO_API#endifLIBHELLO_API void hello(const char* name);#endif //DBZHANG_HELLO_∙修改libhello/CMakeList.txt 文件set(LIB_SRC hello.c)add_definitions("-DLIBHELLO_BUILD")add_library(libhello SHARED ${LIB_SRC})set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")恩,剩下来的工作就和原来一样了。

相关文档
最新文档