如何将'target_sources'命令与INTERFACE库一起使用? [英] How to use 'target_sources' command with INTERFACE library?
问题描述
我的项目按子目录组织(一打),子目录之间有一些包含项.其中一些子目录仅包含头文件(例如,dir1).
这是该项目的组织结构:
项目|| ----- src-dir1<-仅标头的库||| --- dir1.h||| --- CMakeLists.txt||||||-dir2||| --- dir2.cpp||| --- dir2.h||| --- CMakeLists.txt||||-file.h||--- CMakeLists.txt||| ----- test-dir1-test.cpp||---- dir2-test.cpp||---- includeFile.h||| ----- CMakeLists.txt
我想拥有一个包含src目录中所有代码的库以及一个用于运行单元测试的可执行文件.在对stackOverFlow和Cmake示例进行了一些研究之后,我来到了这些CMake文件.每个src子目录只有一个makefile,一个用于将所有库分组,一个用于全局.
dir1 CMakeLists
add_library(dir1接口)target_sources(dir1接口dir1.h)target_include_directories(dir1接口"$ {PROJECT_SOURCE_DIR}/src/dir1")
dir2 CMakeLists
set(dir2_srcdir2.cpp dir2.h)add_library(dir2 $ {dir2_src})
src CMakeLists
add_subdirectory(dir1)add_subdirectory(dir2)add_library(TheProject INTERFACE)target_sources(The Project INTERFACE file.h)target_include_directories(The Project INTERFACE"$ {PROJECT_SOURCE_DIR}/src/")target_link_libraries(项目接口dir1目录2$ {Boost_LIBRARIES})
主要CMakeLists.txt
project(TheProject)#gtest# 促进#编译标志...#######包含路径include_directories("./src/")include_directories($ {Boost_INCLUDE_DIRS})#######库进行编译add_subdirectory(src)#######可执行文件文件(GLOB SRCS utest/*/*.cpp)add_executable(estest $ {SRCS} test/includeFile.h)target_link_libraries(utest gtest_main TheProject)
我几乎在较小的项目上使用了相同的组织,而没有标头库和INTERFACE,它起作用了.在这里,我对不同的接口库有错误:
CMakeLists.txt:88(add_executable)上的 CMake错误:找不到源文件:文件.h尝试扩展名.c .C .c ++ .cc .cpp .cxx .m .M .mm .h .hh .h ++ .hm .hpp.hxx .in .txx
我认为我对接口的用法不太了解.我已经做了一些研究,但是没有解决我的问题的地方.
我还有几个问题:
- 目录之间存在某些依赖关系(例如dir1中的代码包含一些dir2文件),我是否应该在其cmake文件中指定这些依赖关系(使用target_link_libraries(dir2 dir1))?
- 在代码中,include是在src和utest中用相对路径指定的,使用"dir1/dir1.h"之类的路径是否更好?
相对路径,传递给 target_sources
的路径,与进一步的调用相关> add_executable
(或 add_library
).
由于您从顶层目录调用 add_executable()
,因此CMake相对于顶层目录而不是相对于 src/来搜索
test.h
代码>一个.
对 target_sources
调用使用绝对路径:
target_sources(项目接口$ {CMAKE_CURRENT_SOURCE_DIR}/file.h)
由于CMake 3.13传递到 target_sources
的相对路径会相对于 current 源目录立即得到解析.参见 @markhc的答案.
My project is organized in subdirectories (a dozen), there are some includes between subdirectories. Some of these subdirectories contains only header files (dir1 for example).
Here is a look at the organization of the project:
project
|
|----- src -- dir1 <-- header-only library
| | |--- dir1.h
| | |--- CMakeLists.txt
| |
| |
| | --- dir2
| | |--- dir2.cpp
| | |--- dir2.h
| | |--- CMakeLists.txt
| |
| | --- file.h
| | --- CMakeLists.txt
|
|
|----- test -- dir1 -- test.cpp
| | ---- dir2 -- test.cpp
| | ---- includeFile.h
|
|
|----- CMakeLists.txt
I want to have a library containing all the code from src directory and an executable to run unit tests. After some research on stackOverFlow and Cmake examples, I arrived to these CMake files. There is one makefile per src subdirectories, one for grouping all the library and one global.
dir1 CMakeLists
add_library(dir1 INTERFACE)
target_sources(dir1 INTERFACE dir1.h)
target_include_directories(dir1 INTERFACE
"${PROJECT_SOURCE_DIR}/src/dir1"
)
dir2 CMakeLists
set(dir2_src
dir2.cpp dir2.h
)
add_library(dir2 ${dir2_src})
src CMakeLists
add_subdirectory(dir1)
add_subdirectory(dir2)
add_library(TheProject INTERFACE)
target_sources(TheProject INTERFACE file.h)
target_include_directories(TheProject INTERFACE
"${PROJECT_SOURCE_DIR}/src/"
)
target_link_libraries(TheProject INTERFACE dir1
dir2
${Boost_LIBRARIES})
main CMakeLists.txt
project(TheProject)
# gtest
# boost
# compilation flags ...
####### include paths
include_directories("./src/")
include_directories(${Boost_INCLUDE_DIRS})
####### library to compile
add_subdirectory(src)
####### executable
file(GLOB SRCS utest/*/*.cpp)
add_executable(utest ${SRCS} test/includeFile.h)
target_link_libraries(utest gtest_main TheProject)
I almost used the same organization on a smaller project without header only libraries and INTERFACE and it worked. Here, I have an error with the different interface libraries:
CMake Error at CMakeLists.txt:88 (add_executable):
Cannot find source file:
file.h
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
I think I have not well understood the use of INTERFACE. I have done some research but nothing solve my problem.
And I have also a few questions:
- There is some dependancies between directories, (e.g. code in dir1 has an include of some dir2 files), should I specify these dependance in their cmake file (with target_link_libraries(dir2 dir1)) ?
- In the code, include are specified with relative paths in src and utest, is it not better to use paths like "dir1/dir1.h"?
Relative paths, passed to target_sources
, are interpreted relative to further invocations of add_executable
(or add_library
).
Because you call add_executable()
from the top directory, CMake searches test.h
relative to the top directory, not relative to the src/
one.
Use absolute paths for target_sources
calls:
target_sources(TheProject INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/file.h)
Since CMake 3.13 relative paths passed to target_sources
are resolved immediately, relative the current source directory. See @markhc's answer.
这篇关于如何将'target_sources'命令与INTERFACE库一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!