I have the following project structure:
我有以下项目结构:
- CMakeLists.txt
- lib1/CMakeLists.txt and all cpp and header files of the lib
- lib2/CMakeLists.txt and all cpp and header files of the lib
- app/CMakeLists.txt and all cpp and header files of the app
lib1 / CMakeLists.txt以及lib的所有cpp和头文件
lib2 / CMakeLists.txt以及lib的所有cpp和头文件
app / CMakeLists.txt以及该应用的所有cpp和头文件
CMakeLists.txt lib1 / CMakeLists.txt以及lib lib2 / CMakeLists.txt的所有cpp和头文件以及lib app / CMakeLists.txt的所有cpp和头文件以及app的所有cpp和头文件
The main CMakeLists.txt looks like:
主CMakeLists.txt看起来像:
PROJECT( ${PROJECT_NAME} )
add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
The lib1/CMakeLists.txt looks eg like (stripped):
lib1 / CMakeLists.txt看起来像(剥离):
SET(SOURCE
file.cpp
)
SET(HEADERS
some_lib_header.h
)
add_library( lib1 ${SOURCE} ${HEADERS} )
and the one for the app looks the same except of ADD_EXECUTABLE:
除了ADD_EXECUTABLE之外,app的应用程序看起来相同:
SET(SOURCE
main.cpp
)
SET(HEADERS
some_header.h
)
add_library( lib1 ${SOURCE} ${HEADERS} )
ADD_EXECUTABLE( app ${SOURCE} ${HEADERS} )
I found the setup working well this way because out of this, I can generate one Visual Studio solution file which contains all those three projects. But my problem is that my app includes header files of lib1 (and also of lib2, which depends on lib1). When I do
我发现这个设置运行良好,因为我可以生成一个包含所有这三个项目的Visual Studio解决方案文件。但我的问题是我的应用程序包含lib1的头文件(以及lib2的头文件,它依赖于lib1)。当我做
$mkdir build
$cd build
$cmake -C ..\myproject
it generates out-of-source VS .sln file as I want it, but the app doesn't compile because it can't find the header files of lib1 (obviously).
它根据我的需要生成了源外VS.sln文件,但是app不能编译,因为它找不到lib1的头文件(显然)。
Now I read and tried many things, like TARGET_LINK_LIBRARIES( app lib1 )
(which got the app to link with the lib1, but not solve the header include issue), and things like add_subdirectory( ../lib1 )
in various variants in the CMakeLists.txt of app (which all throwed errors that I couldn't fix), and also find_package (which I guess is the wrong approach).
现在我阅读并尝试了很多东西,比如TARGET_LINK_LIBRARIES(应用程序lib1)(它让应用程序与lib1链接,但没有解决头部包含问题),以及类似于CMakeLists中各种变体的add_subdirectory(../lib1) app的.txt(这些都抛出了我无法解决的错误),还有find_package(我猜这是错误的方法)。
So how can I solve this (I guess simple...) problem?
那我怎么解决这个问题(我想简单......)问题呢?
2 个解决方案
#1
17
Here's one possible solution:
这是一个可能的解决方案:
Root CMakeLists.txt:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(${PROJECT_NAME})
add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
lib1/CMakeLists.txt:
project(Lib1)
add_library(lib1 lib1.cpp lib1.h)
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)
app/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)
There are plenty of different ways to achieve the same end result here. For a relatively small project, I'd probably just use a single CMakeLists.txt:
这里有很多不同的方法可以达到相同的最终结果。对于一个相对较小的项目,我可能只使用一个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)
For further info on the relevant commands and their rationale, run:
有关相关命令及其基本原理的更多信息,请运行:
cmake --help-command add_subdirectory
cmake --help-command include_directories
cmake --help-command target_link_libraries
#2
5
Project
CMakeLists.txt
\-lib1
CMakeLists.txt
\- include \ lib1
\- src
\-lib2
CMakeLists.txt
\- include \ lib2
\- src
\-app
CMakeLists.txt
\- src
Suppose dependencies as follow:
假设依赖关系如下:
lib1 ---> lib2 ---> app
\--------------> app
Something like this:
像这样的东西:
CMakeLists.txt:
add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
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)
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)
so in lib2/src/file.cpp you could do #include <lib1/header.hpp>
所以在lib2 / src / file.cpp中你可以做#include
app/CMakeLists.txt:
file(GLOB_RECURSE _SRCS "src/*.[hc]pp")
add_executable(app ${_SRCS})
target_link_libraries(app lib1 lib2)
install(TARGETS app DESTINATION bin)
so in app/src/file.cpp you could do #include <lib1/header.hpp>
and #include <lib2/header.hpp>
所以在app / src / file.cpp中你可以做#include
The magic is target_include_directories which attach the "include" directory to the target, so when linking with it you pull the include directory also ;)
神奇的是target_include_directories,它将“include”目录附加到目标,因此当与它链接时,你也可以拉取include目录;)
#1
17
Here's one possible solution:
这是一个可能的解决方案:
Root CMakeLists.txt:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(${PROJECT_NAME})
add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
lib1/CMakeLists.txt:
project(Lib1)
add_library(lib1 lib1.cpp lib1.h)
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)
app/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)
There are plenty of different ways to achieve the same end result here. For a relatively small project, I'd probably just use a single CMakeLists.txt:
这里有很多不同的方法可以达到相同的最终结果。对于一个相对较小的项目,我可能只使用一个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)
For further info on the relevant commands and their rationale, run:
有关相关命令及其基本原理的更多信息,请运行:
cmake --help-command add_subdirectory
cmake --help-command include_directories
cmake --help-command target_link_libraries
#2
5
Project
CMakeLists.txt
\-lib1
CMakeLists.txt
\- include \ lib1
\- src
\-lib2
CMakeLists.txt
\- include \ lib2
\- src
\-app
CMakeLists.txt
\- src
Suppose dependencies as follow:
假设依赖关系如下:
lib1 ---> lib2 ---> app
\--------------> app
Something like this:
像这样的东西:
CMakeLists.txt:
add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
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)
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)
so in lib2/src/file.cpp you could do #include <lib1/header.hpp>
所以在lib2 / src / file.cpp中你可以做#include
app/CMakeLists.txt:
file(GLOB_RECURSE _SRCS "src/*.[hc]pp")
add_executable(app ${_SRCS})
target_link_libraries(app lib1 lib2)
install(TARGETS app DESTINATION bin)
so in app/src/file.cpp you could do #include <lib1/header.hpp>
and #include <lib2/header.hpp>
所以在app / src / file.cpp中你可以做#include
The magic is target_include_directories which attach the "include" directory to the target, so when linking with it you pull the include directory also ;)
神奇的是target_include_directories,它将“include”目录附加到目标,因此当与它链接时,你也可以拉取include目录;)