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的可执⾏⽂件了。

  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")恩,剩下来的工作就和原来一样了。

相关文档
最新文档