Update build scripts to work under Kokoro+Repo
Kokoro does not support <linkfile> tags. That means two workarounds are
needed:
(a) build.sh is called as "./core/kokoro" (not "./kokoro") and therefore
must adjust ROOT_DIR location - done by checking for presence of
"../.repo_manifest" folder
(b) build.sh must first symlink files specified in <linkfile> tags of
the manifest - done by a Python script
Move init logic like this to a .inc file that can be shared between
build scripts for different projects.
Change-Id: I4d632c7200d34d08981e58d290883bd2cd9e5a04
diff --git a/build/bash/common.inc b/build/bash/common.inc
new file mode 100644
index 0000000..4d7bd73
--- /dev/null
+++ b/build/bash/common.inc
@@ -0,0 +1,130 @@
+# Copyright 2019 The Hafnium Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Fail on any error.
+set -e
+# Fail on any part of a pipeline failing.
+set -o pipefail
+# Treat unset variables as an error.
+set -u
+# Display commands being run.
+set -x
+
+# Returns absolute path to a file or a directory. The path must exist.
+function abs_path() {
+ local rel_path="$1"
+ if [ -d "$rel_path" ]
+ then
+ # Parameter is a directory
+ local rel_dir="$rel_path"
+ local rel_base=""
+ elif [ -f "$rel_path" ]
+ then
+ # Parameter is a regular file
+ local rel_dir="$(dirname "$rel_path")"
+ local rel_base="/$(basename "$rel_path")"
+ else
+ # File does not exist
+ echo "File not found: $rel_path" >&2
+ exit 1
+ fi
+ echo "$(cd $rel_dir && pwd)$rel_base"
+ return 0
+}
+
+# Returns true if the environment contains Kokoro build variables.
+function is_kokoro_build() {
+ [ -v KOKORO_JOB_NAME ]
+ return $?
+}
+
+# Returns true if the `.repo_manifest` folder exists. The folder should contain
+# the manifest and be present in all Repo builds. Eventually this should be
+# obsolete as we switch exclusively to Repo.
+function is_repo_build() {
+ [ -d "${ROOT_DIR}/.repo_manifest" ]
+ return $?
+}
+
+# Returns absolute path to the source file that called this function.
+function get_script_path() {
+ abs_path "${BASH_SOURCE[1]}"
+}
+
+# Returns absolute path to the directory containing the source file that called
+# this function.
+function get_script_dir() {
+ local caller_path="${BASH_SOURCE[1]}"
+ local caller_abs_path="$(abs_path $caller_path)"
+ dirname "$caller_abs_path"
+}
+
+# Assigns value (second arg) of a variable (first arg) if it is not set already.
+function default_value {
+ local var_name=$1
+ local value=$2
+ export ${var_name}=${!var_name:-${value}}
+}
+
+# Returns true if `git status` reports uncommitted changes in the source tree.
+# Runs on all projects if Repo is detected.
+function is_repo_dirty() {
+ local cmd=(git status --porcelain=v1)
+ if is_repo_build
+ then
+ # This source tree was checked out using `repo`. Check the
+ # status of all projects.
+ cmd=(${REPO} forall -c "${cmd[@]}")
+ fi
+ ! (u="$(${cmd[@]})" && test -z "$u")
+ return $?
+}
+
+# Prepares the source directory for building. This includes setting global
+# variables and workaronuds for different build environments.
+function init_build() {
+ ##
+ ## Find Hafnium's root directory.
+ ##
+ ROOT_DIR="$(abs_path $(get_script_dir)/../..)"
+ # Temporary workaround for Repo builds. Check if there is a project
+ # folder specific to Repo builds in a parent directory. If it is, the
+ # root is further one level up.
+ if [ -d "${ROOT_DIR}/../.repo_manifest" ]
+ then
+ ROOT_DIR="$(dirname ${ROOT_DIR})"
+ fi
+
+ ##
+ ## Paths to tools
+ ##
+ CLANG="${ROOT_DIR}/prebuilts/linux-x64/clang/bin/clang"
+ REPO="${ROOT_DIR}/prebuilts/generic/repo/repo"
+
+ ##
+ ## Workarounds for Kokoro+Repo builds.
+ ##
+ if is_kokoro_build && is_repo_build
+ then
+ # Kokoro does not correctly initialize the `.repo` folder which
+ # causes `is_repo_dirty` checks to fail. We check out the
+ # manifest as one of the projects and use it to initialize the
+ # `.repo` folder here.
+ (cd "${ROOT_DIR}/.repo_manifest" && git branch master)
+ (cd "${ROOT_DIR}" && "${REPO}" init -u .repo_manifest)
+ # Kokoro does not support '<linkfile>' manifest tags. Parse the
+ # manifest and symlink files here.
+ "$(get_script_dir)/symlink_repo.py" "${ROOT_DIR}"
+ fi
+}
diff --git a/build/bash/symlink_repo.py b/build/bash/symlink_repo.py
new file mode 100755
index 0000000..eefa46b
--- /dev/null
+++ b/build/bash/symlink_repo.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+#
+# Copyright 2019 The Hafnium Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Parse Repo manifest and symlink files specified in <linkfile> tags.
+
+This is a workaround for Kokoro which does not support <linkfile>.
+"""
+
+import argparse
+import os
+import sys
+import xml.etree.ElementTree as ET
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("root_dir", help="root directory")
+ args = parser.parse_args()
+
+ manifest = os.path.join(args.root_dir, ".repo", "manifest.xml")
+ tree = ET.parse(manifest)
+ root = tree.getroot()
+ assert(root.tag == "manifest");
+
+ for proj in root:
+ if proj.tag != "project":
+ continue
+
+ proj_name = proj.attrib["name"]
+ proj_path = proj.attrib["path"]
+
+ for linkfile in proj:
+ if linkfile.tag != "linkfile":
+ continue
+
+ linkfile_src = linkfile.attrib["src"]
+ linkfile_dest = linkfile.attrib["dest"]
+ src_path = os.path.join(
+ args.root_dir, proj_path, linkfile_src)
+ dest_path = os.path.join(args.root_dir, linkfile_dest)
+
+ os.symlink(src_path, dest_path)
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/kokoro/build.sh b/kokoro/build.sh
index 4c65e41..db81d6e 100755
--- a/kokoro/build.sh
+++ b/kokoro/build.sh
@@ -14,43 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-SCRIPT_PATH="${SCRIPT_DIR}/$(basename "${BASH_SOURCE[0]}")"
-ROOT_DIR="$(dirname "${SCRIPT_DIR}")"
+source "$(dirname ${BASH_SOURCE[0]})/../build/bash/common.inc"
-REPO="${ROOT_DIR}/prebuilts/generic/repo/repo"
-
-# Fail on any error.
-set -e
-# Fail on any part of a pipeline failing.
-set -o pipefail
-# Treat unset variables as an error.
-set -u
-# Display commands being run.
-set -x
-
-# Returns true if `git status` reports uncommitted changes in the source tree.
-function is_repo_dirty() {
- local cmd=(git status --porcelain=v1)
- if [ -d ".repo" ]
- then
- # This source tree was checked out using `repo`. Check the
- # status of all projects.
- cmd=(${REPO} forall -c "${cmd[@]}")
- fi
- ! (u="$(${cmd[@]})" && test -z "$u")
- return $?
-}
-
-# Assigns value (second arg) of a variable (first arg) if it is not set already.
-function default_value {
- local var_name=$1
- local value=$2
- export ${var_name}=${!var_name:-${value}}
-}
+# Initialize global variables, prepare repo for building.
+init_build
# Assign default values to variables.
-if [ -v KOKORO_JOB_NAME ]
+if is_kokoro_build
then
# Default config for Kokoro builds.
default_value HAFNIUM_HERMETIC_BUILD true
@@ -68,7 +38,7 @@
# avoid recursion.
if [ "${HAFNIUM_HERMETIC_BUILD}" == "true" ]
then
- exec "${ROOT_DIR}/build/run_in_container.sh" ${SCRIPT_PATH} $@
+ exec "${ROOT_DIR}/build/run_in_container.sh" "$(get_script_path)" $@
fi
USE_FVP=false
@@ -93,8 +63,6 @@
shift
done
-CLANG=${PWD}/prebuilts/linux-x64/clang/bin/clang
-
# Kokoro does something weird that makes all files look dirty to git diff-index;
# this fixes it so that the Linux build doesn't think it has a dirty tree for
# building the Hafnium kernel module (and so end up with a version magic string
@@ -184,5 +152,5 @@
export ARCH=arm64 &&
export CROSS_COMPILE=aarch64-linux-gnu- &&
cd driver/linux &&
-make checkpatch
+make HAFNIUM_PATH="${ROOT_DIR}" checkpatch
)
diff --git a/kokoro/public/presubmit.cfg b/kokoro/public/presubmit.cfg
index 9bb14aa..d71b9c7 100644
--- a/kokoro/public/presubmit.cfg
+++ b/kokoro/public/presubmit.cfg
@@ -1,7 +1,7 @@
# Format: //devtools/kokoro/config/proto/build.proto
# Location of the presubmit bash script in Git.
-build_file: "git/kokoro/build.sh"
+build_file: "git/core/kokoro/build.sh"
action {
define_artifacts {