CMake 基本使用方法--写CMakeList.txt

简介:
http://techbase.kde.org/Development/Tutorials/CMake_(zh_CN)
http://www.cmake.org/Wiki/CMake

这一章将从软件开发者的角度来描述如何实用CMake。也就是说,如果你的目标是用CMake来管理你的生成过程,请阅读这一章。

CMake的输入

COMMAND(args)

这里的 COMMAND 是命令行的名称,args是用空格分割的参数列表。典型的,对与每一个项目的目录存在一个CMakeLists.txt。 下面我们将从一个简单的Hello world例子开始介绍, 它的源代码树形文件包含这些文件:

Hello.c CMakeLists.txt

CMakeLists.txt将包含下面两行:

PROJECT(Hello)
ADD_EXECUTABLE(Hello Hello.c)

为了生成Hello的可执行程序,你只需依照上面CMake运行的过程描述来生成makefiles文件。 PROJECT 命令表明了产生的工作空间的名称。 ADD_EXECUTABLE命令添加可执行的目标到生成程序。这个简单的程序就只需要这些设置。如歌你的项目需要一些文件才能编译也很容易,只想修改ADD_EXECUTABLE命令行如下:

ADD_EXECUTABLE(Hello Hello.c File2.c File3.c File4.c)

ADD_EXECUTABLE只是很多CMake命令中的一种。比如更复杂的如下:

PROJECT(HELLO)
SET(HELLO_SRCS Hell.c File2.c File3.c)
IF(WIN32)
  SET(HELLO_SRCS ${HELLO_SRCS} WinSupport.c)
ELSE (WIN32)
  SET(HELLO_SRCS ${HELLO_SRCS} UnixSupport.c)
ENDIF (WIN32)

ADD_EXECUTABLE (Hello ${HELLO_SRCS})

#look for the Tcl library
FIND_LIBRARY(TCL_LIBRARY NAMES tcl tc184 tc183 tc 182 tc 180
  PATHS /usr/lib /usr/local/lib)
IF (TCL_LIBRARY)
  TARGET_ADD_LIBRARY (Hello TCL_LIBRARY)
ENDIF(TCL_LIBRARY)

在这个例子中 SET 命令用于将源文件组成一个列表。 IF 命令用于增加WinSupport.c或者UnixSupport.c到列表中。 最后 ADD_EXECUTABLE 命令用于 采用源文件列表HELLO_SRCS中列出的文件 生成可执行文件。FIND_LIBRARY命令用于寻找在一些指定目录下的特定的Tcl库文件。如果找到了,就将他们添加到Hello可执行程序的链接命令。 #行为注释行。

CMake 是会定义一些使用的变量在CMakeList文件中。 比如,WIN32总是会在windows系统中被定义,而UNIX
总是在UNIX系统中被定义。

生成目标:(Build Targets)

SET()
SUBDIRS()
ADD_LIBRARY()
  这里生成静态链接文件,例如ADD_LIBRARY(Whole ${HELLO_SRC}),就会生成一个libWhole.a可供链接

ADD_EXECUTABLE()
AUX_SOURCE_DIRECTORY()
PROJECT()

CMake会循环的查找从当前目录到SUBDIRS列出的任何子目录的文件。SET命令用于设定一个变量。ADD_LIBRARY将添加一个库到目标之中。 ADD_EXECUTABLE添加一个可执行程序到目标列表中。(Note:编译器执行的顺序是先编译源文件,然后生成库文件,最后生成可执行文件)。AUX_SOURCE_DIRECTORY表示一个不在当前目录的包含源文件的目录。这些源代码将插入当前的库(LIBRARY)中。所有在AUX_SOURCE_DIRECTORY的文件将被编译(如,*.c,*.cxx,*.cpp等等)。PROJECT(ProjectName)是一个用在MSVC中的特殊变量,用于为编译器生成项目。他也为CMAKE定义连个有用的变量:ProjectName_SOURCE_DIR和ProjectName_BINARY_DIR.

编译的标示和选项。除了上面列出的命令外,CMakeLists.txt还包含如下的命令:
INCLUDE_DIRECTORIES()
LINK_DIRECTORIES()
LINK_LIBRARIES()
TARGET_LINK_LIBRARIES()

这些命令定义了用于编译源代码和生成可执行程序的目录和库。上面列出的目录的一个很重要的特性是它们会被任何子目录继承。也就是说,CMake依照目录的分层结构来承袭这些命令。在每次遇到对这些命令的描述的时候都会被展开一次。比如说,如果在顶层的CMakeLists文件中有定义INCLUDE_DIRECTORIES(/usr/include)和SUBDIRS(./subdir1),并且在./subdir1/CMakeLists.txt有INCLUDE_DIRECTORIES(/tmp/foobar),于是最后网状的结果是
INCLUDE_DIRECTORIES(/usr/include /tmp/foobar)

CMake会定义许多的模块来查找通常会用到的包,比如OpenGL或Java。 这些模块为你节省了很多的时间来编写这些查找包。这些模块可以像这样加到你的CMakeList文件中,如下:

INCLUDE(${CMAKE_ROOT}/Modules/FindTCL.cmake)

CMAKE_ROOT 总是定义在CMake中,用于指向CMake安装的路径。查看Modules子目录下的一些文件可以给你提供一些很好的idea关于怎样用这些CMake命令。

给项目文件添加一个新的目录
一个通用的方法来扩展一个项目文件是给他添加一个新的文件夹。这将包含三个步骤:
1.创建一个新的目录在你的源代码的分层目录中
2.将这个新的目录添加到SUBDIRS命令中
3.在这个新创建的目录中用适当的命令建立一个CMakeLists.txt文件

This section describes how to use CMake from the software developer's point of view. That is, if your aim is to use CMake to manage your build process, read this section first.
Input to CMake

COMMAND(args)
Where COMMAND is the name of the command, and args is a white-space separated list of arguments to the command. (Arguments with embedded white-space should be quoted.) Typically there will be a CMakeLists.txt file for each directory of the project. Let's start with a simple example. Consider building hello world. You would have a source tree with the following files:
Hello.c  CMakeLists.txt
The CMakeLists.txt file would contain two lines:
PROJECT (Hello)
ADD_EXECUTABLE(Hello Hello.c)
To build the Hello executable you just follow the process described in Running CMake above to generate the makefiles or Microsoft project files. The PROJECT command indicates what the name of the resulting workspace should be and the ADD_EXECUTABLE command adds an executable target to the build process. That's all there is to it for this simple example. If your project requires a few files it is also quite easy, just modify the ADD_EXECUTABLE line as shown below.
ADD_EXECUTABLE(Hello Hello.c File2.c File3.c File4.c)

ADD_EXECUTABLE is just one of many commands available in CMake. Consider the more complicated example below.

PROJECT (HELLO)
SET(HELLO_SRCS Hello.c File2.c File3.c)
IF (WIN32)
  SET(HELLO_SRCS ${HELLO_SRCS} WinSupport.c)
ELSE (WIN32)
  SET(HELLO_SRCS ${HELLO_SRCS} UnixSupport.c)
ENDIF (WIN32)
ADD_EXECUTABLE (Hello ${HELLO_SRCS})

# look for the Tcl library
FIND_LIBRARY(TCL_LIBRARY NAMES tcl tcl84 tcl83 tcl82 tcl80
  PATHS  /usr/lib /usr/local/lib)
IF (TCL_LIBRARY)
  TARGET_ADD_LIBRARY (Hello TCL_LIBRARY)
ENDIF (TCL_LIBRARY)
In this example the SET command is used to group together source files into a list. The IF command is used to add either WinSupport.c or UnixSupport.c to this list. And finally the ADD_EXECUTABLE command is used to build the executable with the files listed in the source list HELLO_SRCS. The FIND_LIBRARY command looks for the Tcl library under a few different names and in a few different paths, and if it is found adds it to the link line for the Hello executable target. Note the use of the # character to denote a comment line.
CMake always defines some variables for use within CMakeList files. For example, WIN32 is always defined on windows systems and UNIX is always defined for UNIX systems. CMake defines a number of commands. A brief summary of the most commonly used commands follows here. Later in the document an exhaustive list of all pre-defined commands is presented. (You may also add your own commands, see the Extension Guide for more information.)

Build Targets:


SET()
SUBDIRS()
ADD_LIBRARY()
 这里生成静态链接文件,例如ADD_LIBRARY(Whole ${HELLO_SRC}),就会生成一个libWhole.a,可供链接。

ADD_EXECUTABLE()
AUX_SOURCE_DIRECTORY()
PROJECT()
CMake works recursively, descending from the current directory into any subdirectories listed in the SUBDIRS command. The command SET is used for setting a variable, in this case to a list of source files. (Note: currently only C and C++ code can be compiled.) ADD_LIBRARY adds a library to the list of targets this makefile will produce. ADD_EXECUTABLE adds an executable to the list of targets this makefile will produce. (Note: source code is compiled first, then libraries are built, and then executables are created.) The AUX_SOURCE_DIRECTORY is a directory where other source code, not in this directory, whose object code is to be inserted into the current LIBRARY. All source files in the AUX_SOURCE_DIRECTORY are compiled (e.g. *.c, *.cxx, *.cpp, etc.). PROJECT (PojectName) is a special variable used in the MSVC to create the project for the compiler, it also defines two useful variables for CMAKE: ProjectName_SOURCE_DIR and ProjectName_BINARY_DIR.

Build flags and options. In addition to the commands listed above, CMakeLists.txt often contain the following commands:

INCLUDE_DIRECTORIES()
LINK_DIRECTORIES()
LINK_LIBRARIES()
TARGET_LINK_LIBRARIES()
These commands define directories and libraries used to compile source code and build executables. An important feature of the commands listed above is that are inherited by any subdirectories. That is, as CMake descends through a directory hierarchy (defined by SUBDIRS()) these commands are expanded each time a definition for a command is encountered. For example, if in the top-level CMakeLists file has INCLUDE_DIRECTORIES(/usr/include), with SUBDIRS(./subdir1), and the file ./subdir1/CMakeLists.txt has INCLUDE_DIRECTORIES(/tmp/foobar), then the net result is
INCLUDE_DIRECTORIES(/usr/include /tmp/foobar)
CMake comes with a number of modules that look for commonly used packages such as OpenGL or Java. These modules save you from having to write all the CMake code to find these packages yourself. Modules can be used by including them into your CMakeList file as shown below.

  INCLUDE (${CMAKE_ROOT}/Modules/FindTCL.cmake)
CMAKE_ROOT is always defined in CMake and can be used to point to where CMake was installed. Looking through some of the files in the Modules subdirectory can provide good ideas on how to use some of the CMake commands.

Adding A New Directory to a project

A common way to extend a project is to add a new directory. This involves three steps:
 Create the new directory somewhere in your source directory hierarchy.
 Add the new directory to the SUBDIRS command in the parent directories CMakeLists.txt
 Create a CMakeLists.txt in the new directory with the appropriate commands
目录
相关文章
C++ 捕获所有异常并拿到错误原因的方法
C++ 捕获所有异常并拿到错误原因的方法
605 0
|
Linux Python 监控
Supervisor 、Supervisord-Monitor 的web统一管理安装、配置、使用
Supervisor 安装、配置、使用、web管理,linux下进程管理系统、监听、重启、停止进程。
10510 1
|
8月前
|
传感器 人工智能 数据可视化
构建AI智能体:五十三、反应式应急+深思式优化:反应速度与规划智慧的平衡
智能体系统设计的混合架构研究 本文探讨了智能体系统的两种基本范式及其融合架构。反应式智能体采用"感知-行动"模式,具有响应速度快、资源消耗低的特点,适用于紧急场景;深思熟虑智能体采用"感知-推理-行动"模式,具备复杂问题求解能力,但计算成本高。研究表明,最先进的解决方案是分层混合架构:底层反应层处理紧急任务,上层深思层负责战略规划,二者通过动态交互机制协作。这种架构在扫地机器人等应用场景中展现出显著优势,既能快速应对突发情况,又能执行长期规划任务。
663 11
|
缓存 人工智能 负载均衡
Scale Up!阿里云让大模型一体机真正实现“算得快”、“用得好”
当前,人工智能技术快速发展,中国智能计算市场进入成长期。大模型推理场景面临实时性、负载均衡与成本控制等多重挑战。阿里云通过芯片算子库升级、模型量化创新及推理引擎优化,实现性能加速,并应用于AI Stack训推一体机和百炼专属版等产品,支持大规模模型高效运行,显著提升性价比与用户体验。
1738 0
|
机器学习/深度学习 运维 数据可视化
《生成对抗网络:网络安全态势感知可视化的新引擎》
在数字化时代,网络安全至关重要。网络安全态势感知可视化通过直观展示网络状况,帮助快速发现威胁。生成对抗网络(GANs)作为前沿AI技术,正为这一领域带来变革。GANs由生成器和判别器组成,通过对抗训练生成逼真数据,用于数据增强、异常检测、威胁情报合成及动态场景模拟。尽管面临数据隐私、模型稳定性和可解释性等挑战,GANs的应用前景广阔,有望大幅提升网络安全水平。
643 22
|
存储 运维 监控
Linux--深入理与解linux文件系统与日志文件分析
深入理解 Linux 文件系统和日志文件分析,对于系统管理员和运维工程师来说至关重要。文件系统管理涉及到文件的组织、存储和检索,而日志文件则记录了系统和应用的运行状态,是排查故障和维护系统的重要依据。通过掌握文件系统和日志文件的管理和分析技能,可以有效提升系统的稳定性和安全性。
459 7
|
存储 运维 数据挖掘
|
JSON JavaScript 前端开发
基于Vue+SpringBoot+MySQL实现个人博客系统
基于Vue+SpringBoot+MySQL实现个人博客系统
|
Android开发
使用WakeLock使Android应用程序保持后台唤醒
使用WakeLock使Android应用程序保持后台唤醒
889 0
|
移动开发 前端开发 JavaScript
HTML5 Canvas详解及应用
HTML5 Canvas 允许通过 JavaScript 在网页上动态绘制图形、动画等视觉内容。首先在 HTML 中定义 `<canvas>` 元素,并通过 JavaScript 获取画布上下文进行绘制。常见方法包括绘制矩形、路径、圆形和文本,以及处理图像和创建动画效果。适用于游戏开发、数据可视化、图像编辑和动态图形展示等多种应用场景。需要注意性能优化、无状态绘制及自行处理事件等问题。