Archive:Development/Tutorials/CMake (zh CN)

From KDE TechBase
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.


简介

CMake读取脚本文件并且为它所运行的平台的本地构建系统产生输入文件。它可以生成GNU Makefiles、KDevelop的项目文件、XCode项目文件以及Visual Studio项目文件等多种文件格式。

CMake是自由软件并且是在BSD协议下发布的。它是由Kitware公司开发的。

您可以在TechBase 上的 CMake 页面找到更多 CMake 相关的信息。

为什么使用CMake?

CMake是KDE 4发布中的官方工具,这是在2006年3月决定的,它和以前的KDE工具automake和unsermake的主要技术不同点有:

  • CMake是独立于KDE开发的,它也可以被用于其它项目。
  • 编译时间更快,主要是因为没有再使用libtool。
  • 构建文件更容易编写。

如何使用CMake编译KDE

获取和安装CMake

Linux、BSD及其他Unix系统

这里获得取回最新的CMake稳定版。

下载完后,解压并安装:

$ mkdir cmake-build
$ cd cmake-build
$ ../bootstrap
$ make
$ make install

默认的,这将把CMake安装在/usr/local,因此,确定/usr/local/bin在的执行路径里。要改变安装路径,(例如debian中改为/usr),在bootstrap命令中加入'--prefix=PATH'选项。

如果你想使用当前的开发版本,请遵循这里的指令。

Windows

这里获得取回最新的CMake稳定版。

下载完后,运行cmake的安装程序。

默认将把CMake安装在C:\Program Files\CMake 2.8,,因此要确保<installpath>\bin在你的执行路径中。

如果你想使用当前的开发版本,请遵循这里的指令。

运行CMake

Linux、BSD及其他Unix系统

你必须运行CMake来为你的系统生成build文件。CMake支持in-source和out-of-source构建,不过目前KDE默认禁用in-source构建。

假定你在~/src/kdelibs/中有kdelibs/,那么,输入:

$ ls
kdelibs/
$ mkdir kdelibs-build
$ cd kdelibs-build
$ cmake ../kdelibs

这会在kdelibs-build/中生成构建kdelibs/的Makefiles。

Windows

你必须运行CMake来为你的系统生成build文件。CMake支持in-source和out-of-source构建,不过目前KDE默认禁用in-source构建。

假定你在c:\daten\kde4中有kdelibs\,那么,输入:

c:\daten\kde4> cd kdelibs\win
c:\daten\kde4> cmake
c:\daten\kde4> make 
c:\daten\kde4> make install
c:\daten\kde4> cd ..
c:\daten\kde4> mkdir kdelibs-build
c:\daten\kde4> cd kdelibs-build
c:\daten\kde4\kdelibs-build> cmake ..\kdelibs

这样就生成了在 kdelibs-build\中构建kdelibs\的Makefiles。要获得更多的关于在Windows下编译KDE的信息,请阅读KDE on Windows

KDevelop项目

如果你更喜欢KDevelop的项目文件(基本上就是Makefiles及为KDevelop生成的一些文件),这样运行CMake:

$ cmake ../kdelibs -GKDevelop3

使用“cmake -h”来查看CMake支持那些生成器 (generators)及其他的选项。

CMake和Qt4

为了定位Qt 4,CMake会在你的执行路径中搜索qmake。CMake会使用QTDIR这个环境变量。因此请确保在执行路径中寻找到的第一个qmake就是你希望使用的。

更多细节

当CMake执行完成,它会生成一个叫“CMakeCache.txt”的文件。这个文件包含了CMake在你的系统上检测到的所有设置。如果你希望在其他生成器(generators)上运行CMake,或你希望CMake重新检测系统,请删除这个文件。

如果有些东西你知道它存在,而CMake没有检测到,你可以手动的告诉CMake到哪里去找它。CMake通过变量来存储这些信息。这些变量缓存在前面提到的 CMakeCache.txt中。这里有3个选项来手工调整这些变量:

  • 通过命令行告诉CMake现在的值: cmake ../kdelibs -DNAME_OF_THE_VARIABLE=value
  • 使用ccmake,它提供了一个基于鼠标的GUI来调整CMake变量(运行: ccmake ../kdelibs)
  • 直接编辑CMakeCache.txt(不推荐)

你应该最起码运行一次“ccmake ../kdelibs”,这样你会对CMake使用了那些变量有个印象。按“T”来查看“高级”的变量。如果有些东西CMake没有找到,运行ccmake并手工调整它。

命令行变数

一些你可能希望设置的变量:

  • CMAKE_INSTALL_PREFIX: cmake ../kdelibs -DCMAKE_INSTALL_PREFIX=/opt/kde4 相当于./configure --prefix=/opt/kde4
  • CMAKE_BUILD_TYPE: 决定你如何构建系统。你可以在“debugfull”、“debug”、“profile”、“relwithdebinfo”和“release”中进行选择。默认的是“relwithdebinfo”(-O2 -g)。更多细节查看FindKDE4Internal.cmake。
  • KDE4_BUILD_TESTS=ON: creates Makefiles with build test programs and also provides 'test' targets
  • KDE4_TEST_OUTPUT=xml: Unit tests using the QTestLib framework will create xml formatted logfiles.
  • KDE4_DISABLE_MULTIMEDIA=ON: Build KDE without any multimedia (audio and video) support.
  • BUILD_foo=OFF: disables the build for the project in subdirectory 'foo'.
  • RPATH_STYLE: 这个不再有效了。默认情况下,一切都将在RPATH设置正确的情况下来构建。如果你不希望使用RPATH,将CMAKE_SKIP_RPATH设置为TRUE。
  • WITH_FOO: 这里有一些选项,例如WITH_CUPS或WITH_Jasper。如果你将他们关闭,cmake甚至不会去尝试寻找这个包。如果将它激活,cmake将会尝试寻找这个包。如果这样做失败了,你还可以通过上面介绍的方法手工设置。

环境变量

如果你在CMake没法找到的非标准位置安装了头文件或库( 例如Mac OSX下把fink安装到/sw),那么就请设置下面这些环境变量。尽管有相似的命名规则,这些设置在cmake的命令中并不会做为参数来工作。

  • CMAKE_INCLUDE_PATH,例如 export CMAKE_INCLUDE_PATH=/sw/include
  • CMAKE_LIBRARY_PATH,例如 export CMAKE_LIBRARY_PATH=/sw/lib
  • CMAKE_PROGRAM_PATH,例如 export CMAKE_LIBRARY_PATH=/sw/bin

With CMake 2.6.0 and above the same effect can be achieved by setting just one variable:

  • CMAKE_PREFIX_PATH,例如 export CMAKE_PREFIX_PATH=/sw

关于变量的更多信息,请参考 cmake.org wiki page

更进一步

如果cmake以“Generating done”结束,那表示没有错误,但如果以“Configuring done”结束,那表示有错误需要修正。当cmake成功结束,运行你的构建工具(如make、KDevelop、XCode或MSVC)来构建并等到它结束。然后运行“make install”。

如果你得到如下错误提示:

CMake Error: This project requires some variables to be set,
and cmake can not find them.
Please set the following variables:
X11_XTest_LIB (ADVANCED)

那表示你可能缺少库(或其他依赖包)。在cmake/modules目录中查找cmake无法找到的变量来确定是缺少哪个库文件。在上面的例子中,就是:

FIND_LIBRARY(X11_XTest_LIB Xtst ${X11_LIB_SEARCH_PATH})

这里缺失的库是Xtst。然后你找到这个库(也许是通过安装libXtst-devel)并再次运行cmake。

在简单的应用程序中使用CMake

这是最简单的CMakeLists.txt:

add_executable(hello main.cpp)

这将从main.cpp源码文件创建一个叫“hello”(Windows下叫“hello.exe”)的可执行文件。你可以根据自己的需要将C和C++文件混合。在同一个CMakeLists.txt可以有多个可执行文件和库。同一个源码文件可以用于不同的目的,源码可以从其他目标中为每个目的独立的编译。CMake语言最重要的部分可能是变量:

SET( MY_SOURCES main.cpp widget.cpp)
MESSAGE(STATUS "my sources: ${MY_SOURCES}")

使用SET()命令来为变量设置值。如果你列出了一个以上的字符串,变量将是串列表。列表是一列由分号隔开的字符串。如果只设置个一项,那么这项只有一个值。可以通过${VAR}获得变量的值。可以使用FOREACH()来迭代一份列表:

FOREACH(next_ITEM ${MY_SOURCES})
   MESSAGE(STATUS "next item: ${next_ITEM}")
ENDFOREACH(next_ITEM ${MY_SOURCES})

CMake中的命令是大小写无关的。变量名和参数名是大小写相关的。

还可以测试一些不同的东西:

IF (UNIX)
   MESSAGE(STATUS "This is UNIX (including OS X and CygWin)")
ENDIF (UNIX)

IF (MSVC)
   SET(MY_SRCS ${MY_SRCS} winextra.cpp)
ENDIF (MSVC)

在第二个例子中,你可以看到如何将项目附加到列表中。

在cmake Wiki中有一份使用cmake构建KDE4软件的指导,推荐阅读。

在KDE项目中使用CMake

这里是一份基本的构建一个小KDE4项目的CMakeList文件:

PROJECT( kde4project)
FIND_PACKAGE(KDE4 REQUIRED)
INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} )

SET(KDE4ProjectSources kde4mainapp.cpp someclass.cpp someotherclass.cpp)

KDE4_ADD_EXECUTABLE(kde4project ${KDE4ProjectSources} )

TARGET_LINK_LIBRARIES(kde4project ${KDE4_KDEUI_LIBS} ${KDE4_KPARTS_LIBS} )

target_link_libraries 包含链接到您的程序的开发库。比如说,你想要连结 libtidy-devel,你的函式库的档名可能叫做 /usr/local/lib/libtidy.a。还要加上 -ltidy 让 gcc 呼叫。在这里,请加入 tidy 到您的target_link_libraries。可能的话,请使用预先定义的变量或宏,如 ${KDE4_KDEUI_LIBS}。

install (TARGETS 是最后安装目标的位置。如果你没有这行,就无法使用 make install。

KDE 特定的变量、宏和其他有用的信息,可以在KDE 的 CMake 附加组件页面找到。

扩展CMake

CMake可以通过cmake脚本扩展,CMake带有大量的脚本,在UNIX下,这些脚本默认安装在 /usr/local/share/CMake/Modules/内。KDE库也在/apps/cmake/modules/安装了一些CMake模块。这里的文件将被代替CMake的系统全局模块路径。FindFOO.cmake用来检测软件包, 这里有更多信息。在CMake中也可以写宏文件,对于大多数的软件构建来说,他们足够强大了。这些宏不会做为通用语言来使用。

你还可以在CMake中编写宏。他们非常强大,可以满足你编译的软件中所需要的所有事情,但是他们并不是被用作通用目的的编程语言。

将基于autotools的KDE软件转换为CMake

你可以在kdesdk/cmake/找到am2cmake脚本。这是ruby写成的,所以确定你的系统安装了ruby。在你的源码目录最上层运行am2cmak:

$ cd src/mykooltool/
$ am2cmake --kde4

不要忘了开关“--kde4”,不然系统无法生成适合KDE4的文件。转换文件可能会正常工作,但编译的项目将需要一些额外的编辑。

你可能需要:

  • 使用INCLUDE_DIRECTORIES()添加更多include目录。
  • 使用TARGET_LINK_LIBRARIES()添加更多链接库。
  • 使用ADD_DEFINITIONS()添加更多编译开关。
  • 添加一些“configure”检查,参照如何进行平台检查如何找到已经安装的软件
  • 特别要注意以往的libtool便捷库,CMake并不支持这些库,而是生成一个ConvenienceLibs.cmake文件代替。在这个文件里,你可以为每个便捷库找到一个包含了这个库所有源码的变量。对于链接到这些库的目标,只要在源码中添加这些变量即可。
  • 一个AdditionalInfo.txt文件将被创建。你可以在这里找到项目所有的*.in和*.in.in文件。这些文件完成的任务将被手工转换到CMake.