我正在将一个C++项目迁移到只使用cmake,该项目的配置目前是cmake(CMakeLists.txt)和Make(GNUmakefile)的组合。目前的设置方式是:
myproject
| CMakeLists.txt (add_subdirectory(src))
| src/
| apps/
| myapp/
| [myapp source files]
| GNUmakefile
| ...
| libs/
| mylib/
| [mylib source files]
| GNUmakefile
| ...
| common/
| CMakeLists.txt (add_subdirectory(dir1, dir2, dir3...))
| ...
| include/
myapp和mylib之外还有更多的应用程序和库,但它们都以类似的方式构建和链接,所以如果我有一个,我可以获得所有。
按照项目目前的构建方式,有一个脚本基本上有4行:
cmake path/to/myproject // with the necessary flags and variables passed
make all DESTDIR=$INSTALL_DIR install
cd src/libs ; make all
cd src/apps ; make all
这是因为没有依赖关系的common
首先构建并安装(这里也安装了include
),然后是依赖于common
的libs
,然后是同时依赖于libs
和common
的apps
。
我的问题是,如果我替换libs
和apps
中的GNUmakefile
,我不知道如何更改我在构建脚本中运行的命令,以便cmake和make像这样交织在一起:
- cmake配置
common
- 使编译&从
common
安装所有cmake目标(假设它们是libcommon.so和libcommonutils.so) - cmake配置
libs
- 使编译&安装
libs
中的所有cmake目标(使用common
中的库生成mylib.a
) - cmake配置
apps
- 使编译&安装
apps
(使用mylib.a
和common
共享库)中的所有cmake目标
安装include
也必须在早期的某个时刻进行,因为common
取决于其中的头文件
当然,另一种解决方案也可能有效,但这(将cmake和make调用交织在一起)是我唯一能想到的解决方案。
您可以将ExternalProject_add用于common
、libs
和apps
。
src/CMakeLists.txt:
ExternalProject_add(common
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/common
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/common
# Forward CMAKE_INSTALL_PREFIX to external project.
CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
)
ExternalProject_add(libs
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/libs
# Disable *install* step
INSTALL_COMMAND ""
)
ExternalProject_add(apps
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/apps
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/apps
# Disable *install* step
INSTALL_COMMAND ""
)
# Adjust dependencies between components
add_dependencies(libs common)
add_dependencies(apps libs common)
此脚本的使用(源代码外构建;也支持源代码内构建)
cmake -DCMAKE_INSTALL_PREFIX=<install-dir> <source-dir>
make
等同于以下命令序列:
mkdir src/common && cd src/common
&& cmake -DCMAKE_INSTALL_PREFIX=<install-dir> <source-dir>/src/common && make install
mkdir src/libs && cd src/libs && cmake <source-dir>/src/libs && make all
mkdir src/apps && cd src/apps && cmake <source-dir>/src/apps && make all
include
的处理没有实现,但您可以用类似的方式来实现。