Skip to content

Commit fc72517

Browse files
committed
Add portable compat smoke coverage
1 parent 378ad36 commit fc72517

2 files changed

Lines changed: 323 additions & 0 deletions

File tree

.github/workflows/validate.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,61 @@ jobs:
6767
timeout 1800 bash tests/smoke_compat_imgui.sh
6868
timeout 1800 bash tests/smoke_compat_archive.sh
6969
timeout 1800 bash tests/smoke_compat_imgui_window.sh
70+
71+
smoke-portable:
72+
name: smoke-${{ matrix.platform }}
73+
runs-on: ${{ matrix.os }}
74+
timeout-minutes: 60
75+
strategy:
76+
fail-fast: false
77+
matrix:
78+
include:
79+
- platform: macos
80+
os: macos-15
81+
archive: mcpp-0.0.40-macosx-arm64.tar.gz
82+
root: mcpp-0.0.40-macosx-arm64
83+
mcpp: bin/mcpp
84+
xlings: registry/bin/xlings
85+
- platform: windows
86+
os: windows-latest
87+
archive: mcpp-0.0.40-windows-x86_64.zip
88+
root: mcpp-0.0.40-windows-x86_64
89+
mcpp: bin/mcpp.exe
90+
xlings: registry/bin/xlings.exe
91+
steps:
92+
- uses: actions/checkout@v4
93+
- name: Download mcpp
94+
shell: bash
95+
env:
96+
MCPP_VERSION: "0.0.40"
97+
MCPP_ARCHIVE: ${{ matrix.archive }}
98+
MCPP_ROOT: ${{ matrix.root }}
99+
run: |
100+
curl -L -fsS -o "$MCPP_ARCHIVE" \
101+
"https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/${MCPP_ARCHIVE}"
102+
case "$MCPP_ARCHIVE" in
103+
*.zip)
104+
powershell -NoProfile -Command "Expand-Archive -Force -Path '${MCPP_ARCHIVE}' -DestinationPath '.'"
105+
;;
106+
*)
107+
tar -xzf "$MCPP_ARCHIVE"
108+
;;
109+
esac
110+
111+
root="$PWD/$MCPP_ROOT"
112+
if [[ "$RUNNER_OS" == "Windows" ]]; then
113+
echo "MCPP=$(cygpath -m "$root/${{ matrix.mcpp }}")" >> "$GITHUB_ENV"
114+
echo "MCPP_VENDORED_XLINGS=$(cygpath -m "$root/${{ matrix.xlings }}")" >> "$GITHUB_ENV"
115+
echo "$(cygpath -m "$root/bin")" >> "$GITHUB_PATH"
116+
else
117+
echo "MCPP=$root/${{ matrix.mcpp }}" >> "$GITHUB_ENV"
118+
echo "MCPP_VENDORED_XLINGS=$root/${{ matrix.xlings }}" >> "$GITHUB_ENV"
119+
echo "$root/bin" >> "$GITHUB_PATH"
120+
fi
121+
- name: Run portable compat smoke tests
122+
shell: bash
123+
env:
124+
MCPP_INDEX_MIRROR: GLOBAL
125+
run: |
126+
"$MCPP" --version
127+
bash tests/smoke_compat_portable.sh

tests/smoke_compat_portable.sh

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
#!/usr/bin/env bash
2+
# Cross-platform smoke tests for compat packages that should not depend on
3+
# Linux/X11 runtime libraries.
4+
set -euo pipefail
5+
6+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
7+
MCPP_BIN="${MCPP:-}"
8+
if [[ -z "$MCPP_BIN" ]]; then
9+
MCPP_BIN="$(command -v mcpp || true)"
10+
fi
11+
12+
to_native_path() {
13+
if [[ "${OS:-}" == "Windows_NT" ]] && command -v cygpath >/dev/null 2>&1; then
14+
cygpath -m "$1"
15+
else
16+
printf '%s\n' "$1"
17+
fi
18+
}
19+
20+
to_posix_path() {
21+
if [[ "${OS:-}" == "Windows_NT" ]] && command -v cygpath >/dev/null 2>&1; then
22+
cygpath -u "$1"
23+
else
24+
printf '%s\n' "$1"
25+
fi
26+
}
27+
28+
MCPP_BIN_POSIX=""
29+
if [[ -n "$MCPP_BIN" ]]; then
30+
MCPP_BIN_POSIX="$(to_posix_path "$MCPP_BIN")"
31+
fi
32+
if [[ -z "$MCPP_BIN_POSIX" || ! -f "$MCPP_BIN_POSIX" ]]; then
33+
echo "FATAL: set MCPP=/path/to/mcpp or put mcpp on PATH" >&2
34+
exit 1
35+
fi
36+
37+
platform="$(uname -s)"
38+
if [[ "${OS:-}" == "Windows_NT" ]]; then
39+
platform="Windows_NT"
40+
fi
41+
42+
case "$platform" in
43+
Windows_NT|Darwin)
44+
TOOLCHAIN="${MCPP_INDEX_PORTABLE_TOOLCHAIN:-llvm@20.1.7}"
45+
;;
46+
*)
47+
TOOLCHAIN="${MCPP_INDEX_PORTABLE_TOOLCHAIN:-gcc@16.1.0}"
48+
;;
49+
esac
50+
51+
TMP="$(mktemp -d)"
52+
if [[ "${MCPP_INDEX_KEEP_SMOKE_TMP:-0}" == "1" ]]; then
53+
echo "KEEP: $TMP"
54+
else
55+
trap 'rm -rf "$TMP"' EXIT
56+
fi
57+
58+
MCPP_HOME_POSIX="$TMP/mcpp-home"
59+
mkdir -p "$MCPP_HOME_POSIX"
60+
export MCPP_HOME="$(to_native_path "$MCPP_HOME_POSIX")"
61+
62+
INDEX_ROOT="$(to_native_path "$ROOT")"
63+
SMOKE_CACHE_DIR="${MCPP_INDEX_SMOKE_CACHE_DIR:-}"
64+
65+
USER_MCPP="${MCPP_INDEX_USER_MCPP_HOME:-${HOME}/.mcpp}"
66+
mkdir -p "$MCPP_HOME_POSIX/registry/data/xpkgs"
67+
link_xpkgs() {
68+
local src="$1"
69+
[[ -d "$src" ]] || return 0
70+
find "$src" -mindepth 1 -maxdepth 1 -type d | while read -r pkg; do
71+
[[ "$(basename "$pkg")" == compat-x-* ]] && continue
72+
ln -s "$pkg" "$MCPP_HOME_POSIX/registry/data/xpkgs/$(basename "$pkg")" 2>/dev/null || true
73+
done
74+
}
75+
link_xpkgs "${MCPP_INDEX_SMOKE_XPKGS_DIR:-}"
76+
link_xpkgs "$USER_MCPP/registry/data/xpkgs"
77+
if [[ -d "$USER_MCPP/registry/data/xim-pkgindex" ]]; then
78+
mkdir -p "$MCPP_HOME_POSIX/registry/data/xim-pkgindex"
79+
cp -a "$USER_MCPP/registry/data/xim-pkgindex/." "$MCPP_HOME_POSIX/registry/data/xim-pkgindex/" 2>/dev/null || true
80+
rm -f "$MCPP_HOME_POSIX/registry/data/xim-pkgindex/.xlings-index-cache.json"
81+
fi
82+
if [[ -d "$USER_MCPP/registry/bin" ]]; then
83+
mkdir -p "$MCPP_HOME_POSIX/registry"
84+
ln -s "$USER_MCPP/registry/bin" "$MCPP_HOME_POSIX/registry/bin" 2>/dev/null || true
85+
fi
86+
if [[ -f "$USER_MCPP/config.toml" ]]; then
87+
cp -f "$USER_MCPP/config.toml" "$MCPP_HOME_POSIX/config.toml" 2>/dev/null || true
88+
fi
89+
90+
"$MCPP_BIN_POSIX" self config --mirror "${MCPP_INDEX_MIRROR:-GLOBAL}"
91+
92+
copy_smoke_cache() {
93+
[[ -n "$SMOKE_CACHE_DIR" && -d "$SMOKE_CACHE_DIR" ]] || return 0
94+
mkdir -p .mcpp/.xlings/data/runtimedir
95+
find "$SMOKE_CACHE_DIR" -maxdepth 1 -type f \
96+
\( -name '*.tar.gz' -o -name '*.tar.xz' -o -name '*.zip' \) \
97+
-exec cp -f {} .mcpp/.xlings/data/runtimedir/ \;
98+
}
99+
100+
write_build_ldflags() {
101+
case "$platform" in
102+
Linux)
103+
cat <<'EOF'
104+
105+
[build]
106+
ldflags = ["-ldl", "-lm"]
107+
EOF
108+
;;
109+
Darwin)
110+
cat <<'EOF'
111+
112+
[build]
113+
ldflags = ["-lm"]
114+
EOF
115+
;;
116+
esac
117+
}
118+
119+
make_project() {
120+
local name="$1"
121+
mkdir -p "$TMP/$name/src"
122+
cd "$TMP/$name"
123+
cat > mcpp.toml <<EOF
124+
[package]
125+
name = "$name"
126+
version = "0.1.0"
127+
128+
[toolchain]
129+
default = "$TOOLCHAIN"
130+
131+
[indices]
132+
compat = { path = "$INDEX_ROOT" }
133+
134+
[targets.$name]
135+
kind = "bin"
136+
main = "src/main.cpp"
137+
EOF
138+
copy_smoke_cache
139+
}
140+
141+
make_project "compat-portable-core-smoke"
142+
cat >> mcpp.toml <<'EOF'
143+
144+
[dependencies.compat]
145+
gtest = "1.15.2"
146+
ftxui = "6.1.9"
147+
lua = "5.4.7"
148+
mbedtls = "3.6.1"
149+
opengl = "2026.05.31"
150+
khrplatform = "2026.05.31"
151+
EOF
152+
write_build_ldflags >> mcpp.toml
153+
cat > src/main.cpp <<'EOF'
154+
#include <array>
155+
#include <string>
156+
157+
#include <GL/gl.h>
158+
#include <KHR/khrplatform.h>
159+
#include <ftxui/dom/elements.hpp>
160+
#include <ftxui/screen/screen.hpp>
161+
#include <gtest/gtest.h>
162+
#include <mbedtls/sha256.h>
163+
164+
extern "C" {
165+
#include <lauxlib.h>
166+
#include <lua.h>
167+
#include <lualib.h>
168+
}
169+
170+
TEST(CompatPortableCore, UpstreamHeadersAndRuntime) {
171+
using namespace ftxui;
172+
Element document = hbox({text("compat"), separator(), text("ftxui")});
173+
Screen screen = Screen::Create(Dimension::Fit(document), Dimension::Fit(document));
174+
Render(screen, document);
175+
const std::string rendered = screen.ToString();
176+
EXPECT_NE(rendered.find("compat"), std::string::npos);
177+
EXPECT_NE(rendered.find("ftxui"), std::string::npos);
178+
179+
lua_State* state = luaL_newstate();
180+
ASSERT_NE(state, nullptr);
181+
luaL_openlibs(state);
182+
ASSERT_EQ(luaL_dostring(state, "return 20 + 22"), LUA_OK);
183+
EXPECT_TRUE(lua_isinteger(state, -1));
184+
EXPECT_EQ(lua_tointeger(state, -1), 42);
185+
lua_close(state);
186+
187+
const unsigned char input[] = "abc";
188+
std::array<unsigned char, 32> out{};
189+
mbedtls_sha256(input, 3, out.data(), 0);
190+
EXPECT_EQ(out[0], 0xba);
191+
EXPECT_EQ(out[1], 0x78);
192+
EXPECT_EQ(out[30], 0x15);
193+
EXPECT_EQ(out[31], 0xad);
194+
195+
EXPECT_EQ(GL_TEXTURE_2D, 0x0DE1);
196+
EXPECT_EQ(static_cast<khronos_uint32_t>(1), 1u);
197+
}
198+
EOF
199+
"$MCPP_BIN_POSIX" build
200+
"$MCPP_BIN_POSIX" run
201+
202+
make_project "compat-portable-archive-smoke"
203+
cat >> mcpp.toml <<'EOF'
204+
205+
[dependencies.compat]
206+
libarchive = "3.8.7"
207+
EOF
208+
cat > src/main.cpp <<'EOF'
209+
#include <archive.h>
210+
#include <archive_entry.h>
211+
#include <bzlib.h>
212+
#include <lz4.h>
213+
#include <lzma.h>
214+
#include <zlib.h>
215+
#include <zstd.h>
216+
217+
int main() {
218+
archive* writer = archive_write_new();
219+
if (!writer) return 1;
220+
archive_write_free(writer);
221+
222+
archive_entry* entry = archive_entry_new();
223+
if (!entry) return 2;
224+
archive_entry_free(entry);
225+
226+
if (!archive_version_string()) return 3;
227+
if (!zlibVersion()) return 4;
228+
if (!BZ2_bzlibVersion()) return 5;
229+
if (LZ4_versionNumber() <= 0) return 6;
230+
if (ZSTD_versionNumber() == 0) return 7;
231+
if (lzma_version_number() == 0) return 8;
232+
return 0;
233+
}
234+
EOF
235+
"$MCPP_BIN_POSIX" build
236+
"$MCPP_BIN_POSIX" run
237+
238+
make_project "compat-portable-imgui-glfw-smoke"
239+
cat >> mcpp.toml <<'EOF'
240+
241+
[dependencies.compat]
242+
imgui = "1.92.8"
243+
glfw = "3.4"
244+
EOF
245+
cat > src/main.cpp <<'EOF'
246+
#include <GLFW/glfw3.h>
247+
#include <imgui.h>
248+
#include <imgui_impl_glfw.h>
249+
#include <imgui_impl_opengl3.h>
250+
251+
#include "imgui_impl_glfw.cpp"
252+
#include "imgui_impl_opengl3.cpp"
253+
254+
int main() {
255+
const char* glfw = glfwGetVersionString();
256+
const char* imgui = ImGui::GetVersion();
257+
return glfw && imgui &&
258+
GLFW_VERSION_MAJOR == 3 &&
259+
IMGUI_VERSION_NUM >= 19200 ? 0 : 1;
260+
}
261+
EOF
262+
"$MCPP_BIN_POSIX" build
263+
"$MCPP_BIN_POSIX" run
264+
265+
echo "OK"

0 commit comments

Comments
 (0)