summaryrefslogtreecommitdiffstats
path: root/src/opkbuild.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/opkbuild.sh')
-rw-r--r--src/opkbuild.sh258
1 files changed, 258 insertions, 0 deletions
diff --git a/src/opkbuild.sh b/src/opkbuild.sh
new file mode 100644
index 0000000..faa72ef
--- /dev/null
+++ b/src/opkbuild.sh
@@ -0,0 +1,258 @@
+#! /bin/sh
+#
+# opkhelper
+# src/opkbuild
+# Build opkg packages.
+#
+# Copyright (C) 2012 Patrick "P. J." McDermott
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. @@LIBDIR@@/opkhelper/controlfields
+. @@LIBDIR@@/opkhelper/architecture
+. @@LIBDIR@@/opkhelper/archive
+
+print_usage()
+{
+ printf 'Usage: %s [-r assume-uid0-cmd] [-p target-platform] [-d]\n' "${1}"
+}
+
+error()
+{
+ [ ${#} -eq 1 ] && printf 'opkbuild: [%s] Error\n' "${1}" >&2
+ if ${dbg}; then
+ printf 'opkbuild: Starting debugging shell...\n' >&2
+ /bin/sh
+ fi
+ cd ..
+ rm -Rf tmp 2> /dev/null
+ exit 1
+}
+
+opts=$(getopt -n "${0}" -o 'r:p:d' -- "${@}")
+if [ ${?} -ne 0 ]; then
+ print_usage "${0}" >&2
+ exit 1;
+fi
+eval set -- "${opts}"
+while true; do
+ case "${1}" in
+ -r)
+ uid0_cmd=${2}
+ shift 2
+ ;;
+ -p)
+ platform=${2}
+ shift 2
+ ;;
+ -d)
+ dbg=true
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ print_usage "${0}" >&2
+ exit 1
+ ;;
+ esac
+done
+
+if [ -z "${uid0_cmd}" ]; then
+ uid0_cmd=fakeroot
+fi
+${uid0_cmd} true
+if [ ${?} -ne 0 ]; then
+ printf 'opkbuild: Error running command to gain UID 0\n' >&2
+ exit 1
+fi
+if [ -z "${dbg}" ]; then
+ dbg=false
+fi
+
+# Sanity checks.
+printf 'opkbuild: Checking for sanity...\n'
+if [ ! -f format -o ! -f build -o ! -f control ]; then
+ printf 'Error: Current working directory is not a source package.\n' >&2
+ exit 1
+fi
+if [ "$(cat format)" != '1.0' ]; then
+ printf 'Error: Source package is of an incompatible version.\n' >&2
+ exit 1
+fi
+
+# Attempt to detect the target platform.
+# If there no config files to copy, build platform-independent packages.
+if [ ! -f config ]; then
+ platform=''
+# If a target platform was not specified ...
+elif [ -z "${platform}" ]; then
+ platform=$(opkg print-architecture | \
+ sed -n 's/^arch \([^ -][^ -]*\) [0-9][0-9]*$/\1/p' | \
+ grep -v 'all')
+ # ... and there are config files and zero installable platforms, fail.
+ if [ -z "${platform}" ]; then
+ printf 'opkbuild: Error: %s\n' \
+ 'Building platform-dependent package and no platforms detected' >&2
+ exit 1
+ # ... and there are config files and multiple installable platforms, request
+ # explicit selection.
+ elif [ $(echo "${platform}" | wc -l) -gt 1 ]; then
+ printf 'opkbuild: Error: %s\n' \
+ 'Multiple platforms found while detecting target' >&2
+ exit 1
+ fi
+ # ... and there are config files and one installable platform, build for it.
+fi
+
+# Attempt to detect the target architecture tuple.
+# NB: Currently cross-compiling is not supported.
+arch=$(opkg print-architecture | sed -n \
+ 's/^arch \([^ -][^ -]*-[^ -][^ -]*-[^ -][^ -]*\) [0-9][0-9]*$/\1/p')
+if [ -z "${arch}" ]; then
+ printf 'opkbuild: Error: No installable architecture found\n' >&2
+elif [ $(echo "${arch}" | wc -l) -gt 1 ]; then
+ printf 'opkbuild: Error: Multiple installable architectures found\n' >&2
+fi
+
+# Make work area.
+printf 'opkbuild: Making work area...\n'
+mkdir tmp
+cd tmp
+
+# Get source package name and version.
+printf 'opkbuild: Reading source package control fields...\n'
+srcpkg=$(oh_get_field Source)
+version=$(oh_get_field Version)
+
+# Set environment variables for the build configuration.
+export OH_PLATFORM="${platform}"
+export OH_ARCH="${arch}"
+IFS=- read OH_ARCH_CPU OH_ARCH_KERNEL OH_ARCH_LIBS <<EOF
+${OH_ARCH}
+EOF
+export OH_ARCH_CPU OH_ARCH_KERNEL OH_ARCH_LIBS
+export OH_SRCPKG="${srcpkg}"
+export OH_PKGVER=${version}
+
+# Set build flags.
+. @@DATADIR@@/opkhelper/buildflags/${OH_ARCH_CPU}
+
+# Check build dependencies.
+oh-checkbuilddeps || error "${srcpkg}-src"
+
+printf '\n'
+
+# Build *-src package.
+printf 'opkbuild: Attempting to build package "%s"...\n' "${srcpkg}-src"
+printf 'opkbuild: Installing files for package "%s"...\n' "${srcpkg}-src"
+${uid0_cmd} mkdir -p ${srcpkg}-src.data/usr/src/${srcpkg}_${version} ||
+ error "${srcpkg}-src"
+for file in ../*; do
+ case ${file} in
+ ../tmp)
+ ;;
+ ../*)
+ ${uid0_cmd} cp -R ${file} \
+ ${srcpkg}-src.data/usr/src/${srcpkg}_${version} ||
+ error "${srcpkg}-src"
+ ;;
+ esac
+done
+( ${uid0_cmd} oh-gencontrol -s;) || error "${srcpkg}-src"
+( ${uid0_cmd} oh-buildopk -s;) || error "${srcpkg}-src"
+( ${uid0_cmd} rm -Rf ${srcpkg}-src.data;) || error "${srcpkg}-src"
+printf 'opkbuild: Package "%s" complete!\n\n' "${srcpkg}-src"
+
+# Build other binary packages.
+for binpkgdir in ../*.pkg/; do
+ binpkg=${binpkgdir#'../'}
+ binpkg=${binpkg%'.pkg/'}
+ export OH_BINPKG="${binpkg}"
+ # Check architecture.
+ oh_is_buildable "${binpkg}"
+ if [ ${?} -eq 0 ]; then
+ printf 'opkbuild: Attempting to build package "%s"...\n' "${binpkg}"
+ # Copy or extract software sources to src.
+ if [ -d ../src ]; then
+ printf 'opkbuild: Copying sources into work area...\n'
+ cp -Rp ../src src || error "${binpkg}"
+ else
+ printf 'opkbuild: Extracting sources into work area...\n'
+ oh_archive_extract_source
+ case ${?} in
+ 1)
+ printf 'opkbuild: Error: No source archive found\n' >&2
+ error
+ ;;
+ 2)
+ printf 'opkbuild: Error: Multiple source archives found\n' \
+ >&2
+ error
+ ;;
+ 3)
+ printf 'opkbuild: Error: %s\n' \
+ 'Unsupported archive compression format detected' >&2
+ error
+ ;;
+ 4)
+ printf 'opkbuild: Error: %s\n' \
+ 'No directories found in source archive' >&2
+ error
+ ;;
+ 5)
+ printf 'opkbuild: Error: %s\n' \
+ 'Multiple top-level directories found in source archive' >&2
+ error
+ ;;
+ 6)
+ printf 'opkbuild: Error: %s\n' \
+ 'Failed to extract source archive' >&2
+ error
+ ;;
+ 7)
+ printf 'opkbuild: Error: %s\n' \
+ 'Failed to move extracted sources' >&2
+ error
+ ;;
+ esac
+ fi
+ # Make installation directory.
+ # TODO: Maybe this should be an FHS-compliant filesystem hierarchy.
+ mkdir dest || error "${binpkg}"
+ # Apply patches.
+ oh-applypatches
+ # Copy platform config files.
+ oh-copyconfig || error "${binpkg}"
+ # Build the package.
+ ${uid0_cmd} ../build ${binpkg} || error "${binpkg}"
+ printf 'opkbuild: Package "%s" complete!\n\n' "${binpkg}"
+ # Clean up everything except the build stamps.
+ for file in *; do
+ case ${file} in
+ *.buildstamp)
+ ;;
+ *)
+ ${uid0_cmd} rm -Rf ${file} || error "${binpkg}"
+ ;;
+ esac
+ done
+ fi
+done
+
+# Clean up tmp.
+cd ..
+rm -Rf tmp