Skip to content

[Feature] 支持目标平台条件下的 dialect_cxxflags(及可选的构建脚本接口) #717

Description

@julixian

需求

希望支持按目标平台声明 dialect_cxxflags,例如:

# 期望支持的写法
[target.windows.build]
dialect_cxxflags = ["-fms-runtime-lib=dll"]

该条件决定参数是否启用;一旦启用,参数仍应在当前目标模块图内保持一致,包括标准库 BMI、模块扫描和源码编译,而不是变成仅作用于单个包的普通编译选项。

背景及当前限制

  • 使用环境:Windows,mcpp 2026.9.26.2,LLVM 22.1.8。
  • 项目:GalTranslPP,使用 C++23 模块和 import std;。
  • 当前为使普通 clang++ 构建使用动态 MSVC CRT,项目在无条件的 [build] 中填写:
[build]
dialect_cxxflags = ["-fms-runtime-lib=dll"]

普通 cxxflags / mcpp::cxxflag() 不能等价替代:这个选项不在自动提升到 dialect 参数的名单中,不能据此保证同样传给标准库预编译。

按本地检出的源码 52549fbb2d17939e89efb1e05e0c2717bf30d96c 检查:

因此,平台条件下不能表达这个需求,项目只能暂时无条件传递平台专用参数。

无条件参数的跨平台影响:Clang 实测

以下是 Windows 主机上使用 LLVM 22.1.8 的目标切换测试,不是声称在 Linux/macOS 主机上完成了整个项目构建。源码不使用系统头文件,仅检查参数处理:

'int example;' | clang++ --target=x86_64-unknown-linux-gnu -x c++ -fsyntax-only -fms-runtime-lib=dll -
'int example;' | clang++ --target=arm64-apple-macosx14.0.0 -x c++ -fsyntax-only -fms-runtime-lib=dll -
'int example;' | clang++ --target=x86_64-unknown-linux-gnu -x c++ -fsyntax-only -fms-runtime-lib=dll -Werror -

前两条退出码为 0,但产生:

clang++: warning: argument unused during compilation: '-fms-runtime-lib=dll' [-Wunused-command-line-argument]

第三条退出码为 1,该警告变为错误。相同测试以 x86_64-pc-windows-msvc 为目标时没有此警告。

CRT 可以进一步通过专门的语义配置解决;这里希望解决的是通用的“只在匹配目标下启用模块图参数”的表达能力。

建议行为及验证点

  1. 在标准库 BMI 和目标编译命令生成前,合并匹配的平台条件。
  2. 生效参数统一到达目标标准库 BMI、模块扫描和当前模块图的相关 C++ 编译。
  3. 生效参数进入相关缓存标识,切换平台或参数时不复用不兼容的 BMI/对象。
  4. 明确 workspace 继承、根包与依赖包声明的作用范围,以及已知冲突的处理;依赖不能通过普通追加顺序静默改变整个图的配置。
  5. 非匹配平台不收到该参数,文档说明 [build]、平台条件与依赖声明的关系。

不限定实现必须把字段直接搬进 BuildInputs。其“追加式包输入”和“模块图统一配置”的边界值得保留,可以采用单独的条件配置结构。

可选:让作者考虑构建脚本接口

是否也提供类似以下接口,交由维护者判断,不要求与条件 TOML 支持同时实现:

// 提议的新 API,目前不是可用接口
if (std::string_view(mcpp::target_os()) == "windows") {
    mcpp::dialect_cxxflag("-fms-runtime-lib=dll");
}

如果提供,需要明确:

  • 判断的是目标平台,而非编译脚本的宿主平台;
  • 在目标模块图参数确定前收集,进入相同的验证和缓存机制;
  • 不追溯改变已经用于编译/运行 build.mcpp 的宿主标准库 BMI;
  • 根脚本与依赖脚本的权限和冲突规则。

相关讨论

Activity

  1. added a commit that references this issue on Sep 27, 2026
  2. added a commit that references this issue on Sep 27, 2026
  3. speak-agent commented on Sep 27, 2026

    @speak-agent
    Member

    Implemented in 2026.9.28.1 (#727).

    • The conditional key. [target.<selector>.build] dialect_cxxflags adds its arguments to the graph-wide dialect flags on a matching target. They reach the standard-library BMI prebuild, the module scan and every translation unit, after the root's unconditional [build] dialect_cxxflags.
    • Only the build's root package is read. A dependency's own graph-wide keys reach no command and do not enter its fingerprint (SPEC-004 §3.1, §9 item 10; docs/04).
    • An engine older than 2026.9.28.1 reports the key as unsupported and ignores it; it does not reject the manifest.

    For the specific use in the report (-fms-runtime-lib=dll), see #718. On the MSVC ABI that word is now the resolved model's own, so writing it is warned as redundant and cxx_runtime is the key that states it.

    Verification of the published release. A fresh SubOS sandbox (xlings subos use <name> --sandbox) with the CN mirror configured for both xlings and mcpp installed mcpp@2026.9.28.1 through the index and ran one script over the published binary: 13 ok, 0 failed (the Windows-only items are reported as not run). The same script in a second sandbox against mcpp@2026.9.27.1 reads 5 ok, 8 failed, so each assertion below measures this change rather than the setup it runs in.

    criterion 2026.9.28.1 2026.9.27.1
    [target.linux.build] dialect_cxxflags = ["-DX717=1"] reaches a unit that fails to compile without it ok build failed (unsupported key 'dialect_cxxflags' (ignored))

    e2e 813 covers the std BMI, the scan, a non-matching selector, the A-B-A reuse of the std cache, and a dependency's own key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions