aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Prichard <rprichard@google.com>2021-10-06 23:31:42 -0700
committerRyan Prichard <rprichard@google.com>2021-10-07 19:42:45 -0700
commit6f2186add9a49d51c539fd80f054908e15aadf7a (patch)
tree192ac53b2d22d3a02aa17277483e8adc8ce58e97
parent8a5cfc2750cab37ca28025ed6bc5604032ce2e60 (diff)
downloadninja-6f2186add9a49d51c539fd80f054908e15aadf7a.tar.gz
Build ninja using Kokoro
This script builds ninja on Linux, Windows, and macOS. It produces a zip file containing: * ninja[.exe] * ninja/COPYING (the Apache2 license) On Windows, this script builds the binary using the "Visual Studio 15 2017 Win64" generator. ninja's CMakeLists.txt file sets CMAKE_MSVC_RUNTIME_LIBRARY to MultiThreaded (as opposed to MultiThreadedDLL), so ninja.exe depends only on kernel32.dll. On macOS, this script targets 10.9 and up, and generates a universal arm64+x86_64 binary. On Linux, this script uses g++ 4.8 from CentOS 7 and links with -static-libstdc++. This script runs the ninja tests (ninja_test[.exe]), which complete in just a few seconds. Bug: https://github.com/android/ndk/issues/1548 Test: kokoro/kokoro_build.cmd Test: kokoro/kokoro_build.sh (on Linux and macOS) Change-Id: If4f7055d8791a5b8687fac14356f59350ae894a4
-rw-r--r--kokoro/Dockerfile8
-rwxr-xr-xkokoro/build.py147
-rw-r--r--kokoro/common.cfg9
-rw-r--r--kokoro/darwin.cfg3
-rw-r--r--kokoro/kokoro_build.cmd2
-rwxr-xr-xkokoro/kokoro_build.sh17
-rw-r--r--kokoro/linux.cfg3
-rw-r--r--kokoro/windows.cfg3
8 files changed, 192 insertions, 0 deletions
diff --git a/kokoro/Dockerfile b/kokoro/Dockerfile
new file mode 100644
index 0000000..13af4a1
--- /dev/null
+++ b/kokoro/Dockerfile
@@ -0,0 +1,8 @@
+FROM centos:7
+
+RUN yum -y update && \
+ yum -y install \
+ gcc-c++ \
+ git \
+ libstdc++-static \
+ python3
diff --git a/kokoro/build.py b/kokoro/build.py
new file mode 100755
index 0000000..b61896e
--- /dev/null
+++ b/kokoro/build.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 The Android Open Source Project
+#
+# 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
+#
+# http://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.
+
+import enum
+import os
+from pathlib import Path
+import shlex
+import shutil
+import subprocess
+import sys
+from typing import List, Union
+import zipfile
+
+
+NINJA_SRC = Path(__file__).parent.parent
+TOP = NINJA_SRC.parent.parent
+
+
+@enum.unique
+class Host(enum.Enum):
+ """Enumeration of supported hosts."""
+ Darwin = 'darwin'
+ Linux = 'linux'
+ Windows = 'windows'
+
+
+def get_default_host() -> Host:
+ """Returns the Host matching the current machine."""
+ if sys.platform.startswith('linux'):
+ return Host.Linux
+ if sys.platform.startswith('darwin'):
+ return Host.Darwin
+ if sys.platform.startswith('win'):
+ return Host.Windows
+ raise RuntimeError(f'Unsupported host: {sys.platform}')
+
+
+
+def create_new_dir(path: Path) -> None:
+ if path.exists():
+ shutil.rmtree(path)
+ path.mkdir(parents=True)
+
+
+def run_cmd(args: List[Union[str, Path]], cwd: Path = None) -> None:
+ if cwd is not None:
+ print(f'cd {cwd}')
+ str_args = [str(arg) for arg in args]
+ if get_default_host() == Host.Windows:
+ print(subprocess.list2cmdline(str_args))
+ else:
+ print(' '.join([shlex.quote(arg) for arg in str_args]))
+ sys.stdout.flush()
+ subprocess.run(str_args, cwd=cwd, check=True)
+
+
+def zip_dir(root: Path, out_file: Path) -> None:
+ """Zip a folder with archive paths relative to the root"""
+ with zipfile.ZipFile(out_file, 'w', zipfile.ZIP_DEFLATED) as zip_obj:
+ for parent, _, files in os.walk(root):
+ for file in files:
+ install_file = Path(parent) / file
+ rel_file = install_file.relative_to(root)
+ zip_obj.write(install_file, rel_file)
+
+
+def main() -> None:
+ host = get_default_host()
+ exe = '.exe' if host == Host.Windows else ''
+
+ out = TOP / 'out/ninja'
+ create_new_dir(out)
+ create_new_dir(out / 'build')
+ create_new_dir(out / 'artifact')
+
+ prebuilt_cmake = TOP / f'prebuilts/cmake/{host.value}-x86/bin/cmake{exe}'
+ prebuilt_ninja = TOP / f'prebuilts/ninja/{host.value}-x86/ninja{exe}'
+
+ cmake_conf_args: List[Union[str, Path]] = [
+ prebuilt_cmake,
+ NINJA_SRC,
+ '-B', out / 'build',
+ ]
+ cmake_build_args: List[Union[str, Path]] = [
+ prebuilt_cmake,
+ '--build', out / 'build',
+ '--parallel',
+ '--config', 'Release',
+ ]
+
+ if host == Host.Windows:
+ cmake_conf_args += ['-G', 'Visual Studio 15 2017 Win64']
+ else:
+ # Use the Multi-Config generator for consistency with MSVC, which is also multi-config.
+ # (e.g. "--config Release" replaces CMAKE_BUILD_TYPE, and there is a "Release" subdir.)
+ cmake_conf_args += [
+ '-G', 'Ninja Multi-Config',
+ f'-DCMAKE_MAKE_PROGRAM={prebuilt_ninja}',
+ ]
+ if host == Host.Linux:
+ ldflags = '-static-libstdc++'
+ cmake_conf_args += [
+ f'-DCMAKE_EXE_LINKER_FLAGS={ldflags}',
+ f'-DCMAKE_SHARED_LINKER_FLAGS={ldflags}',
+ ]
+ elif host == Host.Darwin:
+ cmake_conf_args += [
+ '-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9',
+ '-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64',
+ ]
+
+ run_cmd(cmake_conf_args)
+ run_cmd(cmake_build_args)
+
+ ninja_bin = out / f'build/Release/ninja{exe}'
+ if host != Host.Windows:
+ run_cmd(['strip', ninja_bin])
+
+ create_new_dir(out / 'install')
+ shutil.copy2(ninja_bin, out / 'install')
+ shutil.copy2(NINJA_SRC / 'COPYING', out / 'install')
+
+ build_id = os.getenv('KOKORO_BUILD_ID', 'dev')
+ zip_dir(out / 'install', out / f'artifact/ninja-{build_id}.zip')
+ run_cmd([sys.executable, TOP / 'toolchain/ndk-kokoro/gen_manifest.py',
+ '--root', TOP, '-o', out / f'artifact/manifest-{build_id}.xml'])
+
+ # The ninja tests complete in just a few seconds, so run them during the build. Wait until the
+ # end so we can collect artifacts if a test fails.
+ run_cmd([out / f'build/Release/ninja_test{exe}'], cwd=out / 'build')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/kokoro/common.cfg b/kokoro/common.cfg
new file mode 100644
index 0000000..16dbc91
--- /dev/null
+++ b/kokoro/common.cfg
@@ -0,0 +1,9 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+action {
+ define_artifacts {
+ regex: "git/out/ninja/artifact/*"
+ strip_prefix: "git/out/ninja/artifact/"
+ fail_if_no_artifacts: true
+ }
+}
diff --git a/kokoro/darwin.cfg b/kokoro/darwin.cfg
new file mode 100644
index 0000000..5569592
--- /dev/null
+++ b/kokoro/darwin.cfg
@@ -0,0 +1,3 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+build_file: "git/external/ninja/kokoro/kokoro_build.sh"
diff --git a/kokoro/kokoro_build.cmd b/kokoro/kokoro_build.cmd
new file mode 100644
index 0000000..f246076
--- /dev/null
+++ b/kokoro/kokoro_build.cmd
@@ -0,0 +1,2 @@
+setlocal
+py -3 %~dp0build.py
diff --git a/kokoro/kokoro_build.sh b/kokoro/kokoro_build.sh
new file mode 100755
index 0000000..2aca7c5
--- /dev/null
+++ b/kokoro/kokoro_build.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+set -e
+
+top=$(cd $(dirname $0)/../../.. && pwd)
+ninja_src=$top/external/ninja
+
+# On Linux, enter the Docker container and reinvoke this script.
+if [ "$(uname)" == "Linux" -a "$SKIP_DOCKER" == "" ]; then
+ docker build -t ndk-ninja $ninja_src/kokoro
+ export SKIP_DOCKER=1
+ docker run -v$top:$top -eKOKORO_BUILD_ID -eSKIP_DOCKER \
+ --entrypoint $ninja_src/kokoro/kokoro_build.sh \
+ ndk-ninja
+ exit $?
+fi
+
+$ninja_src/kokoro/build.py
diff --git a/kokoro/linux.cfg b/kokoro/linux.cfg
new file mode 100644
index 0000000..5569592
--- /dev/null
+++ b/kokoro/linux.cfg
@@ -0,0 +1,3 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+build_file: "git/external/ninja/kokoro/kokoro_build.sh"
diff --git a/kokoro/windows.cfg b/kokoro/windows.cfg
new file mode 100644
index 0000000..4b6d754
--- /dev/null
+++ b/kokoro/windows.cfg
@@ -0,0 +1,3 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+build_file: "git/external/ninja/kokoro/kokoro_build.cmd"