diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 333d96b..5df9f2b 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -51,7 +51,7 @@ jobs: - uses: actions/checkout@v4 - name: Download mcpp env: - MCPP_VERSION: "0.0.40" + MCPP_VERSION: "0.0.41" run: | curl -L -fsS -o mcpp.tar.gz \ "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/mcpp-${MCPP_VERSION}-linux-x86_64.tar.gz" @@ -67,3 +67,61 @@ jobs: timeout 1800 bash tests/smoke_compat_imgui.sh timeout 1800 bash tests/smoke_compat_archive.sh timeout 1800 bash tests/smoke_compat_imgui_window.sh + + smoke-portable: + name: smoke-${{ matrix.platform }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - platform: macos + os: macos-15 + archive: mcpp-0.0.41-macosx-arm64.tar.gz + root: mcpp-0.0.41-macosx-arm64 + mcpp: bin/mcpp + xlings: registry/bin/xlings + - platform: windows + os: windows-latest + archive: mcpp-0.0.41-windows-x86_64.zip + root: mcpp-0.0.41-windows-x86_64 + mcpp: bin/mcpp.exe + xlings: registry/bin/xlings.exe + steps: + - uses: actions/checkout@v4 + - name: Download mcpp + shell: bash + env: + MCPP_VERSION: "0.0.41" + MCPP_ARCHIVE: ${{ matrix.archive }} + MCPP_ROOT: ${{ matrix.root }} + run: | + curl -L -fsS -o "$MCPP_ARCHIVE" \ + "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/${MCPP_ARCHIVE}" + case "$MCPP_ARCHIVE" in + *.zip) + powershell -NoProfile -Command "Expand-Archive -Force -Path '${MCPP_ARCHIVE}' -DestinationPath '.'" + ;; + *) + tar -xzf "$MCPP_ARCHIVE" + ;; + esac + + root="$PWD/$MCPP_ROOT" + if [[ "$RUNNER_OS" == "Windows" ]]; then + echo "MCPP=$(cygpath -m "$root/${{ matrix.mcpp }}")" >> "$GITHUB_ENV" + echo "MCPP_VENDORED_XLINGS=$(cygpath -m "$root/${{ matrix.xlings }}")" >> "$GITHUB_ENV" + echo "$(cygpath -m "$root/bin")" >> "$GITHUB_PATH" + else + echo "MCPP=$root/${{ matrix.mcpp }}" >> "$GITHUB_ENV" + echo "MCPP_VENDORED_XLINGS=$root/${{ matrix.xlings }}" >> "$GITHUB_ENV" + echo "$root/bin" >> "$GITHUB_PATH" + fi + - name: Run portable compat smoke tests + shell: bash + env: + MCPP_INDEX_MIRROR: GLOBAL + run: | + "$MCPP" --version + bash tests/smoke_compat_portable.sh diff --git a/pkgs/c/compat.ftxui.lua b/pkgs/c/compat.ftxui.lua index c36e5c0..9a816bf 100644 --- a/pkgs/c/compat.ftxui.lua +++ b/pkgs/c/compat.ftxui.lua @@ -51,5 +51,8 @@ package = { }, targets = { ["ftxui"] = { kind = "lib" } }, deps = { }, + windows = { + cxxflags = { "-DUNICODE", "-D_UNICODE" }, + }, }, } diff --git a/pkgs/c/compat.mbedtls.lua b/pkgs/c/compat.mbedtls.lua index e02d929..2613d61 100644 --- a/pkgs/c/compat.mbedtls.lua +++ b/pkgs/c/compat.mbedtls.lua @@ -47,5 +47,8 @@ package = { c_standard = "c11", targets = { ["mbedtls"] = { kind = "lib" } }, deps = { }, + windows = { + ldflags = { "-lbcrypt" }, + }, }, } diff --git a/tests/smoke_compat_imgui_window.sh b/tests/smoke_compat_imgui_window.sh index f0c7e5a..739d972 100755 --- a/tests/smoke_compat_imgui_window.sh +++ b/tests/smoke_compat_imgui_window.sh @@ -85,6 +85,7 @@ fi cat > src/main.cpp <<'EOF' #include +#define GLFW_INCLUDE_NONE #include #include #include diff --git a/tests/smoke_compat_portable.sh b/tests/smoke_compat_portable.sh new file mode 100755 index 0000000..61f5288 --- /dev/null +++ b/tests/smoke_compat_portable.sh @@ -0,0 +1,266 @@ +#!/usr/bin/env bash +# Cross-platform smoke tests for compat packages that should not depend on +# Linux/X11 runtime libraries. +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 + +to_native_path() { + if [[ "${OS:-}" == "Windows_NT" ]] && command -v cygpath >/dev/null 2>&1; then + cygpath -m "$1" + else + printf '%s\n' "$1" + fi +} + +to_posix_path() { + if [[ "${OS:-}" == "Windows_NT" ]] && command -v cygpath >/dev/null 2>&1; then + cygpath -u "$1" + else + printf '%s\n' "$1" + fi +} + +MCPP_BIN_POSIX="" +if [[ -n "$MCPP_BIN" ]]; then + MCPP_BIN_POSIX="$(to_posix_path "$MCPP_BIN")" +fi +if [[ -z "$MCPP_BIN_POSIX" || ! -f "$MCPP_BIN_POSIX" ]]; then + echo "FATAL: set MCPP=/path/to/mcpp or put mcpp on PATH" >&2 + exit 1 +fi + +platform="$(uname -s)" +if [[ "${OS:-}" == "Windows_NT" ]]; then + platform="Windows_NT" +fi + +case "$platform" in + Windows_NT|Darwin) + TOOLCHAIN="${MCPP_INDEX_PORTABLE_TOOLCHAIN:-llvm@20.1.7}" + ;; + *) + TOOLCHAIN="${MCPP_INDEX_PORTABLE_TOOLCHAIN:-gcc@16.1.0}" + ;; +esac + +TMP="$(mktemp -d)" +if [[ "${MCPP_INDEX_KEEP_SMOKE_TMP:-0}" == "1" ]]; then + echo "KEEP: $TMP" +else + trap 'rm -rf "$TMP"' EXIT +fi + +MCPP_HOME_POSIX="$TMP/mcpp-home" +mkdir -p "$MCPP_HOME_POSIX" +export MCPP_HOME="$(to_native_path "$MCPP_HOME_POSIX")" + +INDEX_ROOT="$(to_native_path "$ROOT")" +SMOKE_CACHE_DIR="${MCPP_INDEX_SMOKE_CACHE_DIR:-}" + +USER_MCPP="${MCPP_INDEX_USER_MCPP_HOME:-${HOME}/.mcpp}" +mkdir -p "$MCPP_HOME_POSIX/registry/data/xpkgs" +link_xpkgs() { + local src="$1" + [[ -d "$src" ]] || return 0 + find "$src" -mindepth 1 -maxdepth 1 -type d | while read -r pkg; do + [[ "$(basename "$pkg")" == compat-x-* ]] && continue + ln -s "$pkg" "$MCPP_HOME_POSIX/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_POSIX/registry/data/xim-pkgindex" + cp -a "$USER_MCPP/registry/data/xim-pkgindex/." "$MCPP_HOME_POSIX/registry/data/xim-pkgindex/" 2>/dev/null || true + rm -f "$MCPP_HOME_POSIX/registry/data/xim-pkgindex/.xlings-index-cache.json" +fi +if [[ -d "$USER_MCPP/registry/bin" ]]; then + mkdir -p "$MCPP_HOME_POSIX/registry" + ln -s "$USER_MCPP/registry/bin" "$MCPP_HOME_POSIX/registry/bin" 2>/dev/null || true +fi +if [[ -f "$USER_MCPP/config.toml" ]]; then + cp -f "$USER_MCPP/config.toml" "$MCPP_HOME_POSIX/config.toml" 2>/dev/null || true +fi + +"$MCPP_BIN_POSIX" self config --mirror "${MCPP_INDEX_MIRROR:-GLOBAL}" + +copy_smoke_cache() { + [[ -n "$SMOKE_CACHE_DIR" && -d "$SMOKE_CACHE_DIR" ]] || return 0 + mkdir -p .mcpp/.xlings/data/runtimedir + find "$SMOKE_CACHE_DIR" -maxdepth 1 -type f \ + \( -name '*.tar.gz' -o -name '*.tar.xz' -o -name '*.zip' \) \ + -exec cp -f {} .mcpp/.xlings/data/runtimedir/ \; +} + +write_build_ldflags() { + case "$platform" in + Linux) + cat <<'EOF' + +[build] +ldflags = ["-ldl", "-lm"] +EOF + ;; + Darwin) + cat <<'EOF' + +[build] +ldflags = ["-lm"] +EOF + ;; + esac +} + +make_project() { + local name="$1" + mkdir -p "$TMP/$name/src" + cd "$TMP/$name" + cat > mcpp.toml <> mcpp.toml <<'EOF' + +[dependencies.compat] +gtest = "1.15.2" +ftxui = "6.1.9" +lua = "5.4.7" +mbedtls = "3.6.1" +opengl = "2026.05.31" +khrplatform = "2026.05.31" +EOF +write_build_ldflags >> mcpp.toml +cat > src/main.cpp <<'EOF' +#include +#include + +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +} + +TEST(CompatPortableCore, UpstreamHeadersAndRuntime) { + using namespace ftxui; + Element document = hbox({text("compat"), separator(), text("ftxui")}); + Screen screen = Screen::Create(Dimension::Fit(document), Dimension::Fit(document)); + Render(screen, document); + const std::string rendered = screen.ToString(); + EXPECT_NE(rendered.find("compat"), std::string::npos); + EXPECT_NE(rendered.find("ftxui"), std::string::npos); + + lua_State* state = luaL_newstate(); + ASSERT_NE(state, nullptr); + luaL_openlibs(state); + ASSERT_EQ(luaL_dostring(state, "return 20 + 22"), LUA_OK); + EXPECT_TRUE(lua_isinteger(state, -1)); + EXPECT_EQ(lua_tointeger(state, -1), 42); + lua_close(state); + + const unsigned char input[] = "abc"; + std::array out{}; + mbedtls_sha256(input, 3, out.data(), 0); + EXPECT_EQ(out[0], 0xba); + EXPECT_EQ(out[1], 0x78); + EXPECT_EQ(out[30], 0x15); + EXPECT_EQ(out[31], 0xad); + + EXPECT_EQ(GL_TEXTURE_2D, 0x0DE1); + EXPECT_EQ(static_cast(1), 1u); +} +EOF +"$MCPP_BIN_POSIX" build +"$MCPP_BIN_POSIX" run + +make_project "compat-portable-archive-smoke" +cat >> mcpp.toml <<'EOF' + +[dependencies.compat] +libarchive = "3.8.7" +EOF +cat > src/main.cpp <<'EOF' +#include +#include +#include +#include +#include +#include +#include + +int main() { + archive* writer = archive_write_new(); + if (!writer) return 1; + archive_write_free(writer); + + archive_entry* entry = archive_entry_new(); + if (!entry) return 2; + archive_entry_free(entry); + + if (!archive_version_string()) return 3; + if (!zlibVersion()) return 4; + if (!BZ2_bzlibVersion()) return 5; + if (LZ4_versionNumber() <= 0) return 6; + if (ZSTD_versionNumber() == 0) return 7; + if (lzma_version_number() == 0) return 8; + return 0; +} +EOF +"$MCPP_BIN_POSIX" build +"$MCPP_BIN_POSIX" run + +make_project "compat-portable-imgui-glfw-smoke" +cat >> mcpp.toml <<'EOF' + +[dependencies.compat] +imgui = "1.92.8" +glfw = "3.4" +EOF +cat > src/main.cpp <<'EOF' +#define GLFW_INCLUDE_NONE +#include +#include +#include +#include + +#include "imgui_impl_glfw.cpp" +#include "imgui_impl_opengl3.cpp" + +int main() { + const char* glfw = glfwGetVersionString(); + const char* imgui = ImGui::GetVersion(); + return glfw && imgui && + GLFW_VERSION_MAJOR == 3 && + IMGUI_VERSION_NUM >= 19200 ? 0 : 1; +} +EOF +"$MCPP_BIN_POSIX" build +"$MCPP_BIN_POSIX" run + +echo "OK"