From 938f934dd71be2507f7c299df289c9fb8f4ea823 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Fri, 8 May 2026 17:11:26 +0800 Subject: [PATCH 1/2] feat: add mcpp build support and switch Linux CI to mcpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `mcpp.toml` at the project root so mcpp can build the library natively, dropping the hand-written `mcpp = {}` workaround in mcpp-index. The Linux CI job now bootstraps mcpp via xlings and runs `mcpp build` + `mcpp test`; macOS and Windows continue to use xmake since mcpp's support on those platforms is still WIP. Tests no longer define their own `main()` — `mcpp test` always links `gtest_main`, so `tests/xmake.lua` is updated to request gtest with `main = true` to keep both build systems consistent. README adds a mcpp section under "构建" and "集成到构建工具". --- .github/workflows/ci.yml | 87 ++++++++++++++++++++++++---------------- .gitignore | 1 + README.md | 20 +++++++++ mcpp.toml | 16 ++++++++ tests/cmdline_test.cpp | 5 --- tests/xmake.lua | 2 +- 6 files changed, 91 insertions(+), 40 deletions(-) create mode 100644 mcpp.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 786f348..ec99aa1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,53 +6,72 @@ on: pull_request: branches: [main, master] +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build-linux: - runs-on: ubuntu-latest + name: build + test (linux x86_64, mcpp) + runs-on: ubuntu-24.04 + timeout-minutes: 30 + env: + MCPP_HOME: /home/runner/.mcpp steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Setup xmake - uses: xmake-io/github-action-setup-xmake@v1 + # mcpp's sandbox (musl-gcc + ninja + binutils) is multi-hundred-MB; + # key on mcpp.toml so toolchain changes refresh the cache. + - name: Cache mcpp sandbox + uses: actions/cache@v4 with: - xmake-version: latest - package-cache: true + path: ~/.mcpp + key: mcpp-sandbox-${{ runner.os }}-${{ hashFiles('mcpp.toml') }} + restore-keys: | + mcpp-sandbox-${{ runner.os }}- - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y build-essential - - - name: Install Xlings - run: curl -fsSL https://d2learn.org/xlings-install.sh | bash - - - name: Install GCC 15.1 with Xlings + - name: Cache xlings + uses: actions/cache@v4 + with: + path: ~/.xlings + key: xlings-${{ runner.os }} + restore-keys: | + xlings-${{ runner.os }}- + + - name: Bootstrap mcpp via xlings + env: + XLINGS_NON_INTERACTIVE: '1' run: | - export PATH=/home/xlings/.xlings_data/bin:$PATH - xlings install gcc@15.1 -y + if [ ! -x "$HOME/.xlings/subos/default/bin/xlings" ]; then + curl -fsSL https://d2learn.org/xlings-install.sh | bash + fi + export PATH="$HOME/.xlings/subos/default/bin:$PATH" + xlings --version + xlings install mcpp -y + mcpp --version + echo "$HOME/.xlings/subos/default/bin" >> "$GITHUB_PATH" + + - name: Cache target/ (build artifacts + BMIs) + uses: actions/cache@v4 + with: + path: target + key: mcpp-target-${{ runner.os }}-${{ hashFiles('src/**', 'tests/**', 'mcpp.toml') }} + restore-keys: | + mcpp-target-${{ runner.os }}- - name: Build - run: | - export PATH=/home/xlings/.xlings_data/bin:$PATH - xmake -y -vv + run: mcpp build - name: Test - run: | - export PATH=/home/xlings/.xlings_data/bin:$PATH - xmake run cmdline_test - - - name: Run examples (smoke) - run: | - export PATH=/home/xlings/.xlings_data/bin:$PATH - xmake run with_dispatch -- add python 3.12 - xmake run with_dispatch -- remove foo + run: mcpp test + # mcpp is Linux-x86_64 first; macOS/Windows support is still WIP, so the + # cross-platform xmake build keeps coverage for those targets. build-macos: + name: build (macOS, xmake) runs-on: macos-latest steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - name: Setup xmake uses: xmake-io/github-action-setup-xmake@v1 @@ -69,10 +88,10 @@ jobs: xmake -y -vv build-windows: + name: build + test (Windows, xmake) runs-on: windows-latest steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - name: Setup xmake uses: xmake-io/github-action-setup-xmake@v1 diff --git a/.gitignore b/.gitignore index 173fb6e..4ceeed5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .xmake build +target diff --git a/README.md b/README.md index bcacbc2..1c765cf 100644 --- a/README.md +++ b/README.md @@ -76,12 +76,21 @@ auto r3 = app.parse_from("myapp remove x --yes"); ## 构建 +**使用 xmake** + ```shell xmake # 构建库 xmake run basic # 运行基础示例 xmake -y run cmdline_test # 运行测试(自动安装 gtest) ``` +**使用 mcpp** + +```shell +mcpp build # 构建库 +mcpp test # 运行 tests/ 下的测试 +``` + ## 集成到构建工具 ### xmake @@ -101,6 +110,17 @@ target("mytool") set_policy("build.c++.modules", true) ``` +### mcpp + +在项目的 `mcpp.toml` 中声明依赖: + +```toml +[dependencies] +"mcpplibs.cmdline" = "^0.0.2" +``` + +然后在源码中 `import mcpplibs.cmdline;` 即可使用。 + ## 相关链接 - [社区官网](https://mcpp.d2learn.org) diff --git a/mcpp.toml b/mcpp.toml new file mode 100644 index 0000000..9bcdb69 --- /dev/null +++ b/mcpp.toml @@ -0,0 +1,16 @@ +[package] +name = "mcpplibs.cmdline" +version = "0.0.2" +description = "A simple command-line parsing library/framework for modern C++" +license = "Apache-2.0" +authors = ["mcpplibs"] +repo = "https://github.com/mcpplibs/cmdline" + +# Library target — exposes module `mcpplibs.cmdline` to dependents. +# Sources default to src/**/*.{cppm,cpp,cc,c}; tests/ and examples/ are +# discovered separately (`mcpp test` / standalone builds). +[targets.cmdline] +kind = "lib" + +[dev-dependencies] +gtest = "1.15.2" diff --git a/tests/cmdline_test.cpp b/tests/cmdline_test.cpp index 2e99609..5aaeebc 100644 --- a/tests/cmdline_test.cpp +++ b/tests/cmdline_test.cpp @@ -3,11 +3,6 @@ import std; import mcpplibs.cmdline; -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - using namespace mcpplibs::cmdline; // Build argv from program name + args for parse() diff --git a/tests/xmake.lua b/tests/xmake.lua index 08f653a..6f60568 100644 --- a/tests/xmake.lua +++ b/tests/xmake.lua @@ -1,7 +1,7 @@ add_rules("mode.debug", "mode.release") set_languages("c++23") -add_requires("gtest") +add_requires("gtest", { configs = { main = true } }) target("cmdline_test") set_kind("binary") From 4c1dfe4e529fa7e765e8719ab9758954069bafb8 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Fri, 8 May 2026 17:20:23 +0800 Subject: [PATCH 2/2] fix(ci): unblock Windows xmake test link (LNK1561) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xmake's gtest package defaults to `gmock = true`, so with `main = true` it links `gmock_main.lib` (not `gtest_main.lib`). On Windows, MSVC's linker doesn't scan inside static libs for the entry point, so it reports `LNK1561: entry point must be defined`. - Disable gmock — we don't use it; this switches the linked main archive to `gtest_main.lib`. - Add `/WHOLEARCHIVE:gtest_main.lib` on Windows to force the entry point object into the link, side-stepping MSVC's lazy lib resolution. --- tests/xmake.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/xmake.lua b/tests/xmake.lua index 6f60568..8634659 100644 --- a/tests/xmake.lua +++ b/tests/xmake.lua @@ -1,7 +1,7 @@ add_rules("mode.debug", "mode.release") set_languages("c++23") -add_requires("gtest", { configs = { main = true } }) +add_requires("gtest", { configs = { main = true, gmock = false } }) target("cmdline_test") set_kind("binary") @@ -9,3 +9,8 @@ target("cmdline_test") add_deps("cmdline") add_packages("gtest") set_policy("build.c++.modules", true) + -- MSVC 不会从静态库扫描入口点,需要 /WHOLEARCHIVE 把 gtest_main.lib + -- 强制整体链入,否则报 LNK1561: entry point must be defined。 + if is_plat("windows") then + add_ldflags("/wholearchive:gtest_main.lib", { force = true }) + end