#!/usr/bin/env bash # Copyright (C) 2016 Paul Kocialkowski # # 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 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") ( set +e project_action_arguments "extract" "${project}" "$@" && return 0 project_action_arguments "download" "${project}" "$@" && return 0 ) ;; "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 case ${action} in *) if ! tool_function_check "${tool}" "${action}"; then libreboot_usage exit 1 fi if [[ "${action}" == "usage" ]]; then tool_action "${action}" "${tool}" "$@" else tool_action_arguments_recursive "${action}" "${tool}" "$@" fi ;; esac } libreboot_setup() { root="$(readlink -f "$(dirname "$0")")" executable="$(basename "$0")" local requirements="git" local requirement_path libreboot_setup_include libreboot_setup_variables for requirement in ${requirements}; do requirement_path="$(which "${requirement}" || true)" if [[ -z "${requirement_path}" ]]; then printf '%s\n' "Missing requirement: ${requirement}" >&2 exit 1 fi done } 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_variables() { local vboot_tools_path="$(project_install_path 'vboot' 'tools')" local version_path="${root}/${DOTVERSION}" 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="$(cat "${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="$(cat "${epoch_path}")" else SOURCE_DATE_EPOCH="$(date +%s)" fi fi 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="$(cat "${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 CONFIG_SHELL="${CONFIG_SHELL:-$(which bash)}" EDITOR="${EDITOR:-$(which vi || true)}" TASKS="${TASKS:-1}" # Environment variables useful for creating reproducible builds 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 [[ -z "${action}" ]] || [[ -z "${target}" ]]; then libreboot_usage exit 1 fi requirements 'tar' 'sed' 'gpg' 'sha256sum' 'wget' 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 "$@"