Changes to bldpkg:

-> Updated version
-> Added a maintainer comment check
-> genchecksum if/else is now a function
-> Simplified check for existence of lib64,usr and sbin directories inside staging directory
-> Replaced group of commands used for scanning binaries and libraries with scanelf inside a new function findelffiles
-> Part of the command to scan for libtool archive files moved into findlibtoolfiles function
-> Part of the code for resetting SECONDS variable now placed inside showsummary if/else check
-> Discarded unnecessary if/else when appending old doinst.sh to a new one
-> Discarded code to remove lib directory twice
-> Discarded unnecessary if/else when removing lib/charset.alias
-> Removed unnecessary tmpfs=1 check in several places
-> Miscellaneous fixes
This commit is contained in:
PktSurf 2023-04-15 16:43:33 +05:30
parent 5b737f7164
commit 27ca3c74e8

175
bldpkg
View file

@ -3,7 +3,7 @@
# Part of the SMLinux distribution # Part of the SMLinux distribution
# http://git.pktsurf.in/smlinux # http://git.pktsurf.in/smlinux
# #
# /bin/bldpkg version 0.1 # /bin/bldpkg version 0.100
# Bash script to build SMLinux-specific packages # Bash script to build SMLinux-specific packages
# #
# Copyright (c) 2022-2023 PktSurf <smlinux@pktsurf.in> # Copyright (c) 2022-2023 PktSurf <smlinux@pktsurf.in>
@ -128,8 +128,12 @@ validatebldfile() {
[[ ! ${!reqvars} ]] && err "Required variable '$reqvars' is not set in $buildfile!" [[ ! ${!reqvars} ]] && err "Required variable '$reqvars' is not set in $buildfile!"
done done
# Check if 'Maintainer' comment exists
if ! grep -q "^# Maintainer" "$buildfile" ; then
err "Please provide a Maintainer name and email as a comment at the top of the build file"
# Validate $app # Validate $app
if ! echo "$app" | grep -E -q '\w[a-z0-9-]+\w'; then elif ! echo "$app" | grep -E -q '\w[a-z0-9-]+\w'; then
err "Only lower case, numeric characters and dash allowed in the 'app' variable in the build file." err "Only lower case, numeric characters and dash allowed in the 'app' variable in the build file."
# Validate $version # Validate $version
@ -323,6 +327,39 @@ runtime() {
fi fi
} }
# Generate and insert sha512sums into the build file
genchecksum() {
# File types whose checksums will go into the new build file
info "Discarding any old sha512sums from '$buildfile'"
sed -E -i \
-e '/^sha512sums=".*"$/d' \
-e '/^sha512sums="/,/"$/d' \
-e "/^sha512sums='.*'\$/d" \
"$buildfile"
info "Adding new sha512sums in '$buildfile'"
printf 'sha512sums="\n' >> "$buildfile"
files=( *.tar.* *.zip *.t?z *.patch *.diff *.c *.h )
# For loop that searches for files matching the above extension and prints them to the bottom of the build file
for file in "${files[@]}" ; do
if [[ -f $file ]] ; then
info "Adding $file"
sha512sum "$file" >> "$buildfile"
fi
done
printf '"' >> "$buildfile"
if [[ $(find . -type d -maxdepth 1 -print0 | wc -l) -ge 1 ]]; then
warn "SHA512 checksums not generated for files inside directories!"
fi
info "You may now run 'bldpkg' again"
exit 0
}
preprunitservice() { preprunitservice() {
# Usage: preprunitservice -s chrony -d -f # Usage: preprunitservice -s chrony -d -f
while getopts ':dfs:' option; do while getopts ':dfs:' option; do
@ -464,19 +501,13 @@ mkfinalpkg() {
info "Performing packaging tasks..." info "Performing packaging tasks..."
# Check if /lib64 was created inside $pkg # Check if /lib64 was created inside $pkg
if [[ -d lib64 ]] ; then [[ -d lib64 ]] && err "Multilib directory '/lib64' created inside '$pkg' not supported by musl C library."
err "'$app' has /lib64 directory within the staging directory. Musl does not support multilib.
Please fix the build options and ensure the /lib64 is not created."
fi
# Check if /usr and /sbin were created inside staging directory $pkg # Check if /usr and /sbin were created inside staging directory $pkg
# of its build file. Ignore their existence if $ignoreusr is set to 1 in the pkg build file # of its build file. Ignore their existence if $ignoreusr is set to 1 in the pkg build file
if [[ -z $ignoreusr ]] ; then if [[ -z $ignoreusr ]] ; then
for directory in usr sbin ; do for directory in usr sbin ; do
if [[ -d $directory ]] ; then [[ -d $directory ]] && err "$pkg/$directory is a symlink to '/bin'. Fix your build options and ensure such a directory is not created"
err "'$app' has '$directory' directory within the staging directory which is a symlink to /bin on SMLinux.
Please fix the build options and ensure '$directory' is not created"
fi
done done
fi fi
@ -517,12 +548,6 @@ EOF
) )
fi fi
# Remove libtool archive files
if [[ -d lib ]] ; then
info "Discarding any libtool archive (.la) files..."
find "$pkg" -type f -name "*.la" -exec rm -v {} \;
fi
# Provide a copy of the package build file as a source of reference for users # Provide a copy of the package build file as a source of reference for users
if [[ -n $origbuildfile ]] && [[ -f $srcdir/$origbuildfile ]] ; then if [[ -n $origbuildfile ]] && [[ -f $srcdir/$origbuildfile ]] ; then
install -Dm 644 "$srcdir/$origbuildfile" "$pkgdocs/$app.SMBuild" install -Dm 644 "$srcdir/$origbuildfile" "$pkgdocs/$app.SMBuild"
@ -530,32 +555,40 @@ EOF
install -Dm 644 "$srcdir/$buildfile" "$pkgdocs/$app.SMBuild" install -Dm 644 "$srcdir/$buildfile" "$pkgdocs/$app.SMBuild"
fi fi
# Now strip the binaries and shared libraries. --strip-unneeded is unnecessary for binutils 2.34+ # Remove libtool archive files
if [[ -z $debug ]] && [[ $debug != 1 ]]; then if [[ -d lib ]] && [[ "$(findlibtoolfiles | wc -l)" -ge 1 ]] ; then
find "$pkg" -type f -print0 | xargs -0 file -m /etc/file/magic/elf | \ info "Discarding libtool archive (.la) files..."
grep -E "ELF.*(executable|shared object|statically linked)" |\ findlibtoolfiles -exec rm -v {} \;
cut -d: -f1 | xargs strip 2>/dev/null || true
fi fi
# If $preservestaticlibs is not set in the package build file, delete all static libraries # If $preservestaticlibs is not set in the package build file, delete all static libraries
if [[ -z $preservestaticlibs ]] ; then if [[ -d lib ]] && [[ -z $preservestaticlibs ]] ; then
info "Discarding any static libraries..." if [[ "$(findarchivefiles | wc -l)" -ge 1 ]] ; then
find "$pkg" -type f -print0 | xargs -0 file -m /etc/file/magic/archive | \ info "Discarding static libraries..."
grep -E "current ar archive" | awk '{print $1}' | cut -d: -f1 | \ findarchivefiles | xargs rm -v
xargs rm -v 2>/dev/null || true fi
fi fi
# Now strip the binaries and libraries.
if [[ -z $debug ]] ; then
if [[ "$(findelffiles | wc -l)" -ge 1 ]] ; then
info "Stripping ELF files..."
# scanelf will, if a static archive is found, return object files inside that archive, so play safe
findelffiles | cut -d: -f1 | uniq | xargs strip --strip-unneeded
fi
fi
# Calculate total files, directories, symlinks and uncompressed staging directory size # Calculate total files, directories, symlinks and uncompressed staging directory size
if [[ $showsummary = 1 ]] ; then if [[ $showsummary = 1 ]] ; then
totalfilecount=$(find "$pkg" -type f | wc -l) totalfilecount=$(find "$pkg" -type f | wc -l)
totaldircount=$(find "$pkg" -type d | wc -l) totaldircount=$(find "$pkg" -type d | wc -l)
totalsymcount=$(find "$pkg" -type l | wc -l) totalsymcount=$(find "$pkg" -type l | wc -l)
packusize1=$(du -s "$pkg" | awk '{print $1}') packusize1=$(du -s "$pkg" | awk '{print $1}')
fi
# Here we ascertain the packaging time taken to actually prepare the final package. For this, we # Here we ascertain the packaging time taken to actually prepare the final package. For this, we
# must reset the SECONDS variable to ensure accuracy # must reset the SECONDS variable to ensure accuracy
SECONDS=0 SECONDS=0
fi
# Store package location inside this variable: # Store package location inside this variable:
newpkglocation="$pkgdest/$app-$version-$arch-$build.$pkgext" newpkglocation="$pkgdest/$app-$version-$arch-$build.$pkgext"
@ -571,21 +604,13 @@ EOF
if find . -type l | grep -qm1 .; then if find . -type l | grep -qm1 .; then
info "Found symlinks, preparing install/doinst.sh..." info "Found symlinks, preparing install/doinst.sh..."
find . -type l -printf '( cd %h ; rm -rf %f )\n( cd %h ; ln -sf %l %f )\n' -delete > install/symlinks find . -type l -printf '( cd %h ; rm -rf %f )\n( cd %h ; ln -sf %l %f )\n' -delete > install/symlinks
if [[ -f install/doinst.sh ]]; then [[ -f install/doinst.sh ]] && printf '\n' | cat - install/doinst.sh >> install/symlinks
printf '\n' | cat - install/doinst.sh >> install/symlinks
fi
mv install/symlinks install/doinst.sh mv install/symlinks install/doinst.sh
fi fi
fi fi
# Discard install directory if it's empty but don't error out
rmdir lib &> /dev/null || true
# Discard charset.alias # Discard charset.alias
if [[ -f lib/charset.alias ]] ; then [[ -f lib/charset.alias ]] && rm lib/charset.alias
info "Discarding charset.alias"
rm lib/charset.alias
fi
# Also discard the lib directory if it's empty but don't error out # Also discard the lib directory if it's empty but don't error out
rmdir lib &> /dev/null || true rmdir lib &> /dev/null || true
@ -619,13 +644,13 @@ EOF
if [[ $showsummary = 1 ]]; then if [[ $showsummary = 1 ]]; then
# Determine size of SRCDIR aka source directory # Determine size of srcdir aka source directory
srcdirsize=$(du -s "$srcdir" | awk '{print $1}') srcdirsize=$(du -s "$srcdir" | awk '{print $1}')
# Determine size of tmp aka build directory size # Determine size of tmp aka build directory size
builddirsize=$(du -s "$tmp" | awk '{print $1}') builddirsize=$(du -s "$tmp" | awk '{print $1}')
# Calculate SSD write savings if TMPFS has been used # Calculate SSD write savings if TMPFS has been used
if [[ $tmpfs = 1 ]] && [[ $tmpfsenabledforthispackage = 1 ]] ; then if [[ $tmpfsenabledforthispackage = 1 ]] ; then
# Determine size of staging directory # Determine size of staging directory
pkgdirsize=$(du -s "$pkg" | awk '{print $1}') pkgdirsize=$(du -s "$pkg" | awk '{print $1}')
@ -648,6 +673,18 @@ EOF
[[ $preservepackagedir = 0 ]] && rm -rf "$pkg" [[ $preservepackagedir = 0 ]] && rm -rf "$pkg"
} }
findarchivefiles() {
find "lib" -type f -name "*.a"
}
findlibtoolfiles() {
find "lib" -type f -name "*.la" "$@"
}
findelffiles() {
scanelf --archives --nobanner --recursive --symlink --format "%F" --etype "ET_EXEC,ET_DYN,ET_REL" .
}
buildfilecleanup() { buildfilecleanup() {
# Discard all temporary files # Discard all temporary files
rm "$parenttmp/BUILDING" rm "$parenttmp/BUILDING"
@ -702,7 +739,6 @@ prepbuildoutput() {
buildsys="Manual" buildsys="Manual"
fi fi
# Determine if distcc was used. If $distcc set to 1, set distccstats in the build summary # Determine if distcc was used. If $distcc set to 1, set distccstats in the build summary
if [[ $distcc = 1 ]] ; then if [[ $distcc = 1 ]] ; then
# If distcc was used, cut out --randomize and output rest of the DISTCC_HOSTS variable # If distcc was used, cut out --randomize and output rest of the DISTCC_HOSTS variable
@ -716,7 +752,7 @@ prepbuildoutput() {
# Determine if ccache was used. If we are compiling inside tmpfs, we are not using ccache at all, so set # Determine if ccache was used. If we are compiling inside tmpfs, we are not using ccache at all, so set
# ccachestats accordingly in the build summary # ccachestats accordingly in the build summary
if [[ $ccache = 1 ]] && [[ $tmpfs = 1 ]] && [[ $tmpfsenabledforthispackage = 1 ]] ; then if [[ $ccache = 1 ]] && [[ $tmpfsenabledforthispackage = 1 ]] ; then
ccachestats="Set to 1 but disabled due to tmpfs" ccachestats="Set to 1 but disabled due to tmpfs"
elif [[ $ccache = 1 ]] && [[ $tmpfs = 0 ]] ; then elif [[ $ccache = 1 ]] && [[ $tmpfs = 0 ]] ; then
@ -731,7 +767,6 @@ prepbuildoutput() {
ccachestats="No, disabled in bldpkg.conf" ccachestats="No, disabled in bldpkg.conf"
fi fi
# Determine the build type # Determine the build type
if [[ $debug = 1 ]] ; then if [[ $debug = 1 ]] ; then
bldtype="*DEBUG* build" bldtype="*DEBUG* build"
@ -740,7 +775,7 @@ prepbuildoutput() {
fi fi
# Determine whether tmpfs was used # Determine whether tmpfs was used
if [[ $tmpfs = 1 ]] && [[ $tmpfsenabledforthispackage = 1 ]] ; then if [[ $tmpfsenabledforthispackage = 1 ]] ; then
tmpfsstate="Yes" tmpfsstate="Yes"
elif [[ $tmpfs = 1 ]] && [[ $tmpfsenabledforthispackage = 0 ]]; then elif [[ $tmpfs = 1 ]] && [[ $tmpfsenabledforthispackage = 0 ]]; then
@ -753,7 +788,6 @@ prepbuildoutput() {
tmpfsstate="No, disabled in bldpkg.conf" tmpfsstate="No, disabled in bldpkg.conf"
fi fi
# Determine if the build was successful or not # Determine if the build was successful or not
if [[ $pkgstatus = 0 ]] ; then if [[ $pkgstatus = 0 ]] ; then
# Determine the compressed size # Determine the compressed size
@ -865,7 +899,7 @@ while getopts ':def:ghj:o:rstvx' option; do
e) extractprompt=0; e) extractprompt=0;
autoextract=1 ;; # Automatically extract the final pkg installer inside user's PWD autoextract=1 ;; # Automatically extract the final pkg installer inside user's PWD
f) setbuildfile="$OPTARG" ;; f) setbuildfile="$OPTARG" ;;
g) genchecksum=1 ;; g) genchecksum ;;
h) help ;; h) help ;;
j) custommakeflags="$OPTARG" ;; j) custommakeflags="$OPTARG" ;;
o) origbuildfile="$OPTARG" ;; o) origbuildfile="$OPTARG" ;;
@ -951,39 +985,6 @@ fi
# Unset OPTIND and OPTARG to avoid problems if getopts is used again in the future # Unset OPTIND and OPTARG to avoid problems if getopts is used again in the future
unset OPTIND OPTARG unset OPTIND OPTARG
# Generate and insert sha512sums into the build file
if [[ $genchecksum = 1 ]] ; then
# File types whose checksums will go into the new build file
info "Discarding any old sha512sums from '$buildfile'"
sed -E -i \
-e '/^sha512sums=".*"$/d' \
-e '/^sha512sums="/,/"$/d' \
-e "/^sha512sums='.*'\$/d" \
"$buildfile"
info "Adding new sha512sums in '$buildfile'"
printf 'sha512sums="\n' >> "$buildfile"
files=( *.tar.* *.zip *.t?z *.patch *.diff *.c *.h )
# For loop that searches for files matching the above extension and prints them to the bottom of the build file
for file in "${files[@]}" ; do
if [[ -f $file ]] ; then
sha512sum "$file" >> "$buildfile"
fi
done
printf '"' >> "$buildfile"
if [[ $(find . -type d -maxdepth 1 -print0 | wc -l) -ge 1 ]]; then
warn "SHA512 checksums not generated for files inside directories!"
fi
info "You may now run 'bldpkg' again"
exit 0
fi
# Display the package and its version we are building or resuming # Display the package and its version we are building or resuming
if [[ -z $resumepkgbuild ]] ; then if [[ -z $resumepkgbuild ]] ; then
info "Building package '$app' version '$version' ..." info "Building package '$app' version '$version' ..."
@ -1123,6 +1124,8 @@ if [[ $tmpfs = 1 ]] && [[ -z $tmpfscheckfailed ]] ; then
# is solely for deciding whether $app is in the exception list or not. # is solely for deciding whether $app is in the exception list or not.
if inarray "${app}" "${tmpfsexceptionlist[@]}" ; then if inarray "${app}" "${tmpfsexceptionlist[@]}" ; then
info "'$app' is in tmpfs exception list. Falling back to non-tmpfs directory"
# We DO NOT compile inside tmpfsdir # We DO NOT compile inside tmpfsdir
tmpfsenabledforthispackage=0 tmpfsenabledforthispackage=0
@ -1290,9 +1293,7 @@ trap "prepbuildoutput" EXIT
trap "interruptoutput" INT trap "interruptoutput" INT
# If $tmp exists, get the path to the $.app-$version.extraction.complete file # If $tmp exists, get the path to the $.app-$version.extraction.complete file
if [[ -d $tmp ]] ; then [[ -d $tmp ]] && buildresumepath="$(find $tmp -type f -name .$app-$version.extraction.complete)"
buildresumepath="$(find $tmp -type f -name .$app-$version.extraction.complete)"
fi
# If the above file exists, $resumepkgbuild and $autobuild are unset # If the above file exists, $resumepkgbuild and $autobuild are unset
# and $autoresumepkgbuild is set to 1 in bldpkg.conf, prompt the user # and $autoresumepkgbuild is set to 1 in bldpkg.conf, prompt the user
@ -1307,9 +1308,7 @@ if [[ -f $buildresumepath ]] && [[ -z $resumepkgbuild ]] && [[ $autoresumepkgbui
fi fi
# If $resumepkgbuild variable is not set in getopts, only then execute prepbuilddir variable # If $resumepkgbuild variable is not set in getopts, only then execute prepbuilddir variable
if [[ -z $resumepkgbuild ]] ; then [[ -z $resumepkgbuild ]] && prepbuilddir
prepbuilddir
fi
# If $resumepkgbuild is set either in getopts or from the user prompt above, execute mkandenterbuilddir # If $resumepkgbuild is set either in getopts or from the user prompt above, execute mkandenterbuilddir
# function to enter the build directory. This is being done because mkandenterbuilddir is part of prepbuilddir # function to enter the build directory. This is being done because mkandenterbuilddir is part of prepbuilddir