From fdaed322dfa84f735112792a0ab3d7d94690b14f Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Tue, 25 Mar 2025 19:33:53 +0000 Subject: [PATCH] Fix linking debug builds of C++ wrapper --- .cargo/msvcd-config.toml | 6 ++++++ cxx/CMakeLists.txt | 13 ++++++++----- cxx/README.md | 8 ++++++++ cxx/build.rs | 13 ++++++++++++- 4 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 .cargo/msvcd-config.toml diff --git a/.cargo/msvcd-config.toml b/.cargo/msvcd-config.toml new file mode 100644 index 00000000..c2632a08 --- /dev/null +++ b/.cargo/msvcd-config.toml @@ -0,0 +1,6 @@ +# Config for building the CXX wrapper against the debug MSVC runtime, so that it +# can be used from Debug builds of C++ code. +# From +[env] +CFLAGS = "/MDd" +CXXFLAGS = "/MDd" diff --git a/cxx/CMakeLists.txt b/cxx/CMakeLists.txt index e1c6de29..68e71ae3 100644 --- a/cxx/CMakeLists.txt +++ b/cxx/CMakeLists.txt @@ -27,8 +27,13 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) add_library(libloot-cxx STATIC IMPORTED) # TODO: Define the Rust libloot library path here for Linux builds. if(MSVC) - set_target_properties(libloot-cxx PROPERTIES IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/../target/release/libloot_cxx.lib") + set(LIBLOOT_CXX_FILENAME "libloot_cxx.lib") endif() + +set_target_properties(libloot-cxx PROPERTIES + IMPORTED_CONFIGURATIONS "Release;Debug" + IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/../target/release/${LIBLOOT_CXX_FILENAME}" + IMPORTED_LOCATION_DEBUG "${CMAKE_SOURCE_DIR}/../target/debug/${LIBLOOT_CXX_FILENAME}") target_include_directories(libloot-cxx INTERFACE "${CMAKE_SOURCE_DIR}/../target/cxxbridge") @@ -56,8 +61,7 @@ set(LIBLOOT_SRC_API_CPP_FILES "${CMAKE_SOURCE_DIR}/src/api/plugin.cpp" "${CMAKE_SOURCE_DIR}/src/api/sorting/cyclic_interaction_error.cpp" "${CMAKE_SOURCE_DIR}/src/api/sorting/undefined_group_error.cpp" - "${CMAKE_SOURCE_DIR}/src/api/vertex.cpp" - ) + "${CMAKE_SOURCE_DIR}/src/api/vertex.cpp") set(LIBLOOT_INCLUDE_H_FILES "${CMAKE_SOURCE_DIR}/include/loot/api.h" @@ -92,8 +96,7 @@ set(LIBLOOT_SRC_API_H_FILES "${CMAKE_SOURCE_DIR}/src/api/database.h" "${CMAKE_SOURCE_DIR}/src/api/exception.h" "${CMAKE_SOURCE_DIR}/src/api/game.h" - "${CMAKE_SOURCE_DIR}/src/api/plugin.h" - ) + "${CMAKE_SOURCE_DIR}/src/api/plugin.h") source_group(TREE "${CMAKE_SOURCE_DIR}/src/api" PREFIX "Source Files" diff --git a/cxx/README.md b/cxx/README.md index 86821ad0..ff19250a 100644 --- a/cxx/README.md +++ b/cxx/README.md @@ -17,6 +17,14 @@ cmake -B build . cmake --build build --config RelWithDebInfo ``` +Debug builds need a little extra config to get the static and shared libraries to use the same C runtime library on Windows. + +``` +cargo build --config ../.cargo/msvcd-config.toml +cmake -B build . +cmake --build build --config Debug +``` + This also builds a copy of the public API tests from C++ libloot v0.25.5, which can be run using: ``` diff --git a/cxx/build.rs b/cxx/build.rs index 92388cc9..833a7145 100644 --- a/cxx/build.rs +++ b/cxx/build.rs @@ -3,5 +3,16 @@ fn main() { .std("c++17") .compile("libloot-cxx"); - println!("cargo:rerun-if-changed=src/lib.rs"); + // From + if std::env::var("TARGET").is_ok_and(|s| s.contains("windows-msvc")) { + // MSVC compiler suite + if std::env::var("CFLAGS").is_ok_and(|s| s.contains("/MDd")) { + // debug runtime flag is set + + // Don't link the default CRT + println!("cargo::rustc-link-arg=/nodefaultlib:msvcrt"); + // Link the debug CRT instead + println!("cargo::rustc-link-arg=/defaultlib:msvcrtd"); + } + } }