情况:
cmake_minimum_required(VERSION 3.0)
project(Test)
add_subdirectory(Projekt_B)
add_subdirectory(Projekt_A)
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
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 的内容听起来像......)
答案 0 :(得分:0)
我认为我已经为这种情况找到了解决方案(无需在CMake中设置变量):
...
# 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)
...
# 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)
这样就可以在构建环境中导出标题。在大型项目中非常有用。
我希望它能帮助别人!
干杯。