Move parsing of package lists to make file
authorDaniel Abrecht <public@danielabrecht.ch>
Sat, 13 Jul 2019 17:58:53 +0000 (19:58 +0200)
committerDaniel Abrecht <public@danielabrecht.ch>
Sat, 13 Jul 2019 17:58:53 +0000 (19:58 +0200)
chroot-build-helper/makefile
config/defaults.mk
makefile
script/assemble_image.sh
script/chroot_qemu_static.sh
script/debootstrap.sh
script/rootfs_setup.sh
src/make-helper-functions.mk
src/package_list.mk [new file with mode: 0644]
uboot/makefile

index c0434f8d7fe1f606ce9ebbe1181ea1c8a7a81b31..4ac75e0ca8be1216ccdc91f58892780e6231dfef 100644 (file)
@@ -1,5 +1,8 @@
 include ../src/make-helper-functions.mk
 
+# Only one thing at a time can chroot into the buildenv
+.NOTPARALLEL:
+
 CURDIR=$(realpath .)
 
 TARGETS += deb-flash-kernel
index 15cab26c901c1428c75ce85a5b9d3a7b069f63b2..c6e242fb0a99e51426a966dfaaf77a76312fc239 100644 (file)
@@ -18,6 +18,10 @@ IMAGE_NAME = $(DISTRO)-$(RELEASE)-librem5-$(BOARD)-$(VARIANT).img
 
 CROSS_COMPILER = aarch64-linux-gnu-
 
+PACKAGE_LIST_PATH = default default::$(VARIANT) $(DISTRO) $(DISTRO)::$(VARIANT) $(DISTRO)-$(RELEASE) $(DISTRO)-$(RELEASE)::$(VARIANT)
+
+USER_SHELL = $(shell getent passwd "$$(id -u)" | grep -o '[^:]*$$')
+
 repo-branch@fuseloop = master
 repo-source@fuseloop = https://github.com/jmattsson/fuseloop.git
 
index 54d64693833d04ece1f8cce3b7911ff212683058..7ec165714aea3880051812f081eb794fe6824395 100644 (file)
--- a/makefile
+++ b/makefile
@@ -25,7 +25,8 @@ clean-image:
        rm -f "bin/$(IMAGE_NAME)"
 
 enter-buildenv:
-       $(SETUPBUILDENV) "$(SHELL)"
+       export PROMPT_COMMAND='if [ -z "$$PS_SET" ]; then PS_SET=1; PS1="(buildenv) $$PS1"; fi'; \
+       $(USER_SHELL)
 
 uboot/bin/uboot_firmware_and_dtb.bin:
        $(MAKE) -C uboot
index 762d69a12a53ce7e9df8f60941ee7b46eacb5a56..3f8173f15f1fd012b4a3fa5e18fe4f87c0d323fd 100755 (executable)
@@ -1,5 +1,10 @@
 #!/bin/sh
 
+if [ -z "project_root" ]; then
+  echo "Error: project_root is not set! THis script has to be called from the makefile build env" >&2
+  exit 1
+fi
+
 set -xe
 
 cd "$(dirname "$0")/.."
@@ -7,18 +12,7 @@ base="$PWD"
 
 tmp="$(mktemp -d -p build)"
 
-if [ -z "$DISTRO" ]; then DISTRO="devuan"; fi
-if [ -z "$RELEASE" ]; then RELEASE="ascii"; fi
-if [ -z "$VARIANT" ]; then VARIANT="base"; fi
-if [ -z "$IMAGE_NAME" ]; then IMAGE_NAME="$DISTRO-$RELEASE-librem5-devkit-$(VARIANT).img"; fi
-
-# Some programs like sfdisk are in /sbin/, but they work just fine as non-root on an image
-PATH="$base/build/bin/:$base/script/:/sbin/:/usr/sbin/:$PATH"
-
-# Set image size if not already defined
-if [ -z "$IMGSIZE" ]; then IMGSIZE=32GB; fi
-
-# if there is an old temporari image, remove it
+# if there is an old temporary image, remove it
 rm -f "$tmp/$IMAGE_NAME"
 
 # Create a sparse image
index 2bb46dc5b22c8c42268e0b1b489cc31b6cb9756c..87e61038113b39bca690a7cb97e0704797736fa1 100755 (executable)
@@ -1,5 +1,9 @@
 #!/bin/sh
 
+if [ -z "$AARCH64_EXECUTABLE" ]
+  then echo "Warning: AARCH64_EXECUTABLE is not set! (Note: This script is expected to be called by the make file)" >&2
+fi
+
 rootfs="$1"
 shift
 
index 212c19c40050a1a0360065f4f778c3065403da8e..9533d6db0c43a6e7bdc56010453482478cb30e02 100755 (executable)
@@ -1,7 +1,8 @@
 #!/bin/sh
 
-if [ -z "$AARCH64_EXECUTABLE" ]
-  then echo "Warning: AARCH64_EXECUTABLE is not set! (Note: This script is expected to be called by the make file)" >&2
+if [ -z "project_root" ]; then
+  echo "Error: project_root is not set! THis script has to be called from the makefile build env" >&2
+  exit 1
 fi
 
 set -ex
@@ -10,24 +11,11 @@ set -ex
 cd "$(dirname "$0")/.."
 base="$PWD"
 
-# Make sure debootstrap & co is in path, and that the fake mknod noop helper will be used
-PATH="$base/build/bin/:$base/script/:/sbin/:/usr/sbin/:$PATH"
-
 # If not root, fake being root using user namespace. Map root -> user and 1-subuidcount to subuidmin-subuidmax
 if [ $(id -u) != 0 ]
 then
   exec uexec --allow-setgroups "$(realpath "$0")" "$@"
 fi
-
-# Set release repo if not already defined
-if [ -z "$DISTRO" ]; then DISTRO=devuan; fi
-if [ -z "$RELEASE" ]; then RELEASE=ascii; fi
-if [ -z "$VARIANT" ]; then VARIANT=base; fi
-if [ -z "$IMAGE_NAME" ]; then IMAGE_NAME="$DISTRO-$RELEASE-librem5-devkit-$(VARIANT).img"; fi
-if [ -z "$REPO" ]; then REPO=https://pkgmaster.devuan.org/merged/; fi
-if [ -z "$CHROOT_REPO" ]; then CHROOT_REPO="$REPO"; fi
-if [ -z "$KERNEL_DTB" ]; then echo "Pleas set KERNEL_DTB" >2; exit 1; fi
-
 tmp="$base/build/$IMAGE_NAME/"
 
 # Cleanup if any of the remaining steps fails
@@ -48,65 +36,24 @@ sanitize_pkg_list(){
   sed 's/#.*//' | tr '\n' ',' | sed 's/\(,\|\s\)\+/,/g' | sed 's/^,\+\|,\+$//g'
 }
 
-packages=
-packages_early=
-packages_second_stage=
-packages_download_only=
-packages_exclude_debootstrap=
-
 mkdir -p "$tmp/rootfs/root/post_debootstrap/"
+# TODO: copy scripts
 
-i=0
-for spec in "default" "default::$VARIANT" "$DISTRO-$RELEASE::$VARIANT" "$DISTRO-$RELEASE" "$DISTRO::$VARIANT" "$DISTRO"
-do
-  i="$(expr "$i" + 1)"
-  packages_base="packages/$spec/"
-  if [ -f "$packages_base/install_debootstrap" ]
-    then packages="$packages $(sanitize_pkg_list < "$packages_base/install_debootstrap")"
-  fi
-  if [ -f "$packages_base/download" ]
-    then packages_download_only="$packages_download_only $(sanitize_pkg_list < "$packages_base/download")"
-  fi
-  if [ -f "$packages_base/install_early" ]
-    then packages_early="$packages_early $(sanitize_pkg_list < "$packages_base/install_early")"
-  fi
-  if [ -f "$packages_base/install_second_stage" ]
-    then packages_second_stage="$packages_second_stage $(sanitize_pkg_list < "$packages_base/install_second_stage")"
-  fi
-  if [ -f "$packages_base/debootstrap_exclude" ]
-    then packages_exclude_debootstrap="$packages_exclude_debootstrap $(sanitize_pkg_list < "$packages_base/debootstrap_exclude")"
-  fi
-  if [ -x "$packages_base/post_debootstrap" ]
-    then cp "$packages_base/post_debootstrap" "$tmp/rootfs/root/post_debootstrap/$i-$spec.sh"
-  fi
-done
-
-if [ "$AARCH64_EXECUTABLE" != yes ]
-  then packages="$packages,fakechroot"
-fi
-
-# Add packages for different apt transport if any is used
-if echo "$CHROOT_REPO" | grep -o '^[^:]*' | grep -q 'https'    ; then packages="$packages,apt-transport-https"    ; fi
-if echo "$CHROOT_REPO" | grep -o '^[^:]*' | grep -q 'tor'      ; then packages="$packages,apt-transport-tor"      ; fi
-if echo "$CHROOT_REPO" | grep -o '^[^:]*' | grep -q 'spacewalk'; then packages="$packages,apt-transport-spacewalk"; fi
-
-packages="$(echo "$packages" | sanitize_pkg_list)"
-if [ -n "$packages" ]; then packages="--include=$packages"; fi
-if [ -n "$packages_exclude_debootstrap" ]; then packages_exclude_debootstrap="--exclude=$packages_exclude_debootstrap"; fi
+if [ -n "$PACKAGES_INSTALL_DEBOOTSTRAP" ]; then debootstrap_include="--include=$(printf "%s" "$PACKAGES_INSTALL_DEBOOTSTRAP" | tr ' ' ',')"; fi
 
 # Create usable first-stage rootfs
-debootstrap --foreign --arch=arm64 $packages_exclude_debootstrap $packages "$RELEASE" "$tmp/rootfs" "$REPO"
+debootstrap --foreign --arch=arm64 $debootstrap_include "$RELEASE" "$tmp/rootfs" "$REPO"
 
 touch "$tmp/rootfs/dev/null" # yes, this is a really bad idea, but hacking together a fuse file system just for this is overkill. Also, unionfs-fuse won't work here (fuse default is mounting as nodev), and there is no way to create a proper device file.
 chmod 666 "$tmp/rootfs/dev/null"
-mkdir "$tmp/rootfs/root/helper"
+mkdir -p "$tmp/rootfs/root/helper"
 echo '#!/bin/sh' >"$tmp/rootfs/root/helper/mknod" # Don't worry about this, on boot, the kernel mounts /dev as devtmpfs before calling init anyway
 echo '#!/bin/sh' >"$tmp/rootfs/root/helper/mount"
 chmod +x "$tmp/rootfs/root/helper/"*
 
 chroot_qemu_static.sh "$tmp/rootfs/" /debootstrap/debootstrap --second-stage
 
-mkdir "$tmp/rootfs/root/temp-repo/"
+mkdir -p "$tmp/rootfs/root/temp-repo/"
 cp kernel/bin/linux-image.deb kernel/bin/linux-libc.deb kernel/bin/linux-headers.deb "$tmp/rootfs/root/temp-repo/"
 cp chroot-build-helper/bin/"$DISTRO"/"$RELEASE"/deb-*/*.deb "$tmp/rootfs/root/temp-repo/"
 
@@ -151,7 +98,7 @@ cp chroot-build-helper/bin/"$DISTRO"/"$RELEASE"/deb-*/*.deb "$tmp/rootfs/root/te
 )
 
 # Packages to install on device
-echo "$packages_second_stage" | tr ',' '\n' > "$tmp/rootfs/root/packages_to_install"
+printf '%s\n' $PACKAGES_INSTALL_TARGET > "$tmp/rootfs/root/packages_to_install"
 
 # Temporary source list
 (
@@ -167,8 +114,6 @@ echo "$packages_second_stage" | tr ',' '\n' > "$tmp/rootfs/root/packages_to_inst
 # Do some stuff inside the chroot
 (
   cp script/rootfs_setup.sh "$tmp/rootfs/root/rootfs_setup.sh"
-  export packages="$packages_second_stage $packages_download_only"
-  export install_packages="$packages_early"
   chroot_qemu_static.sh "$tmp/rootfs/" /root/rootfs_setup.sh
   rm "$tmp/rootfs/root/rootfs_setup.sh"
 )
index ef6d9e4353d223df9352068fcfba48c0d532577e..0edc1f3f3866f43be3183f644a6b847a2a791594 100755 (executable)
@@ -1,5 +1,10 @@
 #!/bin/sh
 
+if [ -z "project_root" ]; then
+  echo "Error: project_root is not set! This script has to be called from the makefile build env" >&2
+  exit 1
+fi
+
 set -ex
 
 cd /
@@ -40,7 +45,6 @@ apt-get update
 apt-get -y dist-upgrade
 apt-get -y install $(grep 'Package: ' /root/temp-repo/Packages | sed 's/Package: //' | sort -u | grep -v Auto-Built-debug-symbols)
 rm -rf /root/temp-repo/
-apt-get clean
 
 # Packages such as flash-kernel may have been installed & configured after linux-image, which may have caused some triggers of them not to be run
 # Reconfigure linux-image to make sure flash-kernel & co. get invoked
@@ -50,9 +54,9 @@ dpkg-reconfigure $(dpkg-query -f '${db:Status-Abbrev} ${binary:Package}\n' -W li
 # download packages
 (
   IFS=", "
-  apt-get -y install $install_packages
+  apt-get -y install $PACKAGES_INSTALL_EARLY
   apt-get clean
-  for package in $packages
+  for package in $PACKAGES_INSTALL_TARGET $PACKAGES_TO_DOWNLOAD
   do
     apt-get -d -y install "$package"
   done
@@ -63,7 +67,7 @@ rm /root/temporary-local-repo.list
 
 # Move packages from apt cache to temporary repo
 mkdir /root/temp-repo/
-mv /var/cache/apt/archives/*.deb /root/temp-repo/
+mv /var/cache/apt/archives/*.deb /root/temp-repo/ || true
 
 # Create package list for repo
 (
index 57f3b3a631c26049bee735480463d87de5c60b7f..623d7f1d63a3d71938d9ceb43d5ba29b1e7b42dd 100644 (file)
@@ -4,6 +4,7 @@ default_target: all
 .SECONDARY:
 
 project_root := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))..)
+export project_root
 
 VARS_OLD := $(subst %,,$(subst *,,$(.VARIABLES)))
 
@@ -35,10 +36,6 @@ ifdef REPO-$(DISTRO)-$(RELEASE)
   REPO = $(REPO-$(DISTRO)-$(RELEASE))
 endif
 
-ifdef REPO-$(DISTRO)-$(RELEASE)-$(VARIANT)
-  REPO = $(REPO-$(DISTRO)-$(RELEASE)-$(VARIANT))
-endif
-
 ifdef CHROOT_REPO-$(DISTRO)
   CHROOT_REPO = $(CHROOT_REPO-$(DISTRO))
 endif
@@ -47,10 +44,6 @@ ifdef CHROOT_REPO-$(DISTRO)-$(RELEASE)
   CHROOT_REPO = $(CHROOT_REPO-$(DISTRO)-$(RELEASE))
 endif
 
-ifdef CHROOT_REPO-$(DISTRO)-$(RELEASE)-$(VARIANT)
-  CHROOT_REPO = $(CHROOT_REPO-$(DISTRO)-$(RELEASE)-$(VARIANT))
-endif
-
 CONFIG_VARS := $(sort $(filter-out $(VARS_OLD) VARS_OLD,$(subst %,,$(subst *,,$(.VARIABLES)))))
 IMGSIZE := $(shell echo "$(IMGSIZE)" | sed 's/\s*//g')
 export $(CONFIG_VARS)
@@ -59,8 +52,7 @@ CONF = userdefined
 
 include $(project_root)/src/repositories.mk
 
-SETUPBUILDENV := \
-  export PATH="/helper/bin:$(project_root)/script/:/sbin:/usr/sbin:$$PATH:$(project_root)/build/bin:$(project_root)/bin";
+export PATH := /helper/bin:$(project_root)/script/:/sbin:/usr/sbin:$(PATH):$(project_root)/build/bin:$(project_root)/bin
 
 ifeq (x$(shell echo 'int main(){}' | $(CROSS_COMPILER)gcc -static -x c - -o .aarch64test &>/dev/null; sync .; sleep 0.5; sync .; ./.aarch64test &>/dev/null; echo $$?), x0)
 # This usually means binfmt-misc (qemu-user-binfmt in devuan) is set up, (or we are really on aarch64)
@@ -69,12 +61,13 @@ else
 export AARCH64_EXECUTABLE := no
 endif
 
+include $(project_root)/src/package_list.mk
+
 %/.dir:
        mkdir -p "$(dir $@)"
        touch "$@"
 
 chroot@%:
-       $(SETUPBUILDENV) \
        export PROMPT_COMMAND="export PS1='$@ (\u)> '"; \
        uexec --allow-setgroups chroot_qemu_static.sh "$(realpath $(patsubst chroot@%,%,$@))" /bin/bash
 
diff --git a/src/package_list.mk b/src/package_list.mk
new file mode 100644 (file)
index 0000000..e85a1fd
--- /dev/null
@@ -0,0 +1,39 @@
+define parse_package_list
+$(shell
+    for list in $(PACKAGE_LIST_PATH);
+    do
+      cat "$(project_root)/packages/$$list/$(1)" 2>/dev/null || true;
+    done | sed 's/#.*//' | tr '\n' ' ' | sed 's/\s\+/ /g' | sed 's/^\s\+\|\s\+$$//g';
+  )
+endef
+
+PACKAGES_INSTALL_DEBOOTSTRAP = $(call parse_package_list,install_debootstrap)
+PACKAGES_INSTALL_EARLY       = $(call parse_package_list,install_early)
+PACKAGES_INSTALL_TARGET      = $(call parse_package_list,install_target)
+PACKAGES_TO_DOWNLOAD         = $(call parse_package_list,download)
+PACKAGES_TO_BUILD            = $(call parse_package_list,build)
+
+ifneq ($(AARCH64_EXECUTABLE),yes)
+  PACKAGES_INSTALL_DEBOOTSTRAP+=fakechroot"
+endif
+
+repo-schema = $(shell printf '%s' "$(REPO)" | grep -o '^[^:]*')
+ch-repo-schema = $(shell printf '%s' "$(CHROOT_REPO)" | grep -o '^[^:]*')
+
+ifeq ($(shell [ "$(repo-schema)" = https ] || [ "$(ch-repo-schema)" = https ]; printf $$?),0)
+  PACKAGES_INSTALL_DEBOOTSTRAP+=apt-transport-https
+endif
+
+ifeq ($(shell printf "$(repo-schema)"$$'\n'"$(ch-repo-schema)" | grep -q '^tor'; printf $$?),0)
+  PACKAGES_INSTALL_DEBOOTSTRAP+=apt-transport-tor
+endif
+
+ifeq ($(shell [ "$(repo-schema)" = spacewalk ] || [ "$(ch-repo-schema)" = spacewalk ]; printf $$?),0)
+  PACKAGES_INSTALL_DEBOOTSTRAP+=apt-transport-spacewalk
+endif
+
+export PACKAGES_INSTALL_DEBOOTSTRAP
+export PACKAGES_INSTALL_EARLY
+export PACKAGES_INSTALL_TARGET
+export PACKAGES_TO_DOWNLOAD
+export PACKAGES_TO_BUILD
index e60d51a4412be319a7f51d11a490b9986dd77fe5..2166ab586b525811cfb34d3eb2ec489eb69ea533 100644 (file)
@@ -1,5 +1,8 @@
 include ../src/make-helper-functions.mk
 
+# In theory, it should work without this, but it doesn't...
+.NOTPARALLEL:
+
 BOOTLOADER_COMPONENTS += dtb/$(UBOOT_DTB)
 BOOTLOADER_COMPONENTS += firmware/u-boot-nodtb.bin
 BOOTLOADER_COMPONENTS += firmware/u-boot-spl.bin