CMake包含项目的依赖关系

时间:2015-07-29 10:43:24

标签: c++ msbuild cmake

我试图从基于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_A 的界面时,所有目标都会编译。当我添加标题(已通过 traget_include_directories 导出)时, Projekt_B_Interface 将不再链接。

MsBuild讲述 Projekt_B_Interface

ClCompile:
  C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\CL.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.dir\Debug\\" 
  /Fd"Projekt_B_Interface.dir\Debug\vc120.pdb" /Gd /TC /errorReport:queue 
  D:\Develop\CMake\TEST\Projekt_B\libr.c    
  libr.c
D:\Develop\CMake\TEST\Projekt_B\libr.c(2): fatal error C1083: Cannot open include file: 
'libinc.h': No such file or directory      
[D:\Develop\CMake\TEST\build\Projekt_B\Projekt_B_Interface.vcxproj]

在其他 Projekt_B _ * 项目中,它成功了:

ClCompile:
  C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\CL.exe 
  /c /ID:\Develop\CMake\TEST\Projekt_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.dir\Debug\\" 
  /Fd"Projekt_B_Public.dir\Debug\vc120.pdb" /Gd /TC /errorReport:queue 
  D:\Develop\CMake\TEST\Projekt_B\libr.c
  libr.c
Link:
  C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\link.exe 
  /ERRORREPORT:QUEUE /OUT:"D:\Develop\CMake\TEST\build\
  Projekt_B\Debug\Projekt_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_A\Debug\Projekt_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.dir\Debug\libr.obj
  Projekt_B_Public.vcxproj -> D:\Develop\CMake\TEST\build\Projekt_B\Debug\
  Projekt_B_Public.dll

我有什么想法可以得到类似的东西:

target_compile_libraries(Projekt_B HEADERS Projekt_A)

target_include_directoies 的内容听起来像......)

1 个答案:

答案 0 :(得分:0)

我认为我已经为这种情况找到了解决方案(无需在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)

这样就可以在构建环境中导出标题。在大型项目中非常有用。

我希望它能帮助别人!

干杯。