diff --git a/src/build/flags.cppm b/src/build/flags.cppm index f263706f..08fb435d 100644 --- a/src/build/flags.cppm +++ b/src/build/flags.cppm @@ -103,12 +103,8 @@ CompileFlags compute_flags(const BuildPlan& plan) { // override, the convention cargo/rustc/cc honor) > the manifest's // [build] macos_deployment_target (project default, SwiftPM-style) > // empty (toolchain/SDK default). - std::string macosDeploymentTarget; - if (const char* dt = std::getenv("MACOSX_DEPLOYMENT_TARGET"); dt && *dt) { - macosDeploymentTarget = dt; - } else { - macosDeploymentTarget = plan.manifest.buildConfig.macosDeploymentTarget; - } + std::string macosDeploymentTarget = mcpp::platform::macos::deployment_target( + plan.manifest.buildConfig.macosDeploymentTarget); f.cxxBinary = plan.toolchain.binaryPath; f.ccBinary = mcpp::toolchain::derive_c_compiler(plan.toolchain); diff --git a/src/cli.cppm b/src/cli.cppm index b1bc6d57..d5707259 100644 --- a/src/cli.cppm +++ b/src/cli.cppm @@ -602,12 +602,8 @@ std::string canonical_compile_flags(const mcpp::manifest::Manifest& m) { // Centralize the resolution in one helper, then re-land. // See xlings .agents/docs/2026-06-05-macos-min-version-support.md §5. if constexpr (mcpp::platform::is_macos) { - std::string dtv; - if (const char* dt = std::getenv("MACOSX_DEPLOYMENT_TARGET"); dt && *dt) { - dtv = dt; - } else { - dtv = m.buildConfig.macosDeploymentTarget; - } + auto dtv = mcpp::platform::macos::deployment_target( + m.buildConfig.macosDeploymentTarget); if (!dtv.empty()) { s += " macos_deployment_target="; s += dtv; @@ -3334,7 +3330,9 @@ prepare_build(bool print_fingerprint, std::filesystem::path stdCompatObjectPath; if (needsStdModule) { auto sm = mcpp::toolchain::ensure_built( - *tc, fp.hex, m->package.standard, m->cppStandard.flag); + *tc, fp.hex, m->package.standard, m->cppStandard.flag, + mcpp::platform::macos::deployment_target( + m->buildConfig.macosDeploymentTarget)); if (!sm) return std::unexpected(sm.error().message); stdBmiPath = sm->bmiPath; stdObjectPath = sm->objectPath; diff --git a/src/platform/macos.cppm b/src/platform/macos.cppm index 32b7d19b..c0cf6073 100644 --- a/src/platform/macos.cppm +++ b/src/platform/macos.cppm @@ -32,7 +32,28 @@ bool has_xcode_clt(); // Returns the SDK path if found, or nullopt. std::optional sdk_path(); +// Resolve the effective macOS deployment target: the +// MACOSX_DEPLOYMENT_TARGET env var (explicit per-invocation override, +// the convention cargo/rustc/cc honor) wins over `manifestValue` (the +// [build] macos_deployment_target project default); empty means +// toolchain/SDK default. THE single source of truth — flags.cppm, the +// BMI fingerprint rule and the std-module prebuild must all consume +// this same resolution, or cached std.pcm modules drift from the TUs +// (config-mismatch / unstaged-module failures observed on macos CI). +std::string deployment_target(std::string_view manifestValue); + // Return macOS-specific runtime library directories for LLVM toolchains. +std::string deployment_target(std::string_view manifestValue) { +#if defined(__APPLE__) + if (const char* dt = std::getenv("MACOSX_DEPLOYMENT_TARGET"); dt && *dt) + return dt; + return std::string(manifestValue); +#else + (void)manifestValue; + return {}; +#endif +} + std::vector runtime_lib_dirs(const std::filesystem::path& toolchain_root); diff --git a/src/toolchain/stdmod.cppm b/src/toolchain/stdmod.cppm index eb1edbbf..8389a769 100644 --- a/src/toolchain/stdmod.cppm +++ b/src/toolchain/stdmod.cppm @@ -45,11 +45,16 @@ struct StdModError { std::string message; }; std::filesystem::path default_cache_root(); // Build std module if not already cached. Returns paths to BMI + object. +// `macos_deployment_target` is the RESOLVED value from +// platform::macos::deployment_target() — it must match what flags.cppm +// emits for normal TUs, or the produced std.pcm targets a different +// arm64-apple-macosxNN triple than the code importing it. std::expected ensure_built( const Toolchain& tc, std::string_view fingerprint_hex, std::string_view cpp_standard, std::string_view cpp_standard_flag, + std::string_view macos_deployment_target = {}, const std::filesystem::path& cache_root = default_cache_root()); } // namespace mcpp::toolchain @@ -174,6 +179,7 @@ std::expected ensure_built( std::string_view fingerprint_hex, std::string_view cpp_standard, std::string_view cpp_standard_flag, + std::string_view macos_deployment_target, const std::filesystem::path& cache_root) { if (tc.stdModuleSource.empty()) { @@ -253,6 +259,13 @@ std::expected ensure_built( add_inc(tc.payloadPaths->linuxInclude); } + // Deployment target must mirror what flags.cppm emits for normal TUs + // (single resolver: platform::macos::deployment_target). + if (!macos_deployment_target.empty()) { + sysroot_flag += std::format(" -mmacosx-version-min={}", + macos_deployment_target); + } + std::vector stdCommands; if (is_clang(tc)) { stdCommands = mcpp::toolchain::clang::std_module_build_commands(