-
Notifications
You must be signed in to change notification settings - Fork 4
feat: add fmt 12.2.0 as C++23 module package (import fmt;) #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| -- Form B inline descriptor for {fmt} exposed as the C++23 module `fmt`, so | ||
| -- users can write `import fmt;` out of the box (no `#include` needed). This is | ||
| -- the module sibling of the header-based `compat.fmt` package. Empty namespace | ||
| -- (like the public `imgui` module package) so the dependency key and the module | ||
| -- name are both simply `fmt`. | ||
| -- | ||
| -- fmt's release DOES ship an official C++20 module interface unit at | ||
| -- `src/fmt.cc` (`export module fmt;`), but it cannot be fed to mcpp verbatim: | ||
| -- mcpp's M1 module scanner rejects ANY `import` that appears inside a | ||
| -- conditional preprocessor block (even a dead one), and fmt.cc carries | ||
| -- `#ifdef FMT_IMPORT_STD / import std; / #endif`. So we reproduce fmt.cc via | ||
| -- `generated_files` with exactly those three lines removed — everything else is | ||
| -- upstream fmt.cc verbatim: the global-module-fragment `#include`s, the | ||
| -- `export module fmt;` line, the FMT_EXPORT macro plumbing (fmt's headers | ||
| -- self-`export` under FMT_MODULE), and the tail `#include "format.cc"` / | ||
| -- `"os.cc"` that pulls the implementation INTO the module (so its definitions | ||
| -- attach to module `fmt`; compiling them as standalone TUs would leave them on | ||
| -- the global module and break module linkage). | ||
| -- | ||
| -- include_dirs exposes BOTH `*/include` (so the module unit's `#include | ||
| -- <fmt/*.h>` resolves) and `*/src` (so the tail `#include "format.cc"` / | ||
| -- `"os.cc"` resolve). The wrapper path under mcpp_generated/ is verdir-relative | ||
| -- (no glob), like nlohmann.json / compat.eigen. | ||
| package = { | ||
| spec = "1", | ||
| namespace = "", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个可以加上 作者名 或 org 名 作为命名空间 |
||
| name = "fmt", | ||
| description = "A modern formatting library for C++, exposed as C++23 module fmt", | ||
| licenses = {"MIT"}, | ||
| repo = "https://github.com/fmtlib/fmt", | ||
| type = "package", | ||
|
|
||
| xpm = { | ||
| linux = { | ||
| ["12.2.0"] = { | ||
| url = "https://github.com/fmtlib/fmt/archive/refs/tags/12.2.0.tar.gz", | ||
| sha256 = "8b852bb5aa6e7d8564f9e81394055395dd1d1936d38dfd3a17792a02bebd7af0", | ||
| }, | ||
| }, | ||
| macosx = { | ||
| ["12.2.0"] = { | ||
| url = "https://github.com/fmtlib/fmt/archive/refs/tags/12.2.0.tar.gz", | ||
| sha256 = "8b852bb5aa6e7d8564f9e81394055395dd1d1936d38dfd3a17792a02bebd7af0", | ||
| }, | ||
| }, | ||
| windows = { | ||
| ["12.2.0"] = { | ||
| url = "https://github.com/fmtlib/fmt/archive/refs/tags/12.2.0.tar.gz", | ||
| sha256 = "8b852bb5aa6e7d8564f9e81394055395dd1d1936d38dfd3a17792a02bebd7af0", | ||
| }, | ||
| }, | ||
| }, | ||
|
|
||
| mcpp = { | ||
| schema = "0.1", | ||
| language = "c++23", | ||
| import_std = false, | ||
| modules = { "fmt" }, | ||
| include_dirs = { "*/include", "*/src" }, | ||
| generated_files = { | ||
| ["mcpp_generated/fmt_module.cc"] = "// Formatting library for C++ - C++20 module\n//\n// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\nmodule;\n\n#define FMT_MODULE\n\n#ifdef _MSVC_LANG\n# define FMT_CPLUSPLUS _MSVC_LANG\n#else\n# define FMT_CPLUSPLUS __cplusplus\n#endif\n\n// Put all implementation-provided headers into the global module fragment\n// to prevent attachment to this module.\n#ifndef FMT_IMPORT_STD\n# include <algorithm>\n# include <bitset>\n# include <chrono>\n# include <cmath>\n# include <complex>\n# include <cstddef>\n# include <cstdint>\n# include <cstdio>\n# include <cstdlib>\n# include <cstring>\n# include <ctime>\n# include <exception>\n# if FMT_CPLUSPLUS > 202002L\n# include <expected>\n# endif\n# include <filesystem>\n# include <fstream>\n# include <functional>\n# include <iterator>\n# include <limits>\n# include <locale>\n# include <memory>\n# include <optional>\n# include <ostream>\n# include <source_location>\n# include <stdexcept>\n# include <string>\n# include <string_view>\n# include <system_error>\n# include <thread>\n# include <type_traits>\n# include <typeinfo>\n# include <utility>\n# include <variant>\n# include <vector>\n#else\n# include <limits.h>\n# include <stdint.h>\n# include <stdio.h>\n# include <stdlib.h>\n# include <string.h>\n# include <time.h>\n#endif\n#include <cerrno>\n#include <climits>\n#include <version>\n\n#if __has_include(<cxxabi.h>)\n# include <cxxabi.h>\n#endif\n#if defined(_MSC_VER) || defined(__MINGW32__)\n# include <intrin.h>\n#endif\n#if defined __APPLE__ || defined(__FreeBSD__)\n# include <xlocale.h>\n#endif\n#if __has_include(<winapifamily.h>)\n# include <winapifamily.h>\n#endif\n#if (__has_include(<fcntl.h>) || defined(__APPLE__) || \\\n defined(__linux__)) && \\\n (!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))\n# include <fcntl.h>\n# include <sys/stat.h>\n# include <sys/types.h>\n# ifndef _WIN32\n# include <unistd.h>\n# else\n# include <io.h>\n# endif\n#endif\n#ifdef _WIN32\n# if defined(__GLIBCXX__)\n# include <ext/stdio_filebuf.h>\n# include <ext/stdio_sync_filebuf.h>\n# endif\n# define WIN32_LEAN_AND_MEAN\n# include <windows.h>\n#endif\n\nexport module fmt;\n\n\n#define FMT_EXPORT export\n#define FMT_BEGIN_EXPORT export {\n#define FMT_END_EXPORT }\n\n// If you define FMT_ATTACH_TO_GLOBAL_MODULE\n// - all declarations are detached from module 'fmt'\n// - the module behaves like a traditional static library, too\n// - all library symbols are mangled traditionally\n// - you can mix TUs with either importing or #including the {fmt} API\n#ifdef FMT_ATTACH_TO_GLOBAL_MODULE\nextern \"C++\" {\n#endif\n\n#ifndef FMT_OS\n# define FMT_OS 1\n#endif\n\n// All library-provided declarations and definitions must be in the module\n// purview to be exported.\n#include \"fmt/args.h\"\n#include \"fmt/chrono.h\"\n#include \"fmt/color.h\"\n#include \"fmt/compile.h\"\n#include \"fmt/format.h\"\n#if FMT_OS\n# include \"fmt/os.h\"\n#endif\n#include \"fmt/ostream.h\"\n#include \"fmt/printf.h\"\n#include \"fmt/ranges.h\"\n#include \"fmt/std.h\"\n#include \"fmt/xchar.h\"\n\n#ifdef FMT_ATTACH_TO_GLOBAL_MODULE\n}\n#endif\n\n#ifdef FMT_ATTACH_TO_GLOBAL_MODULE\nextern \"C++\" {\n#endif\n\n#if FMT_HAS_INCLUDE(\"format.cc\")\n# include \"format.cc\"\n#endif\n#if FMT_OS && FMT_HAS_INCLUDE(\"os.cc\")\n# include \"os.cc\"\n#endif\n\n#ifdef FMT_ATTACH_TO_GLOBAL_MODULE\n}\n#endif\n", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个可以使用多行语法展开 不用使用 \n 放到单行。类似下面 |
||
| }, | ||
| sources = { "mcpp_generated/fmt_module.cc" }, | ||
| targets = { ["fmt"] = { kind = "lib" } }, | ||
| deps = { }, | ||
| }, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| #!/usr/bin/env bash | ||
| # Smoke-test the public `fmt` module package through this checkout as a local | ||
| # mcpp path index. Validates user-facing import-only consumption (`import fmt;`). | ||
| # Mirrors tests/smoke_imgui_module.sh — the empty-namespace `fmt` package maps to | ||
| # the builtin default index (mcpplibs), which a workspace member cannot point at | ||
| # a local path, so it needs this thin driver that reseeds the default index. | ||
| set -euo pipefail | ||
|
|
||
| ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" | ||
| MCPP_BIN="${MCPP:-}" | ||
| if [[ -z "$MCPP_BIN" ]]; then | ||
| MCPP_BIN="$(command -v mcpp || true)" | ||
| fi | ||
| if [[ -z "$MCPP_BIN" || ! -x "$MCPP_BIN" ]]; then | ||
| echo "FATAL: set MCPP=/path/to/mcpp or put mcpp on PATH" >&2 | ||
| exit 1 | ||
| fi | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个老式的ci方式已经废弃 可以不用添加 |
||
|
|
||
| TMP="$(mktemp -d)" | ||
| if [[ "${MCPP_INDEX_KEEP_SMOKE_TMP:-0}" == "1" ]]; then | ||
| echo "KEEP: $TMP" | ||
| else | ||
| trap 'rm -rf "$TMP"' EXIT | ||
| fi | ||
|
|
||
| if [[ -n "${MCPP_INDEX_SMOKE_MCPP_HOME:-}" ]]; then | ||
| export MCPP_HOME="$MCPP_INDEX_SMOKE_MCPP_HOME" | ||
| else | ||
| export MCPP_HOME="$TMP/mcpp-home" | ||
| fi | ||
| mkdir -p "$MCPP_HOME/registry/data/xpkgs" | ||
|
|
||
| USER_MCPP="${HOME}/.mcpp" | ||
| link_xpkgs() { | ||
| local src="$1" | ||
| [[ -d "$src" ]] || return 0 | ||
| find "$src" -mindepth 1 -maxdepth 1 -type d | while read -r pkg; do | ||
| ln -s "$pkg" "$MCPP_HOME/registry/data/xpkgs/$(basename "$pkg")" 2>/dev/null || true | ||
| done | ||
| } | ||
| link_xpkgs "${MCPP_INDEX_SMOKE_XPKGS_DIR:-}" | ||
| link_xpkgs "$USER_MCPP/registry/data/xpkgs" | ||
| if [[ -d "$USER_MCPP/registry/data/xim-pkgindex" ]]; then | ||
| mkdir -p "$MCPP_HOME/registry/data/xim-pkgindex" | ||
| cp -a "$USER_MCPP/registry/data/xim-pkgindex/." "$MCPP_HOME/registry/data/xim-pkgindex/" 2>/dev/null || true | ||
| rm -f "$MCPP_HOME/registry/data/xim-pkgindex/.xlings-index-cache.json" | ||
| fi | ||
| if [[ -d "$USER_MCPP/registry/bin" ]]; then | ||
| mkdir -p "$MCPP_HOME/registry" | ||
| ln -s "$USER_MCPP/registry/bin" "$MCPP_HOME/registry/bin" 2>/dev/null || true | ||
| fi | ||
| if [[ -f "$USER_MCPP/config.toml" ]]; then | ||
| cp -f "$USER_MCPP/config.toml" "$MCPP_HOME/config.toml" 2>/dev/null || true | ||
| fi | ||
|
|
||
| default_index="$MCPP_HOME/registry/data/mcpplibs" | ||
| # Reseed cleanly (see smoke_imgui_module.sh for why .git is skipped). | ||
| rm -rf "$default_index" | ||
| mkdir -p "$default_index" | ||
| ( cd "$ROOT" && find . -mindepth 1 -maxdepth 1 ! -name .git -exec cp -a {} "$default_index/" \; ) | ||
| rm -f "$default_index/.xlings-index-cache.json" | ||
| printf 'ok\n' > "$default_index/.mcpp-index-updated" | ||
|
|
||
| "$MCPP_BIN" self config --mirror "${MCPP_INDEX_MIRROR:-GLOBAL}" >/dev/null | ||
|
|
||
| mkdir -p "$TMP/fmt-module-smoke/src" | ||
| cd "$TMP/fmt-module-smoke" | ||
| cat > mcpp.toml <<EOF | ||
| [package] | ||
| name = "fmt-module-smoke" | ||
| version = "0.1.0" | ||
| [toolchain] | ||
| default = "${MCPP_INDEX_FMT_MODULE_TOOLCHAIN:-gcc@16.1.0}" | ||
| [dependencies] | ||
| fmt = "12.2.0" | ||
| [targets.fmt-module-smoke] | ||
| kind = "bin" | ||
| main = "src/main.cpp" | ||
| EOF | ||
|
|
||
| cat > src/main.cpp <<'EOF' | ||
| import std; | ||
| import fmt; | ||
| int main() { | ||
| std::string a = fmt::format("{} + {} = {}", 2, 3, 2 + 3); | ||
| std::string b = fmt::format("{:08.3f}", 3.14159); | ||
| std::string c = fmt::format("{0}-{1}-{0}", "x", "y"); | ||
| std::string d = fmt::format("{:#x}", 255); | ||
| bool ok = a == "2 + 3 = 5" && b == "0003.142" && c == "x-y-x" && d == "0xff"; | ||
| std::println("fmt module package ok: {}", a); | ||
| return ok ? 0 : 1; | ||
| } | ||
| EOF | ||
|
|
||
| "$MCPP_BIN" build | ||
| "$MCPP_BIN" run | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
不用加这个