Use radare2 releases on macOS and Windows and test git on Linux

This commit is contained in:
pancake committed 2026-10-26 20:35:27 +01:00
1 parent 079b4483f8
commit 5e933871b3
6 files changed
+111 -67

No files matched your search

+10 -13
View File
@@ -46,14 +46,14 @@ jobs:
with:
arch: x64
# build r2 from git: the point is to stress test the current r_fs.
# windows uses the release until r2 git builds with msvc again
# Stress test current r_fs on Linux; build against releases elsewhere.
- uses: radareorg/github-actions@v3
id: r2
with:
from-git: ${{ runner.os != 'Windows' }}
from-git: ${{ runner.os == 'Linux' }}
- name: Fetch test images
if: runner.os == 'Linux'
# only fs/ is needed, and other directories have names invalid on windows
run: |
git -c core.protectNTFS=false clone --depth 1 --filter=blob:none --no-checkout https://github.com/radareorg/radare2-testbins testbins
@@ -65,7 +65,7 @@ jobs:
run: make
- name: Test with Make
if: matrix.build_system == 'make'
if: matrix.build_system == 'make' && runner.os == 'Linux'
run: make check TESTBINS=testbins/fs
- name: Setup Meson
@@ -81,19 +81,16 @@ jobs:
meson compile -C build
- name: Test with Meson
if: matrix.build_system == 'meson' && runner.os != 'Windows'
if: matrix.build_system == 'meson' && runner.os == 'Linux'
run: meson test -C build --print-errorlogs
- name: Smoke test (Windows)
if: runner.os == 'Windows'
- name: Smoke test (macOS and Windows)
if: runner.os != 'Linux'
shell: bash
run: |
./build/r2fuse.exe -v
./build/r2fuse.exe -L
ls -la testbins/fs | head
for img in fat.img iso.img ext2.img hfs.img; do
./build/r2fuse.exe -d -s "$(cygpath -w "$PWD/testbins/fs/$img")"
done
bin=${{ matrix.build_system == 'make' && './r2fuse' || './build/r2fuse' }}${{ runner.os == 'Windows' && '.exe' || '' }}
"$bin" -v
"$bin" -L
- name: Mount test (Linux)
if: runner.os == 'Linux' && matrix.build_system == 'make'
+26 -45
View File
@@ -1,8 +1,7 @@
name: Release
# Self-contained r2fuse binaries: radare2 (GPL build, with the grub plugins)
# and libfuse are linked statically, so nothing but the OS FUSE provider is
# needed at runtime (Fusetta on macOS, /dev/fuse on Linux, WinFsp on Windows).
# Portable archives: Linux links radare2 from git and libfuse statically;
# macOS and Windows bundle the libraries from a radare2 release.
on:
push:
@@ -70,21 +69,20 @@ jobs:
- uses: actions/checkout@v4
- name: Install build tools
run: brew install meson ninja
- name: Build static binary (Fusetta libfuse)
- name: Install radare2 release
uses: radareorg/github-actions@v3
- name: Build with release radare2 and static Fusetta libfuse
env:
R2_PREFIX: /usr/local
run: |
./dist/static.sh
# only system libraries and frameworks are allowed
! otool -L r2fuse | tail -n +2 | grep -vE '^[[:space:]]+/(usr/lib|System)/'
- name: Smoke test
run: |
git -c core.protectNTFS=false clone --depth 1 --filter=blob:none --no-checkout https://github.com/radareorg/radare2-testbins testbins
git -C testbins -c core.protectNTFS=false sparse-checkout set fs && git -C testbins -c core.protectNTFS=false checkout
./r2fuse -v
./test/run.sh testbins/fs
- name: Package
run: |
d=r2fuse-$VERSION-macos-arm64
mkdir $d && cp r2fuse README.md LICENSE FSTODO.md $d/
python3 dist/package-macos.py r2fuse "$d" /usr/local/lib
cp README.md LICENSE FSTODO.md "$d/"
"$d/r2fuse" -v
"$d/r2fuse" -L
tar czf $d.tar.gz $d
- uses: actions/upload-artifact@v4
with:
@@ -102,50 +100,33 @@ jobs:
- name: Install build tools
run: |
pip install meson ninja
choco install winfsp pkgconfiglite -y
- name: Cache static radare2
id: r2-cache
uses: actions/cache@v4
with:
path: r2
key: windows-x64-radare2-${{ env.R2_REF }}-c11-mt-v1
- name: Build static radare2
if: steps.r2-cache.outputs.cache-hit != 'true'
choco install winfsp -y
- name: Install radare2 release
id: r2
uses: radareorg/github-actions@v3
- name: Build r2fuse
shell: pwsh
run: |
git init r2src
git -C r2src remote add origin https://github.com/radareorg/radare2
git -C r2src fetch --depth 1 origin $env:R2_REF
git -C r2src checkout --detach FETCH_HEAD
# Use the conforming preprocessor and r2's portable tokenizer for APFS.
meson setup r2build r2src "--prefix=$PWD/r2" --libdir=lib --buildtype=release --default-library=static -Dcli=disabled -Denable_tests=false -Db_vscrt=mt -Dc_std=c11 "-Dc_args=['/Zc:preprocessor', '/Dstrtok_r=r_str_tok_r']"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
ninja -C r2build install
- name: Build static r2fuse
shell: pwsh
run: |
$env:PKG_CONFIG_PATH = "$PWD/r2/lib/pkgconfig"
meson setup build --buildtype=release -Dstatic=true -Db_vscrt=mt -Dc_std=c11 -Dc_args=/Zc:preprocessor
meson setup build --buildtype=release "-Dr2_prefix=${{ steps.r2.outputs.prefix }}" -Db_vscrt=mt -Dc_std=c11 -Dc_args=/Zc:preprocessor
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
meson compile -C build
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
dumpbin /dependents build\r2fuse.exe
- name: Smoke test
shell: bash
run: |
git -c core.protectNTFS=false clone --depth 1 --filter=blob:none --no-checkout https://github.com/radareorg/radare2-testbins testbins
git -C testbins -c core.protectNTFS=false sparse-checkout set fs && git -C testbins -c core.protectNTFS=false checkout
./build/r2fuse.exe -v
./build/r2fuse.exe -L
for img in fat.img iso.img ext2.img; do
./build/r2fuse.exe -s "$(cygpath -w "$PWD/testbins/fs/$img")"
done
- name: Package
shell: pwsh
run: |
$d = "r2fuse-$env:VERSION-windows-x64"
New-Item -ItemType Directory $d | Out-Null
Copy-Item build\r2fuse.exe, README.md, LICENSE, FSTODO.md $d
foreach ($lib in 'r_fs', 'r_io', 'r_util', 'r_cons', 'r_socket', 'r_muta') {
Copy-Item "${{ steps.r2.outputs.prefix }}/bin/$lib.dll" $d
}
# Only the packaged DLLs should supply radare2 at runtime.
$env:PATH = "$env:SystemRoot/System32;$env:SystemRoot"
& "$PWD/$d/r2fuse.exe" -v
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
& "$PWD/$d/r2fuse.exe" -L
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Compress-Archive -Path $d -DestinationPath "$d.zip"
- uses: actions/upload-artifact@v4
with:
+9 -2
View File
@@ -21,8 +21,15 @@ ifeq ($(STATIC),1)
libdir_of=$(firstword $(shell $(PKG_CONFIG) --variable=libdir $(1)))
static_libs=$(foreach l,$(patsubst -l%,%,$(filter -l%,$(shell $(PKG_CONFIG) --static --libs $(1)))),\
$(if $(wildcard $(call libdir_of,$(1))/lib$(l).a),$(call libdir_of,$(1))/lib$(l).a,-l$(l)))
LDFLAGS+=$(call static_libs,r_fs r_io) $(call static_libs,$(FUSE_PC))
LDFLAGS+=$(filter-out -l%,$(shell $(PKG_CONFIG) --static --libs r_fs r_io $(FUSE_PC)))
# Release SDKs contain shared r2 libraries, while libfuse can still be static.
ifeq ($(R2_SHARED),1)
LDFLAGS+=$(shell $(PKG_CONFIG) --libs r_fs r_io)
else
LDFLAGS+=$(call static_libs,r_fs r_io)
LDFLAGS+=$(filter-out -l%,$(shell $(PKG_CONFIG) --static --libs r_fs r_io))
endif
LDFLAGS+=$(call static_libs,$(FUSE_PC))
LDFLAGS+=$(filter-out -l%,$(shell $(PKG_CONFIG) --static --libs $(FUSE_PC)))
ifneq ($(shell uname),Darwin)
LDFLAGS+=-static
endif
+6 -4
View File
@@ -27,8 +27,10 @@ are tracked in [FSTODO.md](FSTODO.md).
The [releases](https://github.com/radareorg/r2fuse/releases) page has one
self-contained binary per platform: Linux x86_64/arm64 (static musl), macOS
arm64 (for Fusetta) and Windows x64. radare2 and libfuse are linked
statically, so radare2 does not need to be installed. You only need the OS
arm64 (for Fusetta) and Windows x64. Linux links radare2 and libfuse statically;
macOS and Windows bundle the libraries from the latest radare2 release.
Keep the archive's binary and libraries together; radare2 does not need to
be installed. You only need the OS
FUSE provider: `/dev/fuse` on Linux, Fusetta on macOS, WinFsp on Windows.
To build the same thing locally (radare2 and libfuse are compiled from source
@@ -188,5 +190,5 @@ files. See [FSTODO.md](FSTODO.md) for the list of `r_fs` features needed to do b
## License
GPL-3.0-only, see [LICENSE](LICENSE). The release binaries statically link
radare2 including its GPL-licensed grub filesystem plugins.
GPL-3.0-only, see [LICENSE](LICENSE). The release archives include radare2
and its GPL-licensed grub filesystem plugins.
+53
View File
@@ -0,0 +1,53 @@
#!/usr/bin/env python3
"""Bundle a macOS binary and its non-system dylibs with relative load paths."""
import pathlib
import shutil
import subprocess
import sys
def run(*args):
return subprocess.check_output(args, text=True)
def dependencies(path):
return [line.strip().split(" (", 1)[0]
for line in run("otool", "-L", str(path)).splitlines()[1:]]
binary, destination, r2_libdir = map(pathlib.Path, sys.argv[1:])
destination.mkdir(parents=True)
libdir = destination / "lib"
libdir.mkdir()
binary = pathlib.Path(shutil.copy2(binary, destination / "r2fuse"))
pending = [binary]
bundled = {}
while pending:
target = pending.pop()
for dependency in dependencies(target):
if dependency.startswith(("/usr/lib/", "/System/")):
continue
name = pathlib.Path(dependency).name
if target.parent == libdir and name == target.name:
continue # LC_ID_DYLIB, rather than a dependency
if name not in bundled:
source = r2_libdir / name
if not source.is_file():
source = pathlib.Path(dependency)
if not source.is_file():
raise RuntimeError(f"Cannot bundle {dependency}")
library = libdir / name
shutil.copy2(source, library)
library.chmod(0o755)
run("install_name_tool", "-id", "@loader_path/" + name, str(library))
bundled[name] = library
pending.append(library)
relative = "@loader_path/lib/" if target == binary else "@loader_path/"
run("install_name_tool", "-change", dependency, relative + name, str(target))
for target in [*bundled.values(), binary]:
run("codesign", "--force", "--sign", "-", str(target))
for dependency in dependencies(target):
if not dependency.startswith(("/usr/lib/", "/System/", "@loader_path/")):
raise RuntimeError(f"Nonportable dependency in {target}: {dependency}")
+7 -3
View File
@@ -5,6 +5,7 @@
# dist/static.sh # clone radare2 master
# R2_SRC=../radare2 dist/static.sh
# R2_REF=6.2.4 dist/static.sh
# R2_PREFIX=/usr/local dist/static.sh # use installed r2 release libraries
#
# Linux: run it inside alpine (musl) to get a fully static binary.
# macOS: libfuse is patched with the Fusetta (FSKit) mount backend.
@@ -14,6 +15,7 @@ ROOT=$(cd "$(dirname "$0")/.." && pwd)
WORK=${WORK:-$ROOT/build-static}
R2_REF=${R2_REF:-master}
R2_SRC=${R2_SRC:-}
R2_PREFIX=${R2_PREFIX:-$WORK/r2}
FUSE_VERSION=3.18.3
FUSE_SHA256=bcd19582c5e30f7fe45dd86a5540e998590aa01903afc7ebcbeea6c8ac5421ee
FUSETTA_REF=${FUSETTA_REF:-main}
@@ -80,8 +82,10 @@ build_fuse() {
build_r2fuse() {
make -C "$ROOT" clean > /dev/null
PKG_CONFIG_PATH="$WORK/fuse/lib/pkgconfig:$WORK/r2/lib/pkgconfig" \
make -C "$ROOT" STATIC=1 FUSETTA_PC=
r2_shared=0
[ "$R2_PREFIX" = "$WORK/r2" ] || r2_shared=1
PKG_CONFIG_PATH="$WORK/fuse/lib/pkgconfig:$R2_PREFIX/lib/pkgconfig" \
make -C "$ROOT" STATIC=1 R2_SHARED="$r2_shared" FUSETTA_PC=
strip "$ROOT/r2fuse" 2> /dev/null || true
echo "Built $ROOT/r2fuse"
case "$OS" in
@@ -90,6 +94,6 @@ build_r2fuse() {
esac
}
build_r2
[ "$R2_PREFIX" != "$WORK/r2" ] || build_r2
build_fuse
build_r2fuse