在我的项目中,我使用的是protobuf 3.5。我至少需要调试和RelWithDebugInfo
配置。为了能够使用protobuf调试库构建项目,仅产生了一些问题:
我需要使用发布和调试目标从源代码构建protobuf库,因为我的库(_ITERATOR_DEBUG_LEVEL
)的= 2
与protobuf库(= 0
)的级别不匹配。在构建调试库以及发布库之后,可以在调试配置中进行编译。
现在,在改回RelWithDebugInfo
后,我再次得到同样的错误,但现在正好相反:我的库的_ITERATOR_DEBUG_LEVEL
是0
,使用的protobuf库的级别是2
。
检查链接器配置时,我可以看到我的库与libprotobufd.lib链接。这是有道理的,因为我已经读过某些不是Release
的东西将使用调试库,如果可用的话。这导致了我的问题:
我不会在开发过程中在Release
中构建我的库。大部分时间都是RelWithDebugInfo
。但是这个配置的_ITERATOR_DEBUG_LEVEL
显然设置为0
(因为它是一个带有附加信息的发布配置)。但是CMake然后链接到protobuf的调试库,这些库与其余的不兼容。
我现在正在寻找一种可能性,告诉CMake不使用库的调试版本,而是使用发布版本而不更改protobuf本身的CMake脚本。
通常我的方法是link different libraries取决于实际的构建配置。但不幸的是,protobuf CMake配置试图自己处理这个问题。
# Load information for each installed configuration.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/protobuf-targets-*.cmake")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
而进口目标是 覆盖 根据实际配置选择:
protobuf的靶点,release.cmake:
# Import target "protobuf::libprotobuf-lite" for configuration "Release"
set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libprotobuf-lite.lib"
)
protobuf的靶点,debug.cmake:
# Import target "protobuf::libprotobuf-lite" for configuration "Debug"
set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/libprotobuf-lited.lib"
)
而我的CMakeLists.txt中的链接如下所示:
target_link_libraries(${PROJECT_NAME} PRIVATE
protobuf::libprotobuf
protobuf::libprotoc
)
我认为没有任何可能指定所需的库。通常我会说我会以某种方式指定它:
target_link_libraries(MyEXE
debug protobuf::libprotobufd optimized protobuf::libprotobuf
debug protobuf::libprotocd optimized protobuf::libprotoc)
或者为它周围的不同构建配置包装一些花哨的if条件。但是由于protobuf有效地覆盖了目标,我不知道如何为每个构建提取正确的库。
有任何想法吗?
我现在正在寻找一种可能性,告诉CMake不要使用库的调试版本,而是使用发布版本
变量CMAKE_MAP_IMPORTED_CONFIG_旨在解决这个问题:
# When build your project in RelWithDebugInfo configuration,
# try to use Release configuration of the *IMPORTED* libraries.
# If some IMPORTED library has no Release configuration, fallback to Debug one.
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBUGINFO Release Debug)
# Imported targets set with given call will be aware of the variable's set above
find_package(Protobuf REQUIRED)
# Simply link with an IMPORTED library.
target_link_libraries(MyExe protobuf::libprotobuf)
如果您只想使用特定IMPORTED库中的Release配置,而不是全部,则可以为这些特定库设置相应的属性:
# Firstly, create needed IMPORTED target.
find_package(Protobuf REQUIRED)
# Then adjust its properties.
# While the target is created by others, given property is specifically
# designed to be set in *your project*.
set_property(TARGET protobuf::libprotobuf PROPERTY MAP_IMPORTED_CONFIG_RELWITHDEBUGINFO Release Debug)
# Simply link with an IMPORTED library.
target_link_libraries(MyExe protobuf::libprotobuf)