#!/bin/bash MODULE_DIR="${ROOT_DIR}/remote" #Create tools directory if not exists TOOL_DIR="${MODULE_DIR}/tools" INIT_DIR="${MODULE_DIR}/stage3.2" # Keep track of processed modules PROCESSED_MODULES="" initial_checks () { for BIN in git locate do local TEST=$(which ${BIN}) [ -z "$TEST" ] && pinfo "Installing $BIN..." && apt-get install $BIN done } read_config () { unset REQUIRED_BINARIES unset REQUIRED_LIBRARIES unset REQUIRED_DIRECTORIES unset REQUIRED_FILES unset REQUIRED_MODULES unset REQUIRED_PACKAGES unset REQUIRED_DEPENDENCIES local TOOL_CONFIG="${TOOL_DIR}/${TOOL}/${TOOL}.conf" if [ -e "${TOOL_CONFIG}.${PACKET_MANAGER}" ]; then # a specific tool.conf seems to exist, try to use that one # TODO: Maybe move this down right after loading the generic one, to allow "overloading".... but might be a bit confusing . "${TOOL_CONFIG}.${PACKET_MANAGER}" || perror "Sourcing '${TOOL_CONFIG}.${PACKET_MANAGER}' failed." else # otherwise, use the generic one [ ! -e "${TOOL_CONFIG}" ] && perror "Config for '$TOOL' not found." . "${TOOL_CONFIG}" || perror "Sourcing '${TOOL_CONFIG}' failed." fi } read_build () { local BUILD_SCRIPT="${TOOL_DIR}/${TOOL}/${TOOL}.build" [ ! -e "${BUILD_SCRIPT}" ] && perror "Build script for specified tool not found." . "${BUILD_SCRIPT}" || perror "Sourcing '${BUILD_SCRIPT}' failed." } copyfileswithdependencies () { [ ! -d build ] && pinfo "No build directory found, skipping dependency copying" && return 0 cd build COPYFILES_LIST="list_wanted_stage3.2" [ -e ${COPYFILES_LIST} ] && rm ${COPYFILES_LIST} [ ! -z "${REQUIRED_BINARIES}" ] && pinfo "Gathering required binaries from config file..." for FILENAME in ${REQUIRED_BINARIES} do local FILE_CANDIDATES=$( find . -name "${FILENAME}" -a \( -type f -o -type l \) ) pdebug "Candidates for $FILENAME are: $FILE_CANDIDATES" local FINAL_LIST="" for FILE in $FILE_CANDIDATES; do local TESTFILE="$(readlink -f "$FILE")" pdebug " $FILE leads to $TESTFILE" [ -f "$TESTFILE" -a -x "$TESTFILE" ] && [ "x$(grep -l -E '^(.ELF|#!)' "$TESTFILE")" != "x" ] && FINAL_LIST="$FINAL_LIST $FILE" done FINAL_LIST=$(trim "$FINAL_LIST") pdebug " Final list is $FINAL_LIST" if [ -z "$FINAL_LIST" ]; then pwarning "\tNo Binary found for ${FILENAME}. Skipping." continue fi if [[ "$FINAL_LIST" == *" "* ]]; then pwarning "Found more than one match for required file '$FILENAME': $FINAL_LIST" else pdebug "\tFound ${FILENAME} at ${FILE}" fi for FILE in $FINAL_LIST; do get_link_chain "${TOOL_DIR}/${TOOL}/build/${FILE}" "${TOOL_DIR}/${TOOL}/build" >> "${COPYFILES_LIST}" get_dynamic_dependencies -l "${TOOL_DIR}/${TOOL}/build" "${FILE}" >> "${COPYFILES_LIST}" done done [ ! -z "${REQUIRED_LIBRARIES}" ] && pinfo "Gathering required libraries from config file..." for LIB in ${REQUIRED_LIBRARIES} do for LOCATION in $(find . -name ${LIB}.so\*) do pdebug "* $LOCATION" get_link_chain "${TOOL_DIR}/${TOOL}/build/${LOCATION}" "${TOOL_DIR}/${TOOL}/build" >> "${COPYFILES_LIST}" get_dynamic_dependencies -l "${TOOL_DIR}/${TOOL}/build" "${LOCATION}" >> "${COPYFILES_LIST}" done done [ ! -z "${REQUIRED_DIRECTORIES}" ] && pinfo "Gathering required directories from config file..." local CURRENT_PWD=$(pwd) # Prevent calling pwd 50000 times inside the loop below for ENTRY in ${REQUIRED_DIRECTORIES} do pdebug "* ./$ENTRY" echo "./${ENTRY}" >> "${COPYFILES_LIST}" for BIN in $(find "./${ENTRY}" -type f -not -name '*.a' | xargs grep -l '^.ELF') do pdebug " Searching libs for ${BIN}..." get_link_chain "${TOOL_DIR}/${TOOL}/build/${BIN}" "${TOOL_DIR}/${TOOL}/build" >> "${COPYFILES_LIST}" get_dynamic_dependencies -l "${TOOL_DIR}/${TOOL}/build" "${BIN}" >> "${COPYFILES_LIST}" done done [ ! -z "${REQUIRED_FILES}" ] && pinfo "Gathering required files from config file..." for ENTRY in ${REQUIRED_FILES} do get_link_chain "${TOOL_DIR}/${TOOL}/build/${ENTRY}" "${TOOL_DIR}/${TOOL}/build" >> "${COPYFILES_LIST}" get_dynamic_dependencies -l "${TOOL_DIR}/${TOOL}/build" "${TOOL_DIR}/${TOOL}/build/.${ENTRY}" >> "${COPYFILES_LIST}" done #copy to initramfsdir pdebug "[stage32] Completed file list generation at ${TOOL_DIR}/${TOOL}/build/${COPYFILES_LIST}." if [ -s "$COPYFILES_LIST" ]; then local CLISTCOUNT=$(cat "$COPYFILES_LIST" | wc -l) pinfo "Copying $CLISTCOUNT files to stage 3.2 target directory." tarcopy "$(cat "$COPYFILES_LIST"|sort -u)" "${INIT_DIR}" fi } generate_stage32 () { initial_checks tarcopy "$(list_basic_libs)" "${INIT_DIR}" # if no arguments assume all. if [ "x$1" = "x" -o "x$1" = "xall" ]; then tools=$(ls ${TOOL_DIR}) set -- $tools fi # now iterate over given tools and copy them while (( "$#" )); do process_module "$1" shift done TOOL_STR="" } process_module() { [ "$#" -ne "1" ] && perror "process_module: want 1 param." local TOOL="$1" [[ "$PROCESSED_MODULES" == *"!${TOOL}!"* ]] && return # Already processed this module PROCESSED_MODULES="${PROCESSED_MODULES}!${TOOL}!" local TOOL_STR="" pinfo ">>>>>>>>>>>>>>>>> Processing module [ $TOOL ]" TOOL_STR="[${TOOL}]" if [ -d "${TOOL_DIR}/${TOOL}" ]; then #[ "x$DEBUG" != "x1" ] \ # && echo "Logging to ${TOOL_DIR}/${TOOL}/stage32.log" \ # && exec 6>&1 > ${TOOL_DIR}/${TOOL}/stage32.log # TODO: Make above work with the new logging system (add function to logging.inc to switch logfile) cd "${TOOL_DIR}/${TOOL}" || perror "Tool dir '${TOOL_DIR}/${TOOL}' seems to exist, but cd to it failed." pinfo "## Reading config" read_config # Check if this module has a dependency that wasn't built yet: if [ ! -z "$REQUIRED_MODULES" ]; then pinfo "$TOOL depends on ${REQUIRED_MODULES}...." for DEP in $REQUIRED_MODULES; do #[[ "$DESIRED_MODULES" != *"!${DEP}!"* ]] && perror "$TOOL has dependency $DEP, but $DEP is not in current profile." process_module "$DEP" done # Read old config again, as it got overwritten by the deps cd "${TOOL_DIR}/${TOOL}" || perror "Tool dir '${TOOL_DIR}/${TOOL}' seems to exist, but cd to it failed (after building deps)." read_config pinfo "<<<<<<<<<<<<<<<<< Dependency modules processed, back to module [ $TOOL ]" fi pinfo "## Reading build" read_build pinfo "## Installing dependencies" install_dependencies pinfo "## Fetching source" fetch_source pinfo "## Building" build # remove *.la files as they might confuse libtool/linker of other tool packages find "${TOOL_DIR}/${TOOL}/build" -name '*.la' -exec rm -f {} \; pinfo "## Copying files with dependencies" copyfileswithdependencies pinfo "## Post copy" post_copy # reset pipes #[ "x$DEBUG" != "x1" ] && exec 1>&6 6>&- # TODO pinfo "Module completed." else perror "Tool directory for '$TOOL' not found." # maybe make this a warning instead of error? fi } clean_tools() { if [ "x$1" = "x" -o "x$1" = "xall" ]; then #clean all if [ -d ${INIT_DIR} ]; then rm -rf "${INIT_DIR}"/* || perror "Error deleting $INIT_DIR" fi for TOOL in $(ls ${TOOL_DIR}); do clean_tool $TOOL done else while (( "$#" )); do clean_tool $1 shift done fi } clean_tool() { TOOLDIR=${TOOL_DIR}/$1 pinfo "Cleaning '${TOOLDIR}'..." #[ -e ${TOOLDIR}/build/list_wanted_stage3.2 ] && cd ${INIT_DIR} \ # && xargs rm < ${TOOLDIR}/build/list_wanted_stage3.2 #[ -d ${TOOLDIR}/data ] && cd ${INIT_DIR} \ # && xargs rm < $(find ${TOOLDIR}/data -type f) if [ -e ${TOOLDIR}/.built ]; then rm "${TOOLDIR}/.built" || perror "Could not clear built flag" fi if [ -e ${TOOLDIR}/.fetched_source ]; then rm "${TOOLDIR}/.fetched_source" || perror "Could not clear fetched_source flag" fi if [ -d ${TOOLDIR}/build ]; then rm -rf "${TOOLDIR}/build" || perror "Could not delete build path" fi if [ -d ${TOOLDIR}/src ]; then rm -rf "${TOOLDIR}/src" || perror "Could not delete src path" fi if [ -e ${TOOLDIR}/list_binaries_and_files ]; then rm "${TOOLDIR}/list_binaries_and_files" || perror "Could not delete list_binaries_and_files" fi }