Author SHA1 Message Date
pancake 3bc4d0a611 Fix plugin installs and name release assets for r2pm 2026-10-03 08:53:05 +02:00
6 changed files with 61 additions and 94 deletions

No files matched your search

+26 -76
View File
@@ -1,87 +1,40 @@
#!/usr/bin/env bash
# Stage r2xsql release trees from a completed build:
# dist/plugin/ — extract ON TOP OF a radare2 install prefix (libr drop-in):
# <r2-plugin-dir>/core_r2xsql.* (r2's own plugin search dir)
#
# The plugin's relative path is derived from the installed prefix layout so the
# plugin drops the plugin exactly where this r2 looks for it — Linux uses
# <libdir>/radare2/<ver>/, Windows uses lib/plugins.
# Stage the same plugins/ layout on every platform for r2pm -bi.
set -euo pipefail
PFX="${GITHUB_WORKSPACE}/r2prefix"
# On Windows runners GITHUB_WORKSPACE is a backslash path (D:\a\r2xsql\r2xsql),
# which find/grep/test choke on under Git-Bash. Normalize to a Unix-style path
# (cygpath exists only in Git-Bash; a no-op elsewhere).
if command -v cygpath >/dev/null 2>&1; then
PFX="$(cygpath -u "${GITHUB_WORKSPACE}")/r2prefix"
fi
# radare2's system plugin dir, RELATIVE to the prefix, derived from the installed
# layout (we do NOT run radare2 — `radare2 -H` drops into r2pipe mode under CI
# pipes). The default meson build links the core plugins statically, so the
# plugin dir often does NOT exist on disk after install (the plugin creates it):
# * Windows (meson): <prefix>/lib/plugins — and there is no
# */radare2/<version> dir at all, so the scan below finds nothing.
# * Unix (meson): <prefix>/<libdir>/radare2/<version> (libdir = lib, lib64,
# or lib/<triplet>), reconstructed from the data-dir <version> and where
# libr_core landed.
# `|| true` keeps an empty find from tripping pipefail+errexit (which would kill
# the script before it prints anything — exactly the Windows symptom).
REL_PLUGIN=""
if [ -d "${PFX}/lib/plugins" ]; then
REL_PLUGIN="lib/plugins"
else
VER_DIR="$(find "${PFX}" -type d -path '*/radare2/*' 2>/dev/null \
| grep -E '/radare2/[0-9][^/]*$' | head -1 || true)"
if [ -n "${VER_DIR}" ]; then
R2_VER="$(basename "${VER_DIR}")"
# Match the import/shared lib (libr_core.* on Unix, r_core.lib on Windows),
# never the header r_core.h.
CORE_LIB="$(find "${PFX}" -maxdepth 4 \
\( -name 'libr_core.*' -o -name 'r_core.lib' -o -name 'r_core.dll.a' \) \
2>/dev/null | head -1 || true)"
if [ -n "${CORE_LIB}" ]; then
REL_LIBDIR="$(dirname "${CORE_LIB}")"
REL_LIBDIR="${REL_LIBDIR#"${PFX}/"}"
REL_PLUGIN="${REL_LIBDIR}/radare2/${R2_VER}"
fi
fi
fi
# Fallback (Windows static-plugin builds expose no versioned dir): radare2 looks
# for system plugins in <prefix>/lib/plugins.
if [ -z "${REL_PLUGIN}" ]; then
REL_PLUGIN="lib/plugins"
fi
echo "radare2 core plugin dir: ${REL_PLUGIN}"
# Helper: copy the first path that exists.
copy_first() {
local dest="$1"; shift
local src
for src in "$@"; do
if [ -f "$src" ]; then cp "$src" "$dest"; return 0; fi
done
echo "ERROR: none of these exist: $*" >&2
return 1
}
# The pinned radare2 predates r2pm -H R2PM_TRIPLET.
case "${RUNNER_OS}-${RUNNER_ARCH}" in
Linux-X64) R2PM_TRIPLET=linux-x86-64; ext=so ;;
Windows-X64) R2PM_TRIPLET=windows-x86-64; ext=dll ;;
macOS-X64) R2PM_TRIPLET=darwin-x86-64; ext=dylib ;;
macOS-ARM64) R2PM_TRIPLET=darwin-arm-64; ext=dylib ;;
*) echo "Unsupported runner: ${RUNNER_OS}-${RUNNER_ARCH}" >&2; exit 1 ;;
esac
rm -rf dist
mkdir -p "dist/plugin/${REL_PLUGIN}"
mkdir -p dist/plugin/plugins
cp "build/bin/core_r2xsql.${ext}" dist/plugin/plugins/
cp LICENSE dist/plugin/
copy_first "dist/plugin/${REL_PLUGIN}/" \
build/bin/core_r2xsql.so build/bin/core_r2xsql.dylib build/bin/core_r2xsql.dll \
build/bin/Release/core_r2xsql.dll build/src/plugin/core_r2xsql.so \
build/src/plugin/Release/core_r2xsql.dll
# Check automatic discovery of the packaged plugin, including its suffix.
result=$(R2_LIBR_PLUGINS="$PWD/dist/plugin/plugins" \
LD_LIBRARY_PATH="$PWD/r2prefix/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" \
DYLD_LIBRARY_PATH="$PWD/r2prefix/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" \
./r2prefix/bin/radare2 -Nq -c 'sqlj SELECT 1 AS ok' -)
[[ "$result" == *'"rows":[["1"]]'* ]] || { echo "$result" >&2; exit 1; }
cat > dist/plugin/README.txt <<EOF
r2xsql — radare2 core plugin
Extract this archive ON TOP OF your matching radare2 install prefix (the
directory that contains bin/radare2[.exe]). It adds:
Built against radare2 ${R2_REF} for ${R2PM_TRIPLET}.
Install with a matching radare2 version and a recent r2pm:
${REL_PLUGIN}/core_r2xsql.* in-r2 plugin
r2pm -U
r2pm -bi r2xsql
Confirm the plugin loaded with Lcj inside radare2.
Or copy plugins/core_r2xsql.${ext} into the directory printed by
radare2 -NN -H R2_USER_PLUGINS (per-user) or R2_LIBR_PLUGINS (system-wide).
Remove that file to uninstall. Rebuild for a different radare2 ABI.
At the radare2 prompt:
aaa
@@ -100,10 +53,7 @@ The plugin also works through radare2's own HTTP server:
Read the command output for errors even when HTTP returns status 200.
Save analysis with Ps NAME before exiting; binary byte writes require -w.
Built against radare2 ${R2_REF}. Rebuild for a different radare2 ABI.
EOF
echo "=== staged tree ==="
printf 'name=r2xsql-%s-%s\n' "$R2_REF" "$R2PM_TRIPLET" >> "$GITHUB_OUTPUT"
find dist -type f | sort
+9 -12
View File
@@ -16,10 +16,7 @@ concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
# radare2 is not a submodule of r2xsql; CI builds it from source to an install
# prefix and points r2xsql at it with -DRadare2_ROOT. R2XSQL_BUILD_FULL=ON
# builds the libr backend and in-r2 plugin. The plugin artifact installs the
# plugin under r2's own plugin dir, on top of a matching radare2 install prefix.
# Build against this radare2 release without changing its version for r2pm.
env:
R2_REF: "6.2.2"
@@ -67,13 +64,14 @@ jobs:
make -C tests R2XSQL_PLUGIN="$GITHUB_WORKSPACE/build/bin/core_r2xsql.so"
- name: Stage artifacts
id: stage
shell: bash
run: bash .github/scripts/stage_artifacts.sh
- name: Upload plugin artifact
uses: actions/upload-artifact@v4
with:
name: r2xsql-linux-plugin
name: ${{ steps.stage.outputs.name }}
path: dist/plugin/
if-no-files-found: error
@@ -130,13 +128,14 @@ jobs:
cmake --build build --config Release
- name: Stage artifacts
id: stage
shell: bash
run: bash .github/scripts/stage_artifacts.sh
- name: Upload plugin artifact
uses: actions/upload-artifact@v4
with:
name: r2xsql-windows-plugin
name: ${{ steps.stage.outputs.name }}
path: dist/plugin/
if-no-files-found: error
@@ -173,19 +172,19 @@ jobs:
cmake --build build --config Release
- name: Stage artifacts
id: stage
shell: bash
run: bash .github/scripts/stage_artifacts.sh
- name: Upload plugin artifact
uses: actions/upload-artifact@v4
with:
name: r2xsql-macos-plugin
name: ${{ steps.stage.outputs.name }}
path: dist/plugin/
if-no-files-found: error
# ============================================================================
# Release — zip each artifact tree (zip root = the deployable layout) and
# attach. Plugin zips extract on top of a radare2 install prefix.
# Release — zip each artifact with plugins/ at the archive root.
# ============================================================================
publish-release:
name: Publish Release
@@ -213,7 +212,5 @@ jobs:
uses: softprops/action-gh-release@v2
with:
files: |
r2xsql-linux-plugin.zip
r2xsql-windows-plugin.zip
r2xsql-macos-plugin.zip
r2xsql-*.zip
generate_release_notes: true
+6 -3
View File
@@ -23,9 +23,9 @@
# with `make R2=radare2` if only the long name is on PATH.
R2?=r2
R2R?=r2r
R2_LIBEXT=$(shell $(R2) -H R2_LIBEXT)
R2_USER_PLUGINS=$(shell $(R2) -H R2_USER_PLUGINS)
R2_LIBR_PLUGINS=$(shell $(R2) -H R2_LIBR_PLUGINS)
R2_LIBEXT=$(shell $(R2) -NN -H R2_LIBEXT)
R2_USER_PLUGINS=$(shell $(R2) -NN -H R2_USER_PLUGINS)
R2_LIBR_PLUGINS=$(shell $(R2) -NN -H R2_LIBR_PLUGINS)
CXX?=g++
CC?=gcc
@@ -84,8 +84,11 @@ OBJS=$(SQLITE_OBJ) $(XSQL_OBJS) $(R2XSQL_OBJS) $(PLUGIN_OBJ)
all: $(PLUGIN)
# Removing files must not fetch or rebuild dependencies via included makefiles.
ifneq ($(filter-out clean mrproper uninstall user-uninstall,$(or $(MAKECMDGOALS),all)),)
-include $(BUILD)/libxsql.mk
-include $(OBJS:.o=.d)
endif
.DELETE_ON_ERROR:
+14 -1
View File
@@ -139,11 +139,17 @@ CMake, matching how radare2 plugins are usually built (plugin paths from
make # -> build-make/core_r2xsql.$(r2 -H R2_LIBEXT)
make user-install # install into the per-user plugin dir (no root)
make install # install system-wide (R2_LIBR_PLUGINS)
make user-uninstall # remove the per-user plugin without building
make uninstall # remove the system-wide plugin without building
make test # load it in r2 and run one SQL query
# only `radare2` (not `r2`) on PATH? -> make R2=radare2
```
or with meson (what radare2 itself uses):
`make install` and `make uninstall` accept `PLUGDIR` and `DESTDIR` for a
custom plugin directory or staged install. User targets use `R2_USER_PLUGINS`;
override it on the make command line when needed.
Or with meson (what radare2 itself uses):
```bash
meson setup build-meson
@@ -157,6 +163,13 @@ consume [`libxsql`](https://github.com/0xeb/libxsql): the Makefile uses a
sibling `../libxsql` checkout (else clones it), and meson pulls it as a
subproject. A current libxsql is required (same as CMake's `FetchContent`).
Release assets are named `r2xsql-<radare2-version>-<R2PM_TRIPLET>.zip`, for
example `r2xsql-6.2.2-linux-x86-64.zip`. Each contains the plugin in `plugins/`.
With a recent r2pm supporting binary installs, use `r2pm -U` followed by
`r2pm -bi r2xsql`; uninstall with `r2pm -u r2xsql`. Only matching radare2
versions and targets are installed. To install manually, copy the plugin to
the directory printed by `radare2 -NN -H R2_USER_PLUGINS`.
### JSON results
Use `sqlj` for programmatic queries and scripts:
+3 -2
View File
@@ -27,9 +27,9 @@ project('r2xsql', ['c', 'cpp'],
# --- radare2 plugin dir, straight from r2 itself ------------------------------
r2 = find_program('radare2', 'r2', required: true)
if get_option('r2_user_plugins')
res = run_command(r2, '-HR2_USER_PLUGINS', capture: true, check: false)
res = run_command(r2, '-NN', '-HR2_USER_PLUGINS', capture: true, check: false)
else
res = run_command(r2, '-HR2_LIBR_PLUGINS', capture: true, check: false)
res = run_command(r2, '-NN', '-HR2_LIBR_PLUGINS', capture: true, check: false)
endif
if res.returncode() == 0 and res.stdout().strip() != ''
r2_plugdir = res.stdout().strip()
@@ -106,6 +106,7 @@ r2xsql_inc = include_directories('src/lib/include', 'src/lib/src', 'src')
shared_module('core_r2xsql',
[r2xsql_srcs, plugin_src],
name_prefix: '',
name_suffix: host_machine.system() == 'darwin' ? 'dylib' : [],
cpp_args: ['-DR2XSQL_HAVE_LIBR=1'],
include_directories: r2xsql_inc,
dependencies: [xsql_dep, r_core, threads],
+3
View File
@@ -19,6 +19,9 @@ set_target_properties(core_r2xsql PROPERTIES
OUTPUT_NAME "core_r2xsql"
PREFIX ""
)
if(APPLE)
set_target_properties(core_r2xsql PROPERTIES SUFFIX ".dylib")
endif()
target_include_directories(core_r2xsql PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../lib/include