#!/usr/bin/env bash # Copyright (C) 2016 Paul Kocialkowski # Copyright (C) 2017 Andrew Robbins # # 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 . GLOBIGNORE=".:.." # This enables the shell option 'dotglob' as well. shopt -s nullglob extglob libreboot_usage() { local action local target printf '%s\n' "${executable} [action] [target] [arguments]" >&2 printf '\n%s\n' 'Generic project actions:' >&2 for action in "${PROJECT_ACTIONS_GENERIC[@]}"; do printf '%s\n' " ${action}" >&2 done printf '\n%s\n' 'Virtual project actions:' >&2 printf '%s\n' ' sources' printf '%s\n' ' produce' printf '%s\n' ' test' printf '\n%s\n' 'Project targets:' >&2 for target in "${root}/${PROJECTS}"/*; do if project_check "${target}"; then printf '%s\n' " ${target}" >&2 fi done printf '\n%s\n' 'Generic tool actions:' >&2 for action in "${TOOL_ACTIONS_GENERIC[@]}"; do printf '%s\n' " ${action}" >&2 done printf '\n%s\n' 'Tool targets:' >&2 for target in "${root}/${TOOLS}"/*; do if tool_check "${target}"; then printf '%s\n' " ${target}" >&2 fi done printf '\n%s\n' 'Environment variables:' >&2 printf '%s\n' ' PROJECTS_FORCE - Projects to always perform actions for' >&2 printf '%s\n' ' TOOLS_FORCE - Tools to always perform actions for' >&2 printf '%s\n' ' RELEASE_KEY - GPG key to use for release' >&2 printf '%s\n' ' VBOOT_KEYS_PATH - Path to the vboot keys' >&2 printf '%s\n' ' LIBFAKETIME_PATH - Path to the libfaketime shared library' >&2 printf '%s\n' ' TASKS - Number of simultaneous tasks to run' >&2 printf '%s\n' ' VERSION - Version string to use' >&2 printf '\n%s\n' 'Configuration files:' >&2 printf '%s\n' " ${BUILD_SYSTEM}.conf - Environment variables configuration" >&2 } libreboot_project() { action="$1" shift project="$1" shift case "${action}" in 'sources') if project_action_arguments 'extract' "${project}" "$@"; then return else printf '\n%s\n\n' 'Attempting to download instead...' project_action_arguments 'download' "${project}" "$@" fi ;; 'produce') for action in 'build' 'install' 'release'; do project_action_arguments "${action}" "${project}" "$@" done ;; 'test') for action in "${PROJECT_ACTIONS[@]}"; do project_action_arguments "${action}" "${project}" "$@" done ;; *) if ! project_function_check "${project}" "${action}"; then libreboot_usage exit 1 elif [[ "${action}" == 'usage' ]]; then project_action "${action}" "${project}" "$@" else project_action_arguments "${action}" "${project}" "$@" fi ;; esac } libreboot_tool() { action="$1" shift tool="$1" shift if ! tool_function_check "${tool}" "${action}"; then libreboot_usage exit 1 elif [[ "${action}" == 'usage' ]]; then tool_action "${action}" "${tool}" "$@" else tool_action_arguments_recursive "${action}" "${tool}" "$@" fi } libreboot_setup() { root="$(readlink -f "$(dirname "$0")")" executable="$(basename "$0")" libreboot_setup_include libreboot_setup_tool_actions libreboot_setup_project_actions requirements 'tar' 'sed' 'gpg' 'sha256sum' 'git' libreboot_setup_variables } libreboot_setup_include() { local libs_path="${root}/libs" local conf_path source "${libs_path}/project" source "${libs_path}/tool" source "${libs_path}/common" source "${libs_path}/git" conf_path="${root}/${BUILD_SYSTEM}.conf" if [[ -f "${conf_path}" ]]; then source "${conf_path}" fi } libreboot_setup_tool_actions() { local -i tool_actions_count="${#TOOL_ACTIONS_GENERIC[@]}" local ignore="${TOOL_ACTIONS_GENERIC_IGNORE_CHECK[*]}" local -a tool_actions for ((i=0; i<"${tool_actions_count}"; i++)); do tool_actions+=("${TOOL_ACTIONS_GENERIC[i]}") if [[ "${TOOL_ACTIONS_GENERIC[i]}" == !(${ignore// /|}) ]]; then tool_actions+=("${TOOL_ACTIONS_GENERIC[i]/%/_check}") fi done TOOL_ACTIONS=("${TOOL_ACTIONS_HELPERS[@]}" "${tool_actions[@]}") } libreboot_setup_project_actions() { local -i project_actions_count="${#PROJECT_ACTIONS_GENERIC[@]}" local ignore="${PROJECT_ACTIONS_GENERIC_IGNORE_CHECK[*]}" local -a project_actions for ((i=0; i<"${project_actions_count}"; i++)); do project_actions+=("${PROJECT_ACTIONS_GENERIC[i]}") if [[ "${PROJECT_ACTIONS_GENERIC[i]}" == !(${ignore// /|}) ]]; then project_actions+=("${PROJECT_ACTIONS_GENERIC[i]/%/_check}") fi done PROJECT_ACTIONS=("${PROJECT_ACTIONS_HELPERS[@]}" "${project_actions[@]}") } libreboot_setup_variables() { local vboot_tools_path="$(project_install_path 'vboot' 'tools')" local version_path="${root}/${DOTVERSION}" if [[ -z "${VERSION}" ]]; then if git_check "${root}"; then VERSION="${BUILD_SYSTEM}-$(git_describe "${root}" 2> /dev/null || echo 'git')" elif [[ -f "${version_path}" ]]; then VERSION="$(< "${version_path}")" else VERSION="${BUILD_SYSTEM}" fi fi if [[ -d "${vboot_tools_path}/devkeys/" ]]; then VBOOT_KEYS_PATH="${VBOOT_KEYS_PATH:-${vboot_tools_path}/devkeys/}" fi libreboot_setup_reproducible_builds_variables } libreboot_setup_reproducible_builds_variables() { local epoch_path="${root}/${DOTEPOCH}" local rnd_seed_path="${root}/${DOTRNDSEED}" # Used by GCC, e.g., -frandom-seed="${RANDOM_SEED}" if [[ -z "${RANDOM_SEED}" ]]; then if [[ -f "${rnd_seed_path}" ]]; then RANDOM_SEED="$(< "${rnd_seed_path}")" else RANDOM_SEED="${RANDOM}" # True randomness is unnecessary fi fi # Also used by GCC, but as an environment variable if [[ -z "${SOURCE_DATE_EPOCH}" ]]; then if git_check "${root}"; then SOURCE_DATE_EPOCH="$(git log -1 --format=%ct)" elif [[ -f "${epoch_path}" ]]; then SOURCE_DATE_EPOCH="$(< "${epoch_path}")" else SOURCE_DATE_EPOCH="$(date +%s)" fi fi # Relevant only when libfaketime is preloaded if [[ -n "${LIBFAKETIME_PATH}" ]]; then BUILD_DATE_FMT="%Y-%m-%d %H:%M:%S" BUILD_DATE="$(date -u -d "@${SOURCE_DATE_EPOCH}" "+${BUILD_DATE_FMT}" 2>/dev/null || date -u -r "${SOURCE_DATE_EPOCH}" "+${BUILD_DATE_FMT}" 2>/dev/null || date -u "+${BUILD_DATE_FMT}")" FAKETIME="@${BUILD_DATE}" LC_ALL='C.UTF-8' LD_PRELOAD="${LIBFAKETIME_PATH}" TZ='UTC' fi } libreboot() { action="$1" shift target="$1" shift set -e libreboot_setup "$@" if project_check "${target}"; then libreboot_project "${action}" "${target}" "$@" elif tool_check "${target}"; then libreboot_tool "${action}" "${target}" "$@" else libreboot_usage exit 1 fi } libreboot "$@"