CMake - 同一项目中的应用程序/库之间的依赖关系(标头)

Ela*_*782 17 c++ dependencies cmake header-files visual-studio-2010

我有以下项目结构:

  • 的CMakeLists.txt
    • lib1/CMakeLists.txt以及lib的所有cpp和头文件
    • lib2/CMakeLists.txt以及lib的所有cpp和头文件
    • app/CMakeLists.txt以及该应用的所有cpp和头文件

主要的CMakeLists.txt看起来像:

PROJECT( ${PROJECT_NAME} )
add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
Run Code Online (Sandbox Code Playgroud)

lib1/CMakeLists.txt看起来像(剥离):

SET(SOURCE
file.cpp
)
SET(HEADERS
    some_lib_header.h
)
add_library( lib1 ${SOURCE} ${HEADERS} )
Run Code Online (Sandbox Code Playgroud)

除了ADD_EXECUTABLE之外,app的应用程序看起来相同:

SET(SOURCE
main.cpp
)
SET(HEADERS
    some_header.h
)
add_library( lib1 ${SOURCE} ${HEADERS} )
ADD_EXECUTABLE( app ${SOURCE} ${HEADERS} )
Run Code Online (Sandbox Code Playgroud)

我发现这个设置运行良好,因为我可以生成一个包含所有这三个项目的Visual Studio解决方案文件.但我的问题是我的应用程序包含lib1的头文件(以及lib2的头文件,它依赖于lib1).当我做

$mkdir build
$cd build
$cmake -C ..\myproject
Run Code Online (Sandbox Code Playgroud)

它会根据我的需要生成源外VS.sln文件,但是应用程序无法编译,因为它无法找到lib1的头文件(显然).

现在我阅读并尝试了很多东西,比如TARGET_LINK_LIBRARIES( app lib1 )(它让应用程序与lib1链接,但没有解决头部包含问题),以及add_subdirectory( ../lib1 )各种变体,如应用程序的CMakeLists.txt(这些都抛出了我无法解决的错误)不修复,还有find_package(我猜这是错误的方法).

那么如何解决这个问题(我想简单......)问题呢?

Fra*_*ser 18

这是一个可能的解决方案:

Root CMakeLists.txt:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(${PROJECT_NAME})
add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
Run Code Online (Sandbox Code Playgroud)


LIB1 /的CMakeLists.txt:

project(Lib1)
add_library(lib1 lib1.cpp lib1.h)
Run Code Online (Sandbox Code Playgroud)


LIB2 /的CMakeLists.txt:

project(Lib2)
add_library(lib2 lib2.cpp lib2.h)

# Add /lib1 to #include search path
include_directories(${Lib1_SOURCE_DIR})
# Specify lib2's dependency on lib1
target_link_libraries(lib2 lib1)
Run Code Online (Sandbox Code Playgroud)


应用程序/的CMakeLists.txt:

project(App)
add_executable(app main.cpp some_header.h)

# Add /lib1 and /lib2 to #include search path
include_directories(${Lib1_SOURCE_DIR} ${Lib2_SOURCE_DIR})
# Specify app's dependency on lib2.
# lib2's dependency on lib1 is automatically added.
target_link_libraries(app lib2)
Run Code Online (Sandbox Code Playgroud)


这里有很多不同的方法可以达到相同的最终结果.对于一个相对较小的项目,我可能只使用一个CMakeLists.txt:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(Test)

add_library(lib1 lib1/lib1.cpp lib1/lib1.h)
add_library(lib2 lib2/lib2.cpp lib2/lib2.h)
add_executable(app app/main.cpp app/some_header.h)

include_directories(${CMAKE_SOURCE_DIR}/lib1 ${CMAKE_SOURCE_DIR}/lib2)

target_link_libraries(lib2 lib1)
target_link_libraries(app lib2)
Run Code Online (Sandbox Code Playgroud)


有关相关命令及其基本原理的更多信息,请运行:

cmake --help-command add_subdirectory
cmake --help-command include_directories
cmake --help-command target_link_libraries
Run Code Online (Sandbox Code Playgroud)


Miz*_*zux 5

Project
 CMakeLists.txt
 \-lib1
   CMakeLists.txt
   \- include \ lib1
   \- src
 \-lib2
   CMakeLists.txt
   \- include \ lib2
   \- src
 \-app
   CMakeLists.txt
   \- src
Run Code Online (Sandbox Code Playgroud)

假设依赖关系如下:

lib1 ---> lib2 ---> app 
   \--------------> app
Run Code Online (Sandbox Code Playgroud)

像这样的东西:

的CMakeLists.txt:

add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
Run Code Online (Sandbox Code Playgroud)

LIB1 /的CMakeLists.txt:

  file(GLOB_RECURSE _HDRS "include/*.hpp")
  file(GLOB_RECURSE _SRCS "src/*.[hc]pp")
  add_library(lib1 ${_HDRS} ${_SRCS})
  #target_link_libraries(lib1)
  target_include_directories(lib1 PUBLIC include)

  install(TARGETS lib1 DESTINATION lib)
  install(FILES ${_HDRS} DESTINATION include/lib1)
Run Code Online (Sandbox Code Playgroud)

LIB2 /的CMakeLists.txt:

  file(GLOB_RECURSE _HDRS "include/*.hpp")
  file(GLOB_RECURSE _SRCS "src/*.[hc]pp")
  add_library(lib2 ${_HDRS} ${_SRCS})
  target_link_libraries(lib2 lib1)
  target_include_directories(lib2 PUBLIC include)

  install(TARGETS lib2 DESTINATION lib)
  install(FILES ${_HDRS} DESTINATION include/lib2)
Run Code Online (Sandbox Code Playgroud)

所以在lib2/src/file.cpp中你可以做到 #include <lib1/header.hpp>

应用程序/的CMakeLists.txt:

  file(GLOB_RECURSE _SRCS "src/*.[hc]pp")
  add_executable(app ${_SRCS})
  target_link_libraries(app lib1 lib2)

  install(TARGETS app DESTINATION bin)
Run Code Online (Sandbox Code Playgroud)

所以在应用/ src目录/ file.cpp你可以做#include <lib1/header.hpp>#include <lib2/header.hpp>

神奇的是target_include_directories,它将"include"目录附加到目标,因此当与它链接时,你也可以拉取include目录;)