Add LunaSVG
This commit is contained in:
@ -0,0 +1,463 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (C) 2016 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.
|
||||
#
|
||||
"""Creates a toolchain installation for a given Android target.
|
||||
|
||||
THIS TOOL IS OBSOLETE. It is no longer necessary to create a separate toolchain for use
|
||||
with build systems that lack explicit NDK support. The compiler installed to
|
||||
<NDK>/toolchains/llvm/prebuilt/<host>/bin can be used directly. See
|
||||
https://developer.android.com/ndk/guides/other_build_systems for more details.
|
||||
"""
|
||||
import argparse
|
||||
import atexit
|
||||
import inspect
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import stat
|
||||
import sys
|
||||
import tempfile
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
THIS_DIR = os.path.realpath(os.path.dirname(__file__))
|
||||
NDK_DIR = os.path.realpath(os.path.join(THIS_DIR, "../.."))
|
||||
|
||||
|
||||
def logger():
|
||||
"""Return the main logger for this module."""
|
||||
return logging.getLogger(__name__)
|
||||
|
||||
|
||||
def check_ndk_or_die():
|
||||
"""Verify that our NDK installation is somewhat present or die."""
|
||||
checks = [
|
||||
"build/core",
|
||||
"prebuilt",
|
||||
"toolchains",
|
||||
]
|
||||
|
||||
for check in checks:
|
||||
check_path = os.path.join(NDK_DIR, check)
|
||||
if not os.path.exists(check_path):
|
||||
sys.exit("Missing {}".format(check_path))
|
||||
|
||||
|
||||
def get_triple(arch):
|
||||
"""Return the triple for the given architecture."""
|
||||
return {
|
||||
"arm": "arm-linux-androideabi",
|
||||
"arm64": "aarch64-linux-android",
|
||||
"riscv64": "riscv64-linux-android",
|
||||
"x86": "i686-linux-android",
|
||||
"x86_64": "x86_64-linux-android",
|
||||
}[arch]
|
||||
|
||||
|
||||
def arch_to_abi(arch: str) -> str:
|
||||
"""Return the ABI name for the given architecture."""
|
||||
return {
|
||||
"arm": "armeabi-v7a",
|
||||
"arm64": "arm64-v8a",
|
||||
"riscv64": "riscv64",
|
||||
"x86": "x86",
|
||||
"x86_64": "x86_64",
|
||||
}[arch]
|
||||
|
||||
|
||||
def get_host_tag_or_die():
|
||||
"""Return the host tag for this platform. Die if not supported."""
|
||||
if sys.platform.startswith("linux"):
|
||||
return "linux-x86_64"
|
||||
elif sys.platform == "darwin":
|
||||
return "darwin-x86_64"
|
||||
elif sys.platform == "win32" or sys.platform == "cygwin":
|
||||
return "windows-x86_64"
|
||||
sys.exit("Unsupported platform: " + sys.platform)
|
||||
|
||||
|
||||
def get_toolchain_path_or_die(host_tag):
|
||||
"""Return the toolchain path or die."""
|
||||
toolchain_path = os.path.join(NDK_DIR, "toolchains/llvm/prebuilt", host_tag)
|
||||
if not os.path.exists(toolchain_path):
|
||||
sys.exit("Could not find toolchain: {}".format(toolchain_path))
|
||||
return toolchain_path
|
||||
|
||||
|
||||
def make_clang_target(triple, api):
|
||||
"""Returns the Clang target for the given GNU triple and API combo."""
|
||||
arch, os_name, env = triple.split("-")
|
||||
if arch == "arm":
|
||||
arch = "armv7a" # Target armv7, not armv5.
|
||||
|
||||
return "{}-{}-{}{}".format(arch, os_name, env, api)
|
||||
|
||||
|
||||
def make_clang_scripts(install_dir, arch, api, windows):
|
||||
"""Creates Clang wrapper scripts.
|
||||
|
||||
The Clang in standalone toolchains historically was designed to be used as
|
||||
a drop-in replacement for GCC for better compatibility with existing
|
||||
projects. Since a large number of projects are not set up for cross
|
||||
compiling (and those that are expect the GCC style), our Clang should
|
||||
already know what target it is building for.
|
||||
|
||||
Create wrapper scripts that invoke Clang with `-target` and `--sysroot`
|
||||
preset.
|
||||
"""
|
||||
with open(os.path.join(install_dir, "AndroidVersion.txt")) as version_file:
|
||||
first_line = version_file.read().strip().splitlines()[0]
|
||||
major, minor, _build = first_line.split(".")
|
||||
|
||||
version_number = major + minor
|
||||
|
||||
exe = ""
|
||||
if windows:
|
||||
exe = ".exe"
|
||||
|
||||
bin_dir = os.path.join(install_dir, "bin")
|
||||
shutil.move(
|
||||
os.path.join(bin_dir, "clang" + exe),
|
||||
os.path.join(bin_dir, "clang{}".format(version_number) + exe),
|
||||
)
|
||||
shutil.move(
|
||||
os.path.join(bin_dir, "clang++" + exe),
|
||||
os.path.join(bin_dir, "clang{}++".format(version_number) + exe),
|
||||
)
|
||||
|
||||
triple = get_triple(arch)
|
||||
target = make_clang_target(triple, api)
|
||||
flags = "-target {}".format(target)
|
||||
|
||||
# We only need mstackrealign to fix issues on 32-bit x86 pre-24. After 24,
|
||||
# this consumes an extra register unnecessarily, which can cause issues for
|
||||
# inline asm.
|
||||
# https://github.com/android-ndk/ndk/issues/693
|
||||
if arch == "i686" and api < 24:
|
||||
flags += " -mstackrealign"
|
||||
|
||||
cxx_flags = str(flags)
|
||||
|
||||
clang_path = os.path.join(install_dir, "bin/clang")
|
||||
with open(clang_path, "w") as clang:
|
||||
clang.write(
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
#!/usr/bin/env bash
|
||||
bin_dir=`dirname "$0"`
|
||||
if [ "$1" != "-cc1" ]; then
|
||||
"$bin_dir/clang{version}" {flags} "$@"
|
||||
else
|
||||
# target/triple already spelled out.
|
||||
"$bin_dir/clang{version}" "$@"
|
||||
fi
|
||||
""".format(
|
||||
version=version_number, flags=flags
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
mode = os.stat(clang_path).st_mode
|
||||
os.chmod(clang_path, mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
||||
|
||||
clangpp_path = os.path.join(install_dir, "bin/clang++")
|
||||
with open(clangpp_path, "w") as clangpp:
|
||||
clangpp.write(
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
#!/usr/bin/env bash
|
||||
bin_dir=`dirname "$0"`
|
||||
if [ "$1" != "-cc1" ]; then
|
||||
"$bin_dir/clang{version}++" {flags} "$@"
|
||||
else
|
||||
# target/triple already spelled out.
|
||||
"$bin_dir/clang{version}++" "$@"
|
||||
fi
|
||||
""".format(
|
||||
version=version_number, flags=cxx_flags
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
mode = os.stat(clangpp_path).st_mode
|
||||
os.chmod(clangpp_path, mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
||||
|
||||
shutil.copy2(
|
||||
os.path.join(install_dir, "bin/clang"),
|
||||
os.path.join(install_dir, "bin", triple + "-clang"),
|
||||
)
|
||||
shutil.copy2(
|
||||
os.path.join(install_dir, "bin/clang++"),
|
||||
os.path.join(install_dir, "bin", triple + "-clang++"),
|
||||
)
|
||||
|
||||
if windows:
|
||||
for pp_suffix in ("", "++"):
|
||||
is_cpp = pp_suffix == "++"
|
||||
exe_name = "clang{}{}.exe".format(version_number, pp_suffix)
|
||||
clangbat_text = textwrap.dedent(
|
||||
"""\
|
||||
@echo off
|
||||
setlocal
|
||||
call :find_bin
|
||||
if "%1" == "-cc1" goto :L
|
||||
|
||||
set "_BIN_DIR=" && "%_BIN_DIR%{exe}" {flags} %*
|
||||
if ERRORLEVEL 1 exit /b 1
|
||||
goto :done
|
||||
|
||||
:L
|
||||
rem target/triple already spelled out.
|
||||
set "_BIN_DIR=" && "%_BIN_DIR%{exe}" %*
|
||||
if ERRORLEVEL 1 exit /b 1
|
||||
goto :done
|
||||
|
||||
:find_bin
|
||||
rem Accommodate a quoted arg0, e.g.: "clang"
|
||||
rem https://github.com/android-ndk/ndk/issues/616
|
||||
set _BIN_DIR=%~dp0
|
||||
exit /b
|
||||
|
||||
:done
|
||||
""".format(
|
||||
exe=exe_name, flags=cxx_flags if is_cpp else flags
|
||||
)
|
||||
)
|
||||
|
||||
for triple_prefix in ("", triple + "-"):
|
||||
clangbat_path = os.path.join(
|
||||
install_dir, "bin", "{}clang{}.cmd".format(triple_prefix, pp_suffix)
|
||||
)
|
||||
with open(clangbat_path, "w") as clangbat:
|
||||
clangbat.write(clangbat_text)
|
||||
|
||||
|
||||
def replace_gcc_wrappers(install_path, triple, is_windows):
|
||||
cmd = ".cmd" if is_windows else ""
|
||||
|
||||
gcc = os.path.join(install_path, "bin", triple + "-gcc" + cmd)
|
||||
clang = os.path.join(install_path, "bin", "clang" + cmd)
|
||||
shutil.copy2(clang, gcc)
|
||||
|
||||
gpp = os.path.join(install_path, "bin", triple + "-g++" + cmd)
|
||||
clangpp = os.path.join(install_path, "bin", "clang++" + cmd)
|
||||
shutil.copy2(clangpp, gpp)
|
||||
|
||||
|
||||
def copytree(src, dst):
|
||||
# A Python invocation running concurrently with make_standalone_toolchain.py
|
||||
# can create a __pycache__ directory inside the src dir. Avoid copying it,
|
||||
# because it can be in an inconsistent state.
|
||||
shutil.copytree(
|
||||
src, dst, ignore=shutil.ignore_patterns("__pycache__"), dirs_exist_ok=True
|
||||
)
|
||||
|
||||
|
||||
def create_toolchain(install_path, arch, api, toolchain_path, host_tag):
|
||||
"""Create a standalone toolchain."""
|
||||
copytree(toolchain_path, install_path)
|
||||
triple = get_triple(arch)
|
||||
make_clang_scripts(install_path, arch, api, host_tag == "windows-x86_64")
|
||||
replace_gcc_wrappers(install_path, triple, host_tag == "windows-x86_64")
|
||||
|
||||
prebuilt_path = os.path.join(NDK_DIR, "prebuilt", host_tag)
|
||||
copytree(prebuilt_path, install_path)
|
||||
|
||||
|
||||
def warn_unnecessary(arch, api, host_tag):
|
||||
"""Emits a warning that this script is no longer needed."""
|
||||
if host_tag == "windows-x86_64":
|
||||
ndk_var = "%NDK%"
|
||||
prompt = "C:\\>"
|
||||
else:
|
||||
ndk_var = "$NDK"
|
||||
prompt = "$ "
|
||||
|
||||
target = make_clang_target(get_triple(arch), api)
|
||||
standalone_toolchain = os.path.join(
|
||||
ndk_var, "build", "tools", "make_standalone_toolchain.py"
|
||||
)
|
||||
toolchain_dir = os.path.join(
|
||||
ndk_var, "toolchains", "llvm", "prebuilt", host_tag, "bin"
|
||||
)
|
||||
old_clang = os.path.join("toolchain", "bin", "clang++")
|
||||
new_clang = os.path.join(toolchain_dir, target + "-clang++")
|
||||
|
||||
logger().warning(
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
THIS TOOL IS OBSOLETE. The {toolchain_dir} directory contains
|
||||
target-specific scripts that perform the same task. For example,
|
||||
instead of:
|
||||
|
||||
{prompt}python {standalone_toolchain} \\
|
||||
--arch {arch} --api {api} --install-dir toolchain
|
||||
{prompt}{old_clang} src.cpp
|
||||
|
||||
Instead use:
|
||||
|
||||
{prompt}{new_clang} src.cpp
|
||||
|
||||
See https://developer.android.com/ndk/guides/other_build_systems for more
|
||||
details.
|
||||
""".format(
|
||||
toolchain_dir=toolchain_dir,
|
||||
prompt=prompt,
|
||||
standalone_toolchain=standalone_toolchain,
|
||||
arch=arch,
|
||||
api=api,
|
||||
old_clang=old_clang,
|
||||
new_clang=new_clang,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def get_min_supported_api_level(arch: str) -> int:
|
||||
abis_json = Path(NDK_DIR) / "meta/abis.json"
|
||||
with abis_json.open(encoding="utf-8") as abis_file:
|
||||
data = json.load(abis_file)
|
||||
return int(data[arch_to_abi(arch)]["min_os_version"])
|
||||
|
||||
|
||||
def parse_args():
|
||||
"""Parse command line arguments from sys.argv."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description=inspect.getdoc(sys.modules[__name__]),
|
||||
# Even when there are invalid arguments, we want to emit the deprecation
|
||||
# warning. We usually wait until after argument parsing to emit that warning so
|
||||
# that we can use the --abi and --api inputs to provide a more complete
|
||||
# replacement example, so to do that in the case of an argument error we need to
|
||||
# catch the error rather than allow it to exit immediately.
|
||||
exit_on_error=False,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--arch", required=True, choices=("arm", "arm64", "riscv64", "x86", "x86_64")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--api", type=int, help='Target the given API version (example: "--api 24").'
|
||||
)
|
||||
parser.add_argument(
|
||||
"--stl", help="Ignored. Retained for compatibility until NDK r19."
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--force",
|
||||
action="store_true",
|
||||
help="Remove existing installation directory if it exists.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v", "--verbose", action="count", help="Increase output verbosity."
|
||||
)
|
||||
|
||||
def path_arg(arg):
|
||||
return os.path.realpath(os.path.expanduser(arg))
|
||||
|
||||
output_group = parser.add_mutually_exclusive_group()
|
||||
output_group.add_argument(
|
||||
"--package-dir",
|
||||
type=path_arg,
|
||||
default=os.getcwd(),
|
||||
help=(
|
||||
"Build a tarball and install it to the given directory. If "
|
||||
"neither --package-dir nor --install-dir is specified, a "
|
||||
"tarball will be created and installed to the current "
|
||||
"directory."
|
||||
),
|
||||
)
|
||||
output_group.add_argument(
|
||||
"--install-dir",
|
||||
type=path_arg,
|
||||
help="Install toolchain to the given directory instead of packaging.",
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
"""Program entry point."""
|
||||
try:
|
||||
args = parse_args()
|
||||
except argparse.ArgumentError as ex:
|
||||
warn_unnecessary("arm64", "21", get_host_tag_or_die())
|
||||
sys.exit(ex)
|
||||
|
||||
if args.verbose is None:
|
||||
logging.basicConfig(level=logging.WARNING)
|
||||
elif args.verbose == 1:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
elif args.verbose >= 2:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
host_tag = get_host_tag_or_die()
|
||||
|
||||
warn_unnecessary(args.arch, args.api, host_tag)
|
||||
|
||||
check_ndk_or_die()
|
||||
|
||||
min_api = get_min_supported_api_level(args.arch)
|
||||
api = args.api
|
||||
if api is None:
|
||||
logger().warning(
|
||||
"Defaulting to target API %d (minimum supported target for %s)",
|
||||
min_api,
|
||||
args.arch,
|
||||
)
|
||||
api = min_api
|
||||
elif api < min_api:
|
||||
sys.exit(
|
||||
"{} is less than minimum platform for {} ({})".format(
|
||||
api, args.arch, min_api
|
||||
)
|
||||
)
|
||||
|
||||
triple = get_triple(args.arch)
|
||||
toolchain_path = get_toolchain_path_or_die(host_tag)
|
||||
|
||||
if args.install_dir is not None:
|
||||
install_path = args.install_dir
|
||||
if os.path.exists(install_path):
|
||||
if args.force:
|
||||
logger().info("Cleaning installation directory %s", install_path)
|
||||
shutil.rmtree(install_path)
|
||||
else:
|
||||
sys.exit("Installation directory already exists. Use --force.")
|
||||
else:
|
||||
tempdir = tempfile.mkdtemp()
|
||||
atexit.register(shutil.rmtree, tempdir)
|
||||
install_path = os.path.join(tempdir, triple)
|
||||
|
||||
create_toolchain(install_path, args.arch, api, toolchain_path, host_tag)
|
||||
|
||||
if args.install_dir is None:
|
||||
if host_tag == "windows-x86_64":
|
||||
package_format = "zip"
|
||||
else:
|
||||
package_format = "bztar"
|
||||
|
||||
package_basename = os.path.join(args.package_dir, triple)
|
||||
shutil.make_archive(
|
||||
package_basename,
|
||||
package_format,
|
||||
root_dir=os.path.dirname(install_path),
|
||||
base_dir=os.path.basename(install_path),
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
49
Android/android-ndk-r27d/build/tools/ndk_bin_common.sh
Normal file
49
Android/android-ndk-r27d/build/tools/ndk_bin_common.sh
Normal file
@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (C) 2022 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.
|
||||
#
|
||||
|
||||
HOST_OS=$(uname -s)
|
||||
case $HOST_OS in
|
||||
Darwin) HOST_OS=darwin;;
|
||||
Linux) HOST_OS=linux;;
|
||||
FreeBsd) HOST_OS=freebsd;;
|
||||
CYGWIN*|*_NT-*) HOST_OS=cygwin;;
|
||||
*) echo "ERROR: Unknown host operating system: $HOST_OS"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
HOST_ARCH=$(uname -m)
|
||||
case $HOST_ARCH in
|
||||
arm64) HOST_ARCH=arm64;;
|
||||
i?86) HOST_ARCH=x86;;
|
||||
x86_64|amd64) HOST_ARCH=x86_64;;
|
||||
*) echo "ERROR: Unknown host CPU architecture: $HOST_ARCH"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
HOST_TAG=$HOST_OS-$HOST_ARCH
|
||||
|
||||
if [ $HOST_TAG = darwin-arm64 ]; then
|
||||
# The NDK ships universal arm64+x86_64 binaries in the darwin-x86_64
|
||||
# directory.
|
||||
HOST_TAG=darwin-x86_64
|
||||
fi
|
||||
|
||||
if [ $HOST_OS = cygwin ]; then
|
||||
ANDROID_NDK_PYTHON=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/windows-x86_64/python3/python.exe
|
||||
else
|
||||
ANDROID_NDK_PYTHON=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOST_TAG/python3/bin/python3
|
||||
fi
|
||||
Reference in New Issue
Block a user