为项目创建Include-Dependencies

CMake Include-Dependencies for Projects

本文关键字:Include-Dependencies 创建 项目      更新时间:2023-10-16

我正试图从一个大型的基于Visual studio的项目(与静态,动态库,可执行文件)切换到CMake。它会工作得很好,但是由于许多静态库都有导出库(不需要将库链接到项目),我需要一种方法来包含项目的接口,只有,而不需要链接静态库。

:

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project(Test)
add_subdirectory(Projekt_B)
add_subdirectory(Projekt_A)

Projekt_A/CMakeLists.txt

add_library(Projekt_A 
    libraryContent.cpp
    libHeader.h
    libInterfaceOnly.h)
target_include_directories(Projekt_A PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})  
# could be **INTERFACE** as well

Projekt_B/CMakeLists.txt

add_library(Projekt_B_Public SHARED
    libraryContentB.cpp
    libHeaderB.h
)
add_library(Projekt_B_Private SHARED
    libraryContentB.cpp
    libHeaderB.h
)
add_library(Projekt_B_Interface SHARED
    libraryContentB.cpp
    libHeaderB.h
)
## this Line works but links Projekt_A 
target_link_libraries(Projekt_B_Public PUBLIC Projekt_A)
## this Line works too, but links Projekt_A to it without passing them on
target_link_libraries(Projekt_B_Private PRIVATE Projekt_A)
## this Line works **only** if no interface of A is used in B
target_link_libraries(Projekt_B_Interface INTERFACE Projekt_A)

因此,在Projekt_B_中使用Projekt_Ano接口时,所有目标都编译。当我包括一个头(已通过traget_include_directories导出),Projekt_B_Interface将不再链接。

MsBuild告诉for Projekt_B_Interface:

ClCompile:
  C:Program Files (x86)Microsoft Visual Studio 12.0VCbinamd64CL.exe 
  /c /Zi /nologo /W3 /WX- /Od /Ob0 /D WIN32 /D _WINDOWS /D _DEBUG /D 
  "CMAKE_INTDIR="Debug"" /D Projekt_B_Interface_EXPORTS /D _WINDLL /D 
  _MBCS /Gm- /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope 
  /Fo"Projekt_B_Interface.dirDebug\" 
  /Fd"Projekt_B_Interface.dirDebugvc120.pdb" /Gd /TC /errorReport:queue 
  D:DevelopCMakeTESTProjekt_Blibr.c    
  libr.c
D:DevelopCMakeTESTProjekt_Blibr.c(2): fatal error C1083: Cannot open include file: 
'libinc.h': No such file or directory      
[D:DevelopCMakeTESTbuildProjekt_BProjekt_B_Interface.vcxproj]

在其他Projekt_B_*项目中它是成功的:

ClCompile:
  C:Program Files (x86)Microsoft Visual Studio 12.0VCbinamd64CL.exe 
  /c /ID:DevelopCMakeTESTProjekt_A /Zi /nologo /W3 /WX- /Od /Ob0 /D 
  WIN32 /D _WINDOWS /D _DEBUG /D "CMAKE_INTDIR="Debug"" 
  /D Projekt_B_Public_EXPORTS /D _WINDLL /D _MBCS /Gm- /RTC1 /MDd /GS 
  /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Projekt_B_Public.dirDebug\" 
  /Fd"Projekt_B_Public.dirDebugvc120.pdb" /Gd /TC /errorReport:queue 
  D:DevelopCMakeTESTProjekt_Blibr.c
  libr.c
Link:
  C:Program Files (x86)Microsoft Visual Studio 12.0VCbinamd64link.exe 
  /ERRORREPORT:QUEUE /OUT:"D:DevelopCMakeTESTbuild
  Projekt_BDebugProjekt_B_Public.dll" /INCREMENTAL /NOLOGO 
  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib
  oleaut32.lib uuid.lib comdlg32.lib advapi32.lib 
  ..Projekt_ADebugProjekt_A.lib /MANIFEST 
  /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG
  /PDB:"D:/Develop/CMake/TEST/build/Projekt_B/Debug/Projekt_B_Public.pdb" 
  /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT     
  /IMPLIB:"D:/Develop/CMake/TEST/build/Projekt_B/Debug/Projekt_B_Public.lib" 
  /MACHINE:X64  /machine:x64 /debug /DLL Projekt_B_Public.dirDebuglibr.obj
  Projekt_B_Public.vcxproj -> D:DevelopCMakeTESTbuildProjekt_BDebug
  Projekt_B_Public.dll

你知道我怎样才能得到这样的东西吗?

target_compile_libraries(Projekt_B HEADERS Projekt_A)

(有些东西 target_include_directories 听起来像…)

我想我已经找到了解决这种情况的方法(不需要在CMake中设置变量):

Projekt_A/CMakeLists.txt:

...
# create a interface
add_library(IProjekt_A INTERFACE)
# add *export* headers to interface
target_include_directories(IProjekt_A INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
# bind interface to project itself (just in case)
target_link_libraries(Projekt_A INTERFACE IProjekt_A)

Projekt_B/CMakeLists.txt

...
# this will add includes *only* and reexports them within Projekt_B
target_link_libraries(Projekt_B PUBLIC IProjekt_A)
# this will add includes and library for link and reexport
target_link_libraries(Projekt_B PUBLIC Projekt_A)
# this will only add the includes for *this* project
target_link_libraries(Projekt_B PRIVATE IProjekt_A)

这使得在构建环境中导出头文件成为可能。在大型项目中非常有用

我希望它也能帮助别人!

欢呼。