forked from openRuyi/rust-rpm-macros
Compare commits
4 Commits
make
...
edaaeb4577
| Author | SHA1 | Date | |
|---|---|---|---|
| edaaeb4577 | |||
| bc3ac38e4c | |||
| f88de4d952 | |||
| 4bf867d933 |
2
Makefile
2
Makefile
@@ -5,5 +5,7 @@ RPMSCRIPTDIR ?= $(PREFIX)/lib/rpm/rust-rpm-macros
|
||||
.PHONY: install
|
||||
install:
|
||||
install -D -m644 macros.buildsystem.rustcrates $(DESTDIR)$(RPMMACRODIR)/macros.buildsystem.rustcrates
|
||||
install -D -m644 macros.buildsystem.rust $(DESTDIR)$(RPMMACRODIR)/macros.buildsystem.rust
|
||||
install -D -m644 macros.rust $(DESTDIR)$(RPMMACRODIR)/macros.rust
|
||||
install -D -m755 rustcrates-gen-feature-specparts.sh $(DESTDIR)$(RPMSCRIPTDIR)/rustcrates-gen-feature-specparts.sh
|
||||
install -D -m755 cargo_buildrequires.sh $(DESTDIR)$(RPMSCRIPTDIR)/cargo_buildrequires.sh
|
||||
|
||||
178
cargo_buildrequires.sh
Normal file
178
cargo_buildrequires.sh
Normal file
@@ -0,0 +1,178 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Generate BuildRequires for Rust projects from Cargo.lock.
|
||||
# This shell implementation avoids Python dependencies in rpmbuild.
|
||||
|
||||
set -u
|
||||
|
||||
print_err() {
|
||||
printf '%s\n' "$*" >&2
|
||||
}
|
||||
|
||||
clean_version() {
|
||||
case "$1" in
|
||||
*+*) printf '%s\n' "${1%%+*}" ;;
|
||||
*) printf '%s\n' "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
usage() {
|
||||
print_err "Usage: cargo_buildrequires.sh --output <file> [--registry <path>]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
REGISTRY_PATH="/usr/share/cargo/registry"
|
||||
OUTPUT_FILE=""
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
-d|--dev)
|
||||
shift
|
||||
;;
|
||||
-b|--build)
|
||||
shift
|
||||
;;
|
||||
--registry)
|
||||
[ "$#" -ge 2 ] || usage
|
||||
REGISTRY_PATH="$2"
|
||||
shift 2
|
||||
;;
|
||||
--output)
|
||||
[ "$#" -ge 2 ] || usage
|
||||
OUTPUT_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ -n "$OUTPUT_FILE" ] || usage
|
||||
|
||||
if [ ! -f Cargo.lock ]; then
|
||||
print_err "Error: Cargo.lock not found"
|
||||
print_err "Hint: Run 'cargo generate-lockfile' or 'cargo update' to generate it"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
output_dir=$(dirname "$OUTPUT_FILE")
|
||||
mkdir -p "$output_dir"
|
||||
|
||||
tmp_output=$(mktemp)
|
||||
tmp_packages=$(mktemp)
|
||||
trap 'rm -f "$tmp_output" "$tmp_packages"' EXIT INT TERM
|
||||
|
||||
printf 'rust\n' > "$tmp_output"
|
||||
|
||||
awk '
|
||||
function flush_pkg() {
|
||||
if (in_pkg && name != "" && version != "") {
|
||||
printf "%s\t%s\t%s\n", name, version, source
|
||||
}
|
||||
}
|
||||
BEGIN {
|
||||
in_pkg = 0
|
||||
name = ""
|
||||
version = ""
|
||||
source = ""
|
||||
}
|
||||
/^\[\[package\]\]/ {
|
||||
flush_pkg()
|
||||
in_pkg = 1
|
||||
name = ""
|
||||
version = ""
|
||||
source = ""
|
||||
next
|
||||
}
|
||||
in_pkg && /^name[[:space:]]*=/ {
|
||||
line = $0
|
||||
sub(/^[^=]*=[[:space:]]*"/, "", line)
|
||||
sub(/"[[:space:]]*$/, "", line)
|
||||
name = line
|
||||
next
|
||||
}
|
||||
in_pkg && /^version[[:space:]]*=/ {
|
||||
line = $0
|
||||
sub(/^[^=]*=[[:space:]]*"/, "", line)
|
||||
sub(/"[[:space:]]*$/, "", line)
|
||||
version = line
|
||||
next
|
||||
}
|
||||
in_pkg && /^source[[:space:]]*=/ {
|
||||
line = $0
|
||||
sub(/^[^=]*=[[:space:]]*"/, "", line)
|
||||
sub(/"[[:space:]]*$/, "", line)
|
||||
source = line
|
||||
next
|
||||
}
|
||||
END {
|
||||
flush_pkg()
|
||||
}
|
||||
' Cargo.lock > "$tmp_packages"
|
||||
|
||||
dep_count=0
|
||||
missing_requirements=0
|
||||
|
||||
while IFS="$(printf '\t')" read -r crate_name crate_version source; do
|
||||
[ -n "$crate_name" ] || continue
|
||||
[ -n "$crate_version" ] || continue
|
||||
|
||||
if [ -z "$source" ]; then
|
||||
print_err "Skipping current project: $crate_name $crate_version"
|
||||
continue
|
||||
fi
|
||||
|
||||
case "$source" in
|
||||
file://*)
|
||||
print_err "Skipping local dependency: $crate_name $crate_version ($source)"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
dep_count=$((dep_count + 1))
|
||||
|
||||
is_installed=0
|
||||
if [ -d "$REGISTRY_PATH" ]; then
|
||||
for d in "$REGISTRY_PATH/$crate_name"-*; do
|
||||
[ -d "$d" ] || continue
|
||||
dir_name=${d##*/}
|
||||
remainder=${dir_name#"$crate_name"-}
|
||||
case "$remainder" in
|
||||
[0-9]*)
|
||||
is_installed=1
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
normalized_name=$(printf '%s' "$crate_name" | tr '_' '-')
|
||||
clean_ver=$(clean_version "$crate_version")
|
||||
dep_full="crate($normalized_name) >= $clean_ver"
|
||||
|
||||
if [ "$is_installed" -eq 1 ]; then
|
||||
print_err "[OK] Requirement satisfied: $crate_name-$crate_version (installed)"
|
||||
else
|
||||
print_err "[MISSING] Requirement not satisfied: $crate_name-$crate_version"
|
||||
missing_requirements=1
|
||||
fi
|
||||
|
||||
printf '%s\n' "$dep_full" >> "$tmp_output"
|
||||
done < "$tmp_packages"
|
||||
|
||||
print_err ""
|
||||
print_err "Found $dep_count dependencies in Cargo.lock"
|
||||
|
||||
mv "$tmp_output" "$OUTPUT_FILE"
|
||||
print_err "Generated BuildRequires written to: $OUTPUT_FILE"
|
||||
|
||||
if [ "$missing_requirements" -eq 1 ]; then
|
||||
print_err ""
|
||||
print_err "Missing dependencies detected - triggering OBS bootstrap cycle"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
print_err ""
|
||||
print_err "All dependencies satisfied"
|
||||
exit 0
|
||||
20
macros.buildsystem.rust
Normal file
20
macros.buildsystem.rust
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
# Example buildsystem for rust crates
|
||||
%buildsystem_rust_prep() %{expand:\
|
||||
%autosetup -C -p1 %* \
|
||||
mkdir -p ~/.cargo \
|
||||
cat > ~/.cargo/config.toml <<EOF\
|
||||
[source.crates-io]\
|
||||
replace-with = "system-registry"\
|
||||
\
|
||||
[source.system-registry]\
|
||||
directory = "/usr/share/cargo/registry"\
|
||||
EOF\
|
||||
}
|
||||
%buildsystem_rust_conf() %nil
|
||||
%buildsystem_rust_build() %{expand:\
|
||||
rm -rf Cargo.lock \
|
||||
cargo build --release \
|
||||
}
|
||||
%buildsystem_rust_install() %nil
|
||||
%buildsystem_rust_check() %nil
|
||||
33
macros.rust
33
macros.rust
@@ -2,9 +2,40 @@
|
||||
# Rust macros
|
||||
#
|
||||
|
||||
# Install a crate to system cargo registry
|
||||
%rust_install_crate \
|
||||
%__install -d %{buildroot}%{_datadir}/cargo/registry/%{crate_name}-%{version} \
|
||||
%__cp -a . %{buildroot}%{_datadir}/cargo/registry/%{crate_name}-%{version}/ \
|
||||
%__rm -f %{buildroot}%{_datadir}/cargo/registry/%{crate_name}-%{version}/*checksum.json \
|
||||
echo '{"files":{},"package":null}' > %{buildroot}%{_datadir}/cargo/registry/%{crate_name}-%{version}/.cargo-checksum.json \
|
||||
%{nil}
|
||||
%{nil}
|
||||
|
||||
# Directory for storing generated buildrequires
|
||||
%_cargo_buildrequires %{_builddir}/%{name}-%{version}-%{release}.%{_arch}-cargo-buildrequires
|
||||
|
||||
# Dynamic BuildRequires generation from Cargo.lock
|
||||
# Usage in spec file:
|
||||
# %generate_buildrequires
|
||||
# %cargo_buildrequires
|
||||
#
|
||||
# This automatically parses Cargo.lock and generates all BuildRequires
|
||||
%cargo_buildrequires() %{expand:\
|
||||
echo 'rust-rpm-macros'
|
||||
echo 'rust'
|
||||
|
||||
# Check if Cargo.lock exists
|
||||
if [ ! -f Cargo.lock ]; then
|
||||
echo 'ERROR: Cargo.lock not found. This is not a valid Cargo project.' >&2
|
||||
echo 'Hint: Run "cargo generate-lockfile" or "cargo update" to generate it.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate buildrequires using Python script
|
||||
mkdir -p "%{_cargo_buildrequires}"
|
||||
%{_rpmconfigdir}/rust-rpm-macros/cargo_buildrequires.sh --output %{_cargo_buildrequires}/buildrequires.txt >&2
|
||||
|
||||
# Output the generated buildrequires
|
||||
if [ -f %{_cargo_buildrequires}/buildrequires.txt ]; then
|
||||
cat %{_cargo_buildrequires}/buildrequires.txt
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user