From c54de35120b85472a978a46cf46699a3c972195f Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Fri, 11 Sep 2026 14:12:01 +0500 Subject: [PATCH] cmake: add fallback configs for opencollada (similar to 05ba93ab6) add --- cmake/CMakeLists.txt | 17 +---------------- cmake/FindOpenCOLLADA.cmake | 1 + cmake/utilities.cmake | 27 +++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f1daa33078..bae0853745 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -326,22 +326,7 @@ if (WITH_ROCKSDB) else() message(FATAL_ERROR "RocksDB found but neither RocksDB::rocksdb nor RocksDB::rocksdb-shared target exists") endif() - # Our win/build-deps.py builds RocksDB separately per Debug/Release config into the - # same install prefix, so the imported target only ever has DEBUG and RELEASE listed in - # IMPORTED_CONFIGURATIONS. On a multi-config generator (Visual Studio), CMake maps any - # unmatched build config to the *first* entry of that list, which happens to be DEBUG - # (RocksDBTargets-debug.cmake sorts before RocksDBTargets-release.cmake). Without an - # explicit mapping, RelWithDebInfo and MinSizeRel builds would end up linking the - # /MDd-flavored rocksdb_d.lib into an /MD (NDEBUG) binary, causing a CRT/runtime-library - # mismatch that depends on nothing but that alphabetical ordering. - # - # Important: we're mixing up MinSizeRel to RelWithDebInfo targets and vice versa, because - # multi-config builds always define targets for each config and it has to be able to find a fallback, - # otherwise configuration would fail. - set_target_properties(${IFCOPENSHELL_ROCKSDB_IMPORTED_TARGET} PROPERTIES - MAP_IMPORTED_CONFIG_RELWITHDEBINFO "RELWITHDEBINFO;RELEASE;MINSIZEREL" - MAP_IMPORTED_CONFIG_MINSIZEREL "MINSIZEREL;RELEASE;RELWITHDEBINFO" - ) + avoid_debug_imported_config_fallback(${IFCOPENSHELL_ROCKSDB_IMPORTED_TARGET}) target_link_libraries(IFCOPENSHELL_RocksDB INTERFACE ${IFCOPENSHELL_ROCKSDB_IMPORTED_TARGET}) if (WITH_ZSTD) diff --git a/cmake/FindOpenCOLLADA.cmake b/cmake/FindOpenCOLLADA.cmake index 94b8fffd1a..e36770ed52 100644 --- a/cmake/FindOpenCOLLADA.cmake +++ b/cmake/FindOpenCOLLADA.cmake @@ -24,6 +24,7 @@ if(NOT OPENCOLLADA_INCLUDE_DIR AND NOT OPENCOLLADA_LIBRARY_DIR) if(OpenCOLLADA_DIR) message(STATUS "Found OpenCOLLADA: '${OpenCOLLADA_DIR}'.") set(OPENCOLLADA_FOUND TRUE) + avoid_debug_imported_config_fallback(${OPENCOLLADA_LIBRARIES}) else() message(STATUS "OpenCOLLADA package not found, falling back to manual search.") endif() diff --git a/cmake/utilities.cmake b/cmake/utilities.cmake index 732c3ddc6d..cfcd86edc7 100644 --- a/cmake/utilities.cmake +++ b/cmake/utilities.cmake @@ -254,6 +254,33 @@ function(get_debug_variant NAME LIBRARY POSTFIX) set(${NAME} "${LIBRARY}" PARENT_SCOPE) endfunction() +# When building specified config, cmake first tries to find target config by the exact match +# (e.g. to find `-relwithdebinfo.cmake` dependency for RelWithDebInfo build), +# but if it fails, it falls back to the first cmake config it can find, alphabetically. +# If there's a Debug config, then it ends up pulling Debug build as the default. +# Which is critical on Windows if dependency is using CRT - linking will fail due to a CRT mismatch. +# To resolve this, we allow `RelWithDebInfo`, `MinSizeRel` to fallback to `Release`. +# +# Especially important on a multi-config generator (e.g. Visual Studio), +# when cmake has to define targets for each possible config. +# Without this fallback, user would need to build each dependency for each of 4 configs +# to guarantee switching between them won't break. +# And in some cases it's not even possible (e.g. OpenCOLLADA hardcodes only Release/Debug builds). +# +# Important: we're mixing up MinSizeRel to RelWithDebInfo targets and vice versa, because +# by setting `MAP_IMPORTED_CONFIG_` we override the fallback, but multi-config builds +# has to be able to find a way to build a target for each config, otherwise configuration would fail. +function(avoid_debug_imported_config_fallback) + foreach(_target ${ARGN}) + if(TARGET ${_target}) + set_target_properties(${_target} PROPERTIES + MAP_IMPORTED_CONFIG_RELWITHDEBINFO "RELWITHDEBINFO;RELEASE;MINSIZEREL" + MAP_IMPORTED_CONFIG_MINSIZEREL "MINSIZEREL;RELEASE;RELWITHDEBINFO" + ) + endif() + endforeach() +endfunction() + function(files_for_ifc_version IFC_VERSION RESULT_NAME) set(IFC_PARSE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../src/ifcparse) set(${RESULT_NAME}