CMake的:如何建立外部项目,包括他们的目标(CMake: How to build extern

2019-07-20 20:20发布

我有一个出口静态库作为目标的一个项目:

install(TARGETS alib DESTINATION lib EXPORT project_a-targets)
install(EXPORT project_a-targets DESTINATION lib/alib)

现在,我想用一个项目从项目B外部项目,包括其内置的目标:

ExternalProject_Add(project_a
  URL ...project_a.tar.gz
  PREFIX ${CMAKE_CURRENT_BINARY_DIR}/project_a
  CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
)

include(${CMAKE_CURRENT_BINARY_DIR}/lib/project_a/project_a-targets.cmake)

问题是,包括运行项目B的CMakeLists当文件尚不存在。

有没有一种方法,使包括依赖于外部项目正在兴建?

更新 :我写了一个简短的CMake通过实例教程在此基础上,我遇到的其他常见问题。

Answer 1:

我觉得你在这里混淆了两个不同的范式。

正如你提到的,高度灵活的ExternalProject模块运行在编译的时候它的命令,所以你不能直接使用A计划的导入文件的,因为一旦一个项目已经安装它不仅创造。

如果要include项目A的导入文件,你就必须调用项目B的的CMakeLists.txt之前手动安装Project A -就像任何其他第三方的依赖性增加这种方式或通过find_file / find_library / find_package

如果你想利用ExternalProject_Add ,你需要添加类似以下到您的CMakeLists.txt:

ExternalProject_Add(project_a
  URL ...project_a.tar.gz
  PREFIX ${CMAKE_CURRENT_BINARY_DIR}/project_a
  CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
)

include(${CMAKE_CURRENT_BINARY_DIR}/lib/project_a/project_a-targets.cmake)

ExternalProject_Get_Property(project_a install_dir)
include_directories(${install_dir}/include)

add_dependencies(project_b_exe project_a)
target_link_libraries(project_b_exe ${install_dir}/lib/alib.lib)


Answer 2:

这篇文章有一个合理的答案:

CMakeLists.txt.in

cmake_minimum_required(VERSION 2.8.2)

project(googletest-download NONE)

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

CMakeLists.txt

# Download and unpack googletest at configure time
configure_file(CMakeLists.txt.in
               googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download )
execute_process(COMMAND ${CMAKE_COMMAND} --build .
  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download )

# Prevent GoogleTest from overriding our compiler/linker options
# when building with Visual Studio
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

# Add googletest directly to our build. This adds
# the following targets: gtest, gtest_main, gmock
# and gmock_main
add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src
                 ${CMAKE_BINARY_DIR}/googletest-build)

# The gtest/gmock targets carry header search path
# dependencies automatically when using CMake 2.8.11 or
# later. Otherwise we have to add them here ourselves.
if (CMAKE_VERSION VERSION_LESS 2.8.11)
  include_directories("${gtest_SOURCE_DIR}/include"
                      "${gmock_SOURCE_DIR}/include")
endif()

# Now simply link your own targets against gtest, gmock,
# etc. as appropriate

然而它似乎相当哈克。 我想提出一个替代的解决方案 - 使用Git的子模块。

cd MyProject/dependencies/gtest
git submodule add https://github.com/google/googletest.git
cd googletest
git checkout release-1.8.0
cd ../../..
git add *
git commit -m "Add googletest"

然后在MyProject/dependencies/gtest/CMakeList.txt你可以这样做:

cmake_minimum_required(VERSION 3.3)

if(TARGET gtest) # To avoid diamond dependencies; may not be necessary depending on you project.
    return()
endif()

add_subdirectory("googletest")

我还没有试过这种广泛但但它似乎更清洁。

编辑:有一个缺点这种方法:子目录可能会遇到install()命令,你不想要的。 这篇文章有禁用它们的方法 ,但它是越野车,对我没有工作。

编辑2:如果您使用add_subdirectory("googletest" EXCLUDE_FROM_ALL)似乎是指install()中不使用默认的子目录命令。



Answer 3:

您也可以强制从属目标的构建在二级make进程

见我的回答对相关主题。



Answer 4:

你可以尝试做的是使用的cmake的出口的内命令project_a 。 它的工作原理有点不同,然后使用install用命令EXPORT option ,它会产生一个你project_a-targets.cmake运行cmake的时候文件。 在内部生成的进口目标project_a-targets.cmake文件指向最初项目的二进制文件目录中没有现有的库文件,这些文件只有你运行构建命令后产生。

为了更好地理解我在说什么,只需创建一个用于创建一个简单的库,然后导出命令(下面的代码没有经过测试)小cmake的项目:

add_library (project_a lib.cpp)
export (
  TARGETS 
    project_a
  FILE
    project_a-targets.cmake
)

您简单的例子运行cmake的命令后,你应该能够找到project_a-targets.cmake您的二进制文件目录中(或它的子文件夹中的一个下)。 检查的文件,你可能会发现,它目前指向没有现有的库文件。 只有运行构建命令后,将图书馆在那里。

所以回到你的问题,你将需要更新project-aCMakeLists.txt到包括export命令。 然后,你需要确保后ExternalProject_Add被处理,它调用的配置步骤,这将产生project_a-targets.cmake ,那么你就可以调用include(.../project_a-targets.cmake)应该工作。 最后,您将需要添加之间的依赖project_bproject_a因此,它迫使project_a试图建立之前,要建project_b



文章来源: CMake: How to build external projects and include their targets