CMake Include-Dependencies 项目
CMake Include-Dependencies for Projects
我正在尝试从大型 Visual Studio-based 项目(带有静态、动态库、可执行文件)切换到 CMake。它会工作得很好,但由于许多静态库都有导出库(不需要 link 将库添加到项目中),我需要一种方法来包含项目的 接口 仅 没有 linking 静态库。
情况:
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_A 的接口在 [=66 中使用时,所有目标都会编译=]。当我包含 header(已通过 traget_include_directories 导出)时,Projekt_B_Interface 不会t link 了。
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 听起来像...)
我想我已经找到了解决这种情况的方法(不需要在 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)
这使得在 构建环境中导出 headers 成为可能。在大型项目中非常有用。
我希望它也能帮助到其他人!
干杯。
我正在尝试从大型 Visual Studio-based 项目(带有静态、动态库、可执行文件)切换到 CMake。它会工作得很好,但由于许多静态库都有导出库(不需要 link 将库添加到项目中),我需要一种方法来包含项目的 接口 仅 没有 linking 静态库。
情况:
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_A 的接口在 [=66 中使用时,所有目标都会编译=]。当我包含 header(已通过 traget_include_directories 导出)时,Projekt_B_Interface 不会t link 了。
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 听起来像...)
我想我已经找到了解决这种情况的方法(不需要在 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)
这使得在 构建环境中导出 headers 成为可能。在大型项目中非常有用。
我希望它也能帮助到其他人!
干杯。