热门搜索 :
考研考公
您的当前位置:首页正文

cmake学习笔记

来源:伴沃教育
  

最大的Qt4程序群(KDE4)采用cmake作为构建系统 Qt4的python绑定(pyside)采用了cmake作为构建系统 开源的图像处理库 opencv 采用cmake 作为构建系统

 ...

看来不学习一下cmake是不行了,一点一点来吧,找个最简单的C程序,慢慢复杂化,试试看: 例子一 例子二 例子三 例子四 例子五 例子六

单个源文件 main.c

==>分解成多个 main.c hello.h hello.c ==>先生成一个静态库,链接该库 ==>将源文件放置到不同的目录 ==>控制生成的程序和库所在的目录 ==>使用动态库而不是静态库

例子一

一个经典的C程序,如何用cmake来进行构建程序呢? //main.c #include 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.exe cmake 真的不太好用哈,使用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 #include \"hello.h\" void hello(const char * name) { printf (\"Hello %s!/n\}  main.c #include \"hello.h\" int main() { hello(\"World\"); return 0; }  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 例子很简单,没什么可说的。 然后准备好CMakeList.txt 文件 例子三

接前面的例子,我们将 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 #endif LIBHELLO_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\") 恩,剩下来的工作就和原来一样了。 Cmake学习笔记二 在 Cmake学习笔记一 中通过一串小例子简单学习了cmake 的使用方式。 这次应该简单看看语法和常用的命令了。 简单的语法

    注释 命令语法 字符串列表 变量(字符串或字符串列表) 设置变量 Foo 等价于 command(a b c) 等价于 command(\"a b c\") 转义,和 a b c无关联 # 我是注释 COMMAND(参数1 参数2 ...) A;B;C # 分号分割或空格分隔的值 set(Foo a b c) command(${Foo}) command(\"${Foo}\") command(\"/${Foo}\")  流控制结构 IF()...ELSE()/ELSEIF()...ENDIF() WHILE()...ENDWHILE() FOREACH()...ENDFOREACH()  正则表达式 部分常用命令

INCLUDE_DIRECTORIES( \"dir1\" \"dir2\" ... )

头文件路径,相当于编译器参数 -Idir1 -Idir2 库文件路径。注意:

LINK_DIRECTORIES(\"dir1\" \"dir2\")

由于历史原因,相对路径会原样传递给链接器。

尽量使用FIND_LIBRARY而避免使用这个。

AUX_SOURCE_DIRECTORY( “sourcedir”

收集目录中的文件名并赋值给变量

variable)

ADD_EXECUTABLE ADD_LIBRARY

可执行程序目标 库目标

ADD_CUSTOM_TARGET

ADD_DEPENDENCIES( target1 t2 t3 )

自定义目标

目标target1依赖于t2 t3

本意是供设置 -D... /D... 等编译预处理需要的宏定义参数,对比 REMOVE_DEFINITIONS()

ADD_DEFINITIONS( \"-Wall -ansi\")

TARGET_LINK_LIBRARIES( target-name lib1 lib2 ...)

LINK_LIBRARIES( lib1 lib2 ...) SET_TARGET_PROPERTIES( ... ) MESSAGE(...)

INSTALL( FILES “f1” “f2”DESTINATION . ) SET(

VAR

value

[CACHE

TYPE

设置单个目标需要链接的库 设置所有目标需要链接的库

设置目标的属性 OUTPUT_NAME, VERSION, ....

DESTINATION 相对${CMAKE_INSTALL_PREFIX}

DOCSTRING [FORCE]])

LIST( APPEND|INSERT|LENGTH|GET|

列表操作

REMOVE_ITEM|REMOVE_AT|SORT ...)

STRING( TOUPPER|TOLOWER|LENGTH|

字符串操作

SUBSTRING|REPLACE|REGEX ...) SEPARATE_ARGUMENTS( VAR ) FILE(

WRITE|READ|APPEND|GLOB|

文件操作

转换空格分隔的字符串到列表

GLOB_RECURSE|REMOVE|MAKE_DIRECTORY ...) FIND_FILE FIND_PATH FIND_LIBRARY FIND_PROGRAM FIND_PACKAGE

注意 CMAKE_INCLUDE_PATH 注意 CMAKE_INCLUDE_PATH 注意 CMAKE_LIBRARY_PATH

注意 CMAKE_MODULE_PATH

EXEC_PROGRAM( bin [work_dir] ARGS <..> [OUTPUT_VARIABLE var] 执行外部程序 [RETURN_VALUE var] )

OPTION( OPTION_VAR “description” [initial

value] )

变量

工程路径

 

CMAKE_SOURCE_DIR PROJECT_SOURCE_DIR

_SOURCE_DIR

这三个变量指代的内容是一致的,是工程顶层目录

 

CMAKE_BINARY_DIR PROJECT_BINARY_DIR

_BINARY_DIR

这三个变量指代的内容是一致的,如果是in source编译,指得就是工程顶层目录,如果 是out-of-source编译,指的是工程编译发生的目录 CMAKE_CURRENT_SOURCE_DIR

指的是当前处理的CMakeLists.txt所在的路径。 CMAKE_CURRRENT_BINARY_DIR

如果是in-source编译,它跟CMAKE_CURRENT_SOURCE_DIR一致,如果是out-ofsource 编译,他指的是target编译目录。 CMAKE_CURRENT_LIST_FILE

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

CMAKE_BUILD_TYPE

控制 Debug 和 Release 模式的构建   CMakeList.txt文件 命令行参数 SET(CMAKE_BUILD_TYPE Debug) cmake DCMAKE_BUILD_TYPE=Release 编译器参数

 CMAKE_C_FLAGS  CMAKE_CXX_FLAGS

也可以通过指令ADD_DEFINITIONS()添加

CMAKE_INCLUDE_PATH

配合 FIND_FILE() 以及 FIND_PATH() 使用。如果头文件没有存放在常规路径

(/usr/include, /usr/local/include等),

则可以通过这些变量就行弥补。如果不使用 FIND_FILE 和 FIND_PATH的话,CMAKE_INCLUDE_PATH,没有任何作用。 CMAKE_LIBRARY_PATH

配合 FIND_LIBRARY() 使用。否则没有任何作用 CMAKE_MODULE_PATH

cmake 为上百个软件包提供了查找器(finder):FindXXXX.cmake

当使用非cmake自带的finder时,需要指定finder的路径,这就是CMAKE_MODULE_PATH,配合 FIND_PACKAGE()使用

CMAKE_INSTALL_PREFIX

控制make install是文件会安装到什么地方。默认定义是/usr/local 或 %PROGRAMFILES%

BUILD_SHARED_LIBS

如果不进行设置,使用ADD_LIBRARY且没有指定库类型,默认编译生成的库是静态库。

UNIX 与 WIN32

 

UNIX,在所有的类UNIX平台为TRUE,包括OS X和cygwin WIN32,在所有的win32平台为TRUE,包括cygwin

参考

http://www.cmake.org/cmake/help/cmake-2-8-docs.html

Cmake 学习笔记三

接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cmake 的使用。 学习一下cmake的 finder。

Cmake Practice --Cjacker

finder是神马东西?

当编译一个需要使用第三方库的软件时,我们需要知道: 去哪儿找头文件 .h 去哪儿找库文件 (.so/.dll/.lib/.dylib/...) 需要链接的库文件的名字 对比GCC的 -I 参数 对比GCC的 -L 参数 对比GCC的 -l 参数 这也是一个 finder 需要返回的最基本的信息。 如何使用?

比如说,我们需要一个第三方库 curl,那么我们的 CMakeLists.txt 需要指定头文件目录,和库文件,类似: include_directiories(/usr/include) target_link_libraries(myprogram curl) 如果借助于cmake提供的finder会怎么样呢?使用cmake的Modules目录下的FindCURL.cmake,相应的 CMakeList.txt 文件: find_package(CURL REQUIRED) include_directories(${CURL_INCLUDE_DIR}) target_link_libraries(curltest ${CURL_LIBRARY}) 或者 find_package(CURL) if(CURL_FOUND) include_directories(${CURL_INCLUDE_DIR}) target_link_libraries(curltest ${CURL_LIBRARY}) else(CURL_FOUND) message(FATAL_ERROR \"curl not found!\") endif(CURL_FOUND) 如果我们使用的finder,不是cmake自带的怎么办?  放置位置:工程根目录下的 cmake/Modules/  然后在 CMakeList.txt 中添加 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} \"${CMAKE_SOURCE_DIR}/cmake/Modules/\") find_package如何工作

find_package 将会在module路径下查找 Find.cmake。首先它搜索 ${CMAKE_MODULE_PATH}中的所有路径,然后搜索 /share/cmake-x.y/Modules/

如果这个文件未找到,它将会查找 Config.cmake 或

-config.cmake 文件。这两个文件是库文件安装时自己安装的,将自己的路径硬编码到其中。

前者称为 module 模式,后者称为 config 模式 每个模块一般都会提供一下几个变量 _FOUND

_INCLUDE_DIR 或 _INCLUDES

_LIBRARY 或 _LIBRARIES 或 _LIBS _DEFINITIONS

编写finder

 首先使用 find_package 探测本软件包依赖的第三方库(参数 QUIETLY 和 REQUIRED应该被传递)  

如果 pkg-config 可用,则可以用其去探测include/library路径 分别使用 find_path 和 find_library 查找头文件和库文件

o pkg-config 提供的路径仅作为参考 o CMake 有很多硬编码的路径

结果放到 _INCLUDE_DIR 和 _LIBRARY (注意:单数而不是复数) 设置 _INCLUDE_DIRS 为 _INCLUDE_DIR _INCLUDE_DIRS ...

设置 _LIBRARIES 为 _LIBRARY _LIBRARIES ...

o 依赖使用复数,包自身使用单数形式(由find_path和find_library提供)

调用宏 find_package_handle_standard_args() 设置 _FOUND 并打印或失败信

参考

http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries http://www.cmake.org/cmake/help/cmake-2-8-docs.html

拖了近一个月了,终于有信心尝试看看 apiextractor-0.10.0 的 CMakeList.txt 了 。简单整理一下,作为学习笔记,备忘。

apiextractor 的CMakeList.txt文件

走马观花

include(icecc.cmake) 包含一个文件,其内容比较简单(如果找到分布式编译器icecc,则使用它) project(apiextractor) cmake_minimum_required(VERSION 2.6) find_package(Qt4 4.5.0 REQUIRED) find_package(LibXml2 2.6.32) find_package(LibXslt 1.1.19) 常规内容,依赖 Qt4(必须),LibXml2,LibXslt 3个软件包 option(DISABLE_DOCSTRINGS \"Disable documentation extraction.\" FALSE) option(BUILD_TESTS \"Build tests.\" TRUE) option(INSTALL_TESTS \"Install tests\" FALSE) option(ENABLE_VERSION_SUFFIX \"Used to use current version in suffix to generated files. This is used to allow multiples versions installed simultaneous.\" FALSE) 4个选项 if (NOT DISABLE_DOCSTRINGS) if (NOT LIBXSLT_FOUND OR NOT LIBXML2_FOUND) set(DISABLE_DOCSTRINGS TRUE) message(WARNING \"libxslt and/or libxml not found, disabling support to doc strings!\") endif() endif() 如果没有禁用DOCSTRINGS,但是没有找到LibXml2和LibXslt,同样禁用 if(MSVC) set(CMAKE_CXX_FLAGS \"/Zc:wchar_t- /GR /EHsc /DWIN32 /D_WINDOWS /D_SCL_SECURE_NO_WARNINGS\") elseif(CMAKE_HOST_UNIX) option(ENABLE_GCC_OPTIMIZATION \"Enable specific GCC flags to optimize library size and performance. Only available on Release Mode\" 0) set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wall -fvisibility=hidden\") set(CMAKE_CXX_FLAGS_DEBUG \"-g\") if(ENABLE_GCC_OPTIMIZATION) set(CMAKE_BUILD_TYPE Release) set(CMAKE_CXX_FLAGS_RELEASE \"-DNDEBUG -Os -Wno-strict-aliasing -Wl,-O1\") if (NOT CMAKE_HOST_APPLE) set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wl,--hash-style=gnu\") endif() endif() if(NOT CMAKE_HOST_APPLE) set(CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} -Wl,--version-script,${CMAKE_CURRENT_SOURCE_DIR}/symbols.filter\") endif() endif() 为MSVC、UNIX等分别设置一些选项 if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() 如果没有设置构建类型,则使用Release if(BUILD_TESTS) set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) endif () 如果需要构建测试程序,则设置库文件输出目录为 tests子目录 set(apiextractor_MAJOR_VERSION 0) set(apiextractor_MINOR_VERSION 10) set(apiextractor_MICRO_VERSION 0) set(apiextractor_VERSION \"${apiextractor_MAJOR_VERSION}.${apiextractor_MINOR_VERSION}.${apiextractor_MICRO_VERSION}\") configure_file(apiextractorversion.h.in ${CMAKE_CURRENT_BINARY_DIR}/apiextractorversion.h @ONLY) set(apiextractor_SOVERSION ${apiextractor_MAJOR_VERSION}.${apiextractor_MINOR_VERSION}) 设置版本号,并使用配置文件(只替代@VAR@这样的变量) set(QT_USE_QTCORE 1) set(QT_USE_QTXML 1) include(${QT_USE_FILE}) add_definitions(${QT_DEFINITIONS}) add_definitions(-DQT_PLUGIN) add_definitions(-DQT_SHARED) add_definitions(-DRXX_ALLOCATOR_INIT_0) Qt的常规设置 if(ENABLE_VERSION_SUFFIX) set(apiextractor_SUFFIX \"-${apiextractor_MAJOR_VERSION}.${apiextractor_MINOR_VERSION}\") else() set(apiextractor_SUFFIX \"\") endif() 控制是否需要后缀 set(apiextractor_SRC apiextractor.cpp abstractmetabuilder.cpp #omit ... ) if (NOT DISABLE_DOCSTRINGS) set(apiextractor_SRC ${apiextractor_SRC} docparser.cpp doxygenparser.cpp qtdocparser.cpp ) set(APIEXTRACTOR_EXTRA_INCLUDES ${LIBXSLT_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR}) set(APIEXTRACTOR_EXTRA_LIBRARIES ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES}) else() set(APIEXTRACTOR_EXTRA_INCLUDES \"\") set(APIEXTRACTOR_EXTRA_LIBRARIES \"\") endif() 将源文件名存入变量 apiextractor_SRC,如果启用了DOCSTRINGS,则设置LibXslt和LibXml2的头文件路径和库 set(LIB_INSTALL_DIR \"${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}\" CACHE PATH \"The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})\" FORCE) 设置一个变量,稍后作为库文件安装路径 qt4_add_resources(apiextractor_RCCS_SRC generator.qrc) qt4_automoc(apiextractor_SRC) Qt 常规设置,注意qt4_automoc 根据源文件中的#include \"xxx.moc\"来确定处理相应的头文件 include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/parser ${CMAKE_CURRENT_SOURCE_DIR}/parser/rpp ${QT_INCLUDE_DIR} ${APIEXTRACTOR_EXTRA_INCLUDES} ) add_library(apiextractor SHARED ${apiextractor_SRC} ${apiextractor_RCCS_SRC}) target_link_libraries(apiextractor ${APIEXTRACTOR_EXTRA_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTXMLPATTERNS_LIBRARY} ${QT_QTXML_LIBRARY}) set_target_properties(apiextractor PROPERTIES VERSION ${apiextractor_VERSION} SOVERSION ${apiextractor_SOVERSION} OUTPUT_NAME \"apiextractor${apiextractor_SUFFIX}\" DEFINE_SYMBOL APIEXTRACTOR_EXPORTS) 设置头文件目录,添加库文件目标,设置目标属性(注意DEFINE_SYMBOL) # uninstall target configure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake\" \"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake\" IMMEDIATE @ONLY) add_custom_target(uninstall \"${CMAKE_COMMAND}\" -P \"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake\") set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${apiextractor_VERSION}) add_custom_target(dist COMMAND mkdir -p \"${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}\" && git log > \"${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}/ChangeLog\" && git archive --prefix=${ARCHIVE_NAME}/ HEAD --format=tar --output=\"${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar\" && tar -C \"${CMAKE_BINARY_DIR}\" --owner=root --group=root -r \"${ARCHIVE_NAME}/ChangeLog\" -f \"${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar\" && bzip2 -f9 \"${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar\" && echo \"Source package created at ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.bz2./n\" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) 两个自定义的目标 uninstall 和 dist set(root_HEADERS apiextractormacros.h abstractmetalang.h apiextractor.h graph.h reporthandler.h typesystem.h fileout.h docparser.h qtdocparser.h include.h typedatabase.h ) 将文件放于变量 root_HEADERS,稍后会用在install中。(这些文件最终会被安装) if (BUILD_TESTS) enable_testing() add_subdirectory(tests) endif() 控制单元测试的启用 add_subdirectory(data) add_subdirectory(doc) 前者生成ApiExtractorConfig.cmake等文件,后者生成文档 install(FILES ${root_HEADERS} DESTINATION include/apiextractor${apiextractor_SUFFIX}) install(TARGETS apiextractor EXPORT apiextractor LIBRARY DESTINATION \"${LIB_INSTALL_DIR}\" ARCHIVE DESTINATION \"${LIB_INSTALL_DIR}\" RUNTIME DESTINATION bin) 需要安装的文件,及安装到的路径 知识点备忘

 

布尔真:1, ON, YES, TRUE, Y, 非零数

布尔假:0, OFF, NO, FALSE, N, IGNORE, \"\后缀为'-NOTFOUND'的

option()

option( \"describing\" [initial value]) 为用户提供ON/OFF选项,初始值没有指定的话,采用OFF set_target_properties()

set_target_properties(target1 target2 ... PROPERTIES prop1 value1 prop2 value2 ...) DEFINE_SYMBOL 在生成动态库,定义编译预处理器符号。如果没有指定,默认是 target_EXPORTS

VERSION 与 SOVERSION 分别是构建版本号 和 api 版本号 PREFIX 与 SUFFIX 分别是前缀(比如lib)和后缀(比如.so) IMPORT_PREFIX 与 IMPORT_SUFFIX 导入库的前缀和后缀 OUTPUT_NAME

install(TARGETS...)

install(TARGETS targets... [EXPORT ] [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE| PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE] [DESTINATION

] [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT ] [OPTIONAL] [NAMELINK_ONLY|NAMELINK_SKIP] ] [...])  EXPORT 必须出现在 RUNTIME, LIBRARY, ARCHIVE 之前。配合下面的 install(EXPORT) 使用 install(EXPORT...)

install(EXPORT DESTINATION

[NAMESPACE ] [FILE .cmake] [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT ]) 

有助于外部的工程使用本工程构建和安装的目标。

因篇幅问题不能全部显示,请点此查看更多更全内容

Top