From 0a07d5c8b5294b71b03d9abefcb318dd783d2f6e Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 1 Dec 2025 19:31:37 +0800 Subject: [PATCH 01/40] tests: migrate deprecated std::is_trivial_v --- tests/proxy_reflection_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/proxy_reflection_tests.cpp b/tests/proxy_reflection_tests.cpp index 2041e9a2..633de66a 100644 --- a/tests/proxy_reflection_tests.cpp +++ b/tests/proxy_reflection_tests.cpp @@ -17,7 +17,7 @@ struct TraitsReflector { is_copy_constructible_(std::is_copy_constructible_v), is_nothrow_move_constructible_(std::is_nothrow_move_constructible_v), is_nothrow_destructible_(std::is_nothrow_destructible_v), - is_trivial_(std::is_trivial_v) {} + is_trivial_(std::is_trivially_default_constructible_v && std::is_trivially_copyable_v) {} template struct accessor { From 9904bdd15d194d5c03e56fbd4a284d55c56c4e85 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 1 Dec 2025 19:35:12 +0800 Subject: [PATCH 02/40] tools: add python typings --- tools/extract_example_code_from_docs.py | 67 ++++++++++++++++--------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/tools/extract_example_code_from_docs.py b/tools/extract_example_code_from_docs.py index 405c1dcf..18d2a387 100644 --- a/tools/extract_example_code_from_docs.py +++ b/tools/extract_example_code_from_docs.py @@ -1,42 +1,63 @@ -import os +#!/usr/bin/env python3 +# pyright: strict + import re -import sys +from pathlib import Path + +EXAMPLE_PATTERN = re.compile(r"## Example\r?\n\r?\n```cpp\r?\n(.*?)\r?\n```", re.DOTALL) -def extract_cpp_code(md_path, cpp_path): - with open(md_path, 'r', encoding='utf-8') as f: + +def extract_cpp_code(md_path: Path, cpp_path: Path) -> None: + with open(md_path, "r", encoding="utf-8") as f: content = f.read() - pattern = r'## Example\r?\n\r?\n```cpp\r?\n(.*?)\r?\n```' - code_blocks = re.findall(pattern, content, re.DOTALL) + code_blocks: list[str] = re.findall(EXAMPLE_PATTERN, content) if len(code_blocks) == 0: return # No match, skip elif len(code_blocks) > 1: - raise ValueError(f"File '{md_path}' contains more than one '## Example' C++ code block.") + msg = f"File '{md_path}' contains more than one '## Example' C++ code block." + raise ValueError(msg) cpp_code = code_blocks[0] - header = f"// This file was auto-generated from:\n// {md_path}\n\n" + header = f""" +// This file was auto-generated from: +// {md_path} + +""".lstrip() - with open(cpp_path, 'w', encoding='utf-8') as out: - out.write(header) - out.write(cpp_code) + with open(cpp_path, "w", encoding="utf-8") as out: + _ = out.write(header) + _ = out.write(cpp_code) -def main(): - if len(sys.argv) != 3: - print("Usage: python extract_example_code_from_docs.py ") - sys.exit(1) - input_dir = sys.argv[1] - output_dir = sys.argv[2] +def main() -> None: + import argparse + import os + from dataclasses import dataclass + + @dataclass(frozen=True) + class Args: + input_dir: Path + output_dir: Path + + parser = argparse.ArgumentParser() + _ = parser.add_argument("input_dir", type=Path, help="Path to Markdown documents") + _ = parser.add_argument("output_dir", type=Path, help="Source code output path") + args = parser.parse_args(namespace=Args) + + input_dir = args.input_dir + output_dir = args.output_dir for root, _, files in os.walk(input_dir): for file in files: - if file.endswith('.md'): - md_path = os.path.join(root, file) - rel_path = os.path.relpath(md_path, input_dir) - rel_base = os.path.splitext(rel_path)[0].replace(os.sep, '_') - cpp_path = os.path.join(output_dir, f"example_{rel_base}.cpp") + if file.endswith(".md"): + md_path = Path(root) / file + rel_path = md_path.relative_to(input_dir) + rel_base = "_".join([*rel_path.parent.parts, rel_path.stem]) + cpp_path = output_dir / f"example_{rel_base}.cpp" extract_cpp_code(md_path, cpp_path) -if __name__ == '__main__': + +if __name__ == "__main__": main() From b33dc01a528499392766e420e855a9d0708aa506 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 1 Dec 2025 22:00:31 +0800 Subject: [PATCH 03/40] build: support meson build system CMake feature parity: - [x] Export meson target - [x] Export meson c++20 modules target - [ ] Export cmake target - [x] Installing headers - [x] Googletest support - [x] Freestanding tests - [x] Modules tests - [x] Google Benchmark support - [x] Extract examples from docs Extra features: - [x] Export pkgconfig target - [x] clang-format support - [x] Make fmtlib optional when building examples - [x] Install documents to docdir Tested on Fedora Linux 44 (gcc/clang/msvc-wine + ninja) and Windows 10 22H2 (msvc + vs2022). --- .gitignore | 4 + benchmarks/meson.build | 68 +++++++ docs/example.cpp.in | 4 + docs/meson.build | 176 ++++++++++++++++ meson.build | 124 +++++++++++ meson.format | 4 + meson.options | 35 ++++ subprojects/fmt.wrap | 13 ++ subprojects/google-benchmark.wrap | 13 ++ subprojects/gtest.wrap | 16 ++ tests/meson.build | 328 ++++++++++++++++++++++++++++++ tests/modules/meson.build | 14 ++ 12 files changed, 799 insertions(+) create mode 100644 benchmarks/meson.build create mode 100644 docs/example.cpp.in create mode 100644 docs/meson.build create mode 100644 meson.build create mode 100644 meson.format create mode 100644 meson.options create mode 100644 subprojects/fmt.wrap create mode 100644 subprojects/google-benchmark.wrap create mode 100644 subprojects/gtest.wrap create mode 100644 tests/meson.build create mode 100644 tests/modules/meson.build diff --git a/.gitignore b/.gitignore index 631c2447..6b46461b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ # Ignore build directories build/ Testing/ + +# Meson subprojects +/subprojects/* +!/subprojects/*.wrap diff --git a/benchmarks/meson.build b/benchmarks/meson.build new file mode 100644 index 00000000..e4170d4d --- /dev/null +++ b/benchmarks/meson.build @@ -0,0 +1,68 @@ +benchmarks_exe = executable( + 'msft_proxy_benchmarks', + files( + 'proxy_creation_benchmark.cpp', + 'proxy_operation_benchmark.cpp', + 'proxy_operation_benchmark_context.cpp', + ), + implicit_include_directories: false, + dependencies: [msft_proxy4_dep, benchmark_dep], + build_by_default: false, +) + +# manually written, list all benchmarks with: +# builddir/benchmarks/msft_proxy_benchmarks --benchmark_list_tests +benchmarks = { + 'ObjectCreation': [ + 'BM_SmallObjectCreationWithProxy', + 'BM_SmallObjectCreationWithProxy_Shared', + 'BM_SmallObjectCreationWithProxy_SharedPooled', + 'BM_SmallObjectCreationWithUniquePtr', + 'BM_SmallObjectCreationWithSharedPtr', + 'BM_SmallObjectCreationWithSharedPtr_Pooled', + 'BM_SmallObjectCreationWithAny', + 'BM_LargeObjectCreationWithProxy', + 'BM_LargeObjectCreationWithProxy_Pooled', + 'BM_LargeObjectCreationWithProxy_Shared', + 'BM_LargeObjectCreationWithProxy_SharedPooled', + 'BM_LargeObjectCreationWithUniquePtr', + 'BM_LargeObjectCreationWithSharedPtr', + 'BM_LargeObjectCreationWithSharedPtr_Pooled', + 'BM_LargeObjectCreationWithAny', + ], + 'ObjectInvocation': [ + 'BM_SmallObjectInvocationViaProxy', + 'BM_SmallObjectInvocationViaProxy_Shared', + 'BM_SmallObjectInvocationViaProxyView', + 'BM_SmallObjectInvocationViaVirtualFunction', + 'BM_SmallObjectInvocationViaVirtualFunction_Shared', + 'BM_SmallObjectInvocationViaVirtualFunction_RawPtr', + 'BM_LargeObjectInvocationViaProxy', + 'BM_LargeObjectInvocationViaProxy_Shared', + 'BM_LargeObjectInvocationViaProxyView', + 'BM_LargeObjectInvocationViaVirtualFunction', + 'BM_LargeObjectInvocationViaVirtualFunction_Shared', + 'BM_LargeObjectInvocationViaVirtualFunction_RawPtr', + ], + 'ObjectOperation': [ + 'BM_SmallObjectRelocationViaProxy', + 'BM_SmallObjectRelocationViaProxy_NothrowRelocatable', + 'BM_SmallObjectRelocationViaUniquePtr', + 'BM_SmallObjectRelocationViaAny', + 'BM_LargeObjectRelocationViaProxy', + 'BM_LargeObjectRelocationViaProxy_NothrowRelocatable', + 'BM_LargeObjectRelocationViaUniquePtr', + 'BM_LargeObjectRelocationViaAny', + ], +} + +foreach suite : benchmarks.keys() + foreach name : benchmarks[suite] + benchmark( + name, + benchmarks_exe, + args: [f'--benchmark_filter=^@name@$'], + suite: suite, + ) + endforeach +endforeach diff --git a/docs/example.cpp.in b/docs/example.cpp.in new file mode 100644 index 00000000..1f228572 --- /dev/null +++ b/docs/example.cpp.in @@ -0,0 +1,4 @@ +// This file was auto-generated from: +// @MD_PATH@ + +@CODE@ diff --git a/docs/meson.build b/docs/meson.build new file mode 100644 index 00000000..f3437f81 --- /dev/null +++ b/docs/meson.build @@ -0,0 +1,176 @@ +fs = import('fs') + +maybe_fmt_dep = dependency( + 'fmt', + version: fmt_spec, + required: false, + disabler: true, +) + +# glob **.md +docs = [ + 'README.md', + 'faq.md', + 'modules_support.md', + 'spec/PRO_DEF_FREE_AS_MEM_DISPATCH.md', + 'spec/PRO_DEF_FREE_DISPATCH.md', + 'spec/PRO_DEF_MEM_DISPATCH.md', + 'spec/ProAccessible.md', + 'spec/ProBasicConvention.md', + 'spec/ProBasicFacade.md', + 'spec/ProBasicReflection.md', + 'spec/ProConvention.md', + 'spec/ProDispatch.md', + 'spec/ProFacade.md', + 'spec/ProOverload.md', + 'spec/ProReflection.md', + 'spec/README.md', + 'spec/allocate_proxy.md', + 'spec/allocate_proxy_shared.md', + 'spec/bad_proxy_cast.md', + 'spec/basic_facade_builder/README.md', + 'spec/basic_facade_builder/add_convention.md', + 'spec/basic_facade_builder/add_facade.md', + 'spec/basic_facade_builder/add_reflection.md', + 'spec/basic_facade_builder/add_skill.md', + 'spec/basic_facade_builder/build.md', + 'spec/basic_facade_builder/restrict_layout.md', + 'spec/basic_facade_builder/support_copy.md', + 'spec/basic_facade_builder/support_destruction.md', + 'spec/basic_facade_builder/support_relocation.md', + 'spec/constraint_level.md', + 'spec/explicit_conversion_dispatch/README.md', + 'spec/explicit_conversion_dispatch/accessor.md', + 'spec/explicit_conversion_dispatch/operator_call.md', + 'spec/facade.md', + 'spec/facade_aware_overload_t.md', + 'spec/implicit_conversion_dispatch/README.md', + 'spec/implicit_conversion_dispatch/accessor.md', + 'spec/implicit_conversion_dispatch/operator_call.md', + 'spec/inplace_proxiable_target.md', + 'spec/is_bitwise_trivially_relocatable.md', + 'spec/make_proxy.md', + 'spec/make_proxy_inplace.md', + 'spec/make_proxy_shared.md', + 'spec/make_proxy_view.md', + 'spec/msft_lib_proxy.md', + 'spec/not_implemented.md', + 'spec/operator_dispatch/README.md', + 'spec/operator_dispatch/accessor.md', + 'spec/operator_dispatch/operator_call.md', + 'spec/proxiable.md', + 'spec/proxiable_target.md', + 'spec/proxy/README.md', + 'spec/proxy/assignment.md', + 'spec/proxy/constructor.md', + 'spec/proxy/destructor.md', + 'spec/proxy/emplace.md', + 'spec/proxy/friend_operator_equality.md', + 'spec/proxy/friend_swap.md', + 'spec/proxy/indirection.md', + 'spec/proxy/operator_bool.md', + 'spec/proxy/reset.md', + 'spec/proxy/swap.md', + 'spec/proxy_indirect_accessor.md', + 'spec/proxy_invoke.md', + 'spec/proxy_reflect.md', + 'spec/proxy_view.md', + 'spec/skills_as_view.md', + 'spec/skills_as_weak.md', + 'spec/skills_fmt_format.md', + 'spec/skills_format.md', + 'spec/skills_rtti/README.md', + 'spec/skills_rtti/proxy_cast.md', + 'spec/skills_rtti/proxy_typeid.md', + 'spec/skills_slim.md', + 'spec/substitution_dispatch/README.md', + 'spec/substitution_dispatch/accessor.md', + 'spec/substitution_dispatch/operator_call.md', + 'spec/weak_dispatch/README.md', + 'spec/weak_dispatch/operator_call.md', + 'spec/weak_proxy.md', +] + +docdir = get_option('docdir') +if docdir == '' + docdir = get_option('datadir') / 'doc' / meson.project_name() +endif +install_data( + docs, + follow_symlinks: true, + install_dir: docdir, + preserve_path: true, + install_tag: 'docs', +) + +examples = [] + +foreach doc : docs + code = '' + deps = [msft_proxy4_dep] + + state = 0 + lines = fs.read(doc).splitlines() + foreach line : lines + if state == 0 + if line.contains('## Example') + if code != '' + error( + 'File', + doc, + 'contains more than one "## Example" C++ code block.', + ) + endif + state = 1 + endif + elif state == 1 + if line == '' + state = 2 + else + state = 0 + endif + elif state == 2 + if line == '```cpp' + state = 3 + else + state = 0 + endif + elif state == 3 + if line != '```' + if line.contains('') + deps += maybe_fmt_dep + endif + code += line + '\n' + else + code = code.substring(0, -1) + state = 0 + endif + endif + endforeach + if code != '' + cfg = { + 'MD_PATH': 'docs' / doc, + 'CODE': code, + } + name = doc.replace('/', '_').substring(0, -3) + example_exe = executable( + f'example_@name@', + configure_file( + configuration: cfg, + input: 'example.cpp.in', + output: f'example_@name@.cpp', + ), + implicit_include_directories: false, + dependencies: deps, + build_by_default: false, + ) + examples += example_exe + test( + name, + example_exe, + suite: 'ProxyExamples', + ) + endif +endforeach + +alias_target('examples', examples) diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..15879caf --- /dev/null +++ b/meson.build @@ -0,0 +1,124 @@ +project( + 'msft_proxy4', + 'cpp', + version: '4.0.1', + license: 'MIT', + license_files: 'LICENSE', + meson_version: '>=1.3', + default_options: { + 'cpp_std': ['vc++latest', 'c++26', 'c++23', 'c++20'], + 'warning_level': '3', + }, +) + +cxx = meson.get_compiler('cpp') + +inc = include_directories('include') + +hdrs = files( + 'include/proxy/proxy.h', + 'include/proxy/proxy_fmt.h', + 'include/proxy/proxy_macros.h', +) +hdrs_v4 = files( + 'include/proxy/v4/proxy.h', + 'include/proxy/v4/proxy_fmt.h', + 'include/proxy/v4/proxy_macros.h', +) +hdrs_mod = files('include/proxy/v4/proxy.ixx') + +msft_proxy4_dep = declare_dependency( + sources: hdrs + hdrs_v4, + include_directories: inc, +) +modules = get_option('modules') +modules_interface_spec = { + 'gcc': { + 'flags': ['-fmodules', '-fdeps-format=p1689r5'], + 'check_only': ['-M'], + }, + 'msvc': { + 'flags': ['/interface'], + }, +}[cxx.get_argument_syntax()] +if cxx.has_multi_arguments( + modules_interface_spec.get('flags'), + modules_interface_spec.get('check_only', []), + required: modules, +) + modules_interface_cflags = modules_interface_spec['flags'] + msft_proxy4_mod = declare_dependency( + include_directories: inc, + dependencies: msft_proxy4_dep, + link_with: static_library( + 'msft_proxy4_module', + hdrs_mod, + include_directories: inc, + cpp_args: modules_interface_cflags, + implicit_include_directories: false, + build_by_default: true, + ), + ) +else + modules_interface_cflags = [] + msft_proxy4_mod = disabler() +endif + +install_headers( + hdrs, + subdir: 'proxy', +) +install_headers( + hdrs_v4, + subdir: 'proxy/v4', +) +install_headers( + hdrs_mod, + subdir: 'proxy/v4', +) +pkgconfig = import( + 'pkgconfig', + required: false, +) +if pkgconfig.found() + pkgconfig.generate( + name: meson.project_name(), + description: 'Next Generation Polymorphism in C++', + url: 'https://microsoft.github.io/proxy/', + ) +endif + +meson.override_dependency(meson.project_name(), msft_proxy4_dep) +meson.override_dependency(meson.project_name() + '_module', msft_proxy4_mod) + +tests = get_option('tests') +gtest_dep = dependency( + 'gtest_main', + main: true, + required: tests, +) +fmt_spec = ['>=6.1.0'] +fmt_dep = dependency( + 'fmt', + version: fmt_spec, + required: tests, +) +subdir( + 'tests', + if_found: [gtest_dep, fmt_dep], +) + +benchmarks = get_option('benchmarks') +benchmark_dep = dependency( + 'benchmark_main', + required: benchmarks, +) +subdir( + 'benchmarks', + if_found: benchmark_dep, +) + +examples = get_option('examples').disable_auto_if(meson.is_subproject()) +if examples.allowed() + subdir('docs') +endif diff --git a/meson.format b/meson.format new file mode 100644 index 00000000..66e2f726 --- /dev/null +++ b/meson.format @@ -0,0 +1,4 @@ +indent_by=' ' +end_of_line=lf +insert_final_newline=true +kwargs_force_multiline=true diff --git a/meson.options b/meson.options new file mode 100644 index 00000000..2d88e8ed --- /dev/null +++ b/meson.options @@ -0,0 +1,35 @@ +option( + 'tests', + type: 'feature', + value: 'auto', + description: 'Build tests', +) +option( + 'tests_freestanding', + type: 'feature', + value: 'auto', + description: 'Build freestanding tests', +) +option( + 'benchmarks', + type: 'feature', + value: 'auto', + description: 'Build benchmarks', +) +option( + 'examples', + type: 'feature', + value: 'auto', + description: 'Extract and build examples from docs', +) +option( + 'modules', + type: 'feature', + value: 'auto', + description: 'Build with C++ modules support', +) +option( + 'docdir', + type: 'string', + description: 'Documentation directory', +) diff --git a/subprojects/fmt.wrap b/subprojects/fmt.wrap new file mode 100644 index 00000000..7e9c5c42 --- /dev/null +++ b/subprojects/fmt.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = fmt-12.0.0 +source_url = https://github.com/fmtlib/fmt/archive/12.0.0.tar.gz +source_filename = fmt-12.0.0.tar.gz +source_hash = aa3e8fbb6a0066c03454434add1f1fc23299e85758ceec0d7d2d974431481e40 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/fmt_12.0.0-1/fmt-12.0.0.tar.gz +patch_filename = fmt_12.0.0-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/fmt_12.0.0-1/get_patch +patch_hash = 307f288ebf3850abf2f0c50ac1fb07de97df9538d39146d802f3c0d6cada8998 +wrapdb_version = 12.0.0-1 + +[provide] +dependency_names = fmt diff --git a/subprojects/google-benchmark.wrap b/subprojects/google-benchmark.wrap new file mode 100644 index 00000000..7e2e6e73 --- /dev/null +++ b/subprojects/google-benchmark.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = benchmark-1.8.4 +source_url = https://github.com/google/benchmark/archive/refs/tags/v1.8.4.tar.gz +source_filename = benchmark-1.8.4.tar.gz +source_hash = 3e7059b6b11fb1bbe28e33e02519398ca94c1818874ebed18e504dc6f709be45 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/google-benchmark_1.8.4-5/benchmark-1.8.4.tar.gz +patch_filename = google-benchmark_1.8.4-5_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/google-benchmark_1.8.4-5/get_patch +patch_hash = 671ffed65f1e95e8c20edb7a06eb54476797e58169160b255f52dc71f4b83957 +wrapdb_version = 1.8.4-5 + +[provide] +dependency_names = benchmark, benchmark_main diff --git a/subprojects/gtest.wrap b/subprojects/gtest.wrap new file mode 100644 index 00000000..9902a4f7 --- /dev/null +++ b/subprojects/gtest.wrap @@ -0,0 +1,16 @@ +[wrap-file] +directory = googletest-1.17.0 +source_url = https://github.com/google/googletest/archive/refs/tags/v1.17.0.tar.gz +source_filename = googletest-1.17.0.tar.gz +source_hash = 65fab701d9829d38cb77c14acdc431d2108bfdbf8979e40eb8ae567edf10b27c +patch_filename = gtest_1.17.0-4_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/gtest_1.17.0-4/get_patch +patch_hash = 3abf7662d09db706453a5b064a1e914678c74b9d9b0b19382747ca561d0d8750 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/gtest_1.17.0-4/googletest-1.17.0.tar.gz +wrapdb_version = 1.17.0-4 + +[provide] +gtest = gtest_dep +gtest_main = gtest_main_dep +gmock = gmock_dep +gmock_main = gmock_main_dep diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..48475163 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,328 @@ +tests_exe = executable( + 'msft_proxy_tests', + files( + 'proxy_creation_tests.cpp', + 'proxy_dispatch_tests.cpp', + 'proxy_fmt_format_tests.cpp', + 'proxy_format_tests.cpp', + 'proxy_integration_tests.cpp', + 'proxy_invocation_tests.cpp', + 'proxy_lifetime_tests.cpp', + 'proxy_reflection_tests.cpp', + 'proxy_regression_tests.cpp', + 'proxy_rtti_tests.cpp', + 'proxy_traits_tests.cpp', + 'proxy_view_tests.cpp', + ), + implicit_include_directories: false, + dependencies: [msft_proxy4_dep, gtest_dep, fmt_dep], + build_by_default: false, +) + +# to generate this, run: +# builddir/tests/msft_proxy_tests --gtest_list_tests --gtest_output=json:/dev/stderr 2>| jq '.testsuites | map({key: .name, value: .testsuite | map(.name)}) | from_entries' +tests = { + 'ProxyCreationTests': [ + 'TestMakeProxyInplace_FromValue', + 'TestMakeProxyInplace_InPlace', + 'TestMakeProxyInplace_InPlaceInitializerList', + 'TestMakeProxyInplace_Lifetime_Copy', + 'TestMakeProxyInplace_Lifetime_Move', + 'TestAllocateProxy_DirectAllocator_FromValue', + 'TestAllocateProxy_DirectAllocator_InPlace', + 'TestAllocateProxy_DirectAllocator_InPlaceInitializerList', + 'TestAllocateProxy_DirectAllocator_Lifetime_Copy', + 'TestAllocateProxy_DirectAllocator_Lifetime_Move', + 'TestAllocateProxy_IndirectAllocator_FromValue', + 'TestAllocateProxy_IndirectAllocator_InPlace', + 'TestAllocateProxy_IndirectAllocator_InPlaceInitializerList', + 'TestAllocateProxy_IndirectAllocator_Lifetime_Copy', + 'TestAllocateProxy_IndirectAllocator_Lifetime_Move', + 'TestMakeProxy_WithSBO_FromValue', + 'TestMakeProxy_WithSBO_InPlace', + 'TestMakeProxy_WithSBO_InPlaceInitializerList', + 'TestMakeProxy_WithSBO_Lifetime_Copy', + 'TestMakeProxy_WithSBO_Lifetime_Move', + 'TestMakeProxy_WithoutSBO_FromValue', + 'TestMakeProxy_WithoutSBO_InPlace', + 'TestMakeProxy_WithoutSBO_InPlaceInitializerList', + 'TestMakeProxy_WithoutSBO_Lifetime_Copy', + 'TestMakeProxy_WithoutSBO_Lifetime_Move', + 'TestMakeProxy_SfinaeUnsafe', + 'TestAllocateProxyShared_SharedCompact_FromValue', + 'TestAllocateProxyShared_SharedCompact_InPlace', + 'TestAllocateProxyShared_SharedCompact_InPlaceInitializerList', + 'TestAllocateProxyShared_SharedCompact_Lifetime_Copy', + 'TestAllocateProxyShared_SharedCompact_Lifetime_Move', + 'TestAllocateProxyShared_StrongCompact_FromValue', + 'TestAllocateProxyShared_StrongCompact_InPlace', + 'TestAllocateProxyShared_StrongCompact_InPlaceInitializerList', + 'TestAllocateProxyShared_StrongCompact_Lifetime_Copy', + 'TestAllocateProxyShared_StrongCompact_Lifetime_Move', + 'TestAllocateProxyShared_StrongCompact_Lifetime_WeakAccess', + 'TestMakeProxyShared_SharedCompact_FromValue', + 'TestMakeProxyShared_SharedCompact_InPlace', + 'TestMakeProxyShared_SharedCompact_InPlaceInitializerList', + 'TestMakeProxyShared_SharedCompact_Lifetime_Copy', + 'TestMakeProxyShared_SharedCompact_Lifetime_Move', + 'TestMakeProxyShared_StrongCompact_FromValue', + 'TestMakeProxyShared_StrongCompact_InPlace', + 'TestMakeProxyShared_StrongCompact_InPlaceInitializerList', + 'TestMakeProxyShared_StrongCompact_Lifetime_Copy', + 'TestMakeProxyShared_StrongCompact_Lifetime_Move', + 'TestMakeProxyShared_StrongCompact_Lifetime_WeakAccess', + 'TestMakeProxyShared_StrongCompact_Lifetime_WeakConversion', + 'TestStdWeakPtrCompatibility', + 'TestMakeProxyView', + ], + 'ProxyDispatchTests': [ + 'TestOpPlus', + 'TestOpMinus', + 'TestOpAsterisk', + 'TestOpSlash', + 'TestOpModulo', + 'TestOpIncrement', + 'TestOpDecrement', + 'TestOpEqualTo', + 'TestOpNotEqualTo', + 'TestOpGreaterThan', + 'TestOpLessThan', + 'TestOpGreaterThanOrEqualTo', + 'TestOpLessThanOrEqualTo', + 'TestOpSpaceship', + 'TestOpLogicalNot', + 'TestOpLogicalAnd', + 'TestOpLogicalOr', + 'TestOpTilde', + 'TestOpAmpersand', + 'TestOpPipe', + 'TestOpCaret', + 'TestOpLeftShift', + 'TestOpRightShift', + 'TestOpPlusAssignment', + 'TestOpMinusAssignment', + 'TestOpMultiplicationAssignment', + 'TestOpDivisionAssignment', + 'TestOpModuloAssignment', + 'TestOpBitwiseAndAssignment', + 'TestOpBitwiseOrAssignment', + 'TestOpBitwiseXorAssignment', + 'TestOpLeftShiftAssignment', + 'TestOpRightShiftAssignment', + 'TestOpComma', + 'TestOpPtrToMem', + 'TestOpParentheses', + 'TestOpBrackets_OneDimensional', + 'TestRhsOpPlus', + 'TestRhsOpMinus', + 'TestRhsOpAsterisk', + 'TestRhsOpSlash', + 'TestRhsOpModulo', + 'TestRhsOpEqualTo', + 'TestRhsOpNotEqualTo', + 'TestRhsOpGreaterThan', + 'TestRhsOpLessThan', + 'TestRhsOpGreaterThanOrEqualTo', + 'TestRhsOpLessThanOrEqualTo', + 'TestRhsOpSpaceship', + 'TestRhsOpLogicalAnd', + 'TestRhsOpLogicalOr', + 'TestRhsOpAmpersand', + 'TestRhsOpPipe', + 'TestRhsOpCaret', + 'TestRhsOpLeftShift', + 'TestRhsOpRightShift', + 'TestRhsOpPlusAssignment', + 'TestRhsOpMinusAssignment', + 'TestRhsOpMultiplicationAssignment', + 'TestRhsOpDivisionAssignment', + 'TestRhsOpModuloAssignment', + 'TestRhsOpBitwiseAndAssignment', + 'TestRhsOpBitwiseOrAssignment', + 'TestRhsOpBitwiseXorAssignment', + 'TestRhsOpLeftShiftAssignment', + 'TestRhsOpRightShiftAssignment', + 'TestRhsOpComma', + 'TestRhsOpPtrToMem', + 'TestIndirectConversion', + 'TestDirectConversion', + 'TestImplciitConversion', + 'TestFreeAsMemDispatch', + 'TestSubstitutionDispatch', + ], + 'ProxyFmtFormatTests': ['TestFormat', 'TestWformat'], + 'ProxyFormatTests': ['TestFormat', 'TestWformat'], + 'ProxyIntegrationTests': ['TestDrawable', 'TestLogger'], + 'ProxyInvocationTests': [ + 'TestArgumentForwarding', + 'TestThrow', + 'TestMultipleDispatches_Unique', + 'TestMultipleDispatches_Duplicated', + 'TestRecursiveDefinition', + 'TestOverloadResolution_Member', + 'TestOverloadResolution_Free', + 'TestOverloadResolution_FreeAsMem', + 'TestNoexcept', + 'TestFunctionPointer', + 'TestMemberDispatchDefault', + 'TestFreeDispatchDefault', + 'TestObserverDispatch', + 'TestQualifiedConvention_Member', + 'TestQualifiedConvention_Free', + ], + 'ProxyLifetimeTests': [ + 'TestDefaultConstrction', + 'TestNullConstrction_Nullptr', + 'TestNullConstrction_TypedNullPointer', + 'TestPolyConstrction_FromValue', + 'TestPolyConstrction_FromValue_Exception', + 'TestPolyConstrction_InPlace', + 'TestPolyConstrction_InPlace_Exception', + 'TestPolyConstrction_InPlaceInitializerList', + 'TestPolyConstrction_InPlaceInitializerList_Exception', + 'TestCopyConstrction_FromValue', + 'TestCopyConstrction_FromValue_Exception', + 'TestCopyConstrction_FromNull', + 'TestMoveConstrction_FromValue', + 'TestMoveConstrction_FromValue_Trivial', + 'TestMoveConstrction_FromNull', + 'TestNullAssignment_FromNullptr_ToValue', + 'TestNullAssignment_FromTypedNullPointer_ToValue', + 'TestNullAssignment_ToNull', + 'TestPolyAssignment_ToValue', + 'TestPolyAssignment_ToValue_Exception', + 'TestPolyAssignment_FromValue_ToNull', + 'TestPolyAssignment_FromValue_ToNull_Exception', + 'TestPolyAssignment_InPlace_ToValue', + 'TestPolyAssignment_InPlace_ToValue_Exception', + 'TestPolyAssignment_InPlace_ToNull', + 'TestPolyAssignment_InPlace_ToNull_Exception', + 'TestPolyAssignment_InPlaceInitializerList_ToValue', + 'TestPolyAssignment_InPlaceInitializerList_ToValue_Exception', + 'TestPolyAssignment_InPlaceInitializerList_ToNull', + 'TestPolyAssignment_InPlaceInitializerList_ToNull_Exception', + 'TestCopyAssignment_FromValue_ToValue', + 'TestCopyAssignment_FromValue_ToValue_Exception', + 'TestCopyAssignment_FromValue_ToSelf', + 'TestCopyAssignment_FromValue_ToNull', + 'TestCopyAssignment_FromValue_ToNull_Exception', + 'TestCopyAssignment_FromNull_ToValue', + 'TestCopyAssignment_FromNull_ToSelf', + 'TestCopyAssignment_FromNull_ToNull', + 'TestMoveAssignment_FromValue_ToValue', + 'TestMoveAssignment_FromValue_ToValue_Exception', + 'TestMoveAssignment_FromValue_ToSelf', + 'TestMoveAssignment_FromValue_ToNull', + 'TestMoveAssignment_FromValue_ToNull_Exception', + 'TestMoveAssignment_FromNull_ToValue', + 'TestMoveAssignment_FromNull_ToSelf', + 'TestMoveAssignment_FromNull_ToNull', + 'TestHasValue', + 'TestOperatorBool', + 'TestEqualsToNullptr', + 'TestReset_FromValue', + 'TestReset_FromNull', + 'TestSwap_Value_Value', + 'TestSwap_Value_Self', + 'TestSwap_Value_Null', + 'TestSwap_Null_Value', + 'TestSwap_Null_Self', + 'TestSwap_Null_Null', + 'TestSwap_Trivial', + 'Test_DirectConvension_Lvalue', + 'Test_DirectConvension_Rvalue', + 'Test_DirectConvension_Rvalue_Exception', + 'Test_CopySubstitution_FromValue', + 'Test_CopySubstitution_FromNull', + 'Test_MoveSubstitution_FromValue', + 'Test_MoveSubstitution_FromNull', + ], + 'ProxyReflectionTests': [ + 'TestRtti_RawPtr', + 'TestRtti_FancyPtr', + 'TestTraits_RawPtr', + 'TestTraits_FancyPtr', + ], + 'ProxyRegressionTests': [ + 'TestUnexpectedCompilerWarning', + 'TestProxiableSelfDependency', + ], + 'ProxyRttiTests': [ + 'TestIndirectCast_Ref_Succeed', + 'TestIndirectCast_Ref_Fail', + 'TestIndirectCast_ConstRef_Succeed', + 'TestIndirectCast_ConstRef_Fail', + 'TestIndirectCast_Copy_Succeed', + 'TestIndirectCast_Copy_Fail', + 'TestIndirectCast_Move_Succeed', + 'TestIndirectCast_Move_Fail', + 'TestIndirectCast_Ptr_Succeed', + 'TestIndirectCast_Ptr_Fail', + 'TestIndirectCast_ConstPtr_Succeed', + 'TestIndirectCast_ConstPtr_Fail', + 'TestIndirectTypeid', + 'TestDirectCast_Ref_Succeed', + 'TestDirectCast_Ref_Fail', + 'TestDirectCast_ConstRef_Succeed', + 'TestDirectCast_ConstRef_Fail', + 'TestDirectCast_Copy_Succeed', + 'TestDirectCast_Copy_Fail', + 'TestDirectCast_Move_Succeed', + 'TestDirectCast_Move_Fail', + 'TestDirectCast_Ptr_Succeed', + 'TestDirectCast_Ptr_Fail', + 'TestDirectCast_ConstPtr_Succeed', + 'TestDirectCast_ConstPtr_Fail', + 'TestDirectTypeid', + ], + 'ProxyViewTests': [ + 'TestViewOfNull', + 'TestViewIndependentUse', + 'TestViewOfOwning', + 'TestViewOfNonOwning', + 'TestOverloadShadowing', + 'TestSubstitution_FromNull', + 'TestSubstitution_FromValue', + 'TestFacadeAware', + ], +} + + +foreach suite : tests.keys() + foreach name : tests[suite] + test( + name, + tests_exe, + args: [f'--gtest_filter=@suite@.@name@'], + protocol: 'gtest', + suite: suite, + ) + endforeach +endforeach + +freestanding = get_option('tests_freestanding') +freestanding_cflags = ['-ffreestanding', '-fno-exceptions', '-fno-rtti'] +freestanding_ldflags = ['-nodefaultlibs'] + +if cxx.has_multi_arguments( + freestanding_cflags + freestanding_ldflags, + required: freestanding, +) + libc_dep = cxx.find_library('c', required: freestanding) + freestanding_tests_exe = executable( + 'msft_proxy_freestanding_tests', + files('freestanding/proxy_freestanding_tests.cpp'), + implicit_include_directories: false, + dependencies: [msft_proxy4_dep, libc_dep], + cpp_args: freestanding_cflags, + link_args: freestanding_ldflags, + build_by_default: false, + ) + test( + 'TestFreestanding', + freestanding_tests_exe, + suite: 'ProxyFreestandingSupportTests', + ) +endif + +subdir('modules', if_found: msft_proxy4_mod) diff --git a/tests/modules/meson.build b/tests/modules/meson.build new file mode 100644 index 00000000..02e4ea5d --- /dev/null +++ b/tests/modules/meson.build @@ -0,0 +1,14 @@ +tests_modules_exe = executable( + 'msft_proxy_tests_modules', + files('foo.cpp', 'impl.cpp', 'main.cpp'), + implicit_include_directories: false, + cpp_args: modules_interface_cflags, + dependencies: [msft_proxy4_mod, gtest_dep], + build_by_default: false, +) +test( + 'TestBasic', + tests_modules_exe, + suite: 'ProxyModuleSupportTests', + protocol: 'gtest', +) From 72bd4d2de802c4f44c340ef943ad6d89d69fdbc4 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 1 Dec 2025 22:13:43 +0800 Subject: [PATCH 04/40] ci: fix shellcheck warnings --- .github/workflows/pipeline-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pipeline-release.yml b/.github/workflows/pipeline-release.yml index 67778741..77a9d2c8 100644 --- a/.github/workflows/pipeline-release.yml +++ b/.github/workflows/pipeline-release.yml @@ -17,8 +17,8 @@ jobs: version=$(grep -oP 'msft_proxy\d+\s+VERSION\s+\K[0-9]+\.[0-9]+\.[0-9]+' CMakeLists.txt) git tag "$version" git push origin "$version" - tar -czf "proxy-$version.tgz" $(git ls-files 'include/**.h' 'include/**.ixx') - echo "PRO_VER=$version" >> $GITHUB_OUTPUT + git ls-files 'include/**.h' 'include/**.ixx' | xargs tar -czf "proxy-$version.tgz" + echo "PRO_VER=$version" >> "$GITHUB_OUTPUT" shell: bash - name: create release draft From a478e01c74305ecd0b96932fee86e6796316bd14 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 1 Dec 2025 22:14:21 +0800 Subject: [PATCH 05/40] ci: add meson tests --- .github/workflows/meson.yml | 165 ++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 .github/workflows/meson.yml diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml new file mode 100644 index 00000000..e5d82aa5 --- /dev/null +++ b/.github/workflows/meson.yml @@ -0,0 +1,165 @@ +on: + push: + branches: [ main, release/** ] + pull_request: + branches: [ main, release/** ] + workflow_dispatch: + +jobs: + meson: + runs-on: ${{ matrix.platform }} + name: meson on ${{ matrix.platform }} (${{ matrix.mode.name }} ${{ matrix.flavor }}) + strategy: + fail-fast: false + matrix: + flavor: + - debug + - release + mode: + - name: default + args: -Dtests=enabled -Dbenchmarks=enabled + extra_envs: {} + + # Alternative compiler setups + - name: gcc + args: -Dtests=enabled -Dbenchmarks=enabled + extra_envs: + CC: gcc + CXX: g++ + - name: clang + args: -Dtests=enabled -Dbenchmarks=enabled + extra_envs: + CC: clang + CXX: clang++ + + - name: sanitize + args: >- + -Dtests=enabled -Dbenchmarks=enabled "-Db_sanitize=address,undefined" + extra_envs: {} + + # This is for MSVC, which only supports AddressSanitizer. + # https://learn.microsoft.com/en-us/cpp/sanitizers/ + - name: sanitize+asanonly + args: -Dtests=enabled -Dbenchmarks=enabled -Db_sanitize=address + extra_envs: + ASAN_OPTIONS: report_globals=0:halt_on_error=1:abort_on_error=1:print_summary=1 + + - name: clang+sanitize + args: >- + -Dtests=enabled -Dbenchmarks=enabled "-Db_sanitize=address,undefined" + extra_envs: + CC: clang + CXX: clang++ + + # default clang on GitHub hosted runners is from MSYS2. + # Use Visual Studio supplied clang-cl instead. + - name: clang-cl + args: >- + -Dtests=enabled -Dbenchmarks=enabled + extra_envs: + CC: clang-cl + CXX: clang-cl + - name: clang-cl+sanitize + args: >- + -Dtests=enabled -Dbenchmarks=enabled "-Db_sanitize=address,undefined" + extra_envs: + CC: clang-cl + CXX: clang-cl + platform: + - ubuntu-latest + - windows-latest + - macos-latest + + exclude: + # clang-cl only makes sense on windows. + - platform: ubuntu-latest + mode: + name: clang-cl + - platform: macos-latest + mode: + name: clang-cl + - platform: ubuntu-latest + mode: + name: clang-cl+sanitize + - platform: macos-latest + mode: + name: clang-cl+sanitize + + # Use clang-cl instead of MSYS2 clang. + # + # we already tested clang+sanitize on linux, + # if this doesn't work, it should be an issue for MSYS2 team to consider. + - platform: windows-latest + mode: + name: clang + - platform: windows-latest + mode: + name: clang+sanitize + + # MSVC-only sanitizers + - platform: ubuntu-latest + mode: + name: sanitize+asanonly + - platform: macos-latest + mode: + name: sanitize+asanonly + - platform: windows-latest + mode: + name: sanitize + + # clang is the default on macos + # also gcc is an alias to clang + - platform: macos-latest + mode: + name: clang + - platform: macos-latest + mode: + name: gcc + + # gcc is the default on linux + - platform: ubuntu-latest + mode: + name: gcc + + # only run sanitizer tests on linux + # + # gcc/clang's codegen shouldn't massively change across platforms, + # and linux supports most of the sanitizers. + - platform: macos-latest + mode: + name: clang+sanitize + - platform: macos-latest + mode: + name: sanitize + + steps: + - name: Setup meson + run: | + pipx install meson ninja + - name: Checkout + uses: actions/checkout@v4 + - name: Activate MSVC and Configure + if: ${{ matrix.platform == 'windows-latest' }} + env: ${{ matrix.mode.extra_envs }} + run: | + meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} ${{ matrix.mode.args }} --vsenv + - name: Configuring + if: ${{ matrix.platform != 'windows-latest' }} + env: ${{ matrix.mode.extra_envs }} + run: | + meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} ${{ matrix.mode.args }} + - name: Building + run: | + meson compile -C build-${{ matrix.flavor }} + meson compile -C build-${{ matrix.flavor }} msft_proxy_tests msft_proxy_benchmarks examples + + - name: Running tests + env: ${{ matrix.mode.extra_envs }} + run: | + meson test -C build-${{ matrix.flavor }} --timeout-multiplier 5 --print-errorlogs + meson test --benchmark -C build-${{ matrix.flavor }} --timeout-multiplier 5 --print-errorlogs + - uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ${{ matrix.platform }}-${{ matrix.mode.name }}-${{ matrix.flavor }}-logs + path: build-${{ matrix.flavor }}/meson-logs From 10c0fd31e055f5b149a33c63d13c35b13da99232 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 1 Dec 2025 23:47:20 +0800 Subject: [PATCH 06/40] style: run clang-format --- tests/proxy_reflection_tests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/proxy_reflection_tests.cpp b/tests/proxy_reflection_tests.cpp index 633de66a..5cc90b40 100644 --- a/tests/proxy_reflection_tests.cpp +++ b/tests/proxy_reflection_tests.cpp @@ -17,7 +17,8 @@ struct TraitsReflector { is_copy_constructible_(std::is_copy_constructible_v), is_nothrow_move_constructible_(std::is_nothrow_move_constructible_v), is_nothrow_destructible_(std::is_nothrow_destructible_v), - is_trivial_(std::is_trivially_default_constructible_v && std::is_trivially_copyable_v) {} + is_trivial_(std::is_trivially_default_constructible_v && + std::is_trivially_copyable_v) {} template struct accessor { From 1363a27940e0d79881064239a1902fd2d4964a90 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Tue, 2 Dec 2025 00:02:24 +0800 Subject: [PATCH 07/40] ci: workaround clang sanitizer linking bug --- .github/workflows/meson.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index e5d82aa5..5aefdb58 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -46,7 +46,7 @@ jobs: - name: clang+sanitize args: >- - -Dtests=enabled -Dbenchmarks=enabled "-Db_sanitize=address,undefined" + -Dtests=enabled -Dbenchmarks=enabled -Db_lundef=false "-Db_sanitize=address,undefined" extra_envs: CC: clang CXX: clang++ From ae9c89eec3ff346c0b06c718648d022cb2510e78 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Tue, 2 Dec 2025 00:22:20 +0800 Subject: [PATCH 08/40] build/meson: fix modules builds on mingw winpthreads --- meson.build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 15879caf..73fe6e2c 100644 --- a/meson.build +++ b/meson.build @@ -34,7 +34,11 @@ msft_proxy4_dep = declare_dependency( modules = get_option('modules') modules_interface_spec = { 'gcc': { - 'flags': ['-fmodules', '-fdeps-format=p1689r5'], + 'flags': [ + '-fmodules', + '-fdeps-format=p1689r5', + '-DWINPTHREAD_COND_DECL=WINPTHREADS_ALWAYS_INLINE', + ], 'check_only': ['-M'], }, 'msvc': { From ec80d044ebdc4d96e1f6577ce7c002d9b44a5034 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Tue, 2 Dec 2025 00:52:30 +0800 Subject: [PATCH 09/40] build/meson: do not link -nodefaultlibs on sanitized builds --- tests/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/meson.build b/tests/meson.build index 48475163..668085eb 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -315,7 +315,7 @@ if cxx.has_multi_arguments( implicit_include_directories: false, dependencies: [msft_proxy4_dep, libc_dep], cpp_args: freestanding_cflags, - link_args: freestanding_ldflags, + link_args: get_option('b_sanitize') == '' ? freestanding_ldflags : [], build_by_default: false, ) test( From 3b8e0633d7cfc52fea6bbfda71a886aea2461b42 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Tue, 2 Dec 2025 01:10:12 +0800 Subject: [PATCH 10/40] build/meson: increase max object section count on msvc --- meson.build | 3 +++ 1 file changed, 3 insertions(+) diff --git a/meson.build b/meson.build index 73fe6e2c..0d9fcb05 100644 --- a/meson.build +++ b/meson.build @@ -12,6 +12,9 @@ project( ) cxx = meson.get_compiler('cpp') +if cxx.get_argument_syntax() == 'msvc' + add_project_arguments('/bigobj', language: 'cpp') +endif inc = include_directories('include') From d998003eb5628c2ad0794713d9b5c35b77b778f5 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 01:10:19 +0800 Subject: [PATCH 11/40] ci: only test release builds, do not run benchmarks --- .github/workflows/meson.yml | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index 5aefdb58..cf1a8d88 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -8,45 +8,42 @@ on: jobs: meson: runs-on: ${{ matrix.platform }} - name: meson on ${{ matrix.platform }} (${{ matrix.mode.name }} ${{ matrix.flavor }}) + name: meson on ${{ matrix.platform }} (${{ matrix.mode.name }}) strategy: fail-fast: false matrix: - flavor: - - debug - - release mode: - name: default - args: -Dtests=enabled -Dbenchmarks=enabled + args: -Dtests=enabled -Dbenchmarks=disabled extra_envs: {} # Alternative compiler setups - name: gcc - args: -Dtests=enabled -Dbenchmarks=enabled + args: -Dtests=enabled -Dbenchmarks=disabled extra_envs: CC: gcc CXX: g++ - name: clang - args: -Dtests=enabled -Dbenchmarks=enabled + args: -Dtests=enabled -Dbenchmarks=disabled extra_envs: CC: clang CXX: clang++ - name: sanitize args: >- - -Dtests=enabled -Dbenchmarks=enabled "-Db_sanitize=address,undefined" + -Dtests=enabled -Dbenchmarks=disabled "-Db_sanitize=address,undefined" extra_envs: {} # This is for MSVC, which only supports AddressSanitizer. # https://learn.microsoft.com/en-us/cpp/sanitizers/ - name: sanitize+asanonly - args: -Dtests=enabled -Dbenchmarks=enabled -Db_sanitize=address + args: -Dtests=enabled -Dbenchmarks=disabled -Db_sanitize=address extra_envs: ASAN_OPTIONS: report_globals=0:halt_on_error=1:abort_on_error=1:print_summary=1 - name: clang+sanitize args: >- - -Dtests=enabled -Dbenchmarks=enabled -Db_lundef=false "-Db_sanitize=address,undefined" + -Dtests=enabled -Dbenchmarks=disabled -Db_lundef=false "-Db_sanitize=address,undefined" extra_envs: CC: clang CXX: clang++ @@ -55,13 +52,13 @@ jobs: # Use Visual Studio supplied clang-cl instead. - name: clang-cl args: >- - -Dtests=enabled -Dbenchmarks=enabled + -Dtests=enabled -Dbenchmarks=disabled extra_envs: CC: clang-cl CXX: clang-cl - name: clang-cl+sanitize args: >- - -Dtests=enabled -Dbenchmarks=enabled "-Db_sanitize=address,undefined" + -Dtests=enabled -Dbenchmarks=disabled "-Db_sanitize=address,undefined" extra_envs: CC: clang-cl CXX: clang-cl @@ -142,24 +139,23 @@ jobs: if: ${{ matrix.platform == 'windows-latest' }} env: ${{ matrix.mode.extra_envs }} run: | - meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} ${{ matrix.mode.args }} --vsenv + meson setup build --buildtype=release ${{ matrix.mode.args }} --vsenv - name: Configuring if: ${{ matrix.platform != 'windows-latest' }} env: ${{ matrix.mode.extra_envs }} run: | - meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} ${{ matrix.mode.args }} + meson setup build --buildtype=release ${{ matrix.mode.args }} - name: Building run: | - meson compile -C build-${{ matrix.flavor }} - meson compile -C build-${{ matrix.flavor }} msft_proxy_tests msft_proxy_benchmarks examples + meson compile -C build + meson compile -C build msft_proxy_tests examples - name: Running tests env: ${{ matrix.mode.extra_envs }} run: | - meson test -C build-${{ matrix.flavor }} --timeout-multiplier 5 --print-errorlogs - meson test --benchmark -C build-${{ matrix.flavor }} --timeout-multiplier 5 --print-errorlogs + meson test -C build --timeout-multiplier 5 --print-errorlogs - uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: ${{ matrix.platform }}-${{ matrix.mode.name }}-${{ matrix.flavor }}-logs - path: build-${{ matrix.flavor }}/meson-logs + name: ${{ matrix.platform }}-${{ matrix.mode.name }}-logs + path: build/meson-logs From de5f1bb8a9c412028509c1338192bb5b56d2643b Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 01:26:33 +0800 Subject: [PATCH 12/40] ci: pin runner versions --- .github/workflows/meson.yml | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index cf1a8d88..62ae1cae 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -63,22 +63,22 @@ jobs: CC: clang-cl CXX: clang-cl platform: - - ubuntu-latest - - windows-latest - - macos-latest + - ubuntu-24.04 + - windows-2025 + - macos-15 exclude: # clang-cl only makes sense on windows. - - platform: ubuntu-latest + - platform: ubuntu-24.04 mode: name: clang-cl - - platform: macos-latest + - platform: macos-15 mode: name: clang-cl - - platform: ubuntu-latest + - platform: ubuntu-24.04 mode: name: clang-cl+sanitize - - platform: macos-latest + - platform: macos-15 mode: name: clang-cl+sanitize @@ -86,35 +86,35 @@ jobs: # # we already tested clang+sanitize on linux, # if this doesn't work, it should be an issue for MSYS2 team to consider. - - platform: windows-latest + - platform: windows-2025 mode: name: clang - - platform: windows-latest + - platform: windows-2025 mode: name: clang+sanitize # MSVC-only sanitizers - - platform: ubuntu-latest + - platform: ubuntu-24.04 mode: name: sanitize+asanonly - - platform: macos-latest + - platform: macos-15 mode: name: sanitize+asanonly - - platform: windows-latest + - platform: windows-2025 mode: name: sanitize # clang is the default on macos # also gcc is an alias to clang - - platform: macos-latest + - platform: macos-15 mode: name: clang - - platform: macos-latest + - platform: macos-15 mode: name: gcc # gcc is the default on linux - - platform: ubuntu-latest + - platform: ubuntu-24.04 mode: name: gcc @@ -122,10 +122,10 @@ jobs: # # gcc/clang's codegen shouldn't massively change across platforms, # and linux supports most of the sanitizers. - - platform: macos-latest + - platform: macos-15 mode: name: clang+sanitize - - platform: macos-latest + - platform: macos-15 mode: name: sanitize @@ -136,12 +136,12 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Activate MSVC and Configure - if: ${{ matrix.platform == 'windows-latest' }} + if: ${{ matrix.platform == 'windows-2025' }} env: ${{ matrix.mode.extra_envs }} run: | meson setup build --buildtype=release ${{ matrix.mode.args }} --vsenv - name: Configuring - if: ${{ matrix.platform != 'windows-latest' }} + if: ${{ matrix.platform != 'windows-2025' }} env: ${{ matrix.mode.extra_envs }} run: | meson setup build --buildtype=release ${{ matrix.mode.args }} From dffce2012a20c980243c5239b2f3e657c37a1f17 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 01:27:27 +0800 Subject: [PATCH 13/40] ci: exclude unsupported / broken platforms --- .github/workflows/meson.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index 62ae1cae..f28e6967 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -82,6 +82,15 @@ jobs: mode: name: clang-cl+sanitize + # FIXME: clang-cl is currently broken: + # https://github.com/llvm/llvm-project/issues/143245 + - platform: windows-2025 + mode: + name: clang-cl + - platform: windows-2025 + mode: + name: clang-cl+sanitize + # Use clang-cl instead of MSYS2 clang. # # we already tested clang+sanitize on linux, @@ -118,6 +127,11 @@ jobs: mode: name: gcc + # MinGW is not officially tested + - platform: windows-2025 + mode: + name: gcc + # only run sanitizer tests on linux # # gcc/clang's codegen shouldn't massively change across platforms, From 4c3ff5271e319b3dfdf588a62ff7b864aa688f54 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 01:28:27 +0800 Subject: [PATCH 14/40] build: add a notice about clang-cl broken msvc compatibility --- meson.build | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 0d9fcb05..4aa69ce5 100644 --- a/meson.build +++ b/meson.build @@ -12,8 +12,32 @@ project( ) cxx = meson.get_compiler('cpp') +if cxx.compute_int('__has_cpp_attribute(msvc::no_unique_address)') != 0 and not cxx.compiles( + ''' + struct A {}; + + struct B { + [[msvc::no_unique_address]] A val; + }; + + struct C : B { + char x; + }; + + static_assert(sizeof(C) == 1); + ''', + name: 'msvc::no_unique_address behaves correctly', +) + error( + 'unsupported compiler:', + 'https://github.com/llvm/llvm-project/issues/143245', + ) +endif if cxx.get_argument_syntax() == 'msvc' - add_project_arguments('/bigobj', language: 'cpp') + add_project_arguments( + '/bigobj', + language: 'cpp', + ) endif inc = include_directories('include') From 5e8745e885b86742d99f824adcc20354f076d7cc Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 03:04:56 +0800 Subject: [PATCH 15/40] build: meson gtest autodiscovery --- meson.build | 2 ++ tests/meson.build | 29 ++++++++++++++++++++---- tests/modules/meson.build | 40 ++++++++++++++++++++++++++++---- tools/meson.build | 1 + tools/meson_autogen_tests.py | 44 ++++++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 tools/meson.build create mode 100644 tools/meson_autogen_tests.py diff --git a/meson.build b/meson.build index 4aa69ce5..4f9686ce 100644 --- a/meson.build +++ b/meson.build @@ -122,6 +122,8 @@ endif meson.override_dependency(meson.project_name(), msft_proxy4_dep) meson.override_dependency(meson.project_name() + '_module', msft_proxy4_mod) +subdir('tools') + tests = get_option('tests') gtest_dep = dependency( 'gtest_main', diff --git a/tests/meson.build b/tests/meson.build index 668085eb..4f185e1b 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -19,8 +19,20 @@ tests_exe = executable( build_by_default: false, ) -# to generate this, run: -# builddir/tests/msft_proxy_tests --gtest_list_tests --gtest_output=json:/dev/stderr 2>| jq '.testsuites | map({key: .name, value: .testsuite | map(.name)}) | from_entries' +autogen_tests = custom_target( + command: [ + autogen_tests_exe, + custom_target( + command: [tests_exe, '--gtest_list_tests', '--gtest_output=json:@OUTPUT@'], + output: 'tests.json', + ), + meson.current_source_dir() / 'meson.build', + ], + output: 'autogen.stamp', + build_by_default: true, +) + +#pragma autogen push tests = { 'ProxyCreationTests': [ 'TestMakeProxyInplace_FromValue', @@ -286,7 +298,7 @@ tests = { 'TestFacadeAware', ], } - +#pragma autogen pop foreach suite : tests.keys() foreach name : tests[suite] @@ -296,6 +308,7 @@ foreach suite : tests.keys() args: [f'--gtest_filter=@suite@.@name@'], protocol: 'gtest', suite: suite, + depends: autogen_tests, ) endforeach endforeach @@ -308,7 +321,10 @@ if cxx.has_multi_arguments( freestanding_cflags + freestanding_ldflags, required: freestanding, ) - libc_dep = cxx.find_library('c', required: freestanding) + libc_dep = cxx.find_library( + 'c', + required: freestanding, + ) freestanding_tests_exe = executable( 'msft_proxy_freestanding_tests', files('freestanding/proxy_freestanding_tests.cpp'), @@ -325,4 +341,7 @@ if cxx.has_multi_arguments( ) endif -subdir('modules', if_found: msft_proxy4_mod) +subdir( + 'modules', + if_found: msft_proxy4_mod, +) diff --git a/tests/modules/meson.build b/tests/modules/meson.build index 02e4ea5d..c6ffde59 100644 --- a/tests/modules/meson.build +++ b/tests/modules/meson.build @@ -6,9 +6,39 @@ tests_modules_exe = executable( dependencies: [msft_proxy4_mod, gtest_dep], build_by_default: false, ) -test( - 'TestBasic', - tests_modules_exe, - suite: 'ProxyModuleSupportTests', - protocol: 'gtest', + +autogen_modules_tests = custom_target( + command: [ + autogen_tests_exe, + custom_target( + command: [ + tests_modules_exe, + '--gtest_list_tests', + '--gtest_output=json:@OUTPUT@', + ], + output: 'tests.json', + ), + meson.current_source_dir() / 'meson.build', + ], + output: 'autogen.stamp', + build_by_default: true, ) + +#pragma autogen push +tests = { + 'ProxyModuleSupportTests': ['TestBasic'], +} +#pragma autogen pop + +foreach suite : tests.keys() + foreach name : tests[suite] + test( + name, + tests_modules_exe, + args: [f'--gtest_filter=@suite@.@name@'], + protocol: 'gtest', + suite: suite, + depends: autogen_modules_tests, + ) + endforeach +endforeach diff --git a/tools/meson.build b/tools/meson.build new file mode 100644 index 00000000..ed68115c --- /dev/null +++ b/tools/meson.build @@ -0,0 +1 @@ +autogen_tests_exe = find_program('./meson_autogen_tests.py') diff --git a/tools/meson_autogen_tests.py b/tools/meson_autogen_tests.py new file mode 100644 index 00000000..d25e02c2 --- /dev/null +++ b/tools/meson_autogen_tests.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# pyright: strict + +import json +import sys +from pathlib import Path + +from mesonbuild import mformat + +testfile = Path(sys.argv[1]) +mesonfile = Path(sys.argv[2]) + +with testfile.open(encoding="utf-8") as f: + tests = { + suites["name"]: [suite["name"] for suite in suites["testsuite"]] + for suites in json.load(f)["testsuites"] + } + +with mesonfile.open(encoding="utf-8") as f: + build = f.readlines() + +begin = -1 +end = -1 + +for i, line in enumerate(build): + if begin == -1 and line.strip() == "#pragma autogen push": + begin = i + 1 + elif end == -1 and line.strip() == "#pragma autogen pop": + end = i + +if begin == -1 or end == -1: + raise ValueError + +config = mformat.get_meson_format([mesonfile]) +formatter = mformat.Formatter(config, False, False) +pretty = formatter.format(f"{tests = }", mesonfile) + +if pretty == "".join(build[begin:end]): + exit() + +with mesonfile.open("w", encoding="utf-8") as f: + f.writelines(build[:begin]) + _ = f.write(pretty) + f.writelines(build[end:]) From 56edfc02c0b8a299a1d1e7d896e20cd381573cbd Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 03:37:34 +0800 Subject: [PATCH 16/40] build: meson doctest autoglob --- .gitignore | 3 + docs/meson.build | 78 +++++++++---------------- tools/extract_example_code_from_docs.py | 13 +++-- tools/meson.build | 1 + tools/meson_autogen_doctest.py | 41 +++++++++++++ 5 files changed, 82 insertions(+), 54 deletions(-) create mode 100644 tools/meson_autogen_doctest.py diff --git a/.gitignore b/.gitignore index 6b46461b..d2e81b70 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ build/ Testing/ +# Python bytecode cache +__pycache__/ + # Meson subprojects /subprojects/* !/subprojects/*.wrap diff --git a/docs/meson.build b/docs/meson.build index f3437f81..fd0ec39c 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -7,27 +7,38 @@ maybe_fmt_dep = dependency( disabler: true, ) -# glob **.md +autogen_glob = custom_target( + command: [autogen_doctest_exe, meson.current_source_dir()], + output: 'autogen.stamp', + build_by_default: true, +) + +#pragma autogen push docs = [ - 'README.md', - 'faq.md', - 'modules_support.md', 'spec/PRO_DEF_FREE_AS_MEM_DISPATCH.md', 'spec/PRO_DEF_FREE_DISPATCH.md', 'spec/PRO_DEF_MEM_DISPATCH.md', - 'spec/ProAccessible.md', - 'spec/ProBasicConvention.md', - 'spec/ProBasicFacade.md', - 'spec/ProBasicReflection.md', - 'spec/ProConvention.md', - 'spec/ProDispatch.md', - 'spec/ProFacade.md', - 'spec/ProOverload.md', - 'spec/ProReflection.md', - 'spec/README.md', 'spec/allocate_proxy.md', 'spec/allocate_proxy_shared.md', - 'spec/bad_proxy_cast.md', + 'spec/facade_aware_overload_t.md', + 'spec/inplace_proxiable_target.md', + 'spec/is_bitwise_trivially_relocatable.md', + 'spec/make_proxy.md', + 'spec/make_proxy_inplace.md', + 'spec/make_proxy_shared.md', + 'spec/make_proxy_view.md', + 'spec/msft_lib_proxy.md', + 'spec/proxiable.md', + 'spec/proxiable_target.md', + 'spec/proxy_invoke.md', + 'spec/proxy_reflect.md', + 'spec/proxy_view.md', + 'spec/skills_as_view.md', + 'spec/skills_as_weak.md', + 'spec/skills_fmt_format.md', + 'spec/skills_format.md', + 'spec/skills_slim.md', + 'spec/weak_proxy.md', 'spec/basic_facade_builder/README.md', 'spec/basic_facade_builder/add_convention.md', 'spec/basic_facade_builder/add_facade.md', @@ -38,30 +49,10 @@ docs = [ 'spec/basic_facade_builder/support_copy.md', 'spec/basic_facade_builder/support_destruction.md', 'spec/basic_facade_builder/support_relocation.md', - 'spec/constraint_level.md', 'spec/explicit_conversion_dispatch/README.md', - 'spec/explicit_conversion_dispatch/accessor.md', - 'spec/explicit_conversion_dispatch/operator_call.md', - 'spec/facade.md', - 'spec/facade_aware_overload_t.md', 'spec/implicit_conversion_dispatch/README.md', - 'spec/implicit_conversion_dispatch/accessor.md', - 'spec/implicit_conversion_dispatch/operator_call.md', - 'spec/inplace_proxiable_target.md', - 'spec/is_bitwise_trivially_relocatable.md', - 'spec/make_proxy.md', - 'spec/make_proxy_inplace.md', - 'spec/make_proxy_shared.md', - 'spec/make_proxy_view.md', - 'spec/msft_lib_proxy.md', - 'spec/not_implemented.md', 'spec/operator_dispatch/README.md', - 'spec/operator_dispatch/accessor.md', - 'spec/operator_dispatch/operator_call.md', - 'spec/proxiable.md', - 'spec/proxiable_target.md', 'spec/proxy/README.md', - 'spec/proxy/assignment.md', 'spec/proxy/constructor.md', 'spec/proxy/destructor.md', 'spec/proxy/emplace.md', @@ -70,26 +61,13 @@ docs = [ 'spec/proxy/indirection.md', 'spec/proxy/operator_bool.md', 'spec/proxy/reset.md', - 'spec/proxy/swap.md', - 'spec/proxy_indirect_accessor.md', - 'spec/proxy_invoke.md', - 'spec/proxy_reflect.md', - 'spec/proxy_view.md', - 'spec/skills_as_view.md', - 'spec/skills_as_weak.md', - 'spec/skills_fmt_format.md', - 'spec/skills_format.md', 'spec/skills_rtti/README.md', 'spec/skills_rtti/proxy_cast.md', 'spec/skills_rtti/proxy_typeid.md', - 'spec/skills_slim.md', 'spec/substitution_dispatch/README.md', - 'spec/substitution_dispatch/accessor.md', - 'spec/substitution_dispatch/operator_call.md', 'spec/weak_dispatch/README.md', - 'spec/weak_dispatch/operator_call.md', - 'spec/weak_proxy.md', ] +#pragma autogen pop docdir = get_option('docdir') if docdir == '' @@ -160,6 +138,7 @@ foreach doc : docs input: 'example.cpp.in', output: f'example_@name@.cpp', ), + extra_files: doc, implicit_include_directories: false, dependencies: deps, build_by_default: false, @@ -169,6 +148,7 @@ foreach doc : docs name, example_exe, suite: 'ProxyExamples', + depends: autogen_glob, ) endif endforeach diff --git a/tools/extract_example_code_from_docs.py b/tools/extract_example_code_from_docs.py index 18d2a387..3e8eaac0 100644 --- a/tools/extract_example_code_from_docs.py +++ b/tools/extract_example_code_from_docs.py @@ -2,12 +2,13 @@ # pyright: strict import re +import typing as T from pathlib import Path EXAMPLE_PATTERN = re.compile(r"## Example\r?\n\r?\n```cpp\r?\n(.*?)\r?\n```", re.DOTALL) -def extract_cpp_code(md_path: Path, cpp_path: Path) -> None: +def extract_cpp_code(md_path: Path) -> T.Optional[str]: with open(md_path, "r", encoding="utf-8") as f: content = f.read() @@ -26,9 +27,7 @@ def extract_cpp_code(md_path: Path, cpp_path: Path) -> None: """.lstrip() - with open(cpp_path, "w", encoding="utf-8") as out: - _ = out.write(header) - _ = out.write(cpp_code) + return header + cpp_code def main() -> None: @@ -56,7 +55,11 @@ class Args: rel_path = md_path.relative_to(input_dir) rel_base = "_".join([*rel_path.parent.parts, rel_path.stem]) cpp_path = output_dir / f"example_{rel_base}.cpp" - extract_cpp_code(md_path, cpp_path) + cpp_code = extract_cpp_code(md_path) + if cpp_code is None: + continue + with open(cpp_path, "w", encoding="utf-8") as f: + _ = f.write(cpp_code) if __name__ == "__main__": diff --git a/tools/meson.build b/tools/meson.build index ed68115c..34c84eb9 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -1 +1,2 @@ autogen_tests_exe = find_program('./meson_autogen_tests.py') +autogen_doctest_exe = find_program('./meson_autogen_doctest.py') diff --git a/tools/meson_autogen_doctest.py b/tools/meson_autogen_doctest.py new file mode 100644 index 00000000..75f5c4d1 --- /dev/null +++ b/tools/meson_autogen_doctest.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# pyright: strict + +import sys +from pathlib import Path + +from mesonbuild import mformat + +from extract_example_code_from_docs import extract_cpp_code + +directory = Path(sys.argv[1]) +mesonfile = directory / "meson.build" + +with mesonfile.open(encoding="utf-8") as f: + build = f.readlines() + +begin = -1 +end = -1 + +for i, line in enumerate(build): + if begin == -1 and line.strip() == "#pragma autogen push": + begin = i + 1 + elif end == -1 and line.strip() == "#pragma autogen pop": + end = i + +if begin == -1 or end == -1: + raise ValueError + +docs = [str(path.relative_to(directory).as_posix()) for path in directory.glob("**/*.md") if extract_cpp_code(path) is not None] + +config = mformat.get_meson_format([mesonfile]) +formatter = mformat.Formatter(config, False, False) +pretty = formatter.format(f"{docs = }", mesonfile) + +if pretty == "".join(build[begin:end]): + exit() + +with mesonfile.open("w", encoding="utf-8") as f: + f.writelines(build[:begin]) + _ = f.write(pretty) + f.writelines(build[end:]) From bdcf49f758fda8ed740b36e39554e70c11e5047b Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 03:44:18 +0800 Subject: [PATCH 17/40] ci: manage meson builds from proxy-ci --- .github/workflows/meson.yml | 6 +----- .github/workflows/pipeline-ci.yml | 4 ++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index f28e6967..cede0ba5 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -1,9 +1,5 @@ on: - push: - branches: [ main, release/** ] - pull_request: - branches: [ main, release/** ] - workflow_dispatch: + workflow_call: jobs: meson: diff --git a/.github/workflows/pipeline-ci.yml b/.github/workflows/pipeline-ci.yml index f8037dce..7f311145 100644 --- a/.github/workflows/pipeline-ci.yml +++ b/.github/workflows/pipeline-ci.yml @@ -41,6 +41,10 @@ jobs: name: Generate report needs: [run-bvt-gcc, run-bvt-clang, run-bvt-msvc, run-bvt-appleclang, run-bvt-nvhpc, run-bvt-oneapi] + run-meson: + uses: ./.github/workflows/meson.yml + name: Run builds with meson + mkdocs: uses: ./.github/workflows/mkdocs.yml name: Build mkdocs From 8de73b74bac328b2a3aefea6c0bd28fdc3b15286 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 04:20:25 +0800 Subject: [PATCH 18/40] build: meson benchmarks autogen --- benchmarks/meson.build | 24 ++++++++++---- tools/meson.build | 1 + tools/meson_autogen_benchmarks.py | 52 +++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 tools/meson_autogen_benchmarks.py diff --git a/benchmarks/meson.build b/benchmarks/meson.build index e4170d4d..a607ed35 100644 --- a/benchmarks/meson.build +++ b/benchmarks/meson.build @@ -10,11 +10,23 @@ benchmarks_exe = executable( build_by_default: false, ) -# manually written, list all benchmarks with: -# builddir/benchmarks/msft_proxy_benchmarks --benchmark_list_tests +autogen_benchmarks = custom_target( + command: [ + autogen_benchmarks_exe, + custom_target( + command: [benchmarks_exe, '--benchmark_list_tests'], + capture: true, + output: 'tests.txt', + ), + meson.current_source_dir() / 'meson.build', + ], + output: 'autogen.stamp', + build_by_default: true, +) + +#pragma autogen push benchmarks = { 'ObjectCreation': [ - 'BM_SmallObjectCreationWithProxy', 'BM_SmallObjectCreationWithProxy_Shared', 'BM_SmallObjectCreationWithProxy_SharedPooled', 'BM_SmallObjectCreationWithUniquePtr', @@ -31,7 +43,6 @@ benchmarks = { 'BM_LargeObjectCreationWithAny', ], 'ObjectInvocation': [ - 'BM_SmallObjectInvocationViaProxy', 'BM_SmallObjectInvocationViaProxy_Shared', 'BM_SmallObjectInvocationViaProxyView', 'BM_SmallObjectInvocationViaVirtualFunction', @@ -44,8 +55,7 @@ benchmarks = { 'BM_LargeObjectInvocationViaVirtualFunction_Shared', 'BM_LargeObjectInvocationViaVirtualFunction_RawPtr', ], - 'ObjectOperation': [ - 'BM_SmallObjectRelocationViaProxy', + 'ObjectRelocation': [ 'BM_SmallObjectRelocationViaProxy_NothrowRelocatable', 'BM_SmallObjectRelocationViaUniquePtr', 'BM_SmallObjectRelocationViaAny', @@ -55,6 +65,7 @@ benchmarks = { 'BM_LargeObjectRelocationViaAny', ], } +#pragma autogen pop foreach suite : benchmarks.keys() foreach name : benchmarks[suite] @@ -63,6 +74,7 @@ foreach suite : benchmarks.keys() benchmarks_exe, args: [f'--benchmark_filter=^@name@$'], suite: suite, + depends: autogen_benchmarks, ) endforeach endforeach diff --git a/tools/meson.build b/tools/meson.build index 34c84eb9..cb4591bd 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -1,2 +1,3 @@ autogen_tests_exe = find_program('./meson_autogen_tests.py') autogen_doctest_exe = find_program('./meson_autogen_doctest.py') +autogen_benchmarks_exe = find_program('./meson_autogen_benchmarks.py') diff --git a/tools/meson_autogen_benchmarks.py b/tools/meson_autogen_benchmarks.py new file mode 100644 index 00000000..d85e5998 --- /dev/null +++ b/tools/meson_autogen_benchmarks.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# pyright: strict + +import re +import sys +from pathlib import Path + +from mesonbuild import mformat + +PATTERN = re.compile(r"(?=[A-Z])") + +benchmarkfile = Path(sys.argv[1]) +mesonfile = Path(sys.argv[2]) + +with benchmarkfile.open(encoding="utf-8") as f: + bench = [line.rstrip() for line in f.readlines()] + +with mesonfile.open(encoding="utf-8") as f: + build = f.readlines() + +begin = -1 +end = -1 + +for i, line in enumerate(build): + if begin == -1 and line.strip() == "#pragma autogen push": + begin = i + 1 + elif end == -1 and line.strip() == "#pragma autogen pop": + end = i + +if begin == -1 or end == -1: + raise ValueError + +benchmarks: "dict[str, list[str]]" = {} + +for name in bench: + suite = "".join(PATTERN.split(name.split('_', 1)[1])[2:4]) + if suite not in benchmarks: + benchmarks[suite] = [] + else: + benchmarks[suite].append(name) + +config = mformat.get_meson_format([mesonfile]) +formatter = mformat.Formatter(config, False, False) +pretty = formatter.format(f"{benchmarks = }", mesonfile) + +if pretty == "".join(build[begin:end]): + exit() + +with mesonfile.open("w", encoding="utf-8") as f: + f.writelines(build[:begin]) + _ = f.write(pretty) + f.writelines(build[end:]) From 4e64a00db73df8489c77f20b8ba3c19d43e0b6d3 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 13:22:11 +0800 Subject: [PATCH 19/40] build: make meson use common doctest extract logic --- docs/meson.build | 90 +++++++++------------------------- tools/meson.build | 1 + tools/meson_autogen_doctest.py | 6 ++- tools/meson_extract_doctest.py | 18 +++++++ 4 files changed, 47 insertions(+), 68 deletions(-) create mode 100644 tools/meson_extract_doctest.py diff --git a/docs/meson.build b/docs/meson.build index fd0ec39c..dc496c02 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -1,5 +1,3 @@ -fs = import('fs') - maybe_fmt_dep = dependency( 'fmt', version: fmt_spec, @@ -84,73 +82,31 @@ install_data( examples = [] foreach doc : docs - code = '' deps = [msft_proxy4_dep] - - state = 0 - lines = fs.read(doc).splitlines() - foreach line : lines - if state == 0 - if line.contains('## Example') - if code != '' - error( - 'File', - doc, - 'contains more than one "## Example" C++ code block.', - ) - endif - state = 1 - endif - elif state == 1 - if line == '' - state = 2 - else - state = 0 - endif - elif state == 2 - if line == '```cpp' - state = 3 - else - state = 0 - endif - elif state == 3 - if line != '```' - if line.contains('') - deps += maybe_fmt_dep - endif - code += line + '\n' - else - code = code.substring(0, -1) - state = 0 - endif - endif - endforeach - if code != '' - cfg = { - 'MD_PATH': 'docs' / doc, - 'CODE': code, - } - name = doc.replace('/', '_').substring(0, -3) - example_exe = executable( - f'example_@name@', - configure_file( - configuration: cfg, - input: 'example.cpp.in', - output: f'example_@name@.cpp', - ), - extra_files: doc, - implicit_include_directories: false, - dependencies: deps, - build_by_default: false, - ) - examples += example_exe - test( - name, - example_exe, - suite: 'ProxyExamples', - depends: autogen_glob, - ) + if doc.contains('fmt') + deps += maybe_fmt_dep endif + + name = doc.replace('/', '_').substring(0, -3) + example_exe = executable( + f'example_@name@', + custom_target( + command: [extract_doctest_exe, '@INPUT@', '@OUTPUT@'], + input: doc, + output: f'@name@.cpp', + ), + extra_files: doc, + implicit_include_directories: false, + dependencies: deps, + build_by_default: false, + ) + examples += example_exe + test( + name, + example_exe, + suite: 'ProxyExamples', + depends: autogen_glob, + ) endforeach alias_target('examples', examples) diff --git a/tools/meson.build b/tools/meson.build index cb4591bd..87398024 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -1,3 +1,4 @@ autogen_tests_exe = find_program('./meson_autogen_tests.py') autogen_doctest_exe = find_program('./meson_autogen_doctest.py') autogen_benchmarks_exe = find_program('./meson_autogen_benchmarks.py') +extract_doctest_exe = find_program('./meson_extract_doctest.py') diff --git a/tools/meson_autogen_doctest.py b/tools/meson_autogen_doctest.py index 75f5c4d1..f07efcf3 100644 --- a/tools/meson_autogen_doctest.py +++ b/tools/meson_autogen_doctest.py @@ -26,7 +26,11 @@ if begin == -1 or end == -1: raise ValueError -docs = [str(path.relative_to(directory).as_posix()) for path in directory.glob("**/*.md") if extract_cpp_code(path) is not None] +docs = [ + str(path.relative_to(directory).as_posix()) + for path in directory.glob("**/*.md") + if extract_cpp_code(path) is not None +] config = mformat.get_meson_format([mesonfile]) formatter = mformat.Formatter(config, False, False) diff --git a/tools/meson_extract_doctest.py b/tools/meson_extract_doctest.py new file mode 100644 index 00000000..243ab654 --- /dev/null +++ b/tools/meson_extract_doctest.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# pyright: strict + +import sys +from pathlib import Path + +from extract_example_code_from_docs import extract_cpp_code + +infile = Path(sys.argv[1]) +outfile = Path(sys.argv[2]) + +cpp_code = extract_cpp_code(infile) + +if not cpp_code: + raise ValueError + +with open(outfile, "w") as f: + _ = f.write(cpp_code) From 337c368773c3fe78a1fe2af5c46963f0c92b0963 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 14:08:52 +0800 Subject: [PATCH 20/40] build/meson: auto disable tests if in a subproject --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 4f9686ce..a54d815a 100644 --- a/meson.build +++ b/meson.build @@ -124,7 +124,7 @@ meson.override_dependency(meson.project_name() + '_module', msft_proxy4_mod) subdir('tools') -tests = get_option('tests') +tests = get_option('tests').disable_auto_if(meson.is_subproject()) gtest_dep = dependency( 'gtest_main', main: true, From cf353915f7a3f2460f6384402a519b2d206b7109 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 14:24:56 +0800 Subject: [PATCH 21/40] build/meson: auto disable benchmarks if in a subproject --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index a54d815a..d88f1367 100644 --- a/meson.build +++ b/meson.build @@ -141,7 +141,7 @@ subdir( if_found: [gtest_dep, fmt_dep], ) -benchmarks = get_option('benchmarks') +benchmarks = get_option('benchmarks').disable_auto_if(meson.is_subproject()) benchmark_dep = dependency( 'benchmark_main', required: benchmarks, From 479b2c169e3cd2e12bcb990eaec87ec8a70cd407 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Wed, 3 Dec 2025 14:26:26 +0800 Subject: [PATCH 22/40] build/meson: remove docdir installation the glob only contains files with C++ source code now. --- docs/meson.build | 12 ------------ meson.options | 5 ----- 2 files changed, 17 deletions(-) diff --git a/docs/meson.build b/docs/meson.build index dc496c02..3a513325 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -67,18 +67,6 @@ docs = [ ] #pragma autogen pop -docdir = get_option('docdir') -if docdir == '' - docdir = get_option('datadir') / 'doc' / meson.project_name() -endif -install_data( - docs, - follow_symlinks: true, - install_dir: docdir, - preserve_path: true, - install_tag: 'docs', -) - examples = [] foreach doc : docs diff --git a/meson.options b/meson.options index 2d88e8ed..f337dd2e 100644 --- a/meson.options +++ b/meson.options @@ -28,8 +28,3 @@ option( value: 'auto', description: 'Build with C++ modules support', ) -option( - 'docdir', - type: 'string', - description: 'Documentation directory', -) From 66929532e58953b3c9389a8fcdec69c2a714481c Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Sat, 6 Dec 2025 01:23:18 +0800 Subject: [PATCH 23/40] build/meson: remove all autogen --- benchmarks/meson.build | 90 +------ docs/example.cpp.in | 4 - docs/meson.build | 77 +----- meson.build | 10 +- tests/meson.build | 378 ++++-------------------------- tests/modules/meson.build | 54 +---- tools/meson.build | 4 - tools/meson_autogen_benchmarks.py | 52 ---- tools/meson_autogen_doctest.py | 45 ---- tools/meson_autogen_tests.py | 44 ---- tools/meson_extract_doctest.py | 7 + 11 files changed, 94 insertions(+), 671 deletions(-) delete mode 100644 docs/example.cpp.in delete mode 100644 tools/meson.build delete mode 100644 tools/meson_autogen_benchmarks.py delete mode 100644 tools/meson_autogen_doctest.py delete mode 100644 tools/meson_autogen_tests.py diff --git a/benchmarks/meson.build b/benchmarks/meson.build index a607ed35..41ae9ef9 100644 --- a/benchmarks/meson.build +++ b/benchmarks/meson.build @@ -1,80 +1,14 @@ -benchmarks_exe = executable( - 'msft_proxy_benchmarks', - files( - 'proxy_creation_benchmark.cpp', - 'proxy_operation_benchmark.cpp', - 'proxy_operation_benchmark_context.cpp', - ), - implicit_include_directories: false, - dependencies: [msft_proxy4_dep, benchmark_dep], - build_by_default: false, -) - -autogen_benchmarks = custom_target( - command: [ - autogen_benchmarks_exe, - custom_target( - command: [benchmarks_exe, '--benchmark_list_tests'], - capture: true, - output: 'tests.txt', +benchmark( + 'ProxyBenchmarks', + executable( + 'msft_proxy_benchmarks', + files( + 'proxy_creation_benchmark.cpp', + 'proxy_operation_benchmark.cpp', + 'proxy_operation_benchmark_context.cpp', ), - meson.current_source_dir() / 'meson.build', - ], - output: 'autogen.stamp', - build_by_default: true, + implicit_include_directories: false, + dependencies: [msft_proxy4_dep, benchmark_dep], + build_by_default: false, + ), ) - -#pragma autogen push -benchmarks = { - 'ObjectCreation': [ - 'BM_SmallObjectCreationWithProxy_Shared', - 'BM_SmallObjectCreationWithProxy_SharedPooled', - 'BM_SmallObjectCreationWithUniquePtr', - 'BM_SmallObjectCreationWithSharedPtr', - 'BM_SmallObjectCreationWithSharedPtr_Pooled', - 'BM_SmallObjectCreationWithAny', - 'BM_LargeObjectCreationWithProxy', - 'BM_LargeObjectCreationWithProxy_Pooled', - 'BM_LargeObjectCreationWithProxy_Shared', - 'BM_LargeObjectCreationWithProxy_SharedPooled', - 'BM_LargeObjectCreationWithUniquePtr', - 'BM_LargeObjectCreationWithSharedPtr', - 'BM_LargeObjectCreationWithSharedPtr_Pooled', - 'BM_LargeObjectCreationWithAny', - ], - 'ObjectInvocation': [ - 'BM_SmallObjectInvocationViaProxy_Shared', - 'BM_SmallObjectInvocationViaProxyView', - 'BM_SmallObjectInvocationViaVirtualFunction', - 'BM_SmallObjectInvocationViaVirtualFunction_Shared', - 'BM_SmallObjectInvocationViaVirtualFunction_RawPtr', - 'BM_LargeObjectInvocationViaProxy', - 'BM_LargeObjectInvocationViaProxy_Shared', - 'BM_LargeObjectInvocationViaProxyView', - 'BM_LargeObjectInvocationViaVirtualFunction', - 'BM_LargeObjectInvocationViaVirtualFunction_Shared', - 'BM_LargeObjectInvocationViaVirtualFunction_RawPtr', - ], - 'ObjectRelocation': [ - 'BM_SmallObjectRelocationViaProxy_NothrowRelocatable', - 'BM_SmallObjectRelocationViaUniquePtr', - 'BM_SmallObjectRelocationViaAny', - 'BM_LargeObjectRelocationViaProxy', - 'BM_LargeObjectRelocationViaProxy_NothrowRelocatable', - 'BM_LargeObjectRelocationViaUniquePtr', - 'BM_LargeObjectRelocationViaAny', - ], -} -#pragma autogen pop - -foreach suite : benchmarks.keys() - foreach name : benchmarks[suite] - benchmark( - name, - benchmarks_exe, - args: [f'--benchmark_filter=^@name@$'], - suite: suite, - depends: autogen_benchmarks, - ) - endforeach -endforeach diff --git a/docs/example.cpp.in b/docs/example.cpp.in deleted file mode 100644 index 1f228572..00000000 --- a/docs/example.cpp.in +++ /dev/null @@ -1,4 +0,0 @@ -// This file was auto-generated from: -// @MD_PATH@ - -@CODE@ diff --git a/docs/meson.build b/docs/meson.build index 3a513325..1b18b777 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -1,78 +1,18 @@ -maybe_fmt_dep = dependency( - 'fmt', - version: fmt_spec, - required: false, - disabler: true, -) +extract_doctest_exe = find_program('../tools/meson_extract_doctest.py') -autogen_glob = custom_target( - command: [autogen_doctest_exe, meson.current_source_dir()], - output: 'autogen.stamp', - build_by_default: true, -) - -#pragma autogen push -docs = [ - 'spec/PRO_DEF_FREE_AS_MEM_DISPATCH.md', - 'spec/PRO_DEF_FREE_DISPATCH.md', - 'spec/PRO_DEF_MEM_DISPATCH.md', - 'spec/allocate_proxy.md', - 'spec/allocate_proxy_shared.md', - 'spec/facade_aware_overload_t.md', - 'spec/inplace_proxiable_target.md', - 'spec/is_bitwise_trivially_relocatable.md', - 'spec/make_proxy.md', - 'spec/make_proxy_inplace.md', - 'spec/make_proxy_shared.md', - 'spec/make_proxy_view.md', - 'spec/msft_lib_proxy.md', - 'spec/proxiable.md', - 'spec/proxiable_target.md', - 'spec/proxy_invoke.md', - 'spec/proxy_reflect.md', - 'spec/proxy_view.md', - 'spec/skills_as_view.md', - 'spec/skills_as_weak.md', - 'spec/skills_fmt_format.md', - 'spec/skills_format.md', - 'spec/skills_slim.md', - 'spec/weak_proxy.md', - 'spec/basic_facade_builder/README.md', - 'spec/basic_facade_builder/add_convention.md', - 'spec/basic_facade_builder/add_facade.md', - 'spec/basic_facade_builder/add_reflection.md', - 'spec/basic_facade_builder/add_skill.md', - 'spec/basic_facade_builder/build.md', - 'spec/basic_facade_builder/restrict_layout.md', - 'spec/basic_facade_builder/support_copy.md', - 'spec/basic_facade_builder/support_destruction.md', - 'spec/basic_facade_builder/support_relocation.md', - 'spec/explicit_conversion_dispatch/README.md', - 'spec/implicit_conversion_dispatch/README.md', - 'spec/operator_dispatch/README.md', - 'spec/proxy/README.md', - 'spec/proxy/constructor.md', - 'spec/proxy/destructor.md', - 'spec/proxy/emplace.md', - 'spec/proxy/friend_operator_equality.md', - 'spec/proxy/friend_swap.md', - 'spec/proxy/indirection.md', - 'spec/proxy/operator_bool.md', - 'spec/proxy/reset.md', - 'spec/skills_rtti/README.md', - 'spec/skills_rtti/proxy_cast.md', - 'spec/skills_rtti/proxy_typeid.md', - 'spec/substitution_dispatch/README.md', - 'spec/weak_dispatch/README.md', -] -#pragma autogen pop +docs = run_command( + extract_doctest_exe, + meson.current_source_dir(), + capture: true, + check: true, +).stdout().strip('\0').split('\0') examples = [] foreach doc : docs deps = [msft_proxy4_dep] if doc.contains('fmt') - deps += maybe_fmt_dep + deps += fmt_dep endif name = doc.replace('/', '_').substring(0, -3) @@ -93,7 +33,6 @@ foreach doc : docs name, example_exe, suite: 'ProxyExamples', - depends: autogen_glob, ) endforeach diff --git a/meson.build b/meson.build index d88f1367..c00b0089 100644 --- a/meson.build +++ b/meson.build @@ -122,23 +122,21 @@ endif meson.override_dependency(meson.project_name(), msft_proxy4_dep) meson.override_dependency(meson.project_name() + '_module', msft_proxy4_mod) -subdir('tools') - tests = get_option('tests').disable_auto_if(meson.is_subproject()) gtest_dep = dependency( 'gtest_main', main: true, required: tests, ) -fmt_spec = ['>=6.1.0'] fmt_dep = dependency( 'fmt', - version: fmt_spec, - required: tests, + version: '>=6.1.0', + required: false, + disabler: true, ) subdir( 'tests', - if_found: [gtest_dep, fmt_dep], + if_found: gtest_dep, ) benchmarks = get_option('benchmarks').disable_auto_if(meson.is_subproject()) diff --git a/tests/meson.build b/tests/meson.build index 4f185e1b..fa4be9cb 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,316 +1,40 @@ -tests_exe = executable( - 'msft_proxy_tests', - files( - 'proxy_creation_tests.cpp', - 'proxy_dispatch_tests.cpp', - 'proxy_fmt_format_tests.cpp', - 'proxy_format_tests.cpp', - 'proxy_integration_tests.cpp', - 'proxy_invocation_tests.cpp', - 'proxy_lifetime_tests.cpp', - 'proxy_reflection_tests.cpp', - 'proxy_regression_tests.cpp', - 'proxy_rtti_tests.cpp', - 'proxy_traits_tests.cpp', - 'proxy_view_tests.cpp', - ), - implicit_include_directories: false, - dependencies: [msft_proxy4_dep, gtest_dep, fmt_dep], - build_by_default: false, -) - -autogen_tests = custom_target( - command: [ - autogen_tests_exe, - custom_target( - command: [tests_exe, '--gtest_list_tests', '--gtest_output=json:@OUTPUT@'], - output: 'tests.json', - ), - meson.current_source_dir() / 'meson.build', - ], - output: 'autogen.stamp', - build_by_default: true, -) - -#pragma autogen push -tests = { - 'ProxyCreationTests': [ - 'TestMakeProxyInplace_FromValue', - 'TestMakeProxyInplace_InPlace', - 'TestMakeProxyInplace_InPlaceInitializerList', - 'TestMakeProxyInplace_Lifetime_Copy', - 'TestMakeProxyInplace_Lifetime_Move', - 'TestAllocateProxy_DirectAllocator_FromValue', - 'TestAllocateProxy_DirectAllocator_InPlace', - 'TestAllocateProxy_DirectAllocator_InPlaceInitializerList', - 'TestAllocateProxy_DirectAllocator_Lifetime_Copy', - 'TestAllocateProxy_DirectAllocator_Lifetime_Move', - 'TestAllocateProxy_IndirectAllocator_FromValue', - 'TestAllocateProxy_IndirectAllocator_InPlace', - 'TestAllocateProxy_IndirectAllocator_InPlaceInitializerList', - 'TestAllocateProxy_IndirectAllocator_Lifetime_Copy', - 'TestAllocateProxy_IndirectAllocator_Lifetime_Move', - 'TestMakeProxy_WithSBO_FromValue', - 'TestMakeProxy_WithSBO_InPlace', - 'TestMakeProxy_WithSBO_InPlaceInitializerList', - 'TestMakeProxy_WithSBO_Lifetime_Copy', - 'TestMakeProxy_WithSBO_Lifetime_Move', - 'TestMakeProxy_WithoutSBO_FromValue', - 'TestMakeProxy_WithoutSBO_InPlace', - 'TestMakeProxy_WithoutSBO_InPlaceInitializerList', - 'TestMakeProxy_WithoutSBO_Lifetime_Copy', - 'TestMakeProxy_WithoutSBO_Lifetime_Move', - 'TestMakeProxy_SfinaeUnsafe', - 'TestAllocateProxyShared_SharedCompact_FromValue', - 'TestAllocateProxyShared_SharedCompact_InPlace', - 'TestAllocateProxyShared_SharedCompact_InPlaceInitializerList', - 'TestAllocateProxyShared_SharedCompact_Lifetime_Copy', - 'TestAllocateProxyShared_SharedCompact_Lifetime_Move', - 'TestAllocateProxyShared_StrongCompact_FromValue', - 'TestAllocateProxyShared_StrongCompact_InPlace', - 'TestAllocateProxyShared_StrongCompact_InPlaceInitializerList', - 'TestAllocateProxyShared_StrongCompact_Lifetime_Copy', - 'TestAllocateProxyShared_StrongCompact_Lifetime_Move', - 'TestAllocateProxyShared_StrongCompact_Lifetime_WeakAccess', - 'TestMakeProxyShared_SharedCompact_FromValue', - 'TestMakeProxyShared_SharedCompact_InPlace', - 'TestMakeProxyShared_SharedCompact_InPlaceInitializerList', - 'TestMakeProxyShared_SharedCompact_Lifetime_Copy', - 'TestMakeProxyShared_SharedCompact_Lifetime_Move', - 'TestMakeProxyShared_StrongCompact_FromValue', - 'TestMakeProxyShared_StrongCompact_InPlace', - 'TestMakeProxyShared_StrongCompact_InPlaceInitializerList', - 'TestMakeProxyShared_StrongCompact_Lifetime_Copy', - 'TestMakeProxyShared_StrongCompact_Lifetime_Move', - 'TestMakeProxyShared_StrongCompact_Lifetime_WeakAccess', - 'TestMakeProxyShared_StrongCompact_Lifetime_WeakConversion', - 'TestStdWeakPtrCompatibility', - 'TestMakeProxyView', - ], - 'ProxyDispatchTests': [ - 'TestOpPlus', - 'TestOpMinus', - 'TestOpAsterisk', - 'TestOpSlash', - 'TestOpModulo', - 'TestOpIncrement', - 'TestOpDecrement', - 'TestOpEqualTo', - 'TestOpNotEqualTo', - 'TestOpGreaterThan', - 'TestOpLessThan', - 'TestOpGreaterThanOrEqualTo', - 'TestOpLessThanOrEqualTo', - 'TestOpSpaceship', - 'TestOpLogicalNot', - 'TestOpLogicalAnd', - 'TestOpLogicalOr', - 'TestOpTilde', - 'TestOpAmpersand', - 'TestOpPipe', - 'TestOpCaret', - 'TestOpLeftShift', - 'TestOpRightShift', - 'TestOpPlusAssignment', - 'TestOpMinusAssignment', - 'TestOpMultiplicationAssignment', - 'TestOpDivisionAssignment', - 'TestOpModuloAssignment', - 'TestOpBitwiseAndAssignment', - 'TestOpBitwiseOrAssignment', - 'TestOpBitwiseXorAssignment', - 'TestOpLeftShiftAssignment', - 'TestOpRightShiftAssignment', - 'TestOpComma', - 'TestOpPtrToMem', - 'TestOpParentheses', - 'TestOpBrackets_OneDimensional', - 'TestRhsOpPlus', - 'TestRhsOpMinus', - 'TestRhsOpAsterisk', - 'TestRhsOpSlash', - 'TestRhsOpModulo', - 'TestRhsOpEqualTo', - 'TestRhsOpNotEqualTo', - 'TestRhsOpGreaterThan', - 'TestRhsOpLessThan', - 'TestRhsOpGreaterThanOrEqualTo', - 'TestRhsOpLessThanOrEqualTo', - 'TestRhsOpSpaceship', - 'TestRhsOpLogicalAnd', - 'TestRhsOpLogicalOr', - 'TestRhsOpAmpersand', - 'TestRhsOpPipe', - 'TestRhsOpCaret', - 'TestRhsOpLeftShift', - 'TestRhsOpRightShift', - 'TestRhsOpPlusAssignment', - 'TestRhsOpMinusAssignment', - 'TestRhsOpMultiplicationAssignment', - 'TestRhsOpDivisionAssignment', - 'TestRhsOpModuloAssignment', - 'TestRhsOpBitwiseAndAssignment', - 'TestRhsOpBitwiseOrAssignment', - 'TestRhsOpBitwiseXorAssignment', - 'TestRhsOpLeftShiftAssignment', - 'TestRhsOpRightShiftAssignment', - 'TestRhsOpComma', - 'TestRhsOpPtrToMem', - 'TestIndirectConversion', - 'TestDirectConversion', - 'TestImplciitConversion', - 'TestFreeAsMemDispatch', - 'TestSubstitutionDispatch', - ], - 'ProxyFmtFormatTests': ['TestFormat', 'TestWformat'], - 'ProxyFormatTests': ['TestFormat', 'TestWformat'], - 'ProxyIntegrationTests': ['TestDrawable', 'TestLogger'], - 'ProxyInvocationTests': [ - 'TestArgumentForwarding', - 'TestThrow', - 'TestMultipleDispatches_Unique', - 'TestMultipleDispatches_Duplicated', - 'TestRecursiveDefinition', - 'TestOverloadResolution_Member', - 'TestOverloadResolution_Free', - 'TestOverloadResolution_FreeAsMem', - 'TestNoexcept', - 'TestFunctionPointer', - 'TestMemberDispatchDefault', - 'TestFreeDispatchDefault', - 'TestObserverDispatch', - 'TestQualifiedConvention_Member', - 'TestQualifiedConvention_Free', - ], - 'ProxyLifetimeTests': [ - 'TestDefaultConstrction', - 'TestNullConstrction_Nullptr', - 'TestNullConstrction_TypedNullPointer', - 'TestPolyConstrction_FromValue', - 'TestPolyConstrction_FromValue_Exception', - 'TestPolyConstrction_InPlace', - 'TestPolyConstrction_InPlace_Exception', - 'TestPolyConstrction_InPlaceInitializerList', - 'TestPolyConstrction_InPlaceInitializerList_Exception', - 'TestCopyConstrction_FromValue', - 'TestCopyConstrction_FromValue_Exception', - 'TestCopyConstrction_FromNull', - 'TestMoveConstrction_FromValue', - 'TestMoveConstrction_FromValue_Trivial', - 'TestMoveConstrction_FromNull', - 'TestNullAssignment_FromNullptr_ToValue', - 'TestNullAssignment_FromTypedNullPointer_ToValue', - 'TestNullAssignment_ToNull', - 'TestPolyAssignment_ToValue', - 'TestPolyAssignment_ToValue_Exception', - 'TestPolyAssignment_FromValue_ToNull', - 'TestPolyAssignment_FromValue_ToNull_Exception', - 'TestPolyAssignment_InPlace_ToValue', - 'TestPolyAssignment_InPlace_ToValue_Exception', - 'TestPolyAssignment_InPlace_ToNull', - 'TestPolyAssignment_InPlace_ToNull_Exception', - 'TestPolyAssignment_InPlaceInitializerList_ToValue', - 'TestPolyAssignment_InPlaceInitializerList_ToValue_Exception', - 'TestPolyAssignment_InPlaceInitializerList_ToNull', - 'TestPolyAssignment_InPlaceInitializerList_ToNull_Exception', - 'TestCopyAssignment_FromValue_ToValue', - 'TestCopyAssignment_FromValue_ToValue_Exception', - 'TestCopyAssignment_FromValue_ToSelf', - 'TestCopyAssignment_FromValue_ToNull', - 'TestCopyAssignment_FromValue_ToNull_Exception', - 'TestCopyAssignment_FromNull_ToValue', - 'TestCopyAssignment_FromNull_ToSelf', - 'TestCopyAssignment_FromNull_ToNull', - 'TestMoveAssignment_FromValue_ToValue', - 'TestMoveAssignment_FromValue_ToValue_Exception', - 'TestMoveAssignment_FromValue_ToSelf', - 'TestMoveAssignment_FromValue_ToNull', - 'TestMoveAssignment_FromValue_ToNull_Exception', - 'TestMoveAssignment_FromNull_ToValue', - 'TestMoveAssignment_FromNull_ToSelf', - 'TestMoveAssignment_FromNull_ToNull', - 'TestHasValue', - 'TestOperatorBool', - 'TestEqualsToNullptr', - 'TestReset_FromValue', - 'TestReset_FromNull', - 'TestSwap_Value_Value', - 'TestSwap_Value_Self', - 'TestSwap_Value_Null', - 'TestSwap_Null_Value', - 'TestSwap_Null_Self', - 'TestSwap_Null_Null', - 'TestSwap_Trivial', - 'Test_DirectConvension_Lvalue', - 'Test_DirectConvension_Rvalue', - 'Test_DirectConvension_Rvalue_Exception', - 'Test_CopySubstitution_FromValue', - 'Test_CopySubstitution_FromNull', - 'Test_MoveSubstitution_FromValue', - 'Test_MoveSubstitution_FromNull', - ], - 'ProxyReflectionTests': [ - 'TestRtti_RawPtr', - 'TestRtti_FancyPtr', - 'TestTraits_RawPtr', - 'TestTraits_FancyPtr', - ], - 'ProxyRegressionTests': [ - 'TestUnexpectedCompilerWarning', - 'TestProxiableSelfDependency', - ], - 'ProxyRttiTests': [ - 'TestIndirectCast_Ref_Succeed', - 'TestIndirectCast_Ref_Fail', - 'TestIndirectCast_ConstRef_Succeed', - 'TestIndirectCast_ConstRef_Fail', - 'TestIndirectCast_Copy_Succeed', - 'TestIndirectCast_Copy_Fail', - 'TestIndirectCast_Move_Succeed', - 'TestIndirectCast_Move_Fail', - 'TestIndirectCast_Ptr_Succeed', - 'TestIndirectCast_Ptr_Fail', - 'TestIndirectCast_ConstPtr_Succeed', - 'TestIndirectCast_ConstPtr_Fail', - 'TestIndirectTypeid', - 'TestDirectCast_Ref_Succeed', - 'TestDirectCast_Ref_Fail', - 'TestDirectCast_ConstRef_Succeed', - 'TestDirectCast_ConstRef_Fail', - 'TestDirectCast_Copy_Succeed', - 'TestDirectCast_Copy_Fail', - 'TestDirectCast_Move_Succeed', - 'TestDirectCast_Move_Fail', - 'TestDirectCast_Ptr_Succeed', - 'TestDirectCast_Ptr_Fail', - 'TestDirectCast_ConstPtr_Succeed', - 'TestDirectCast_ConstPtr_Fail', - 'TestDirectTypeid', - ], - 'ProxyViewTests': [ - 'TestViewOfNull', - 'TestViewIndependentUse', - 'TestViewOfOwning', - 'TestViewOfNonOwning', - 'TestOverloadShadowing', - 'TestSubstitution_FromNull', - 'TestSubstitution_FromValue', - 'TestFacadeAware', - ], -} -#pragma autogen pop +test_srcs = [ + 'proxy_creation_tests.cpp', + 'proxy_dispatch_tests.cpp', + 'proxy_fmt_format_tests.cpp', + 'proxy_format_tests.cpp', + 'proxy_integration_tests.cpp', + 'proxy_invocation_tests.cpp', + 'proxy_lifetime_tests.cpp', + 'proxy_reflection_tests.cpp', + 'proxy_regression_tests.cpp', + 'proxy_rtti_tests.cpp', + 'proxy_traits_tests.cpp', + 'proxy_view_tests.cpp', +] -foreach suite : tests.keys() - foreach name : tests[suite] - test( - name, - tests_exe, - args: [f'--gtest_filter=@suite@.@name@'], - protocol: 'gtest', - suite: suite, - depends: autogen_tests, - ) +foreach src : test_srcs + test_deps = [msft_proxy4_dep, gtest_dep] + name = src.substring(6, -10) + if name.contains('fmt') + test_deps += fmt_dep + endif + title = '' + foreach part : name.split('_') + title += part.substring(0, 1).to_upper() + part.substring(1) endforeach + + test( + f'Proxy@title@Tests', + executable( + f'msft_proxy_@name@_tests', + src, + implicit_include_directories: false, + dependencies: test_deps, + build_by_default: false, + ), + protocol: 'gtest', + ) endforeach freestanding = get_option('tests_freestanding') @@ -318,27 +42,29 @@ freestanding_cflags = ['-ffreestanding', '-fno-exceptions', '-fno-rtti'] freestanding_ldflags = ['-nodefaultlibs'] if cxx.has_multi_arguments( - freestanding_cflags + freestanding_ldflags, + freestanding_cflags, + freestanding_ldflags, required: freestanding, ) libc_dep = cxx.find_library( 'c', required: freestanding, ) - freestanding_tests_exe = executable( - 'msft_proxy_freestanding_tests', - files('freestanding/proxy_freestanding_tests.cpp'), - implicit_include_directories: false, - dependencies: [msft_proxy4_dep, libc_dep], - cpp_args: freestanding_cflags, - link_args: get_option('b_sanitize') == '' ? freestanding_ldflags : [], - build_by_default: false, - ) - test( - 'TestFreestanding', - freestanding_tests_exe, - suite: 'ProxyFreestandingSupportTests', - ) + + if libc_dep.found() + test( + 'ProxyFreestandingSupportTests', + executable( + 'msft_proxy_freestanding_tests', + files('freestanding/proxy_freestanding_tests.cpp'), + implicit_include_directories: false, + dependencies: [msft_proxy4_dep, libc_dep], + cpp_args: freestanding_cflags + freestanding_ldflags, + link_args: get_option('b_sanitize') == 'none' ? freestanding_ldflags : [], + build_by_default: false, + ), + ) + endif endif subdir( diff --git a/tests/modules/meson.build b/tests/modules/meson.build index c6ffde59..136d8378 100644 --- a/tests/modules/meson.build +++ b/tests/modules/meson.build @@ -1,44 +1,12 @@ -tests_modules_exe = executable( - 'msft_proxy_tests_modules', - files('foo.cpp', 'impl.cpp', 'main.cpp'), - implicit_include_directories: false, - cpp_args: modules_interface_cflags, - dependencies: [msft_proxy4_mod, gtest_dep], - build_by_default: false, +test( + 'ProxyModuleSupportTests', + executable( + 'msft_proxy_tests_modules', + files('foo.cpp', 'impl.cpp', 'main.cpp'), + implicit_include_directories: false, + cpp_args: modules_interface_cflags, + dependencies: [msft_proxy4_mod, gtest_dep], + build_by_default: false, + ), + protocol: 'gtest', ) - -autogen_modules_tests = custom_target( - command: [ - autogen_tests_exe, - custom_target( - command: [ - tests_modules_exe, - '--gtest_list_tests', - '--gtest_output=json:@OUTPUT@', - ], - output: 'tests.json', - ), - meson.current_source_dir() / 'meson.build', - ], - output: 'autogen.stamp', - build_by_default: true, -) - -#pragma autogen push -tests = { - 'ProxyModuleSupportTests': ['TestBasic'], -} -#pragma autogen pop - -foreach suite : tests.keys() - foreach name : tests[suite] - test( - name, - tests_modules_exe, - args: [f'--gtest_filter=@suite@.@name@'], - protocol: 'gtest', - suite: suite, - depends: autogen_modules_tests, - ) - endforeach -endforeach diff --git a/tools/meson.build b/tools/meson.build deleted file mode 100644 index 87398024..00000000 --- a/tools/meson.build +++ /dev/null @@ -1,4 +0,0 @@ -autogen_tests_exe = find_program('./meson_autogen_tests.py') -autogen_doctest_exe = find_program('./meson_autogen_doctest.py') -autogen_benchmarks_exe = find_program('./meson_autogen_benchmarks.py') -extract_doctest_exe = find_program('./meson_extract_doctest.py') diff --git a/tools/meson_autogen_benchmarks.py b/tools/meson_autogen_benchmarks.py deleted file mode 100644 index d85e5998..00000000 --- a/tools/meson_autogen_benchmarks.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python3 -# pyright: strict - -import re -import sys -from pathlib import Path - -from mesonbuild import mformat - -PATTERN = re.compile(r"(?=[A-Z])") - -benchmarkfile = Path(sys.argv[1]) -mesonfile = Path(sys.argv[2]) - -with benchmarkfile.open(encoding="utf-8") as f: - bench = [line.rstrip() for line in f.readlines()] - -with mesonfile.open(encoding="utf-8") as f: - build = f.readlines() - -begin = -1 -end = -1 - -for i, line in enumerate(build): - if begin == -1 and line.strip() == "#pragma autogen push": - begin = i + 1 - elif end == -1 and line.strip() == "#pragma autogen pop": - end = i - -if begin == -1 or end == -1: - raise ValueError - -benchmarks: "dict[str, list[str]]" = {} - -for name in bench: - suite = "".join(PATTERN.split(name.split('_', 1)[1])[2:4]) - if suite not in benchmarks: - benchmarks[suite] = [] - else: - benchmarks[suite].append(name) - -config = mformat.get_meson_format([mesonfile]) -formatter = mformat.Formatter(config, False, False) -pretty = formatter.format(f"{benchmarks = }", mesonfile) - -if pretty == "".join(build[begin:end]): - exit() - -with mesonfile.open("w", encoding="utf-8") as f: - f.writelines(build[:begin]) - _ = f.write(pretty) - f.writelines(build[end:]) diff --git a/tools/meson_autogen_doctest.py b/tools/meson_autogen_doctest.py deleted file mode 100644 index f07efcf3..00000000 --- a/tools/meson_autogen_doctest.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python3 -# pyright: strict - -import sys -from pathlib import Path - -from mesonbuild import mformat - -from extract_example_code_from_docs import extract_cpp_code - -directory = Path(sys.argv[1]) -mesonfile = directory / "meson.build" - -with mesonfile.open(encoding="utf-8") as f: - build = f.readlines() - -begin = -1 -end = -1 - -for i, line in enumerate(build): - if begin == -1 and line.strip() == "#pragma autogen push": - begin = i + 1 - elif end == -1 and line.strip() == "#pragma autogen pop": - end = i - -if begin == -1 or end == -1: - raise ValueError - -docs = [ - str(path.relative_to(directory).as_posix()) - for path in directory.glob("**/*.md") - if extract_cpp_code(path) is not None -] - -config = mformat.get_meson_format([mesonfile]) -formatter = mformat.Formatter(config, False, False) -pretty = formatter.format(f"{docs = }", mesonfile) - -if pretty == "".join(build[begin:end]): - exit() - -with mesonfile.open("w", encoding="utf-8") as f: - f.writelines(build[:begin]) - _ = f.write(pretty) - f.writelines(build[end:]) diff --git a/tools/meson_autogen_tests.py b/tools/meson_autogen_tests.py deleted file mode 100644 index d25e02c2..00000000 --- a/tools/meson_autogen_tests.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python3 -# pyright: strict - -import json -import sys -from pathlib import Path - -from mesonbuild import mformat - -testfile = Path(sys.argv[1]) -mesonfile = Path(sys.argv[2]) - -with testfile.open(encoding="utf-8") as f: - tests = { - suites["name"]: [suite["name"] for suite in suites["testsuite"]] - for suites in json.load(f)["testsuites"] - } - -with mesonfile.open(encoding="utf-8") as f: - build = f.readlines() - -begin = -1 -end = -1 - -for i, line in enumerate(build): - if begin == -1 and line.strip() == "#pragma autogen push": - begin = i + 1 - elif end == -1 and line.strip() == "#pragma autogen pop": - end = i - -if begin == -1 or end == -1: - raise ValueError - -config = mformat.get_meson_format([mesonfile]) -formatter = mformat.Formatter(config, False, False) -pretty = formatter.format(f"{tests = }", mesonfile) - -if pretty == "".join(build[begin:end]): - exit() - -with mesonfile.open("w", encoding="utf-8") as f: - f.writelines(build[:begin]) - _ = f.write(pretty) - f.writelines(build[end:]) diff --git a/tools/meson_extract_doctest.py b/tools/meson_extract_doctest.py index 243ab654..63bfc46e 100644 --- a/tools/meson_extract_doctest.py +++ b/tools/meson_extract_doctest.py @@ -7,6 +7,13 @@ from extract_example_code_from_docs import extract_cpp_code infile = Path(sys.argv[1]) +if infile.is_dir(): + for path in infile.glob("**/*.md"): + if extract_cpp_code(path) is None: + continue + print(str(path.relative_to(infile).as_posix()), end="\0") + exit() + outfile = Path(sys.argv[2]) cpp_code = extract_cpp_code(infile) From e020f0bc7cace063bc00241417e8a7bf54dcb46c Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Sat, 6 Dec 2025 01:24:22 +0800 Subject: [PATCH 24/40] build/meson: only add WINPTHREAD_COND_DECL workaround if winpthreads is found --- meson.build | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index c00b0089..4a258a6f 100644 --- a/meson.build +++ b/meson.build @@ -61,11 +61,12 @@ msft_proxy4_dep = declare_dependency( modules = get_option('modules') modules_interface_spec = { 'gcc': { - 'flags': [ - '-fmodules', - '-fdeps-format=p1689r5', + 'flags': ['-fmodules', '-fdeps-format=p1689r5'] + (cxx.has_header_symbol( + 'pthread.h', + '__WINPTHREADS_VERSION', + ) ? [ '-DWINPTHREAD_COND_DECL=WINPTHREADS_ALWAYS_INLINE', - ], + ] : []), 'check_only': ['-M'], }, 'msvc': { From 443b90f71c1b2269ef1776906cf28789171a7509 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Sat, 6 Dec 2025 01:25:38 +0800 Subject: [PATCH 25/40] ci: reword step names --- .github/workflows/meson.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index cede0ba5..f13d0438 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -150,17 +150,17 @@ jobs: env: ${{ matrix.mode.extra_envs }} run: | meson setup build --buildtype=release ${{ matrix.mode.args }} --vsenv - - name: Configuring + - name: Configure if: ${{ matrix.platform != 'windows-2025' }} env: ${{ matrix.mode.extra_envs }} run: | meson setup build --buildtype=release ${{ matrix.mode.args }} - - name: Building + - name: Build run: | meson compile -C build meson compile -C build msft_proxy_tests examples - - name: Running tests + - name: Run tests env: ${{ matrix.mode.extra_envs }} run: | meson test -C build --timeout-multiplier 5 --print-errorlogs From 124bce2edcc7b7e3e91c7d224bdfe91c56c048c2 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Sat, 6 Dec 2025 20:11:22 +0800 Subject: [PATCH 26/40] ci: move meson ci tests into bvt workflows --- .github/workflows/bvt-appleclang.yml | 28 +++- .github/workflows/bvt-clang.yml | 41 ++++-- .github/workflows/bvt-compatibility.yml | 89 ++++++------ .github/workflows/bvt-gcc.yml | 34 ++++- .github/workflows/bvt-msvc.yml | 24 +++- .github/workflows/bvt-nvhpc.yml | 33 ++++- .github/workflows/bvt-oneapi.yml | 43 ++++-- .github/workflows/meson.yml | 171 ------------------------ .github/workflows/pipeline-ci.yml | 4 - 9 files changed, 202 insertions(+), 265 deletions(-) delete mode 100644 .github/workflows/meson.yml diff --git a/.github/workflows/bvt-appleclang.yml b/.github/workflows/bvt-appleclang.yml index 32f84f1c..3e078e3d 100644 --- a/.github/workflows/bvt-appleclang.yml +++ b/.github/workflows/bvt-appleclang.yml @@ -4,28 +4,44 @@ on: jobs: bvt-appleclang: runs-on: macos-15 + strategy: + fail-fast: false + matrix: + buildsystem: [cmake, meson] + steps: - uses: actions/checkout@v4 + - name: install meson + if: ${{ matrix.buildsystem == 'meson' }} + run: pipx install meson + - name: check compiler versions run: | - clang --version + cc --version xcodebuild -version - - name: build and run test with AppleClang + - name: build and run test with AppleClang on cmake + if: ${{ matrix.buildsystem == 'cmake' }} run: | cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE cmake --build build -j ctest --test-dir build -j mkdir build/drop - chmod +x tools/dump_build_env.sh - ./tools/dump_build_env.sh clang++ build/drop/env-info.json + bash ./tools/dump_build_env.sh c++ build/drop/env-info.json - - name: run benchmarks + - name: build and run test with AppleClang on meson + if: ${{ matrix.buildsystem == 'meson' }} run: | - build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json + meson setup builddir --buildtype=release -Dtests=enabled + meson test -C builddir + + - name: run benchmarks + if: ${{ matrix.buildsystem == 'cmake' }} + run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json - name: archive benchmarking results + if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-appleclang diff --git a/.github/workflows/bvt-clang.yml b/.github/workflows/bvt-clang.yml index 4c62cb41..85cf3976 100644 --- a/.github/workflows/bvt-clang.yml +++ b/.github/workflows/bvt-clang.yml @@ -4,37 +4,56 @@ on: jobs: bvt-clang: runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + buildsystem: [cmake, meson] + steps: - uses: actions/checkout@v4 + - name: install meson + if: ${{ matrix.buildsystem == 'meson' }} + run: pipx install meson + - name: install clang run: | - wget https://apt.llvm.org/llvm.sh - chmod +x llvm.sh - sudo ./llvm.sh 21 - sudo apt install -y libc++-21-dev clang-format-21 + curl https://apt.llvm.org/llvm.sh | sudo bash -s -- 21 + sudo apt install -y clang-21 libc++-21-dev clang-format-21 + cat <<'EOF' >> "$GITHUB_ENV" + CC=clang-21 + CXX=clang++-21 + CXXFLAGS=-stdlib=libc++ + EOF - name: check compiler version run: | - clang++-21 --version + "$CXX" --version - - name: build and run test with clang 21 + - name: build and run test with clang 20 on cmake + if: ${{ matrix.buildsystem == 'cmake' }} run: | - cmake -B build -GNinja -DCMAKE_C_COMPILER=clang-21 -DCMAKE_CXX_COMPILER=clang++-21 -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE + cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE mapfile -t FILES < <(find include tests benchmarks build/examples_from_docs tools -type f \( -name '*.h' -o -name '*.ixx' -o -name '*.cpp' \)) echo "Running clang-format on ${#FILES[@]} files: ${FILES[*]}" clang-format-21 --dry-run --Werror "${FILES[@]}" cmake --build build -j ctest --test-dir build -j mkdir build/drop - chmod +x tools/dump_build_env.sh - ./tools/dump_build_env.sh clang++-21 build/drop/env-info.json + bash ./tools/dump_build_env.sh "$CXX" build/drop/env-info.json - - name: run benchmarks + - name: build and run test with clang 20 on meson + if: ${{ matrix.buildsystem == 'meson' }} run: | - build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json + meson setup builddir --buildtype=release -Dtests=enabled + meson test -C builddir + + - name: run benchmarks + if: ${{ matrix.buildsystem == 'cmake' }} + run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json - name: archive benchmarking results + if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-clang diff --git a/.github/workflows/bvt-compatibility.yml b/.github/workflows/bvt-compatibility.yml index 83f41dfe..f8fafecc 100644 --- a/.github/workflows/bvt-compatibility.yml +++ b/.github/workflows/bvt-compatibility.yml @@ -4,63 +4,58 @@ on: jobs: bvt-compatibility: runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + compiler: + - {compiler: gcc, version: 13, modules: false} + - {compiler: gcc, version: 14, modules: true} + - {compiler: clang, version: 16, modules: false} + - {compiler: clang, version: 17, modules: false} + - {compiler: clang, version: 18, modules: false} + - {compiler: clang, version: 19, modules: false} + - {compiler: clang, version: 20, modules: true} + buildsystem: [cmake, meson] + steps: - uses: actions/checkout@v4 - - name: install compilers - run: | - wget https://apt.llvm.org/llvm.sh - chmod +x llvm.sh - sudo ./llvm.sh 20 - sudo apt install -y gcc-13 g++-13 gcc-14 g++-14 clang-16 clang-17 clang-18 clang-19 libc++-17-dev - - - name: check compiler versions - run: | - g++-13 --version - g++-14 --version - clang++-16 --version - clang++-17 --version - clang++-18 --version - clang++-19 --version - clang++-20 --version + - name: install meson + if: ${{ matrix.buildsystem == 'meson' }} + run: pipx install meson - - name: build and run test with gcc 14 + - name: install gcc + if: ${{ matrix.compiler.compiler == 'gcc' }} run: | - cmake -B build-gcc-14 -GNinja -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE - cmake --build build-gcc-14 -j - ctest --test-dir build-gcc-14 -j + sudo apt install -y 'g++-${{ matrix.compiler.version }}' + cat <<'EOF' >> "$GITHUB_ENV" + CC=gcc-${{ matrix.compiler.version }} + CXX=g++-${{ matrix.compiler.version }} + EOF - - name: build and run test with gcc 13 - run: | - cmake -B build-gcc-13 -DCMAKE_C_COMPILER=gcc-13 -DCMAKE_CXX_COMPILER=g++-13 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE - cmake --build build-gcc-13 -j - ctest --test-dir build-gcc-13 -j - - - name: build and run test with clang 20 - run: | - cmake -B build-clang-20 -GNinja -DCMAKE_C_COMPILER=clang-20 -DCMAKE_CXX_COMPILER=clang++-20 -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE - cmake --build build-clang-20 -j - ctest --test-dir build-clang-20 -j - - name: build and run test with clang 19 + - name: install clang + if: ${{ matrix.compiler.compiler == 'clang' }} run: | - cmake -B build-clang-19 -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE - cmake --build build-clang-19 -j - ctest --test-dir build-clang-19 -j + sudo apt install -y 'clang-${{ matrix.compiler.version }}' 'clang-tools-${{ matrix.compiler.version }}' 'libc++-${{ matrix.compiler.version }}-dev' 'libc++abi-${{ matrix.compiler.version }}-dev' + cat <<'EOF' >> "$GITHUB_ENV" + CC=clang-${{ matrix.compiler.version }} + CXX=clang++-${{ matrix.compiler.version }} + CXXFLAGS=-stdlib=libc++ + EOF - - name: build and run test with clang 18 + - name: check compiler version run: | - cmake -B build-clang-18 -DCMAKE_C_COMPILER=clang-18 -DCMAKE_CXX_COMPILER=clang++-18 -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE - cmake --build build-clang-18 -j - ctest --test-dir build-clang-18 -j + "$CXX" --version - - name: build and run test with clang 17 + - name: build and run test with cmake + if: ${{ matrix.buildsystem == 'cmake' }} run: | - cmake -B build-clang-17 -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17 -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE - cmake --build build-clang-17 -j - ctest --test-dir build-clang-17 -j + cmake -B build -GNinja -DCMAKE_BUILD_TYPE=Release '-DPROXY_BUILD_MODULES=${{ matrix.compiler.modules }}' + cmake --build build -j + ctest --test-dir build -j - - name: build and run test with clang 16 + - name: build and run test with meson + if: ${{ matrix.buildsystem == 'meson' }} run: | - cmake -B build-clang-16 -DCMAKE_C_COMPILER=clang-16 -DCMAKE_CXX_COMPILER=clang++-16 -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE - cmake --build build-clang-16 -j - ctest --test-dir build-clang-16 -j + meson setup build --buildtype=release -Dmodules=${{ matrix.compiler.modules && 'auto' || 'disabled' }} + meson test -C build diff --git a/.github/workflows/bvt-gcc.yml b/.github/workflows/bvt-gcc.yml index b0909e21..44d425ca 100644 --- a/.github/workflows/bvt-gcc.yml +++ b/.github/workflows/bvt-gcc.yml @@ -5,32 +5,52 @@ jobs: bvt-gcc: runs-on: ubuntu-24.04 container: gcc:15 + strategy: + fail-fast: false + matrix: + buildsystem: [cmake, meson] + steps: - uses: actions/checkout@v4 - - name: install dependencies + - name: install cmake + if: ${{ matrix.buildsystem == 'cmake' }} run: | apt-get update apt-get install -y cmake ninja-build + - name: install meson + if: ${{ matrix.buildsystem == 'meson' }} + run: | + apt-get update + apt-get install -y meson ninja-build + - name: check compiler version run: | - g++ --version + c++ --version - - name: build and run test with gcc 15 + - name: build and run test with gcc 15 on cmake + if: ${{ matrix.buildsystem == 'cmake' }} run: | - cmake -B build -GNinja -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE + cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE cmake --build build -j ctest --test-dir build -j mkdir build/drop chmod +x tools/dump_build_env.sh - ./tools/dump_build_env.sh g++ build/drop/env-info.json + ./tools/dump_build_env.sh c++ build/drop/env-info.json - - name: run benchmarks + - name: build and run test with gcc 15 on meson + if: ${{ matrix.buildsystem == 'meson' }} run: | - build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json + meson setup builddir --buildtype=release -Dtests=enabled + meson test -C builddir + + - name: run benchmarks + if: ${{ matrix.buildsystem == 'cmake' }} + run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json - name: archive benchmarking results + if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-gcc diff --git a/.github/workflows/bvt-msvc.yml b/.github/workflows/bvt-msvc.yml index bf38ae2f..43e04871 100644 --- a/.github/workflows/bvt-msvc.yml +++ b/.github/workflows/bvt-msvc.yml @@ -4,13 +4,24 @@ on: jobs: bvt-msvc: runs-on: windows-2025 + strategy: + fail-fast: false + matrix: + buildsystem: [cmake, meson] + steps: - uses: actions/checkout@v4 + - name: install meson + if: ${{ matrix.buildsystem == 'meson' }} + run: pipx install meson + - name: add cl.exe to PATH + if: ${{ matrix.buildsystem == 'cmake' }} uses: ilammy/msvc-dev-cmd@v1 - - name: build and run test with MSVC + - name: build and run test with MSVC on cmake + if: ${{ matrix.buildsystem == 'cmake' }} run: | cmake -B build -DCMAKE_CXX_STANDARD=23 -DPROXY_BUILD_MODULES=TRUE ` && cmake --build build --config Release -j ` @@ -18,11 +29,18 @@ jobs: && mkdir build\drop > $null ` && .\tools\dump_build_env_msvc.ps1 -OutputPath build\drop\env-info.json - - name: run benchmarks + - name: build and run test with MSVC on meson + if: ${{ matrix.buildsystem == 'meson' }} run: | - build\benchmarks\Release\msft_proxy_benchmarks.exe --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build\drop\benchmarking-results.json + meson setup builddir --buildtype=release -Dtests=enabled --vsenv + meson test -C builddir + + - name: run benchmarks + if: ${{ matrix.buildsystem == 'cmake' }} + run: build\benchmarks\Release\msft_proxy_benchmarks.exe --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build\drop\benchmarking-results.json - name: archive benchmarking results + if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-msvc diff --git a/.github/workflows/bvt-nvhpc.yml b/.github/workflows/bvt-nvhpc.yml index 9a333311..49bd8196 100644 --- a/.github/workflows/bvt-nvhpc.yml +++ b/.github/workflows/bvt-nvhpc.yml @@ -4,34 +4,55 @@ on: jobs: bvt-nvhpc: runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + buildsystem: [cmake, meson] + steps: - uses: actions/checkout@v4 - name: free disk space uses: jlumbroso/free-disk-space@v1.3.1 + - name: install meson + if: ${{ matrix.buildsystem == 'meson' }} + # FIXME: install from upstream once https://github.com/mesonbuild/meson/pull/15353 is released + run: pipx install git+https://github.com/mesonbuild/meson@02b85a846629090a0c7f18e860bab0a10ea4349b + - name: install NVHPC 25.11 run: | curl https://developer.download.nvidia.com/hpc-sdk/ubuntu/DEB-GPG-KEY-NVIDIA-HPC-SDK | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-hpcsdk-archive-keyring.gpg echo 'deb [signed-by=/usr/share/keyrings/nvidia-hpcsdk-archive-keyring.gpg] https://developer.download.nvidia.com/hpc-sdk/ubuntu/amd64 /' | sudo tee /etc/apt/sources.list.d/nvhpc.list sudo apt-get update -y sudo apt-get install -y nvhpc-25-11 + cat<<'EOF' >> "$GITHUB_ENV" + CC=/opt/nvidia/hpc_sdk/Linux_x86_64/25.11/compilers/bin/nvc + CXX=/opt/nvidia/hpc_sdk/Linux_x86_64/25.11/compilers/bin/nvc++ + EOF - - name: build and run test with NVHPC 25.11 + - name: build and run test with NVHPC 25.11 on cmake + if: ${{ matrix.buildsystem == 'cmake' }} run: | - PATH=/opt/nvidia/hpc_sdk/Linux_x86_64/25.11/compilers/bin:$PATH; export PATH - cmake -B build -GNinja -DCMAKE_C_COMPILER=nvc -DCMAKE_CXX_COMPILER=nvc++ -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE + cmake -B build -GNinja -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE cmake --build build -j ctest --test-dir build -j mkdir build/drop chmod +x tools/dump_build_env.sh - ./tools/dump_build_env.sh nvc++ build/drop/env-info.json + ./tools/dump_build_env.sh "$CXX" build/drop/env-info.json - - name: run benchmarks + - name: build and run test with NVHPC 25.11 on meson + if: ${{ matrix.buildsystem == 'meson' }} run: | - build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json + meson setup builddir --buildtype=release -Dtests=enabled + meson test -C builddir + + - name: run benchmarks + if: ${{ matrix.buildsystem == 'cmake' }} + run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json - name: archive benchmarking results + if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-nvhpc diff --git a/.github/workflows/bvt-oneapi.yml b/.github/workflows/bvt-oneapi.yml index 3bc1d43e..82aaf12c 100644 --- a/.github/workflows/bvt-oneapi.yml +++ b/.github/workflows/bvt-oneapi.yml @@ -4,12 +4,24 @@ on: jobs: bvt-oneapi: runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + buildsystem: [cmake, meson] + steps: - uses: actions/checkout@v4 + - name: install meson + if: ${{ matrix.buildsystem == 'meson' }} + run: pipx install meson + - name: install libc++ run: | - sudo apt-get install -y libc++-19-dev libc++abi-19-dev + sudo apt-get install -y libc++-19-dev + cat <<'EOF' >> "$GITHUB_ENV" + CXXFLAGS=-stdlib=libc++ + EOF - name: install intel oneAPI run: | @@ -18,27 +30,38 @@ jobs: sudo apt update sudo apt install -y intel-oneapi-compiler-dpcpp-cpp source /opt/intel/oneapi/setvars.sh - echo "PATH=$PATH" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >> $GITHUB_ENV + cat<<-EOF >> "$GITHUB_ENV" + PATH=$PATH + LD_LIBRARY_PATH=$LD_LIBRARY_PATH + CC=$(which icx) + CXX=$(which icpx) + EOF - name: check compiler version run: | - icpx --version + "$CXX" --version - - name: build and run test with oneapi + - name: build and run test with oneapi on cmake + if: ${{ matrix.buildsystem == 'cmake' }} run: | - cmake -B build -GNinja -DCMAKE_CXX_COMPILER=icpx -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-stdlib=libc++" + cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release cmake --build build -j ctest --test-dir build -j mkdir build/drop - chmod +x tools/dump_build_env.sh - ./tools/dump_build_env.sh icpx build/drop/env-info.json + bash ./tools/dump_build_env.sh "$CXX" build/drop/env-info.json - - name: run benchmarks + - name: build and run test with oneapi on meson + if: ${{ matrix.buildsystem == 'meson' }} run: | - build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json + meson setup builddir --buildtype=release -Dtests=enabled + meson test -C builddir + + - name: run benchmarks + if: ${{ matrix.buildsystem == 'cmake' }} + run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json - name: archive benchmarking results + if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-oneapi diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml deleted file mode 100644 index f13d0438..00000000 --- a/.github/workflows/meson.yml +++ /dev/null @@ -1,171 +0,0 @@ -on: - workflow_call: - -jobs: - meson: - runs-on: ${{ matrix.platform }} - name: meson on ${{ matrix.platform }} (${{ matrix.mode.name }}) - strategy: - fail-fast: false - matrix: - mode: - - name: default - args: -Dtests=enabled -Dbenchmarks=disabled - extra_envs: {} - - # Alternative compiler setups - - name: gcc - args: -Dtests=enabled -Dbenchmarks=disabled - extra_envs: - CC: gcc - CXX: g++ - - name: clang - args: -Dtests=enabled -Dbenchmarks=disabled - extra_envs: - CC: clang - CXX: clang++ - - - name: sanitize - args: >- - -Dtests=enabled -Dbenchmarks=disabled "-Db_sanitize=address,undefined" - extra_envs: {} - - # This is for MSVC, which only supports AddressSanitizer. - # https://learn.microsoft.com/en-us/cpp/sanitizers/ - - name: sanitize+asanonly - args: -Dtests=enabled -Dbenchmarks=disabled -Db_sanitize=address - extra_envs: - ASAN_OPTIONS: report_globals=0:halt_on_error=1:abort_on_error=1:print_summary=1 - - - name: clang+sanitize - args: >- - -Dtests=enabled -Dbenchmarks=disabled -Db_lundef=false "-Db_sanitize=address,undefined" - extra_envs: - CC: clang - CXX: clang++ - - # default clang on GitHub hosted runners is from MSYS2. - # Use Visual Studio supplied clang-cl instead. - - name: clang-cl - args: >- - -Dtests=enabled -Dbenchmarks=disabled - extra_envs: - CC: clang-cl - CXX: clang-cl - - name: clang-cl+sanitize - args: >- - -Dtests=enabled -Dbenchmarks=disabled "-Db_sanitize=address,undefined" - extra_envs: - CC: clang-cl - CXX: clang-cl - platform: - - ubuntu-24.04 - - windows-2025 - - macos-15 - - exclude: - # clang-cl only makes sense on windows. - - platform: ubuntu-24.04 - mode: - name: clang-cl - - platform: macos-15 - mode: - name: clang-cl - - platform: ubuntu-24.04 - mode: - name: clang-cl+sanitize - - platform: macos-15 - mode: - name: clang-cl+sanitize - - # FIXME: clang-cl is currently broken: - # https://github.com/llvm/llvm-project/issues/143245 - - platform: windows-2025 - mode: - name: clang-cl - - platform: windows-2025 - mode: - name: clang-cl+sanitize - - # Use clang-cl instead of MSYS2 clang. - # - # we already tested clang+sanitize on linux, - # if this doesn't work, it should be an issue for MSYS2 team to consider. - - platform: windows-2025 - mode: - name: clang - - platform: windows-2025 - mode: - name: clang+sanitize - - # MSVC-only sanitizers - - platform: ubuntu-24.04 - mode: - name: sanitize+asanonly - - platform: macos-15 - mode: - name: sanitize+asanonly - - platform: windows-2025 - mode: - name: sanitize - - # clang is the default on macos - # also gcc is an alias to clang - - platform: macos-15 - mode: - name: clang - - platform: macos-15 - mode: - name: gcc - - # gcc is the default on linux - - platform: ubuntu-24.04 - mode: - name: gcc - - # MinGW is not officially tested - - platform: windows-2025 - mode: - name: gcc - - # only run sanitizer tests on linux - # - # gcc/clang's codegen shouldn't massively change across platforms, - # and linux supports most of the sanitizers. - - platform: macos-15 - mode: - name: clang+sanitize - - platform: macos-15 - mode: - name: sanitize - - steps: - - name: Setup meson - run: | - pipx install meson ninja - - name: Checkout - uses: actions/checkout@v4 - - name: Activate MSVC and Configure - if: ${{ matrix.platform == 'windows-2025' }} - env: ${{ matrix.mode.extra_envs }} - run: | - meson setup build --buildtype=release ${{ matrix.mode.args }} --vsenv - - name: Configure - if: ${{ matrix.platform != 'windows-2025' }} - env: ${{ matrix.mode.extra_envs }} - run: | - meson setup build --buildtype=release ${{ matrix.mode.args }} - - name: Build - run: | - meson compile -C build - meson compile -C build msft_proxy_tests examples - - - name: Run tests - env: ${{ matrix.mode.extra_envs }} - run: | - meson test -C build --timeout-multiplier 5 --print-errorlogs - - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ${{ matrix.platform }}-${{ matrix.mode.name }}-logs - path: build/meson-logs diff --git a/.github/workflows/pipeline-ci.yml b/.github/workflows/pipeline-ci.yml index 7f311145..f8037dce 100644 --- a/.github/workflows/pipeline-ci.yml +++ b/.github/workflows/pipeline-ci.yml @@ -41,10 +41,6 @@ jobs: name: Generate report needs: [run-bvt-gcc, run-bvt-clang, run-bvt-msvc, run-bvt-appleclang, run-bvt-nvhpc, run-bvt-oneapi] - run-meson: - uses: ./.github/workflows/meson.yml - name: Run builds with meson - mkdocs: uses: ./.github/workflows/mkdocs.yml name: Build mkdocs From 32071d5afa1e629eb79aa89bce54e15c05a38cea Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Sat, 6 Dec 2025 20:55:56 +0800 Subject: [PATCH 27/40] build/meson: support pgi compilers --- meson.build | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/meson.build b/meson.build index 4a258a6f..a68a0949 100644 --- a/meson.build +++ b/meson.build @@ -58,8 +58,7 @@ msft_proxy4_dep = declare_dependency( sources: hdrs + hdrs_v4, include_directories: inc, ) -modules = get_option('modules') -modules_interface_spec = { +modules_interface_specs = { 'gcc': { 'flags': ['-fmodules', '-fdeps-format=p1689r5'] + (cxx.has_header_symbol( 'pthread.h', @@ -72,13 +71,16 @@ modules_interface_spec = { 'msvc': { 'flags': ['/interface'], }, -}[cxx.get_argument_syntax()] -if cxx.has_multi_arguments( - modules_interface_spec.get('flags'), - modules_interface_spec.get('check_only', []), +} +modules = get_option('modules').disable_if( + not modules_interface_specs.has_key(cxx.get_argument_syntax()), +) +if modules.allowed() and cxx.has_multi_arguments( + modules_interface_specs[cxx.get_argument_syntax()].get('flags'), + modules_interface_specs[cxx.get_argument_syntax()].get('check_only', []), required: modules, ) - modules_interface_cflags = modules_interface_spec['flags'] + modules_interface_cflags = modules_interface_specs[cxx.get_argument_syntax()]['flags'] msft_proxy4_mod = declare_dependency( include_directories: inc, dependencies: msft_proxy4_dep, From df5bd1b55f6dc2d1ce6c1ddebf984a1110511099 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Sat, 6 Dec 2025 22:21:01 +0800 Subject: [PATCH 28/40] ci: remove meson from compatibility tests --- .github/workflows/bvt-compatibility.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/bvt-compatibility.yml b/.github/workflows/bvt-compatibility.yml index f8fafecc..8852a6d5 100644 --- a/.github/workflows/bvt-compatibility.yml +++ b/.github/workflows/bvt-compatibility.yml @@ -15,15 +15,10 @@ jobs: - {compiler: clang, version: 18, modules: false} - {compiler: clang, version: 19, modules: false} - {compiler: clang, version: 20, modules: true} - buildsystem: [cmake, meson] steps: - uses: actions/checkout@v4 - - name: install meson - if: ${{ matrix.buildsystem == 'meson' }} - run: pipx install meson - - name: install gcc if: ${{ matrix.compiler.compiler == 'gcc' }} run: | @@ -48,14 +43,7 @@ jobs: "$CXX" --version - name: build and run test with cmake - if: ${{ matrix.buildsystem == 'cmake' }} run: | cmake -B build -GNinja -DCMAKE_BUILD_TYPE=Release '-DPROXY_BUILD_MODULES=${{ matrix.compiler.modules }}' cmake --build build -j ctest --test-dir build -j - - - name: build and run test with meson - if: ${{ matrix.buildsystem == 'meson' }} - run: | - meson setup build --buildtype=release -Dmodules=${{ matrix.compiler.modules && 'auto' || 'disabled' }} - meson test -C build From f32138f656e008d6ec385f59a8efa8e193a811af Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Sat, 6 Dec 2025 22:28:17 +0800 Subject: [PATCH 29/40] ci: run meson and cmake in one pass --- .github/workflows/bvt-appleclang.yml | 10 ---------- .github/workflows/bvt-clang.yml | 10 ---------- .github/workflows/bvt-gcc.yml | 20 ++------------------ .github/workflows/bvt-msvc.yml | 11 ----------- .github/workflows/bvt-nvhpc.yml | 10 ---------- .github/workflows/bvt-oneapi.yml | 10 ---------- 6 files changed, 2 insertions(+), 69 deletions(-) diff --git a/.github/workflows/bvt-appleclang.yml b/.github/workflows/bvt-appleclang.yml index 3e078e3d..64c935d7 100644 --- a/.github/workflows/bvt-appleclang.yml +++ b/.github/workflows/bvt-appleclang.yml @@ -4,16 +4,10 @@ on: jobs: bvt-appleclang: runs-on: macos-15 - strategy: - fail-fast: false - matrix: - buildsystem: [cmake, meson] - steps: - uses: actions/checkout@v4 - name: install meson - if: ${{ matrix.buildsystem == 'meson' }} run: pipx install meson - name: check compiler versions @@ -22,7 +16,6 @@ jobs: xcodebuild -version - name: build and run test with AppleClang on cmake - if: ${{ matrix.buildsystem == 'cmake' }} run: | cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE cmake --build build -j @@ -31,17 +24,14 @@ jobs: bash ./tools/dump_build_env.sh c++ build/drop/env-info.json - name: build and run test with AppleClang on meson - if: ${{ matrix.buildsystem == 'meson' }} run: | meson setup builddir --buildtype=release -Dtests=enabled meson test -C builddir - name: run benchmarks - if: ${{ matrix.buildsystem == 'cmake' }} run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json - name: archive benchmarking results - if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-appleclang diff --git a/.github/workflows/bvt-clang.yml b/.github/workflows/bvt-clang.yml index 85cf3976..a3836e68 100644 --- a/.github/workflows/bvt-clang.yml +++ b/.github/workflows/bvt-clang.yml @@ -4,16 +4,10 @@ on: jobs: bvt-clang: runs-on: ubuntu-24.04 - strategy: - fail-fast: false - matrix: - buildsystem: [cmake, meson] - steps: - uses: actions/checkout@v4 - name: install meson - if: ${{ matrix.buildsystem == 'meson' }} run: pipx install meson - name: install clang @@ -31,7 +25,6 @@ jobs: "$CXX" --version - name: build and run test with clang 20 on cmake - if: ${{ matrix.buildsystem == 'cmake' }} run: | cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE mapfile -t FILES < <(find include tests benchmarks build/examples_from_docs tools -type f \( -name '*.h' -o -name '*.ixx' -o -name '*.cpp' \)) @@ -43,17 +36,14 @@ jobs: bash ./tools/dump_build_env.sh "$CXX" build/drop/env-info.json - name: build and run test with clang 20 on meson - if: ${{ matrix.buildsystem == 'meson' }} run: | meson setup builddir --buildtype=release -Dtests=enabled meson test -C builddir - name: run benchmarks - if: ${{ matrix.buildsystem == 'cmake' }} run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json - name: archive benchmarking results - if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-clang diff --git a/.github/workflows/bvt-gcc.yml b/.github/workflows/bvt-gcc.yml index 44d425ca..382cd887 100644 --- a/.github/workflows/bvt-gcc.yml +++ b/.github/workflows/bvt-gcc.yml @@ -5,32 +5,19 @@ jobs: bvt-gcc: runs-on: ubuntu-24.04 container: gcc:15 - strategy: - fail-fast: false - matrix: - buildsystem: [cmake, meson] - steps: - uses: actions/checkout@v4 - - name: install cmake - if: ${{ matrix.buildsystem == 'cmake' }} - run: | - apt-get update - apt-get install -y cmake ninja-build - - - name: install meson - if: ${{ matrix.buildsystem == 'meson' }} + - name: install cmake and meson run: | apt-get update - apt-get install -y meson ninja-build + apt-get install -y cmake meson ninja-build - name: check compiler version run: | c++ --version - name: build and run test with gcc 15 on cmake - if: ${{ matrix.buildsystem == 'cmake' }} run: | cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE cmake --build build -j @@ -40,17 +27,14 @@ jobs: ./tools/dump_build_env.sh c++ build/drop/env-info.json - name: build and run test with gcc 15 on meson - if: ${{ matrix.buildsystem == 'meson' }} run: | meson setup builddir --buildtype=release -Dtests=enabled meson test -C builddir - name: run benchmarks - if: ${{ matrix.buildsystem == 'cmake' }} run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json - name: archive benchmarking results - if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-gcc diff --git a/.github/workflows/bvt-msvc.yml b/.github/workflows/bvt-msvc.yml index 43e04871..2fa86ede 100644 --- a/.github/workflows/bvt-msvc.yml +++ b/.github/workflows/bvt-msvc.yml @@ -4,24 +4,16 @@ on: jobs: bvt-msvc: runs-on: windows-2025 - strategy: - fail-fast: false - matrix: - buildsystem: [cmake, meson] - steps: - uses: actions/checkout@v4 - name: install meson - if: ${{ matrix.buildsystem == 'meson' }} run: pipx install meson - name: add cl.exe to PATH - if: ${{ matrix.buildsystem == 'cmake' }} uses: ilammy/msvc-dev-cmd@v1 - name: build and run test with MSVC on cmake - if: ${{ matrix.buildsystem == 'cmake' }} run: | cmake -B build -DCMAKE_CXX_STANDARD=23 -DPROXY_BUILD_MODULES=TRUE ` && cmake --build build --config Release -j ` @@ -30,17 +22,14 @@ jobs: && .\tools\dump_build_env_msvc.ps1 -OutputPath build\drop\env-info.json - name: build and run test with MSVC on meson - if: ${{ matrix.buildsystem == 'meson' }} run: | meson setup builddir --buildtype=release -Dtests=enabled --vsenv meson test -C builddir - name: run benchmarks - if: ${{ matrix.buildsystem == 'cmake' }} run: build\benchmarks\Release\msft_proxy_benchmarks.exe --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build\drop\benchmarking-results.json - name: archive benchmarking results - if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-msvc diff --git a/.github/workflows/bvt-nvhpc.yml b/.github/workflows/bvt-nvhpc.yml index 49bd8196..af2e019b 100644 --- a/.github/workflows/bvt-nvhpc.yml +++ b/.github/workflows/bvt-nvhpc.yml @@ -4,11 +4,6 @@ on: jobs: bvt-nvhpc: runs-on: ubuntu-24.04 - strategy: - fail-fast: false - matrix: - buildsystem: [cmake, meson] - steps: - uses: actions/checkout@v4 @@ -16,7 +11,6 @@ jobs: uses: jlumbroso/free-disk-space@v1.3.1 - name: install meson - if: ${{ matrix.buildsystem == 'meson' }} # FIXME: install from upstream once https://github.com/mesonbuild/meson/pull/15353 is released run: pipx install git+https://github.com/mesonbuild/meson@02b85a846629090a0c7f18e860bab0a10ea4349b @@ -32,7 +26,6 @@ jobs: EOF - name: build and run test with NVHPC 25.11 on cmake - if: ${{ matrix.buildsystem == 'cmake' }} run: | cmake -B build -GNinja -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE cmake --build build -j @@ -42,17 +35,14 @@ jobs: ./tools/dump_build_env.sh "$CXX" build/drop/env-info.json - name: build and run test with NVHPC 25.11 on meson - if: ${{ matrix.buildsystem == 'meson' }} run: | meson setup builddir --buildtype=release -Dtests=enabled meson test -C builddir - name: run benchmarks - if: ${{ matrix.buildsystem == 'cmake' }} run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json - name: archive benchmarking results - if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-nvhpc diff --git a/.github/workflows/bvt-oneapi.yml b/.github/workflows/bvt-oneapi.yml index 82aaf12c..99d403d5 100644 --- a/.github/workflows/bvt-oneapi.yml +++ b/.github/workflows/bvt-oneapi.yml @@ -4,16 +4,10 @@ on: jobs: bvt-oneapi: runs-on: ubuntu-24.04 - strategy: - fail-fast: false - matrix: - buildsystem: [cmake, meson] - steps: - uses: actions/checkout@v4 - name: install meson - if: ${{ matrix.buildsystem == 'meson' }} run: pipx install meson - name: install libc++ @@ -42,7 +36,6 @@ jobs: "$CXX" --version - name: build and run test with oneapi on cmake - if: ${{ matrix.buildsystem == 'cmake' }} run: | cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release cmake --build build -j @@ -51,17 +44,14 @@ jobs: bash ./tools/dump_build_env.sh "$CXX" build/drop/env-info.json - name: build and run test with oneapi on meson - if: ${{ matrix.buildsystem == 'meson' }} run: | meson setup builddir --buildtype=release -Dtests=enabled meson test -C builddir - name: run benchmarks - if: ${{ matrix.buildsystem == 'cmake' }} run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json - name: archive benchmarking results - if: ${{ matrix.buildsystem == 'cmake' }} uses: actions/upload-artifact@v4 with: name: drop-oneapi From 886f11fa7245b92a831b7835ac46906fb70ff9f7 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Sat, 6 Dec 2025 23:13:54 +0800 Subject: [PATCH 30/40] Test for std::format using __cpp_lib_format With specialization for libc++. Fixes compilation on libc++ 16-18 that has incomplete std::format support. --- docs/spec/proxy_view.md | 1 + include/proxy/v4/proxy.h | 15 +++++++++------ include/proxy/v4/proxy.ixx | 8 ++++---- tests/proxy_dispatch_tests.cpp | 4 ++++ tests/proxy_format_tests.cpp | 10 ++++++++++ tools/extract_example_code_from_docs.py | 13 +++++++++++++ 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/docs/spec/proxy_view.md b/docs/spec/proxy_view.md index 3fb1c5a0..2f81c5d3 100644 --- a/docs/spec/proxy_view.md +++ b/docs/spec/proxy_view.md @@ -37,6 +37,7 @@ using proxy_view = proxy>; ## Example ```cpp +#include #include #include diff --git a/include/proxy/v4/proxy.h b/include/proxy/v4/proxy.h index 923e41c5..0c486105 100644 --- a/include/proxy/v4/proxy.h +++ b/include/proxy/v4/proxy.h @@ -23,6 +23,9 @@ #if __has_include() #include #endif // __has_include() +#if __cpp_lib_format || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 170000) +#define _PRO4D_HAS_FORMAT +#endif // __cpp_lib_format || _LIBCPP_VERSION >= 170000 #endif // __STDC_HOSTED__ #if __cpp_rtti >= 199711L @@ -2125,7 +2128,7 @@ struct weak_conversion_dispatch : cast_dispatch_base { template using weak_conversion_overload = weak_proxy() const noexcept; -#if __STDC_HOSTED__ && __has_include() +#ifdef _PRO4D_HAS_FORMAT template struct format_overload_traits; template <> @@ -2166,7 +2169,7 @@ struct format_dispatch { return impl.format(self, fc); } }; -#endif // __STDC_HOSTED__ && __has_include() +#endif // _PRO4D_HAS_FORMAT #if __cpp_rtti >= 199711L struct proxy_cast_context { @@ -2273,7 +2276,7 @@ struct proxy_typeid_reflector { namespace skills { -#if __STDC_HOSTED__ && __has_include() +#ifdef _PRO4D_HAS_FORMAT template using format = typename FB::template add_convention using wformat = typename FB::template add_convention>; -#endif // __STDC_HOSTED__ && __has_include() +#endif // _PRO4D_HAS_FORMAT #if __cpp_rtti >= 199711L template @@ -2604,7 +2607,7 @@ struct weak_dispatch : D { // == Adapters (std::formatter) == // ============================================================================= -#if __STDC_HOSTED__ && __has_include() +#ifdef _PRO4D_HAS_FORMAT namespace std { template @@ -2635,7 +2638,7 @@ struct formatter, CharT> { }; } // namespace std -#endif // __STDC_HOSTED__ && __has_include() +#endif // _PRO4D_HAS_FORMAT #undef PROD_UNREACHABLE #undef PROD_NO_UNIQUE_ADDRESS_ATTRIBUTE diff --git a/include/proxy/v4/proxy.ixx b/include/proxy/v4/proxy.ixx index f1ad5985..3463e33d 100644 --- a/include/proxy/v4/proxy.ixx +++ b/include/proxy/v4/proxy.ixx @@ -41,10 +41,10 @@ using v4::weak_proxy; namespace skills { -#if __STDC_HOSTED__ && __has_include() +#ifdef _PRO4D_HAS_FORMAT using skills::format; using skills::wformat; -#endif // __STDC_HOSTED__ && __has_include() +#endif // _PRO4D_HAS_FORMAT #if __cpp_rtti >= 199711L using skills::direct_rtti; @@ -60,10 +60,10 @@ using skills::slim; } // namespace pro::inline v4 -#if __STDC_HOSTED__ && __has_include() +#ifdef _PRO4D_HAS_FORMAT export namespace std { using std::formatter; } // namespace std -#endif // __STDC_HOSTED__ && __has_include() +#endif // _PRO4D_HAS_FORMAT diff --git a/tests/proxy_dispatch_tests.cpp b/tests/proxy_dispatch_tests.cpp index e2a71aa8..284cce37 100644 --- a/tests/proxy_dispatch_tests.cpp +++ b/tests/proxy_dispatch_tests.cpp @@ -829,6 +829,7 @@ TEST(ProxyDispatchTests, TestFreeAsMemDispatch) { } TEST(ProxyDispatchTests, TestSubstitutionDispatch) { +#ifdef _PRO4D_HAS_FORMAT struct Base : pro::facade_builder // ::add_skill // ::build {}; @@ -844,4 +845,7 @@ TEST(ProxyDispatchTests, TestSubstitutionDispatch) { pro::proxy p3 = std::move(p1); ASSERT_FALSE(p1.has_value()); ASSERT_EQ(std::format("{}", *p3), "123"); +#else + GTEST_SKIP() << "std::format not available"; +#endif // _PRO4D_HAS_FORMAT } diff --git a/tests/proxy_format_tests.cpp b/tests/proxy_format_tests.cpp index 7b0d2248..186198bf 100644 --- a/tests/proxy_format_tests.cpp +++ b/tests/proxy_format_tests.cpp @@ -4,6 +4,7 @@ #include #include +#ifdef _PRO4D_HAS_FORMAT namespace proxy_format_tests_details { struct NonFormattable : pro::facade_builder::build {}; @@ -29,17 +30,26 @@ static_assert( } // namespace proxy_format_tests_details namespace details = proxy_format_tests_details; +#endif // _PRO4D_HAS_FORMAT TEST(ProxyFormatTests, TestFormat) { +#ifdef _PRO4D_HAS_FORMAT int v = 123; pro::proxy p = &v; ASSERT_EQ(std::format("{}", *p), "123"); ASSERT_EQ(std::format("{:*<6}", *p), "123***"); +#else + GTEST_SKIP() << "std::format not available"; +#endif // _PRO4D_HAS_FORMAT } TEST(ProxyFormatTests, TestWformat) { +#ifdef _PRO4D_HAS_FORMAT int v = 123; pro::proxy p = &v; ASSERT_EQ(std::format(L"{}", *p), L"123"); ASSERT_EQ(std::format(L"{:*<6}", *p), L"123***"); +#else + GTEST_SKIP() << "std::format not available"; +#endif // _PRO4D_HAS_FORMAT } diff --git a/tools/extract_example_code_from_docs.py b/tools/extract_example_code_from_docs.py index 3e8eaac0..b07220e2 100644 --- a/tools/extract_example_code_from_docs.py +++ b/tools/extract_example_code_from_docs.py @@ -27,6 +27,19 @@ def extract_cpp_code(md_path: Path) -> T.Optional[str]: """.lstrip() + if "pro::skills::format" in cpp_code: + cpp_code = f""" +#include +#ifdef _PRO4D_HAS_FORMAT +{cpp_code} +#else +int main() {{ + // std::format not available + return 77; +}} +#endif +""".strip() + return header + cpp_code From 76e68d20c19f064b1eb993f623cb55ed6fc6048f Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 8 Dec 2025 21:54:23 +0800 Subject: [PATCH 31/40] build/meson: remove module support too many compiler-specific workarounds. waiting for better upstream support. --- meson.build | 40 --------------------------------------- meson.options | 6 ------ tests/meson.build | 5 ----- tests/modules/meson.build | 12 ------------ 4 files changed, 63 deletions(-) delete mode 100644 tests/modules/meson.build diff --git a/meson.build b/meson.build index a68a0949..24d5a84d 100644 --- a/meson.build +++ b/meson.build @@ -58,45 +58,6 @@ msft_proxy4_dep = declare_dependency( sources: hdrs + hdrs_v4, include_directories: inc, ) -modules_interface_specs = { - 'gcc': { - 'flags': ['-fmodules', '-fdeps-format=p1689r5'] + (cxx.has_header_symbol( - 'pthread.h', - '__WINPTHREADS_VERSION', - ) ? [ - '-DWINPTHREAD_COND_DECL=WINPTHREADS_ALWAYS_INLINE', - ] : []), - 'check_only': ['-M'], - }, - 'msvc': { - 'flags': ['/interface'], - }, -} -modules = get_option('modules').disable_if( - not modules_interface_specs.has_key(cxx.get_argument_syntax()), -) -if modules.allowed() and cxx.has_multi_arguments( - modules_interface_specs[cxx.get_argument_syntax()].get('flags'), - modules_interface_specs[cxx.get_argument_syntax()].get('check_only', []), - required: modules, -) - modules_interface_cflags = modules_interface_specs[cxx.get_argument_syntax()]['flags'] - msft_proxy4_mod = declare_dependency( - include_directories: inc, - dependencies: msft_proxy4_dep, - link_with: static_library( - 'msft_proxy4_module', - hdrs_mod, - include_directories: inc, - cpp_args: modules_interface_cflags, - implicit_include_directories: false, - build_by_default: true, - ), - ) -else - modules_interface_cflags = [] - msft_proxy4_mod = disabler() -endif install_headers( hdrs, @@ -123,7 +84,6 @@ if pkgconfig.found() endif meson.override_dependency(meson.project_name(), msft_proxy4_dep) -meson.override_dependency(meson.project_name() + '_module', msft_proxy4_mod) tests = get_option('tests').disable_auto_if(meson.is_subproject()) gtest_dep = dependency( diff --git a/meson.options b/meson.options index f337dd2e..87729d76 100644 --- a/meson.options +++ b/meson.options @@ -22,9 +22,3 @@ option( value: 'auto', description: 'Extract and build examples from docs', ) -option( - 'modules', - type: 'feature', - value: 'auto', - description: 'Build with C++ modules support', -) diff --git a/tests/meson.build b/tests/meson.build index fa4be9cb..895bfc3a 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -66,8 +66,3 @@ if cxx.has_multi_arguments( ) endif endif - -subdir( - 'modules', - if_found: msft_proxy4_mod, -) diff --git a/tests/modules/meson.build b/tests/modules/meson.build deleted file mode 100644 index 136d8378..00000000 --- a/tests/modules/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -test( - 'ProxyModuleSupportTests', - executable( - 'msft_proxy_tests_modules', - files('foo.cpp', 'impl.cpp', 'main.cpp'), - implicit_include_directories: false, - cpp_args: modules_interface_cflags, - dependencies: [msft_proxy4_mod, gtest_dep], - build_by_default: false, - ), - protocol: 'gtest', -) From 09e7ef26d4eef85317f4ca9a19c101e06a1f6b34 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 8 Dec 2025 22:05:44 +0800 Subject: [PATCH 32/40] fixup! ci: add meson tests --- .github/workflows/bvt-appleclang.yml | 18 ++++++++-------- .github/workflows/bvt-clang.yml | 24 ++++++++++----------- .github/workflows/bvt-compatibility.yml | 18 ++++++++-------- .github/workflows/bvt-gcc.yml | 20 +++++++++--------- .github/workflows/bvt-msvc.yml | 18 ++++++++-------- .github/workflows/bvt-nvhpc.yml | 28 ++++++++++++------------- .github/workflows/bvt-oneapi.yml | 20 +++++++++--------- 7 files changed, 73 insertions(+), 73 deletions(-) diff --git a/.github/workflows/bvt-appleclang.yml b/.github/workflows/bvt-appleclang.yml index 64c935d7..28c0a26c 100644 --- a/.github/workflows/bvt-appleclang.yml +++ b/.github/workflows/bvt-appleclang.yml @@ -17,22 +17,22 @@ jobs: - name: build and run test with AppleClang on cmake run: | - cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE - cmake --build build -j - ctest --test-dir build -j - mkdir build/drop - bash ./tools/dump_build_env.sh c++ build/drop/env-info.json + cmake -B build-cmake -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE + cmake --build build-cmake -j + ctest --test-dir build-cmake -j + mkdir build-cmake/drop + bash ./tools/dump_build_env.sh c++ build-cmake/drop/env-info.json - name: build and run test with AppleClang on meson run: | - meson setup builddir --buildtype=release -Dtests=enabled - meson test -C builddir + meson setup build-meson --buildtype=release -Dtests=enabled + meson test -C build-meson - name: run benchmarks - run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json + run: build-cmake/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake/drop/benchmarking-results.json - name: archive benchmarking results uses: actions/upload-artifact@v4 with: name: drop-appleclang - path: build/drop/ + path: build-cmake/drop/ diff --git a/.github/workflows/bvt-clang.yml b/.github/workflows/bvt-clang.yml index a3836e68..acdd9a02 100644 --- a/.github/workflows/bvt-clang.yml +++ b/.github/workflows/bvt-clang.yml @@ -24,27 +24,27 @@ jobs: run: | "$CXX" --version - - name: build and run test with clang 20 on cmake + - name: build and run test with clang 21 on cmake run: | - cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE - mapfile -t FILES < <(find include tests benchmarks build/examples_from_docs tools -type f \( -name '*.h' -o -name '*.ixx' -o -name '*.cpp' \)) + cmake -B build-cmake -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE + mapfile -t FILES < <(find include tests benchmarks build-cmake/examples_from_docs tools -type f \( -name '*.h' -o -name '*.ixx' -o -name '*.cpp' \)) echo "Running clang-format on ${#FILES[@]} files: ${FILES[*]}" clang-format-21 --dry-run --Werror "${FILES[@]}" - cmake --build build -j - ctest --test-dir build -j - mkdir build/drop - bash ./tools/dump_build_env.sh "$CXX" build/drop/env-info.json + cmake --build build-cmake -j + ctest --test-dir build-cmake -j + mkdir build-cmake/drop + bash ./tools/dump_build_env.sh "$CXX" build-cmake/drop/env-info.json - - name: build and run test with clang 20 on meson + - name: build and run test with clang 21 on meson run: | - meson setup builddir --buildtype=release -Dtests=enabled - meson test -C builddir + meson setup build-meson --buildtype=release -Dtests=enabled + meson test -C build-meson - name: run benchmarks - run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json + run: build-cmake/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake/drop/benchmarking-results.json - name: archive benchmarking results uses: actions/upload-artifact@v4 with: name: drop-clang - path: build/drop/ + path: build-cmake/drop/ diff --git a/.github/workflows/bvt-compatibility.yml b/.github/workflows/bvt-compatibility.yml index 8852a6d5..6dda7740 100644 --- a/.github/workflows/bvt-compatibility.yml +++ b/.github/workflows/bvt-compatibility.yml @@ -8,19 +8,19 @@ jobs: fail-fast: false matrix: compiler: - - {compiler: gcc, version: 13, modules: false} - - {compiler: gcc, version: 14, modules: true} - - {compiler: clang, version: 16, modules: false} - - {compiler: clang, version: 17, modules: false} - - {compiler: clang, version: 18, modules: false} - - {compiler: clang, version: 19, modules: false} - - {compiler: clang, version: 20, modules: true} + - {family: gcc, version: 13, modules: false} + - {family: gcc, version: 14, modules: true} + - {family: clang, version: 16, modules: false} + - {family: clang, version: 17, modules: false} + - {family: clang, version: 18, modules: false} + - {family: clang, version: 19, modules: false} + - {family: clang, version: 20, modules: true} steps: - uses: actions/checkout@v4 - name: install gcc - if: ${{ matrix.compiler.compiler == 'gcc' }} + if: ${{ matrix.compiler.family == 'gcc' }} run: | sudo apt install -y 'g++-${{ matrix.compiler.version }}' cat <<'EOF' >> "$GITHUB_ENV" @@ -29,7 +29,7 @@ jobs: EOF - name: install clang - if: ${{ matrix.compiler.compiler == 'clang' }} + if: ${{ matrix.compiler.family == 'clang' }} run: | sudo apt install -y 'clang-${{ matrix.compiler.version }}' 'clang-tools-${{ matrix.compiler.version }}' 'libc++-${{ matrix.compiler.version }}-dev' 'libc++abi-${{ matrix.compiler.version }}-dev' cat <<'EOF' >> "$GITHUB_ENV" diff --git a/.github/workflows/bvt-gcc.yml b/.github/workflows/bvt-gcc.yml index 382cd887..2ee2df1a 100644 --- a/.github/workflows/bvt-gcc.yml +++ b/.github/workflows/bvt-gcc.yml @@ -15,27 +15,27 @@ jobs: - name: check compiler version run: | - c++ --version + g++ --version - name: build and run test with gcc 15 on cmake run: | - cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE - cmake --build build -j - ctest --test-dir build -j - mkdir build/drop + cmake -B build-cmake -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=TRUE + cmake --build build-cmake -j + ctest --test-dir build-cmake -j + mkdir build-cmake/drop chmod +x tools/dump_build_env.sh - ./tools/dump_build_env.sh c++ build/drop/env-info.json + ./tools/dump_build_env.sh g++ build-cmake/drop/env-info.json - name: build and run test with gcc 15 on meson run: | - meson setup builddir --buildtype=release -Dtests=enabled - meson test -C builddir + meson setup build-meson --buildtype=release -Dtests=enabled + meson test -C build-meson - name: run benchmarks - run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json + run: build-cmake/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake/drop/benchmarking-results.json - name: archive benchmarking results uses: actions/upload-artifact@v4 with: name: drop-gcc - path: build/drop/ + path: build-cmake/drop/ diff --git a/.github/workflows/bvt-msvc.yml b/.github/workflows/bvt-msvc.yml index 2fa86ede..fafe6b5e 100644 --- a/.github/workflows/bvt-msvc.yml +++ b/.github/workflows/bvt-msvc.yml @@ -15,22 +15,22 @@ jobs: - name: build and run test with MSVC on cmake run: | - cmake -B build -DCMAKE_CXX_STANDARD=23 -DPROXY_BUILD_MODULES=TRUE ` - && cmake --build build --config Release -j ` - && ctest --test-dir build -j ` - && mkdir build\drop > $null ` - && .\tools\dump_build_env_msvc.ps1 -OutputPath build\drop\env-info.json + cmake -B build-cmake -DCMAKE_CXX_STANDARD=23 -DPROXY_BUILD_MODULES=TRUE ` + && cmake --build build-cmake --config Release -j ` + && ctest --test-dir build-cmake -j ` + && mkdir build-cmake\drop > $null ` + && .\tools\dump_build_env_msvc.ps1 -OutputPath build-cmake\drop\env-info.json - name: build and run test with MSVC on meson run: | - meson setup builddir --buildtype=release -Dtests=enabled --vsenv - meson test -C builddir + meson setup build-meson --buildtype=release -Dtests=enabled --vsenv + meson test -C build-meson - name: run benchmarks - run: build\benchmarks\Release\msft_proxy_benchmarks.exe --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build\drop\benchmarking-results.json + run: build-cmake\benchmarks\Release\msft_proxy_benchmarks.exe --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake\drop\benchmarking-results.json - name: archive benchmarking results uses: actions/upload-artifact@v4 with: name: drop-msvc - path: build/drop/ + path: build-cmake/drop/ diff --git a/.github/workflows/bvt-nvhpc.yml b/.github/workflows/bvt-nvhpc.yml index af2e019b..f5548ddb 100644 --- a/.github/workflows/bvt-nvhpc.yml +++ b/.github/workflows/bvt-nvhpc.yml @@ -10,9 +10,9 @@ jobs: - name: free disk space uses: jlumbroso/free-disk-space@v1.3.1 - - name: install meson - # FIXME: install from upstream once https://github.com/mesonbuild/meson/pull/15353 is released - run: pipx install git+https://github.com/mesonbuild/meson@02b85a846629090a0c7f18e860bab0a10ea4349b + # - name: install meson + # # FIXME: install from upstream once https://github.com/mesonbuild/meson/pull/15353 is released + # run: pipx install git+https://github.com/mesonbuild/meson@02b85a846629090a0c7f18e860bab0a10ea4349b - name: install NVHPC 25.11 run: | @@ -27,23 +27,23 @@ jobs: - name: build and run test with NVHPC 25.11 on cmake run: | - cmake -B build -GNinja -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE - cmake --build build -j - ctest --test-dir build -j - mkdir build/drop + cmake -B build-cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DPROXY_BUILD_MODULES=FALSE + cmake --build build-cmake -j + ctest --test-dir build-cmake -j + mkdir build-cmake/drop chmod +x tools/dump_build_env.sh - ./tools/dump_build_env.sh "$CXX" build/drop/env-info.json + ./tools/dump_build_env.sh "$CXX" build-cmake/drop/env-info.json - - name: build and run test with NVHPC 25.11 on meson - run: | - meson setup builddir --buildtype=release -Dtests=enabled - meson test -C builddir + # - name: build and run test with NVHPC 25.11 on meson + # run: | + # meson setup build-meson --buildtype=release -Dtests=enabled + # meson test -C build-meson - name: run benchmarks - run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json + run: build-cmake/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake/drop/benchmarking-results.json - name: archive benchmarking results uses: actions/upload-artifact@v4 with: name: drop-nvhpc - path: build/drop/ + path: build-cmake/drop/ diff --git a/.github/workflows/bvt-oneapi.yml b/.github/workflows/bvt-oneapi.yml index 99d403d5..6417887e 100644 --- a/.github/workflows/bvt-oneapi.yml +++ b/.github/workflows/bvt-oneapi.yml @@ -12,7 +12,7 @@ jobs: - name: install libc++ run: | - sudo apt-get install -y libc++-19-dev + sudo apt-get install -y libc++-19-dev libc++abi-19-dev cat <<'EOF' >> "$GITHUB_ENV" CXXFLAGS=-stdlib=libc++ EOF @@ -37,22 +37,22 @@ jobs: - name: build and run test with oneapi on cmake run: | - cmake -B build -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release - cmake --build build -j - ctest --test-dir build -j - mkdir build/drop - bash ./tools/dump_build_env.sh "$CXX" build/drop/env-info.json + cmake -B build-cmake -GNinja -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release + cmake --build build-cmake -j + ctest --test-dir build-cmake -j + mkdir build-cmake/drop + bash ./tools/dump_build_env.sh "$CXX" build-cmake/drop/env-info.json - name: build and run test with oneapi on meson run: | - meson setup builddir --buildtype=release -Dtests=enabled - meson test -C builddir + meson setup build-meson --buildtype=release -Dtests=enabled + meson test -C build-meson - name: run benchmarks - run: build/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build/drop/benchmarking-results.json + run: build-cmake/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake/drop/benchmarking-results.json - name: archive benchmarking results uses: actions/upload-artifact@v4 with: name: drop-oneapi - path: build/drop/ + path: build-cmake/drop/ From 5dd012dd346dbe1cac1a02746801312807fb2f7b Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 8 Dec 2025 22:05:59 +0800 Subject: [PATCH 33/40] fixup! Test for std::format using __cpp_lib_format --- include/proxy/v4/proxy.h | 16 ++++++++-------- include/proxy/v4/proxy.ixx | 8 ++++---- tests/proxy_dispatch_tests.cpp | 4 ++-- tests/proxy_format_tests.cpp | 12 ++++++------ tools/extract_example_code_from_docs.py | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/proxy/v4/proxy.h b/include/proxy/v4/proxy.h index 0c486105..b9ccf752 100644 --- a/include/proxy/v4/proxy.h +++ b/include/proxy/v4/proxy.h @@ -23,8 +23,8 @@ #if __has_include() #include #endif // __has_include() -#if __cpp_lib_format || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 170000) -#define _PRO4D_HAS_FORMAT +#if __cpp_lib_format >= 201907L || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 170000) +#define PRO4D_HAS_FORMAT #endif // __cpp_lib_format || _LIBCPP_VERSION >= 170000 #endif // __STDC_HOSTED__ @@ -2128,7 +2128,7 @@ struct weak_conversion_dispatch : cast_dispatch_base { template using weak_conversion_overload = weak_proxy() const noexcept; -#ifdef _PRO4D_HAS_FORMAT +#ifdef PRO4D_HAS_FORMAT template struct format_overload_traits; template <> @@ -2169,7 +2169,7 @@ struct format_dispatch { return impl.format(self, fc); } }; -#endif // _PRO4D_HAS_FORMAT +#endif // PRO4D_HAS_FORMAT #if __cpp_rtti >= 199711L struct proxy_cast_context { @@ -2276,7 +2276,7 @@ struct proxy_typeid_reflector { namespace skills { -#ifdef _PRO4D_HAS_FORMAT +#ifdef PRO4D_HAS_FORMAT template using format = typename FB::template add_convention using wformat = typename FB::template add_convention>; -#endif // _PRO4D_HAS_FORMAT +#endif // PRO4D_HAS_FORMAT #if __cpp_rtti >= 199711L template @@ -2607,7 +2607,7 @@ struct weak_dispatch : D { // == Adapters (std::formatter) == // ============================================================================= -#ifdef _PRO4D_HAS_FORMAT +#ifdef PRO4D_HAS_FORMAT namespace std { template @@ -2638,7 +2638,7 @@ struct formatter, CharT> { }; } // namespace std -#endif // _PRO4D_HAS_FORMAT +#endif // PRO4D_HAS_FORMAT #undef PROD_UNREACHABLE #undef PROD_NO_UNIQUE_ADDRESS_ATTRIBUTE diff --git a/include/proxy/v4/proxy.ixx b/include/proxy/v4/proxy.ixx index 3463e33d..37fb9811 100644 --- a/include/proxy/v4/proxy.ixx +++ b/include/proxy/v4/proxy.ixx @@ -41,10 +41,10 @@ using v4::weak_proxy; namespace skills { -#ifdef _PRO4D_HAS_FORMAT +#ifdef PRO4D_HAS_FORMAT using skills::format; using skills::wformat; -#endif // _PRO4D_HAS_FORMAT +#endif // PRO4D_HAS_FORMAT #if __cpp_rtti >= 199711L using skills::direct_rtti; @@ -60,10 +60,10 @@ using skills::slim; } // namespace pro::inline v4 -#ifdef _PRO4D_HAS_FORMAT +#ifdef PRO4D_HAS_FORMAT export namespace std { using std::formatter; } // namespace std -#endif // _PRO4D_HAS_FORMAT +#endif // PRO4D_HAS_FORMAT diff --git a/tests/proxy_dispatch_tests.cpp b/tests/proxy_dispatch_tests.cpp index 284cce37..ca7fc85b 100644 --- a/tests/proxy_dispatch_tests.cpp +++ b/tests/proxy_dispatch_tests.cpp @@ -829,7 +829,7 @@ TEST(ProxyDispatchTests, TestFreeAsMemDispatch) { } TEST(ProxyDispatchTests, TestSubstitutionDispatch) { -#ifdef _PRO4D_HAS_FORMAT +#ifdef PRO4D_HAS_FORMAT struct Base : pro::facade_builder // ::add_skill // ::build {}; @@ -847,5 +847,5 @@ TEST(ProxyDispatchTests, TestSubstitutionDispatch) { ASSERT_EQ(std::format("{}", *p3), "123"); #else GTEST_SKIP() << "std::format not available"; -#endif // _PRO4D_HAS_FORMAT +#endif // PRO4D_HAS_FORMAT } diff --git a/tests/proxy_format_tests.cpp b/tests/proxy_format_tests.cpp index 186198bf..89479733 100644 --- a/tests/proxy_format_tests.cpp +++ b/tests/proxy_format_tests.cpp @@ -4,7 +4,7 @@ #include #include -#ifdef _PRO4D_HAS_FORMAT +#ifdef PRO4D_HAS_FORMAT namespace proxy_format_tests_details { struct NonFormattable : pro::facade_builder::build {}; @@ -30,26 +30,26 @@ static_assert( } // namespace proxy_format_tests_details namespace details = proxy_format_tests_details; -#endif // _PRO4D_HAS_FORMAT +#endif // PRO4D_HAS_FORMAT TEST(ProxyFormatTests, TestFormat) { -#ifdef _PRO4D_HAS_FORMAT +#ifdef PRO4D_HAS_FORMAT int v = 123; pro::proxy p = &v; ASSERT_EQ(std::format("{}", *p), "123"); ASSERT_EQ(std::format("{:*<6}", *p), "123***"); #else GTEST_SKIP() << "std::format not available"; -#endif // _PRO4D_HAS_FORMAT +#endif // PRO4D_HAS_FORMAT } TEST(ProxyFormatTests, TestWformat) { -#ifdef _PRO4D_HAS_FORMAT +#ifdef PRO4D_HAS_FORMAT int v = 123; pro::proxy p = &v; ASSERT_EQ(std::format(L"{}", *p), L"123"); ASSERT_EQ(std::format(L"{:*<6}", *p), L"123***"); #else GTEST_SKIP() << "std::format not available"; -#endif // _PRO4D_HAS_FORMAT +#endif // PRO4D_HAS_FORMAT } diff --git a/tools/extract_example_code_from_docs.py b/tools/extract_example_code_from_docs.py index b07220e2..cef1440a 100644 --- a/tools/extract_example_code_from_docs.py +++ b/tools/extract_example_code_from_docs.py @@ -30,7 +30,7 @@ def extract_cpp_code(md_path: Path) -> T.Optional[str]: if "pro::skills::format" in cpp_code: cpp_code = f""" #include -#ifdef _PRO4D_HAS_FORMAT +#ifdef PRO4D_HAS_FORMAT {cpp_code} #else int main() {{ From e5fad93eddc9296100334625ed77af966dff2082 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Mon, 8 Dec 2025 22:11:52 +0800 Subject: [PATCH 34/40] build/meson: add test and benchmarks to all targets, only test build benchmark on ci --- .github/workflows/bvt-appleclang.yml | 2 +- .github/workflows/bvt-clang.yml | 2 +- .github/workflows/bvt-gcc.yml | 2 +- .github/workflows/bvt-msvc.yml | 2 +- .github/workflows/bvt-nvhpc.yml | 2 +- .github/workflows/bvt-oneapi.yml | 2 +- benchmarks/meson.build | 1 - meson.options | 6 ---- tests/meson.build | 49 ++++++++++++---------------- 9 files changed, 27 insertions(+), 41 deletions(-) diff --git a/.github/workflows/bvt-appleclang.yml b/.github/workflows/bvt-appleclang.yml index 28c0a26c..3ff12ed4 100644 --- a/.github/workflows/bvt-appleclang.yml +++ b/.github/workflows/bvt-appleclang.yml @@ -25,7 +25,7 @@ jobs: - name: build and run test with AppleClang on meson run: | - meson setup build-meson --buildtype=release -Dtests=enabled + meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled meson test -C build-meson - name: run benchmarks diff --git a/.github/workflows/bvt-clang.yml b/.github/workflows/bvt-clang.yml index acdd9a02..c79d7ee9 100644 --- a/.github/workflows/bvt-clang.yml +++ b/.github/workflows/bvt-clang.yml @@ -37,7 +37,7 @@ jobs: - name: build and run test with clang 21 on meson run: | - meson setup build-meson --buildtype=release -Dtests=enabled + meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled meson test -C build-meson - name: run benchmarks diff --git a/.github/workflows/bvt-gcc.yml b/.github/workflows/bvt-gcc.yml index 2ee2df1a..199fba9d 100644 --- a/.github/workflows/bvt-gcc.yml +++ b/.github/workflows/bvt-gcc.yml @@ -28,7 +28,7 @@ jobs: - name: build and run test with gcc 15 on meson run: | - meson setup build-meson --buildtype=release -Dtests=enabled + meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled meson test -C build-meson - name: run benchmarks diff --git a/.github/workflows/bvt-msvc.yml b/.github/workflows/bvt-msvc.yml index fafe6b5e..4e738026 100644 --- a/.github/workflows/bvt-msvc.yml +++ b/.github/workflows/bvt-msvc.yml @@ -23,7 +23,7 @@ jobs: - name: build and run test with MSVC on meson run: | - meson setup build-meson --buildtype=release -Dtests=enabled --vsenv + meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled --vsenv meson test -C build-meson - name: run benchmarks diff --git a/.github/workflows/bvt-nvhpc.yml b/.github/workflows/bvt-nvhpc.yml index f5548ddb..4733fdd9 100644 --- a/.github/workflows/bvt-nvhpc.yml +++ b/.github/workflows/bvt-nvhpc.yml @@ -36,7 +36,7 @@ jobs: # - name: build and run test with NVHPC 25.11 on meson # run: | - # meson setup build-meson --buildtype=release -Dtests=enabled + # meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled # meson test -C build-meson - name: run benchmarks diff --git a/.github/workflows/bvt-oneapi.yml b/.github/workflows/bvt-oneapi.yml index 6417887e..5eb83919 100644 --- a/.github/workflows/bvt-oneapi.yml +++ b/.github/workflows/bvt-oneapi.yml @@ -45,7 +45,7 @@ jobs: - name: build and run test with oneapi on meson run: | - meson setup build-meson --buildtype=release -Dtests=enabled + meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled meson test -C build-meson - name: run benchmarks diff --git a/benchmarks/meson.build b/benchmarks/meson.build index 41ae9ef9..f878c364 100644 --- a/benchmarks/meson.build +++ b/benchmarks/meson.build @@ -9,6 +9,5 @@ benchmark( ), implicit_include_directories: false, dependencies: [msft_proxy4_dep, benchmark_dep], - build_by_default: false, ), ) diff --git a/meson.options b/meson.options index 87729d76..584693ac 100644 --- a/meson.options +++ b/meson.options @@ -4,12 +4,6 @@ option( value: 'auto', description: 'Build tests', ) -option( - 'tests_freestanding', - type: 'feature', - value: 'auto', - description: 'Build freestanding tests', -) option( 'benchmarks', type: 'feature', diff --git a/tests/meson.build b/tests/meson.build index 895bfc3a..15eec398 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,7 +1,6 @@ -test_srcs = [ +test_srcs = files( 'proxy_creation_tests.cpp', 'proxy_dispatch_tests.cpp', - 'proxy_fmt_format_tests.cpp', 'proxy_format_tests.cpp', 'proxy_integration_tests.cpp', 'proxy_invocation_tests.cpp', @@ -11,44 +10,39 @@ test_srcs = [ 'proxy_rtti_tests.cpp', 'proxy_traits_tests.cpp', 'proxy_view_tests.cpp', -] +) -foreach src : test_srcs - test_deps = [msft_proxy4_dep, gtest_dep] - name = src.substring(6, -10) - if name.contains('fmt') - test_deps += fmt_dep - endif - title = '' - foreach part : name.split('_') - title += part.substring(0, 1).to_upper() + part.substring(1) - endforeach +test_deps = [msft_proxy4_dep, gtest_dep] - test( - f'Proxy@title@Tests', - executable( - f'msft_proxy_@name@_tests', - src, - implicit_include_directories: false, - dependencies: test_deps, - build_by_default: false, - ), - protocol: 'gtest', +if fmt_dep.found() + test_srcs += files( + 'proxy_fmt_format_tests.cpp', ) -endforeach + test_deps += fmt_dep +endif + +test( + 'ProxyTests', + executable( + 'msft_proxy_tests', + test_srcs, + implicit_include_directories: false, + dependencies: test_deps, + ), + protocol: 'gtest', +) -freestanding = get_option('tests_freestanding') freestanding_cflags = ['-ffreestanding', '-fno-exceptions', '-fno-rtti'] freestanding_ldflags = ['-nodefaultlibs'] if cxx.has_multi_arguments( freestanding_cflags, freestanding_ldflags, - required: freestanding, + required: false, ) libc_dep = cxx.find_library( 'c', - required: freestanding, + required: false, ) if libc_dep.found() @@ -61,7 +55,6 @@ if cxx.has_multi_arguments( dependencies: [msft_proxy4_dep, libc_dep], cpp_args: freestanding_cflags + freestanding_ldflags, link_args: get_option('b_sanitize') == 'none' ? freestanding_ldflags : [], - build_by_default: false, ), ) endif From 952456ffb12d9fb0979bb564e8580fc76933706d Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Tue, 9 Dec 2025 00:22:07 +0800 Subject: [PATCH 35/40] fixup! Test for std::format using __cpp_lib_format --- include/proxy/v4/proxy.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/proxy/v4/proxy.h b/include/proxy/v4/proxy.h index b9ccf752..dcebcd3e 100644 --- a/include/proxy/v4/proxy.h +++ b/include/proxy/v4/proxy.h @@ -23,7 +23,8 @@ #if __has_include() #include #endif // __has_include() -#if __cpp_lib_format >= 201907L || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 170000) +#if __cpp_lib_format >= 201907L || \ + (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 170000) #define PRO4D_HAS_FORMAT #endif // __cpp_lib_format || _LIBCPP_VERSION >= 170000 #endif // __STDC_HOSTED__ From a7406735860fce07c62381da83cbebcad37a88f4 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Tue, 9 Dec 2025 01:02:00 +0800 Subject: [PATCH 36/40] fixup! build/meson: add test and benchmarks to all targets, only test build benchmark on ci --- tests/meson.build | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/meson.build b/tests/meson.build index 15eec398..fbf36f2c 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -28,11 +28,12 @@ test( test_srcs, implicit_include_directories: false, dependencies: test_deps, + build_by_default: false, ), protocol: 'gtest', ) -freestanding_cflags = ['-ffreestanding', '-fno-exceptions', '-fno-rtti'] +freestanding_cflags = ['-ffreestanding'] freestanding_ldflags = ['-nodefaultlibs'] if cxx.has_multi_arguments( @@ -55,6 +56,11 @@ if cxx.has_multi_arguments( dependencies: [msft_proxy4_dep, libc_dep], cpp_args: freestanding_cflags + freestanding_ldflags, link_args: get_option('b_sanitize') == 'none' ? freestanding_ldflags : [], + override_options: { + 'cpp_eh': 'none', + 'cpp_rtti': false, + }, + build_by_default: false, ), ) endif From 717c86de856705b774f1fcba6fc625fb5c25eb70 Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Tue, 9 Dec 2025 03:25:15 +0800 Subject: [PATCH 37/40] fixup! build/meson: add test and benchmarks to all targets, only test build benchmark on ci --- .github/workflows/bvt-appleclang.yml | 1 + .github/workflows/bvt-clang.yml | 1 + .github/workflows/bvt-gcc.yml | 1 + .github/workflows/bvt-msvc.yml | 1 + .github/workflows/bvt-nvhpc.yml | 1 + .github/workflows/bvt-oneapi.yml | 1 + 6 files changed, 6 insertions(+) diff --git a/.github/workflows/bvt-appleclang.yml b/.github/workflows/bvt-appleclang.yml index 3ff12ed4..2f4a8079 100644 --- a/.github/workflows/bvt-appleclang.yml +++ b/.github/workflows/bvt-appleclang.yml @@ -27,6 +27,7 @@ jobs: run: | meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled meson test -C build-meson + meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true - name: run benchmarks run: build-cmake/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake/drop/benchmarking-results.json diff --git a/.github/workflows/bvt-clang.yml b/.github/workflows/bvt-clang.yml index c79d7ee9..4601c732 100644 --- a/.github/workflows/bvt-clang.yml +++ b/.github/workflows/bvt-clang.yml @@ -39,6 +39,7 @@ jobs: run: | meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled meson test -C build-meson + meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true - name: run benchmarks run: build-cmake/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake/drop/benchmarking-results.json diff --git a/.github/workflows/bvt-gcc.yml b/.github/workflows/bvt-gcc.yml index 199fba9d..2423975d 100644 --- a/.github/workflows/bvt-gcc.yml +++ b/.github/workflows/bvt-gcc.yml @@ -30,6 +30,7 @@ jobs: run: | meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled meson test -C build-meson + meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true - name: run benchmarks run: build-cmake/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake/drop/benchmarking-results.json diff --git a/.github/workflows/bvt-msvc.yml b/.github/workflows/bvt-msvc.yml index 4e738026..429b9ab1 100644 --- a/.github/workflows/bvt-msvc.yml +++ b/.github/workflows/bvt-msvc.yml @@ -25,6 +25,7 @@ jobs: run: | meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled --vsenv meson test -C build-meson + meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true - name: run benchmarks run: build-cmake\benchmarks\Release\msft_proxy_benchmarks.exe --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake\drop\benchmarking-results.json diff --git a/.github/workflows/bvt-nvhpc.yml b/.github/workflows/bvt-nvhpc.yml index 4733fdd9..6191a8de 100644 --- a/.github/workflows/bvt-nvhpc.yml +++ b/.github/workflows/bvt-nvhpc.yml @@ -38,6 +38,7 @@ jobs: # run: | # meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled # meson test -C build-meson + # meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true - name: run benchmarks run: build-cmake/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake/drop/benchmarking-results.json diff --git a/.github/workflows/bvt-oneapi.yml b/.github/workflows/bvt-oneapi.yml index 5eb83919..e2bafd00 100644 --- a/.github/workflows/bvt-oneapi.yml +++ b/.github/workflows/bvt-oneapi.yml @@ -47,6 +47,7 @@ jobs: run: | meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled meson test -C build-meson + meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true - name: run benchmarks run: build-cmake/benchmarks/msft_proxy_benchmarks --benchmark_min_warmup_time=0.1 --benchmark_min_time=0.1s --benchmark_repetitions=30 --benchmark_enable_random_interleaving=true --benchmark_report_aggregates_only=true --benchmark_format=json > build-cmake/drop/benchmarking-results.json From 4744c25ccd53ef45710245d7e02ad91eba0870de Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Tue, 9 Dec 2025 03:25:57 +0800 Subject: [PATCH 38/40] build/meson: update fmt to 12.1.0 --- subprojects/fmt.wrap | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/subprojects/fmt.wrap b/subprojects/fmt.wrap index 7e9c5c42..65448572 100644 --- a/subprojects/fmt.wrap +++ b/subprojects/fmt.wrap @@ -1,13 +1,13 @@ [wrap-file] -directory = fmt-12.0.0 -source_url = https://github.com/fmtlib/fmt/archive/12.0.0.tar.gz -source_filename = fmt-12.0.0.tar.gz -source_hash = aa3e8fbb6a0066c03454434add1f1fc23299e85758ceec0d7d2d974431481e40 -source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/fmt_12.0.0-1/fmt-12.0.0.tar.gz -patch_filename = fmt_12.0.0-1_patch.zip -patch_url = https://wrapdb.mesonbuild.com/v2/fmt_12.0.0-1/get_patch -patch_hash = 307f288ebf3850abf2f0c50ac1fb07de97df9538d39146d802f3c0d6cada8998 -wrapdb_version = 12.0.0-1 +directory = fmt-12.1.0 +source_url = https://github.com/fmtlib/fmt/archive/12.1.0.tar.gz +source_filename = fmt-12.1.0.tar.gz +source_hash = ea7de4299689e12b6dddd392f9896f08fb0777ac7168897a244a6d6085043fea +source_fallback_url = https://github.com/wrapdb/fmt/releases/download/12.1.0-4/fmt-12.1.0.tar.gz +patch_filename = fmt_12.1.0-4_patch.zip +patch_url = https://github.com/wrapdb/fmt/releases/download/12.1.0-4/fmt_12.1.0-4_patch.zip +patch_hash = 65b7fe3c29f25528011bc295e83e4f6f10028c922407e003b7856bb79789f345 +3rdparty_wrapdb_version = 12.1.0-4 [provide] dependency_names = fmt From 2c7f068496459b15778cc58afbdb1c316c5e717d Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Tue, 9 Dec 2025 03:37:42 +0800 Subject: [PATCH 39/40] fixup! tools: add python typings --- tools/extract_example_code_from_docs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/extract_example_code_from_docs.py b/tools/extract_example_code_from_docs.py index cef1440a..becbb947 100644 --- a/tools/extract_example_code_from_docs.py +++ b/tools/extract_example_code_from_docs.py @@ -2,13 +2,13 @@ # pyright: strict import re -import typing as T +from typing import Optional from pathlib import Path EXAMPLE_PATTERN = re.compile(r"## Example\r?\n\r?\n```cpp\r?\n(.*?)\r?\n```", re.DOTALL) -def extract_cpp_code(md_path: Path) -> T.Optional[str]: +def extract_cpp_code(md_path: Path) -> Optional[str]: with open(md_path, "r", encoding="utf-8") as f: content = f.read() From 0ad0d06c9b336c86ed486ad3858afb9d906c391b Mon Sep 17 00:00:00 2001 From: Zephyr Lykos Date: Tue, 9 Dec 2025 03:54:17 +0800 Subject: [PATCH 40/40] fixup! build/meson: remove all autogen --- .github/workflows/bvt-appleclang.yml | 2 +- .github/workflows/bvt-clang.yml | 2 +- .github/workflows/bvt-gcc.yml | 2 +- .github/workflows/bvt-msvc.yml | 2 +- .github/workflows/bvt-nvhpc.yml | 2 +- .github/workflows/bvt-oneapi.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/bvt-appleclang.yml b/.github/workflows/bvt-appleclang.yml index 2f4a8079..ace58802 100644 --- a/.github/workflows/bvt-appleclang.yml +++ b/.github/workflows/bvt-appleclang.yml @@ -25,7 +25,7 @@ jobs: - name: build and run test with AppleClang on meson run: | - meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled + meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled --force-fallback-for=fmt meson test -C build-meson meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true diff --git a/.github/workflows/bvt-clang.yml b/.github/workflows/bvt-clang.yml index 4601c732..1706930a 100644 --- a/.github/workflows/bvt-clang.yml +++ b/.github/workflows/bvt-clang.yml @@ -37,7 +37,7 @@ jobs: - name: build and run test with clang 21 on meson run: | - meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled + meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled --force-fallback-for=fmt meson test -C build-meson meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true diff --git a/.github/workflows/bvt-gcc.yml b/.github/workflows/bvt-gcc.yml index 2423975d..4a5e6138 100644 --- a/.github/workflows/bvt-gcc.yml +++ b/.github/workflows/bvt-gcc.yml @@ -28,7 +28,7 @@ jobs: - name: build and run test with gcc 15 on meson run: | - meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled + meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled --force-fallback-for=fmt meson test -C build-meson meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true diff --git a/.github/workflows/bvt-msvc.yml b/.github/workflows/bvt-msvc.yml index 429b9ab1..fe06cca7 100644 --- a/.github/workflows/bvt-msvc.yml +++ b/.github/workflows/bvt-msvc.yml @@ -23,7 +23,7 @@ jobs: - name: build and run test with MSVC on meson run: | - meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled --vsenv + meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled --force-fallback-for=fmt --vsenv meson test -C build-meson meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true diff --git a/.github/workflows/bvt-nvhpc.yml b/.github/workflows/bvt-nvhpc.yml index 6191a8de..e9c1eea3 100644 --- a/.github/workflows/bvt-nvhpc.yml +++ b/.github/workflows/bvt-nvhpc.yml @@ -36,7 +36,7 @@ jobs: # - name: build and run test with NVHPC 25.11 on meson # run: | - # meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled + # meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled --force-fallback-for=fmt # meson test -C build-meson # meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true diff --git a/.github/workflows/bvt-oneapi.yml b/.github/workflows/bvt-oneapi.yml index e2bafd00..86f19141 100644 --- a/.github/workflows/bvt-oneapi.yml +++ b/.github/workflows/bvt-oneapi.yml @@ -45,7 +45,7 @@ jobs: - name: build and run test with oneapi on meson run: | - meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled + meson setup build-meson --buildtype=release -Dtests=enabled -Dbenchmarks=enabled --force-fallback-for=fmt meson test -C build-meson meson test -C build-meson --benchmark --test-args=--benchmark_list_tests=true