Skip to content

Export C++20 requirement to CMake consumers - #3971

Merged
zcbenz merged 1 commit into
ml-explore:mainfrom
PhysicistJohn:draft/cpu-jit-cxx20
Aug 4, 2026
Merged

Export C++20 requirement to CMake consumers#3971
zcbenz merged 1 commit into
ml-explore:mainfrom
PhysicistJohn:draft/cpu-jit-cxx20

Conversation

@PhysicistJohn

@PhysicistJohn PhysicistJohn commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Proposed changes

MLX's installed public C++ headers use C++20 defaulted comparisons in
Device and Stream, but the exported CMake target does not advertise that
requirement.

This exports cxx_std_20 to CMake C++ consumers, aligns the three shipped
external CMake examples, and removes the stale, non-transitive
CXX_STANDARD 17 property from the installed target configuration.

Runtime CPU JIT and compiled-preamble compilation remain on C++17.

Validation

  • An installed-package consumer declaring C++17 inherited -std=c++20,
    linked, and ran
  • A strict C++17 include-only probe fails at mlx/device.h:28; the same probe
    passes under C++20
  • All three external CMake examples configured and built; the sample ran and
    the extension imported
  • CPU-only Release: 244/244 native cases and 3,238/3,238 assertions
  • Static Metal Release: 260/260 native cases and 3,490/3,490 assertions
  • CPU JIT remains on g++ -std=c++17; native compile coverage passed 31/31
    cases and 136/136 assertions
  • pre-commit run --all-files and git diff --check passed

Checklist

  • I have read the CONTRIBUTING document
  • I have run pre-commit run --all-files to format my code / installed pre-commit prior to committing changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the necessary documentation (if needed)

@zcbenz zcbenz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The project requiring C++20 does not mean all the dependents would also need C++20 to use it.

@zcbenz zcbenz closed this Aug 3, 2026
@PhysicistJohn

Copy link
Copy Markdown
Contributor Author

Agreed that MLX being built as C++20 does not, by itself, make C++20 a downstream usage requirement. Let's table the JIT/preamble question for now.

Setting that aside, the current installed public interface raises a separate, narrow usage-requirement question. At this PR's base, mlx/device.h contains:

bool operator==(const Device&) const = default;

That form of defaulted comparison requires C++20. mlx/device.h is included by mlx/mlx.h, and the package installs these public headers.

An include-only probe against the exact base commit:

printf '#include "mlx/device.h"\n' |
  clang++ -std=c++17 -pedantic-errors -I. -x c++ -fsyntax-only -

fails at device.h:28 with defaulted comparison operators are a C++20 extension; the same probe passes under C++20. Plain Apple Clang accepts it in C++17 mode as an extension, so this is specifically a standard-conforming/portable C++17 issue.

CMake's compile-feature model uses PUBLIC or INTERFACE requirements when a library's public interface requires a feature, including when a compiler happens to accept it as an extension.

That appears to leave two coherent downstream contracts:

  1. If portable C++17 consumers are supported, these public comparisons need C++17-compatible implementations and the C++17 examples should test that contract strictly.
  2. If the public headers remain as written, the exported target should advertise cxx_std_20; INTERFACE would be sufficient for that narrower purpose.

Which contract is intended? Any follow-up can be scoped specifically to that decision, leaving JIT/preamble out.

@zcbenz

zcbenz commented Aug 3, 2026

Copy link
Copy Markdown
Member

That's a valid point thanks for clarification. I agree we should require C++20 since device.h uses the feature, but we should still not require C++20 for JIT compilation which is not yet available in many client machines.

@zcbenz zcbenz reopened this Aug 3, 2026
@PhysicistJohn

Copy link
Copy Markdown
Contributor Author

Thanks, understood. The distinction between the installed public C++ interface and the runtime JIT compiler makes sense.

I will narrow this PR to the public usage requirement: export cxx_std_20 through the target interface, retain only the consumer-facing CMake/example cleanup, and remove the JIT/preamble changes and associated regression test. I will also update the title, description, and validation to match that scope.

@PhysicistJohn PhysicistJohn changed the title Complete the C++20 compiler migration Export C++20 requirement to CMake consumers Aug 3, 2026

@zcbenz zcbenz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Advertise cxx_std_20 through the installed target interface because public headers use C++20 defaulted comparisons.

Align the shipped external CMake examples and remove stale C++17 target metadata while leaving runtime JIT and preamble compilation on C++17.
@zcbenz
zcbenz force-pushed the draft/cpu-jit-cxx20 branch from 30a683b to 98c6a2f Compare August 4, 2026 06:27
@zcbenz
zcbenz merged commit 2448298 into ml-explore:main Aug 4, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants