This is a really ugly patch, but allows mkinitcpio to read hooks from multiple locations, namely: /usr/lib/initcpio/{install,hooks} /lib/initcpio/{install,hooks} Preference is given to the first. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- Makefile | 24 ++++++++-------- functions | 18 ++++++++++-- install/base | 4 +-- install/shutdown | 2 +- mkinitcpio | 82 ++++++++++++++++++++++++++++++++---------------------- 5 files changed, 79 insertions(+), 51 deletions(-) diff --git a/Makefile b/Makefile index e1fe5aa..a9c6351 100644 --- a/Makefile +++ b/Makefile @@ -6,9 +6,9 @@ DIRS = \ /usr/bin \ /etc/bash_completion.d \ /etc/mkinitcpio.d \ - /lib/initcpio/hooks \ - /lib/initcpio/install \ - /lib/initcpio/udev \ + /usr/lib/initcpio/hooks \ + /usr/lib/initcpio/install \ + /usr/lib/initcpio/udev \ /usr/share/man/man8 DIST_EXTRA = \ @@ -20,26 +20,26 @@ install: all $(foreach dir,${DIRS},install -dm755 ${DESTDIR}${dir};) sed -e 's|^CONFIG=.*|CONFIG=/etc/mkinitcpio.conf|' \ - -e 's|^FUNCTIONS=.*|FUNCTIONS=/lib/initcpio/functions|' \ - -e 's|^HOOKDIR=.*|HOOKDIR=/lib/initcpio/hooks|' \ - -e 's|^INSTDIR=.*|INSTDIR=/lib/initcpio/install|' \ + -e 's|^FUNCTIONS=.*|FUNCTIONS=/usr/lib/initcpio/functions|' \ + -e 's|^HOOKDIR=.*|HOOKDIR=({/usr,}/lib/initcpio/hooks)|' \ + -e 's|^INSTDIR=.*|INSTDIR=({/usr,}/lib/initcpio/install)|' \ -e 's|^PRESETDIR=.*|PRESETDIR=/etc/mkinitcpio.d|' \ -e 's|%VERSION%|${VERSION}|g' \ < mkinitcpio > ${DESTDIR}/usr/bin/mkinitcpio - sed -e 's|\(^declare FUNCTIONS\)=.*|\1=/lib/initcpio/functions|' \ + sed -e 's|\(^declare FUNCTIONS\)=.*|\1=/usr/lib/initcpio/functions|' \ -e 's|%VERSION%|${VERSION}|g' \ < lsinitcpio > ${DESTDIR}/usr/bin/lsinitcpio chmod 755 ${DESTDIR}/usr/bin/lsinitcpio ${DESTDIR}/usr/bin/mkinitcpio install -m644 mkinitcpio.conf ${DESTDIR}/etc/mkinitcpio.conf - install -m755 -t ${DESTDIR}/lib/initcpio init shutdown - install -m644 -t ${DESTDIR}/lib/initcpio init_functions functions - install -m644 01-memdisk.rules ${DESTDIR}/lib/initcpio/udev/01-memdisk.rules + install -m755 -t ${DESTDIR}/usr/lib/initcpio init shutdown + install -m644 -t ${DESTDIR}/usr/lib/initcpio init_functions functions + install -m644 01-memdisk.rules ${DESTDIR}/usr/lib/initcpio/udev/01-memdisk.rules - install -m644 -t ${DESTDIR}/lib/initcpio/hooks hooks/* - install -m644 -t ${DESTDIR}/lib/initcpio/install install/* + install -m644 -t ${DESTDIR}/usr/lib/initcpio/hooks hooks/* + install -m644 -t ${DESTDIR}/usr/lib/initcpio/install install/* install -m644 -t ${DESTDIR}/etc/mkinitcpio.d mkinitcpio.d/* install -m644 mkinitcpio.8 ${DESTDIR}/usr/share/man/man8/mkinitcpio.8 diff --git a/functions b/functions index c85806a..5485578 100644 --- a/functions +++ b/functions @@ -337,7 +337,7 @@ parse_hook() { # prior to the start of hook processing, and after each hook's build # function is run. - local item= + local item= script= for item in $MODULES; do if [[ ${item:(-1)} = '?' ]]; then @@ -355,7 +355,21 @@ parse_hook() { add_file "$item" done - [[ $SCRIPT ]] && add_file "$HOOKDIR/$SCRIPT" "/hooks/$SCRIPT" + if [[ $SCRIPT ]]; then + script=$(find_in_dirs "$SCRIPT" "${HOOKDIR[@]}") && + add_file "$script" "/hooks/$SCRIPT" + fi +} + +find_in_dirs() { + for dir in "${@:2}"; do + if [[ -e $dir/$1 ]]; then + printf '%s' "$dir/$1" + return 0 + fi + done + + return 1 } # vim: set ft=sh ts=4 sw=4 et: diff --git a/install/base b/install/base index 3b7632f..db82fdc 100644 --- a/install/base +++ b/install/base @@ -31,8 +31,8 @@ build() { # Add an empty fstab to avoid mount warning when -o remount is used >"$BUILDROOT/etc/fstab" - add_file "/lib/initcpio/init_functions" "/init_functions" - add_file "/lib/initcpio/init" "/init" + add_file "/usr/lib/initcpio/init_functions" "/init_functions" + add_file "/usr/lib/initcpio/init" "/init" add_file "/lib/modprobe.d/usb-load-ehci-first.conf" # write a new config file. re-source the config as we can't guarantee the diff --git a/install/shutdown b/install/shutdown index 7c6b7bc..5b56f17 100644 --- a/install/shutdown +++ b/install/shutdown @@ -4,7 +4,7 @@ build() { BINARIES='cp' SCRIPT='shutdown' - add_file "/lib/initcpio/shutdown" "/shutdown" + add_file "/usr/lib/initcpio/shutdown" "/shutdown" } help() { diff --git a/mkinitcpio b/mkinitcpio index 637795f..9d59f0b 100755 --- a/mkinitcpio +++ b/mkinitcpio @@ -110,32 +110,34 @@ trap 'cleanup 130' INT trap 'cleanup 143' TERM while getopts ':c:k:sb:g:p:m:nvH:LMhS:t:z:' arg; do - case "${arg}" in - c) CONFIG="${OPTARG}" ;; + case $arg in + c) CONFIG=$OPTARG ;; k) optkver=$OPTARG ;; - s) SAVELIST=1; ;; - b) BASEDIR="${OPTARG}" ;; - g) GENIMG="${OPTARG}" ;; + s) SAVELIST=1 ;; + b) BASEDIR=$OPTARG ;; + g) GENIMG=$OPTARG ;; h) usage ;; - p) PRESET="${OPTARG}" ;; + p) PRESET=$OPTARG ;; n) COLOR=0 ;; v) QUIET=0 ;; S) IFS=, read -r -a SKIPHOOKS <<< "$OPTARG" ;; - H) if [[ ! -r "${INSTDIR}/${OPTARG}" ]]; then - error "No hook ${OPTARG}" + H) if script=$(find_in_dirs "$OPTARG" "${INSTDIR[@]}"); then + . "$script" + if [[ $(type -t help) != function ]]; then + error "No help for hook $OPTARG" + exit 1 + fi + else + error "No hook '$OPTARG'" exit 1 fi - . "${INSTDIR}/${OPTARG}" - if [[ $(type -t help) != function ]]; then - error "No help for hook ${OPTARG}" - exit 1 - fi - msg "Help for hook '${OPTARG}':" + msg "Help for hook '$OPTARG':" help exit 0 ;; L) msg "Available hooks" - cd "$INSTDIR" >/dev/null - printf ' %s\n' * | column -c$(tput cols) + for dir in "${INSTDIR[@]}"; do + ( cd "$dir" >/dev/null; printf ' %s\n' * ) + done | column -c$(tput cols) exit 0 ;; M) SHOW_AUTOMODS=1 ;; t) TMPDIR=$OPTARG ;; @@ -276,9 +278,10 @@ fi if (( SHOW_AUTOMODS )); then msg "Modules autodetected" - . "${INSTDIR}/autodetect" + autodetect=$(find_in_dirs 'autodetect' "${INSTDIR[@]}") + . "$autodetect" build - cat "${MODULE_FILE}" + cat "$MODULE_FILE" cleanup 0 fi @@ -307,26 +310,37 @@ done for hook in ${HOOKS}; do in_array "$hook" "${SKIPHOOKS[@]}" && continue unset MODULES BINARIES FILES SCRIPT - build () { error "$hook: no build function..."; } - - # A hook is considered deprecated if it is a symlink within $INSTDIR. - if [[ -L "$INSTDIR/$hook" ]]; then - newhook=$(readlink -e "$INSTDIR/$hook") - if [[ $newhook && "$INSTDIR/${newhook##*/}" -ef "$newhook" ]]; then - newhook=${newhook##*/} - warning "Hook '%s' is deprecated. Replace it with '%s' in your config" "$hook" "$newhook" - hook=$newhook + build() { error "$hook: no build function..."; return 1; } + + # find script in install dirs + if ! script=$(find_in_dirs "$hook" "${INSTDIR[@]}"); then + error "Hook '$hook' cannot be found." + (( ++builderrors )) + continue + fi + + # check for deprecation + if [[ -L $script ]]; then + if ! realscript=$(readlink -e "$script"); then + error "$script is a broken symlink to $(realpath "$script")" + (( ++builderrors )) + continue fi + warning "Hook '%s' is deprecated. Replace it with '%s' in your config" "$script" "$realscript" + script=$realscript fi - if [[ -r "${INSTDIR}/${hook}" ]]; then - . "${INSTDIR}/${hook}" - msg2 "Parsing hook: [%s]" "$hook" - build - parse_hook - else - error "Hook '$hook' can not be found." + + # source + if ! . "$script"; then + error 'Failed to read %s' "$script" (( ++builderrors )) + continue fi + + # run + msg2 "Parsing hook: [%s]" "${script##*/}" + build + parse_hook done # restore $CONFIG vars add to image -- 1.7.9.2