CMake 学习笔记 02 - 更复杂的项目

CMake 学习笔记 02 - 更复杂的项目

源代码见 https://github.com/fengyc/cmake-tutorial

源代码目录组织

一般的项目,会划分为多个子目录,每个子目录中包含不同的模块,并定义好模块间的依赖关系。出于项目组织的需要,还会划分为 src 、 doc 、 tool/utils 、 build 等目录。

以第一个 helloworld 项目为例,现在把源代码 main.c 放到 src 目录下,并将生成的内容放到 bin 目录下,形成 helloworld2 。

每个子目录下都需要一个 CMakeLists.txt,src 中的 CMakeLists.txt 内容如下::

ADD_EXECUTABLE(hello main.c)

如果这个子目录生成的是一个库,那么可用 ADD_LIBRARY 指令。

顶层目录的 CMakeLists.txt 内容如下 ::

PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)

ADD_SUBDIRECTORY 指令用于向项目添加子目录,用法为 ADD_SUBDIRECTORY(源代码目录 Binary目录)。如果不加 Binary 目录,相当于直接在构建目录中对应的源代码目录中保存中间生成的文件。通过 SET 指令,指定 EXECUTABLE_OUTPUT_PATHLIBRARY_OUTPUT_PATH ,可覆盖之前设置的目标输出,如 ::

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

PROJECT_BINARY_DIR 为构建目录,即 build 目录)

整个目录树如下 ::

.
├── CMakeLists.txt
└── src
    ├── CMakeLists.txt
    └── main.c

同样可建立 build 目录,然后进行外部构建 ::

mkdir build
(cd build; cmake ..; build)

这时,会在 build/bin 目录下生成 hello 可执行文件。

安装

cmake 的 INSTALL 指令用于进行安装,它使用到 CMAKE_INSTALL_PREFIX 用于指定安装位置。执行时用 ::

cmake -DCMAKE_INSTALL_PREFIX=/usr/local install

进行安装。

INSTALL 可安装目标文件(生成的文件)、普通文件、非目标可执行文件等等。

安装目标文件如下 ::

INSTALL(TARGETS targets...
    [
        [ARCHIVE|LIBRARY|RUNTIME]
        [DESTINATION <dir>]
        [PERMISSIONS permissions...]
        [CONFIGURATIONS [Debug|Release|...]]
        [COMPONENT <component>]
        [OPTIONAL]
    ] [...])

TARGETS 后面为通过 ADD_EXECUTABLEADD_LIBRARY 添加的目标,类型 RUNTIME 为可执行目标文件,ARCHIVE 为静态类库,LIBRARY 为动态类库,DESTINATION 为目标路径,通常是用相对于 CMAKE_INSTALL_PREFIX 的路径。这里不需要关注目标文件生成时的具体路径,cmake 会自动进行寻找,如 ::

INSTALL(TARGETS myrun mylib mystaticlib
    RUNTIME DESTINATION bin
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION libstatic)

非目标普通文件或可执行文件,如一些辅助脚本 ::

INSTALL(FILES|PROGRAMS files... DESTINATION <dir>
    [PERMISSIONS permissions...]
    [CONFIGURATIONS [Debug|Release|...]]
    [COMPONENT <component>]
    [RENAME <name>] [OPTIONAL])

如 ::

INSTALL(FILES my.conf DESTINATION etc/${PROJECT_NAME})
INSTALL(PROGRAMS my.sh DESTINATION bin)

FILES 和 PROGRAMS 的区别在于安装后的文件默认权限不同,PROGRAMS 自动加上可执行。

安装源代码中的目录 ::

INSTALL(DIRECTORY dirs... DESTINATION <dir>
    [FILE_PERMISSIONS permissions...]
    [DIRECTORY_PERMISSIONS permissions...]
    [USE_SOURCE_PERMISSIONS]
    [CONFIGURATIONS [Debug|Release|...]]
    [COMPONENT <component>]
    [[PATTERN <pattern> | REGEX <regex>]
        [EXCLUDE] [PERMISSIONS permissions...]]
    [...])

如 ::

INSTALL(DIRECTORY init/ DESTINATION /etc/init
    PATTERN "*.conf")

目录列表中路径写法需要注意,它是相对于源代码中的路径,abc 表示拷贝整个目录(包含目录本身),abc/ 表示只拷贝目录内的内容(不包含目录本身)。

更新项目

现在更新项目来支持安装,复制 helloworld2 整个项目到 helloworld3 。

往里面加入 doc/hello.txt,随便写点东西。在源代码根目录加一个 README 文件,随便写点东西。加入一个 runhello.sh 文件,调用 hello,内容为 ::

#!/bin/sh

./hello

修改顶层目录上的 CMakeLists.txt,增加安装内容,整个文件内容为 ::

PROJECT(HELLO)
ADD_SUBDIRECTORY(src)

INSTALL(PROGRAMS runhello.sh DESTINATION bin)
INSTALL(FILES README DESTINATION share/doc/${PROJECT_NAME})
INSTALL(DIRECTORY doc/ DESTINATION share/doc/${PROJECT_NAME})

修改 src 中的 CMakeLists.txt,增加安装内容 ::

ADD_EXECUTABLE(hello main.c)

INSTALL(TARGETS hello DESTINATION bin)

(cd build; cmake -DCMAKE_INSTALL_PREFIX=$PWD/usr ..; make install) 进行构建,以及在 build 目录的 usr 下进行安装。在默认情况下,CMAKE_INSTALL_PREFIX/usr/local ,这里改为 build 中的 usr 。

posted @ 2017-01-20 16:47  drop *  阅读(656)  评论(0编辑  收藏  举报