В моем проекте я использую protobuf 3.5. Мне нужны как минимум конфигурации отладки и RelWithDebugInfo
. Чтобы иметь возможность собрать проект с отладочными библиотеками protobuf, возникли некоторые проблемы:
Мне нужно было собрать библиотеки protobuf из исходного кода, используя как релиз, так и цель отладки, поскольку _ITERATOR_DEBUG_LEVEL
моих библиотек (= 2
) не соответствовали уровню библиотек protobuf (= 0
). После сборки библиотек отладки, а также библиотек релизов, возможна компиляция в конфигурации отладки.
Теперь, после возврата на RelWithDebugInfo
я снова получаю ту же ошибку, но теперь как раз наоборот: _ITERATOR_DEBUG_LEVEL
моих библиотек - 0
, а уровень используемых библиотек protobuf - 2
.
При проверке конфигурации компоновщика я вижу, что мои библиотеки связаны с libprotobuf d .lib. Это имеет смысл, поскольку я где-то читал, что все, что является , а не Release
, будет использовать библиотеки отладки, если они доступны. И это приводит к моей проблеме:
Я не буду строить свои библиотеки в Release
во время разработки. Большую часть времени RelWithDebugInfo
. Но _ITERATOR_DEBUG_LEVEL
для этой конфигурации, очевидно, установлено на 0
(поскольку является конфигурацией выпуска с дополнительной информацией). Но затем CMake связывается с библиотеками отладки protobuf, которые не совместимы с остальными.
Сейчас я ищу возможность сказать CMake не использовать отладочную версию библиотек, а версию выпуска вместо без изменения сценариев CMake самого protobuf .
Обычно мой путь - связывать различные библиотеки в зависимости от фактической конфигурации сборки. Но, к сожалению, конфигурация 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 эффективно перезаписывает цель, я не знаю, как извлечь правильную библиотеку для каждой сборки.
Есть идеи?