Skip to content

fix: preserve conditional dialect flags in workspace build configurations #786

Description

@julixian

Reproduction

On mcpp 2026.10.5.3, create a workspace with one executable member. Put an architecture-specific dialect flag in the member manifest:

# root/mcpp.toml
[workspace]
members = ["app"]
# root/app/mcpp.toml
[package]
name = "app"
version = "0.1.0"
standard = "c++23"

[build]
sources = ["main.cpp"]

[targets.app]
kind = "bin"
main = "main.cpp"

[target.i686-windows-msvc.build]
dialect_cxxflags = ["-D__cpp_impl_coroutine=201902L"]

With Clang 23.1.3 and the MSVC 14.44 STL, run mcpp build -p app --target i686-windows-msvc. The std precompile command omits the macro and fails in <generator> with missing suspend_always and coroutine_handle. The same conditional dialect mechanism works in a standalone package. A platform-independent reproduction can use a matching platform selector and inspect a harmless -D flag in the std-module cache record and generated compiler commands.

Expected behavior

A selected workspace member's matching conditional dialect flags reach the graph configuration, std/std.compat precompilation, scanning and all C++ translation units. A nonmatching architecture contributes nothing. Members with different conditional graph configurations must not be grouped into a plan that silently takes only the first member's flags. Ordinary dependency dialect flags remain ignored.

Actual behavior and source analysis

select_workspace_members creates virtual_workspace_root before conditional configuration is evaluated. The virtual root copies only first.buildConfig.dialectCxxflags, dropping first.conditionalConfigs. Later conditional merging of the member cannot update the graph-wide root used for std precompilation. root_position_key also ignores conditional dialect declarations when grouping workspace members.

Starting the command inside the member does not bypass the issue: that entry point also uses workspace member selection.

Environment

  • mcpp 2026.10.5.3
  • Windows x64 host, i686-windows-msvc target
  • LLVM 23.1.3
  • MSVC 14.44.35207 / Windows SDK 10.0.26100.0

This is a workspace regression at the intersection of conditional dialect support (#717) and virtual workspace plans. It does not require changing the public manifest syntax or target-table inheritance policy.

Activity

  1. Sunrisepeak commented on Oct 8, 2026

    @Sunrisepeak
    Member

    Thanks for the report. The failure is real, and its cause is the compiler rather than the workspace path.

    clang 23 does not support C++20 coroutines on the 32-bit x86 Microsoft ABI. It no longer predefines __cpp_impl_coroutine for i686-pc-windows-msvc (clang 22.1.8 does; x86_64-pc-windows-msvc, i686-pc-windows-gnu and the Linux targets still do), and it reports code that uses coroutines there with -Wcoroutines-unsupported-target. The MSVC STL keys <coroutine> on that macro, so the header is empty on this target, and the C++23 std module stops inside <generator> — the error in this issue. Measured on probe PR #788 (MSVC 14.44 and 14.51 have the same guards).

    mcpp 2026.10.8.1 follows the compiler: it does not define the macro, and it appends a note to that failure (and to code that uses coroutines on this target) with the options:

    • build the package as C++20: import std and import std.compat build and run on i686-windows-msvc with clang 23.1.3;
    • or, optionally, name an LLVM that still enables coroutines for this target:
      [target.i686-windows-msvc]
      toolchain = "llvm@22.1.8"
      (the newer compiler treats coroutines on this ABI as unsupported, so code that uses them there is at your own risk).

    Defining __cpp_impl_coroutine through dialect_cxxflags switches on a feature the compiler has declared unsupported for this ABI, so we do not recommend it. See docs/20, "Known Toolchain Limitation: Coroutines on the 32-bit x86 Microsoft ABI".

    The workspace behaviour you describe — a virtual workspace root not carrying the selected member's conditional dialect_cxxflags, and root_position_key not including conditional declarations — is a separate, real defect. It is tracked here and will be handled on its own.

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