diff options
author | Ryan Prichard <rprichard@google.com> | 2021-10-06 23:31:42 -0700 |
---|---|---|
committer | Ryan Prichard <rprichard@google.com> | 2021-10-07 19:42:45 -0700 |
commit | 6f2186add9a49d51c539fd80f054908e15aadf7a (patch) | |
tree | 192ac53b2d22d3a02aa17277483e8adc8ce58e97 | |
parent | 8a5cfc2750cab37ca28025ed6bc5604032ce2e60 (diff) | |
download | ninja-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/Dockerfile | 8 | ||||
-rwxr-xr-x | kokoro/build.py | 147 | ||||
-rw-r--r-- | kokoro/common.cfg | 9 | ||||
-rw-r--r-- | kokoro/darwin.cfg | 3 | ||||
-rw-r--r-- | kokoro/kokoro_build.cmd | 2 | ||||
-rwxr-xr-x | kokoro/kokoro_build.sh | 17 | ||||
-rw-r--r-- | kokoro/linux.cfg | 3 | ||||
-rw-r--r-- | kokoro/windows.cfg | 3 |
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" |