首页 > 解决方案 > cmake 外部(git)项目作为依赖项

问题描述

项目1

├── CMakeLists.txt
├── config
│       └── download-project2.cmake.in
└── cmake
        └── project2.cmake

项目1->配置->下载-proeject2.cmake.in

cmake_minimum_required(VERSION 3.13)

project(proeject2-download NONE)

include(ExternalProject)
ExternalProject_Add(
    galToolbox_utils
    GIT_REPOSITORY    https://github.com/xxx/proeject2.git
    GIT_TAG           master
    SOURCE_DIR        "${CMAKE_CURRENT_BINARY_DIR}/proeject2-src"
    BINARY_DIR        "${CMAKE_CURRENT_BINARY_DIR}/proeject2-build"
    CONFIGURE_COMMAND ""
    BUILD_COMMAND     ""
    INSTALL_COMMAND   ""
    TEST_COMMAND      ""
)

project1 -> cmake -> proeject2.cmake

configure_file(${CONFIG_PATH}/galToolbox_utils-config.cmake.in galToolbox_utils-download/CMakeLists.txt)

execute_process(
        COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
        RESULT_VARIABLE result-proeject2
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/proeject2-download
)
if(result-proeject2)
    message(FATAL_ERROR "CMake step for download proeject2 failed: ${result-proeject2}")
endif()

execute_process(COMMAND ${CMAKE_COMMAND} --build .
        RESULT_VARIABLE result-proeject2
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/proeject2-download
)
if(result-proeject2)
    message(FATAL_ERROR "Build step for proeject2 failed: ${result-proeject2}")
endif()

add_subdirectory(
        ${CMAKE_CURRENT_BINARY_DIR}/proeject2-src
        ${CMAKE_CURRENT_BINARY_DIR}/proeject2-build
        EXCLUDE_FROM_ALL
)

项目 1 -> CMakeLists.txt

// exposition only below, the content is not complete.
project(project1)

include(project2.cmake) ## download project

add_library(${PROJECT_NAME} INTERFACE)

target_include_directories(
        ${PROJECT_NAME}
        INTERFACE
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include/${PROJECT_NAME}>
)

target_compile_options(
        ${PROJECT_NAME}
        INTERFACE
        $<$<CXX_COMPILER_ID:MSVC>:/std:c++latest /W4 /WX>
        $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-std=c++2a -Wall -Wextra -Wpedantic -Werror>
)

#--- Package
include(CMakePackageConfigHelpers)

string(TOLOWER ${PROJECT_NAME} PACKAGE_NAME)

write_basic_package_version_file(
        ${PROJECT_BINARY_DIR}/cmake/${PACKAGE_NAME}-config-version.cmake
        VERSION ${VERSION}
        COMPATIBILITY AnyNewerVersion
)

install(
        TARGETS ${PROJECT_NAME}
        EXPORT ${PROJECT_NAME}-targets
        ARCHIVE DESTINATION lib
        LIBRARY DESTINATION lib
        RUNTIME DESTINATION bin
)

configure_package_config_file(
        ${CONFIG_PATH}/${PROJECT_NAME}-config.cmake.in
        ${PROJECT_BINARY_DIR}/cmake/${PACKAGE_NAME}-config.cmake
        INSTALL_DESTINATION cmake/}
)

install(
        EXPORT ${PROJECT_NAME}-targets
        FILE ${PROJECT_NAME}-targets.cmake
        NAMESPACE gal::
        DESTINATION cmake/
)

install(
        FILES ${GALTOOLBOX_LIBRARY_HEADERS}
        DESTINATION include/${PROJECT_NAME}
)

install(
        FILES
        ${PROJECT_BINARY_DIR}/cmake/${PACKAGE_NAME}-config.cmake
        ${PROJECT_BINARY_DIR}/cmake/${PACKAGE_NAME}-config-version.cmake
        DESTINATION cmake/
)

项目2

├── CMakeLists.txt
└── include
        └── utils # (include all utils header files, such as foo.hpp, bar.hpp)

项目 2 -> CMakeLists.txt

cmake_minimum_required(VERSION 3.13)

project(
        project2
        LANGUAGES CXX
)

add_library(${PROJECT_NAME} INTERFACE)

target_include_directories(
        ${PROJECT_NAME}
        INTERFACE
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include/${PROJECT_NAME}>
)

target_compile_options(
        ${PROJECT_NAME}
        INTERFACE
        $<$<CXX_COMPILER_ID:MSVC>:/std:c++latest /W4 /WX>
        $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-std=c++2a -Wall -Wextra -Wpedantic -Werror>
)

# there should be errors or incomplete content (need help)
install(
        TARGETS ${PROJECT_NAME}
        EXPORT ${PROJECT_NAME}-target
)

project2属于a complete small project,完成a的功能certain direction (as utils)。(还有很多其他的小项目)

project1没有实现任何功能,只是组装这些小项目(就像一个工具箱)。(并安装googletest并测试这些组件的功能)

所有小项目的结构都和project2一样,所以一旦安装了project1(组装所有项目的总项目),就可以简单的使用

#include <utils/balabala>
#include <foo/balabala>
#include <bar/balabala>

假设project1的名字是PRJ,那么其他所有小项目的命名规则都是PRJ-$(functions)。并且希望大家只要安装好project1,就可以使用其他所有小项目的功能。

但是前面提到过,project2也应该单独使用,安装的名称应该使用project1(而不是project2),小项目之间有依赖关系。(毕竟没有 utils 就没有这样的项目,对吧?)

现在的问题是我好像不能使用project2的内容,怎么办?

浏览问题:

从外部项目中获取变量和选项

Git 项目的 CMake 外部项目

...

标签: c++gitcmakeprojectexternal

解决方案


推荐阅读