[cmake] Update CPMUtil (#4123)

Notable changes

- Single cpmfile
- version/min_version/git_version have been fixed and replaced with
  version and min_version
- Docs rewrite
- Legacy options are gone
- Fixed update/version commands
- Added patch creation functionality

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4123
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
This commit is contained in:
crueter 2026-06-26 02:22:04 +02:00
parent 6bdb03d8ac
commit c993bc01a4
No known key found for this signature in database
GPG key ID: 425ACD2D4830EBC6
35 changed files with 1500 additions and 1294 deletions

134
tools/cpm/package/util/fetch.sh Executable file
View file

@ -0,0 +1,134 @@
#!/bin/sh -e
# SPDX-FileCopyrightText: Copyright 2026 crueter
# SPDX-License-Identifier: LGPL-3.0-or-later
# shellcheck disable=SC1091
. "$SCRIPTS"/../common.sh
download_package() {
mkdir -p "$CPM_SOURCE_CACHE"
tmp=$(make_temp_dir)
FILENAME=$(basename "$DOWNLOAD")
OUTFILE="$tmp/$FILENAME"
OUTDIR="${CPM_SOURCE_CACHE}/${LOWER_PACKAGE}/${KEY}"
if [ -d "$OUTDIR" ]; then return; fi
curl "$DOWNLOAD" -sS -L -o "$OUTFILE"
ACTUAL_HASH=$(sha512sum "$OUTFILE" | cut -d" " -f1)
if [ "$ACTUAL_HASH" != "$HASH" ]; then
echo "!! $FILENAME did not match expected hash; expected $HASH but got $ACTUAL_HASH" >&2
exit 1
fi
TMPDIR="$tmp/extracted"
mkdir -p "$OUTDIR"
mkdir -p "$TMPDIR"
PREVDIR="$PWD"
mkdir -p "$TMPDIR"
cd "$TMPDIR"
case "$FILENAME" in
*.7z)
must_install 7z
7z x "$OUTFILE" >/dev/null
;;
*.tar*)
# TODO: Extensions
must_install tar
tar xf "$OUTFILE" >/dev/null
;;
*.zip)
must_install unzip
unzip "$OUTFILE" >/dev/null
;;
esac
# basically if only one real item exists at the top we just move everything from there
# since github and some vendors hate me
DIRS=$(find . -maxdepth 1 -type d -o -type f)
# thanks gnu
if [ "$(echo "$DIRS" | wc -l)" -eq 2 ]; then
SUBDIR=$(find . -maxdepth 1 -type d -not -name ".")
mv "$SUBDIR"/* "$OUTDIR"
mv "$SUBDIR"/.* "$OUTDIR" 2>/dev/null || true
rmdir "$SUBDIR"
else
mv ./* "$OUTDIR"
mv ./.* "$OUTDIR" 2>/dev/null || true
fi
cd "$OUTDIR"
# TODO: Common custom patch/source cache dirs
if echo "$JSON" | grep -e "patches" >/dev/null; then
PATCHES=$(echo "$JSON" | jq -r '.patches | join(" ")')
for patch in $PATCHES; do
abs_patch="$CPMUTIL_PATCH_DIR/$PACKAGE/$patch"
if [ ! -f "$abs_patch" ]; then
echo "-- * Attempted to apply nonexistent patch $patch!"
continue
fi
echo "-- * Applying patch $patch"
patch --binary -p1 <"$abs_patch"
done
fi
cd "$PREVDIR"
rm -rf "$tmp"
}
# TODO: individual platform fetch?
ci_package() {
[ "$REPO" != null ] || { echo "-- ! No repo defined" && return; }
mkdir -p "$CPM_SOURCE_CACHE"
echo "-- CI package $PACKAGE_NAME"
for platform in \
windows-amd64 windows-arm64 \
mingw-amd64 mingw-arm64 \
android-aarch64 android-x86_64 \
linux-amd64 linux-aarch64 \
macos-universal ios-aarch64; do
echo "-- * platform $platform"
case $DISABLED in
*"$platform"*)
echo "-- * -- disabled"
continue
;;
esac
FILENAME="${NAME}-${platform}-${VERSION}.${EXT}"
DOWNLOAD="https://$GIT_HOST/${REPO}/releases/download/v${VERSION}/${FILENAME}"
KEY="$platform-$VERSION"
OUTDIR="${CPM_SOURCE_CACHE}/${LOWER_PACKAGE}/${KEY}"
[ -d "$OUTDIR" ] && continue
HASH_URL="${DOWNLOAD}.sha512sum"
HASH=$(curl "$HASH_URL" -sS -q -L -o -)
download_package
done
}
fetch_package() {
if [ "$CI" = "true" ]; then
ci_package
else
echo "-- Downloading regular package $PACKAGE, with key $KEY, from $DOWNLOAD"
download_package
fi
}

View file

@ -9,18 +9,10 @@
# re-read json files
# shellcheck disable=SC2016
PACKAGES=$(echo "$CPMFILES" | xargs jq -s 'reduce .[] as $item ({}; . * $item)')
export PACKAGES
. "$SCRIPTS"/vars.sh
[ "$CI" = null ] || exit 0
[ "$HASH_URL" = null ] || exit 0
[ "$HASH_SUFFIX" = null ] || exit 0
[ "$HASH" != null ] || { echo "-- * Package has no hash specified" && exit 0; }
ACTUAL=$("$SCRIPTS"/util/url-hash.sh "$DOWNLOAD")
if [ "$ACTUAL" != "$HASH" ] && [ "$QUIET" != true ]; then

View file

@ -86,6 +86,18 @@ optional "Additional find_package arguments, space-separated" \
FIND_ARGS="$reply"
optional "Git host (default: github.com)" \
"The hostname of the Git server, if not GitHub (e.g. codeberg.org, git.crueter.xyz)"
GIT_HOST="$reply"
required "Numeric version of the bundled package" \
"The semantic version of the bundled package. This is only used for package identification,
and if you use tag/artifact fetching. Do not input the entire tag here; for example, if you're using
tag v1.3.0, then set this to 1.3.0 and set the tag to v%VERSION%."
VERSION="$reply"
optional "Is this a CI package? [y/N]" \
"Yes if the package is a prebuilt binary distribution (e.g. crueter-ci),
no if the package is built from source if it's bundled."
@ -96,27 +108,31 @@ case "$reply" in
esac
if [ "$CI" = "false" ]; then
optional "Git host (default: github.com)" \
"The hostname of the Git server, if not GitHub (e.g. codeberg.org, git.crueter.xyz)"
while :; do
required "Use tag or commit sha versioning? [tag/sha]" \
"Tag versioning is compatible with auto-updating.
Use sha versioning for projects with improper tagging practices"
GIT_HOST="$reply"
if [ "$reply" = "tag" ]; then
TAG=1
break
elif [ "$reply" = "sha" ]; then
SHA=1
break
else
echo "-- Invalid choice $reply"
fi
done
if [ "$TAG" = "1" ]; then
required "Numeric version of the bundled package" \
"The semantic version of the bundled package. This is only used for package identification,
and if you use tag/artifact fetching. Do not input the entire tag here; for example, if you're using
tag v1.3.0, then set this to 1.3.0 and set the tag to v%VERSION%."
GIT_VERSION="$reply"
optional "Name of the upstream tag. %VERSION% is replaced by the numeric version (default: %VERSION%)" \
optional "Name of the upstream tag. %VERSION% is replaced by the numeric version ($VERSION) (default: %VERSION%)" \
"Most commonly this will be something like v%VERSION% or release-%VERSION%, or just %VERSION%."
TAGNAME="$reply"
[ -n "$TAGNAME" ] || TAGNAME="%VERSION%"
optional "Name of the release artifact to download, if applicable.
-- %VERSION% is replaced by the numeric version and %TAG% is replaced by the tag name" \
-- %VERSION% is replaced by the numeric version ($VERSION) and %TAG% is replaced by the tag name" \
"Download the specified artifact from the release with the previously specified tag.
If unspecified, the source code at the specified tag will be used instead."
@ -134,11 +150,6 @@ should be set in CMake with AddJsonPackage's OPTIONS parameter."
OPTIONS="$reply"
else
required "Version of the CI package (e.g. 3.6.0-9eff87adb1)" \
"CI artifacts are stored as <name>-<platform>-<version>.tar.zst. This option controls the version."
VERSION="$reply"
required "Name of the CI artifact" \
"CI artifacts are stored as <name>-<platform>-<version>.tar.zst. This option controls the name."
@ -149,7 +160,6 @@ else
windows-amd64 windows-arm64
mingw-amd64 mingw-arm64
android-aarch64 android-x86_64
solaris-amd64 freebsd-amd64 openbsd-amd64
linux-amd64 linux-aarch64
macos-universal ios-aarch64"
@ -163,11 +173,15 @@ jq_input='{repo: "'"$REPO"'"}'
[ -z "$PACKAGE" ] || jq_input="$jq_input + {package: \"$PACKAGE\"}"
[ -z "$MIN_VERSION" ] || jq_input="$jq_input + {min_version: \"$MIN_VERSION\"}"
[ -z "$FIND_ARGS" ] || jq_input="$jq_input + {find_args: \"$FIND_ARGS\"}"
jq_input="$jq_input + {version: \"$VERSION\"}"
if [ -n "$GIT_HOST" ] && [ "$GIT_HOST" != "github.com" ]; then
jq_input="$jq_input + {git_host: \"$GIT_HOST\"}"
fi
if [ "$CI" = "true" ]; then
jq_input="$jq_input + {
ci: true,
version: \"$VERSION\",
artifact: \"$ARTIFACT\"
}"
@ -186,32 +200,29 @@ else
jq_input="$jq_input + {options: $options_json}"
fi
# Git host
if [ -n "$GIT_HOST" ] && [ "$GIT_HOST" != "github.com" ]; then
jq_input="$jq_input + {git_host: \"$GIT_HOST\"}"
fi
# versioning stuff
if [ -n "$GIT_VERSION" ]; then
jq_input="$jq_input + {git_version: \"$GIT_VERSION\"}"
[ -z "$TAGNAME" ] || jq_input="$jq_input + {tag: \"$TAGNAME\"}"
if [ "$TAG" = 1 ]; then
jq_input="$jq_input + {tag: \"$TAGNAME\"}"
[ -z "$ARTIFACT" ] || jq_input="$jq_input + {artifact: \"$ARTIFACT\"}"
else
jq_input="$jq_input + {sha: \"$SHA\"}"
fi
fi
new_json=$(jq -n "$jq_input")
JSON=$(jq -n "$jq_input")
jq --arg key "$PKG" --argjson new "$new_json" \
'.[$key] = $new' "$CPMFILE" --indent 4 >"${CPMFILE}.tmp" &&
mv "${CPMFILE}.tmp" "$CPMFILE"
# shellcheck disable=SC1091
. "$SCRIPTS"/vars.sh
# now correct the hash
if [ "$CI" != true ]; then
# shellcheck disable=SC1091
. "$ROOTDIR"/common.sh
QUIET=true UPDATE=true "$SCRIPTS"/util/fix-hash.sh "$PKG"
HASH=$("$SCRIPTS"/util/url-hash.sh "$DOWNLOAD")
JSON=$(echo "$JSON" | jq ".hash = \"$HASH\"")
fi
echo "Added package $PKG to $CPMFILE. Include it in your project with AddJsonPackage($PKG)"
jq --arg key "$PKG" --argjson new "$JSON" \
'.[$key] = $new' "cpmfile.json" --indent 4 >"cpmfile.json.tmp" &&
mv "cpmfile.json.tmp" cpmfile.json
"$SCRIPTS"/format.sh
echo "Added package $PKG to cpmfile.json. Include it in your project with AddJsonPackage($PKG)"

View file

@ -1,13 +1,11 @@
#!/bin/sh -e
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-FileCopyrightText: Copyright 2026 crueter
# SPDX-License-Identifier: LGPL-3.0-or-later
# Replace a specified package with a modified json.
FILE=$(echo "$CPMFILES" | xargs grep -l "\"$1\"")
jq --indent 4 --argjson repl "$2" ".\"$1\" *= \$repl" cpmfile.json >cpmfile.json.new
mv cpmfile.json.new cpmfile.json
jq --indent 4 --argjson repl "$2" ".\"$1\" *= \$repl" "$FILE" >"$FILE".new
mv "$FILE".new "$FILE"
echo "-- * -- Updated $FILE"
echo "-- * -- Updated cpmfile.json"

27
tools/cpm/package/util/url.sh Executable file
View file

@ -0,0 +1,27 @@
#!/bin/sh -e
# SPDX-FileCopyrightText: Copyright 2026 crueter
# SPDX-License-Identifier: LGPL-3.0-or-later
# Get the download URL for a package
if [ "$URL" != "null" ]; then
DOWNLOAD="$URL"
elif [ "$REPO" != "null" ]; then
GIT_URL="https://$GIT_HOST/$REPO"
if [ "$SHA" != "null" ]; then
DOWNLOAD="${GIT_URL}/archive/${SHA}.tar.gz"
elif [ "$TAG" != "null" ]; then
if [ "$ARTIFACT" != "null" ]; then
DOWNLOAD="${GIT_URL}/releases/download/${TAG}/${ARTIFACT}"
else
DOWNLOAD="${GIT_URL}/archive/refs/tags/${TAG}.tar.gz"
fi
fi
else
echo "!! No repo or URL defined for $PACKAGE_NAME"
exit 1
fi
export DOWNLOAD