如何将'target_sources'命令与INTERFACE库一起使用? [英] How to use 'target_sources' command with INTERFACE library?

查看:67
本文介绍了如何将'target_sources'命令与INTERFACE库一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目按子目录组织(一打),子目录之间有一些包含项.其中一些子目录仅包含头文件(例如,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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆