From 1aaf1a9132f076875e09f5c5c5fb678b7d85d77d Mon Sep 17 00:00:00 2001 From: lordwithcc Date: Tue, 6 Sep 2022 19:01:29 +0800 Subject: [PATCH] Move the build warehouse Signed-off-by: lordwithcc --- build/README.md | 75 ++ build/ark.gni | 17 + build/ark_var.gni | 17 + build/compile_script/.gn | 21 + build/compile_script/ark.py | 212 ++++++ build/compile_script/gen.sh | 98 +++ build/compile_script/test.js | 18 + build/config/BUILD.gn | 37 + build/config/BUILDCONFIG.gn | 140 ++++ build/config/clang/clang.gni | 20 + build/config/compiler/BUILD.gn | 48 ++ build/config/sanitizers/sanitizers.gni | 312 +++++++++ build/core/gn/BUILD.gn | 34 + .../prebuilts_download/prebuilts_download.py | 257 +++++++ .../prebuilts_download/prebuilts_download.sh | 136 ++++ .../prebuilts_download_config.json | 53 ++ build/prebuilts_download/util.py | 100 +++ build/preconfig_ubuntu.md | 32 + build/templates/cxx/cxx.gni | 135 ++++ .../bounds_checking_function/BUILD.gn | 34 + build/third_party_gn/icu/icu4c/BUILD.gn | 659 ++++++++++++++++++ build/third_party_gn/protobuf/BUILD.gn | 416 +++++++++++ build/third_party_gn/zlib/BUILD.gn | 63 ++ build/toolchain/ark/BUILD.gn | 56 ++ build/toolchain/ark/ark_toolchain.gni | 45 ++ build/toolchain/cc_wrapper.gni | 51 ++ build/toolchain/clang_static_analyzer.gni | 20 + build/toolchain/gcc_link_wrapper.py | 104 +++ build/toolchain/gcc_solink_wrapper.py | 172 +++++ build/toolchain/gcc_toolchain.gni | 499 +++++++++++++ build/toolchain/linux/BUILD.gn | 125 ++++ build/toolchain/toolchain.gni | 111 +++ figures/zh-cn_image_arkcompiler.png | Bin 0 -> 34397 bytes 33 files changed, 4117 insertions(+) create mode 100644 build/README.md create mode 100644 build/ark.gni create mode 100644 build/ark_var.gni create mode 100755 build/compile_script/.gn create mode 100644 build/compile_script/ark.py create mode 100755 build/compile_script/gen.sh create mode 100644 build/compile_script/test.js create mode 100644 build/config/BUILD.gn create mode 100644 build/config/BUILDCONFIG.gn create mode 100644 build/config/clang/clang.gni create mode 100644 build/config/compiler/BUILD.gn create mode 100644 build/config/sanitizers/sanitizers.gni create mode 100644 build/core/gn/BUILD.gn create mode 100644 build/prebuilts_download/prebuilts_download.py create mode 100644 build/prebuilts_download/prebuilts_download.sh create mode 100644 build/prebuilts_download/prebuilts_download_config.json create mode 100644 build/prebuilts_download/util.py create mode 100644 build/preconfig_ubuntu.md create mode 100755 build/templates/cxx/cxx.gni create mode 100644 build/third_party_gn/bounds_checking_function/BUILD.gn create mode 100644 build/third_party_gn/icu/icu4c/BUILD.gn create mode 100644 build/third_party_gn/protobuf/BUILD.gn create mode 100644 build/third_party_gn/zlib/BUILD.gn create mode 100755 build/toolchain/ark/BUILD.gn create mode 100755 build/toolchain/ark/ark_toolchain.gni create mode 100755 build/toolchain/cc_wrapper.gni create mode 100755 build/toolchain/clang_static_analyzer.gni create mode 100755 build/toolchain/gcc_link_wrapper.py create mode 100755 build/toolchain/gcc_solink_wrapper.py create mode 100755 build/toolchain/gcc_toolchain.gni create mode 100755 build/toolchain/linux/BUILD.gn create mode 100755 build/toolchain/toolchain.gni create mode 100644 figures/zh-cn_image_arkcompiler.png diff --git a/build/README.md b/build/README.md new file mode 100644 index 00000000..a930d7a8 --- /dev/null +++ b/build/README.md @@ -0,0 +1,75 @@ +# 方舟编译器部件 + +## 简介 +方舟编译器部件供了一个基于GN和Ninja的集成编译构建框架。构建流程由鸿蒙方舟编译分流,并在构建基础上增加跨平台方式。 + +方舟编译器部件架构图: + +![](../figures/zh-cn_image_arkcompiler.png) + +## 目录结构 +``` +/arkcompiler/ +├── profiler # 性能调优组件 +├── ets_runtime # 方舟eTS(兼容JS/TS)运行时时 +├── runtime_core # 方舟运行时公共库 +├── ets_frontend # 方舟eTS(兼容JS/TS)前端编译器 +├── toolchain # 方舟运行时调试调优工具链 +│ └── build # 编译配置 +├── third_party # 三方库 +│ └── protobuf +│ └── icu +│ └── zlib +│ └── bounds_checking_function +``` + +## 环境配置 +获取源码及安装依赖工具,详细参考[点击这里](https://gitee.com/lordwithcc/arkcompiler_toolchain/blob/add_standalone_part/build/preconfig_ubuntu.md) + +## 使用说明 +abc文件:由方舟前端将js文件转换生成的字节码文件 + +ark_js_vm:运行abc文件的工具 + +### step1 生成编译产物ark_js_vm +``` +python ark.py x64.release +``` +### step2 将js文件转换为abc文件 +``` +./out/x64.release/ark/ark/es2abc test.js +``` +### step3 执行生成的abc文件 +``` +LD_LIBRARY_PATH=out/x64.release:prebuilts/clang/ohos/linux-x86_64/llvm/lib ./out/x64.release/ark/ark_js_runtime/ark_js_vm test.abc +``` +### 执行262测试套 +``` +python ark.py x64.release -test262 +``` + +## 编译选项 + +交叉编译可根据目标选择不同平台,在x64平台构建android_arm目标平台 +``` +python ark.py android_arm.release +``` +编译模式选择,在x64平台构建debug版本 +``` +python ark.py x64.debug +``` +获取更多编译说明 +``` +python ark.py -help +``` + +## 相关仓 +[arkcompiler\_runtime\_core](https://gitee.com/openharmony/arkcompiler_runtime_core) + +[arkcompiler\_ets\_runtime](https://gitee.com/openharmony/arkcompiler_ets_runtime) + +[arkcompiler\_ets\_frontend](https://gitee.com/openharmony/arkcompiler_ets_frontend) + +**[arkcompiler\_toolchain](https://gitee.com/openharmony/arkcompiler_toolchain)** + +[developtools\_profiler](https://gitee.com/openharmony/developtools_profiler) \ No newline at end of file diff --git a/build/ark.gni b/build/ark.gni new file mode 100644 index 00000000..0d3472d0 --- /dev/null +++ b/build/ark.gni @@ -0,0 +1,17 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("$build_root/ark_var.gni") + +# import cxx base templates +import("$build_root/templates/cxx/cxx.gni") diff --git a/build/ark_var.gni b/build/ark_var.gni new file mode 100644 index 00000000..82914ea3 --- /dev/null +++ b/build/ark_var.gni @@ -0,0 +1,17 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +declare_args() { + # build version + build_public_version = true +} diff --git a/build/compile_script/.gn b/build/compile_script/.gn new file mode 100755 index 00000000..3c041cd9 --- /dev/null +++ b/build/compile_script/.gn @@ -0,0 +1,21 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +# The location of the build configuration file. +buildconfig = "//toolchain/build/config/BUILDCONFIG.gn" + +# The source root location. +root = "//toolchain/build/core/gn" + +# The executable used to execute scripts in action and exec_script. +script_executable = "/usr/bin/env" diff --git a/build/compile_script/ark.py b/build/compile_script/ark.py new file mode 100644 index 00000000..d07b664e --- /dev/null +++ b/build/compile_script/ark.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. +# + +from __future__ import print_function +import errno +import os +import platform +import re +import subprocess +import sys + +USE_PTY = "linux" in sys.platform +if USE_PTY: + import pty + +ARCHES = ["x64", "arm", "arm64"] +DEFAULT_ARCHES = "x64" +MODES = ["release", "debug"] +DEFAULT_MODES = "release" +TARGETS = ["ark_js_vm"] +DEFAULT_TARGETS = "all" +TARGETS_TEST = ["-test262"] + + +USER_ARGS_TEMPLATE = """\ +is_standard_system = true +%s +""" + +OUTDIR = "out" + + +Help_message = """ +formot like python ark.py [arch].[mode].[options] [test] +for example , python ark.py x64.release +[arch] can be one of ["x64", "arm", "arm64"] +[mode] can be one of ["release", "debug"] +[options] +target: only support ark_js_vm and all now +clean: clear your data in output dir +[test] +-test262: run test262 +""" + +def PrintHelp(): + print(Help_message) + sys.exit(0) + +def _Call(cmd, silent=False): + if not silent: print("# %s" % cmd) + return subprocess.call(cmd, shell=True) + +def _Write(filename, content, mode): + with open(filename, mode) as f: + f.write(content) + +def GetPath(arch,mode): + subdir = "%s.%s" % (arch, mode) + return os.path.join(OUTDIR, subdir) + +def _CallWithOutput(cmd,file): + host, guest = pty.openpty() + h = subprocess.Popen(cmd, shell=True, stdin=guest, stdout=guest, stderr=guest) + os.close(guest) + output_data = [] + while True: + try: + build_data = os.read(host, 512).decode('utf-8') + except OSError as error: + if error == errno.ENOENT: + print ("no such file") + elif error == errno.EPERM: + print ("permission denied") + break + else: + if not build_data: + break + print(build_data) + sys.stdout.flush() + _Write(file, build_data, "a") + os.close(host) + h.wait() + return h.returncode + +def Get_args(argvs): + args_list = argvs + args_len = len(args_list) + if args_len < 1: + print("Wrong usage") + PrintHelp() + elif args_len == 1: + args_out = args_list + if "-help" in args_out: + PrintHelp() + else : + args_out = args_list + return Get_templete(args_out) + +def Get_templete(args_list): + global_arche = DEFAULT_ARCHES + global_mode = DEFAULT_MODES + global_target = DEFAULT_TARGETS + global_test = '' + global_clean = False + for args in args_list: + parameter = args.split(".") + for part in parameter: + if part in ARCHES: + global_arche = part + elif part in MODES: + global_mode = part + elif part in TARGETS: + global_target = part + elif part == "clean": + global_clean = True + elif part in TARGETS_TEST: + global_test = part + else: + print("\033[34mUnkown word: %s\033[0m" % part) + sys.exit(1) + # Determine the target CPU + if global_arche in ("arm", "arm64"): + ARK_cpu = global_arche + else: + ARK_cpu = "x64" + target_cpu = "target_cpu = \"%s\"" % ARK_cpu + # Determine the target OS,Only ohos for now + ARK_os = "ohos" + target_os = "target_os = \"%s\"" % ARK_os + if global_mode == "debug": + is_debug = "is_debug = true" + else: + is_debug = "is_debug = false" + all_part = (is_debug+"\n"+target_os+"\n"+target_cpu) + return [global_arche,global_mode,global_target,global_clean,USER_ARGS_TEMPLATE%(all_part),global_test] + + +def Build(template): + arch = template[0] + mode = template[1] + target = template[2] + clean = template[3] + template_part = template[4] + path = GetPath(arch,mode) + if not os.path.exists(path): + print("# mkdir -p %s" % path) + os.makedirs(path) + if clean: + print("=== start clean ===") + code = _Call("./prebuilts/build-tools/linux-x86/bin/gn clean %s" % path) + code += _Call("./prebuilts/build-tools/linux-x86/bin/ninja -C %s -t clean" % path) + if code != 0: return code + print("=== clean success! ===") + build_log = os.path.join(path, "build.log") + if not os.path.exists("args.gn"): + args_gn = os.path.join(path, "args.gn") + _Write(args_gn, template_part, "w") + if not os.path.exists("build.ninja"): + build_ninja = os.path.join(path, "build.ninja") + code = _Call("./prebuilts/build-tools/linux-x86/bin/gn gen %s" % path) + print("=== gn success! ===") + if code != 0: return code + pass_code = _CallWithOutput("./prebuilts/build-tools/linux-x86/bin/ninja -C %s %s" % + (path, target),build_log) + if pass_code == 0:print("=== ninja success! ===") + return pass_code + + +def RunTest(template): + arch = template[0] + mode = template[1] + test = template[5] + test_dir = arch+"."+mode + test262_code = '''cd ets_frontend + python3 test262/run_test262.py --es2021 all --timeout 180000 --libs-dir ../out/%s:../prebuilts/clang/ohos/linux-x86_64/llvm/lib --ark-tool=../out/%s/ark/ark_js_runtime/ark_js_vm --ark-frontend-binary=../out/%s/clang_x64/ark/ark/es2abc --merge-abc-binary=../out/%s/clang_x64/ark/ark/merge_abc --ark-frontend=es2panda + '''%(test_dir,test_dir,test_dir,test_dir) + if ("-test262" == test): + print("=== come to test ===") + return _Call(test262_code) + else: + print("=== nothing to test ===") + return 0 + + +def Main(argvs): + pass_code = 0 + templete = Get_args(argvs) + pass_code += Build(templete) + if pass_code == 0: + pass_code += RunTest(templete) + if pass_code == 0: + print('\033[32mDone!\033[0m', '\033[32mARK_{} compilation finished successfully.\033[0m'.format(argvs[0].split('.')[0])) + else: + print('\033[31mError!\033[0m', '\033[31mARK_{} compilation finished with errors.\033[0m'.format(argvs[0].split('.')[0])) + return pass_code + +if __name__ == "__main__": + sys.exit(Main(sys.argv[1:])) \ No newline at end of file diff --git a/build/compile_script/gen.sh b/build/compile_script/gen.sh new file mode 100755 index 00000000..a49bf9be --- /dev/null +++ b/build/compile_script/gen.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. +set -e +clear + +echo "++++++++++++++++++++++++++++++++++++++++" +date +%F' '%H:%M:%S +echo $@ +echo "++++++++++++++++++++++++++++++++++++++++" +echo + +source_root_dir=$(cd $(dirname $0);pwd) + +if [[ "${source_root_dir}x" == "x" ]]; then + echo "Error: source_root_dir cannot be empty." + exit 1 +fi + +case $(uname -s) in + Darwin) + HOST_DIR="darwin-x86" + HOST_OS="mac" + ;; + Linux) + HOST_DIR="linux-x86" + HOST_OS="linux" + ;; + *) + echo "Unsupported host platform: $(uname -s)" + RET=1 + exit $RET +esac + +export PATH=${source_root_dir}/prebuilts/build-tools/${HOST_DIR}/bin:$PATH + +tools="${source_root_dir}/prebuilts/build-tools/${HOST_DIR}/bin" +ark_root="out/ark" +add_path="out:${source_root_dir}/prebuilts/clang/ohos/linux-x86_64/llvm/lib" + + +if [ "$1" = "c" ] +then + echo "clear out !" + rm -rf out *.log test.abc test test.js gen.sh .gn +elif [ "$1" = "log" ] +then + $tools/gn gen out + cd out/ + $tools/ninja all -v | tee ../xxx.log + cd .. +elif [ "$1" = "abc" ] +then + export LD_LIBRARY_PATH=$add_path + ./$ark_root/ark/es2abc test.js +elif [ "$1" = "." ] +then + export LD_LIBRARY_PATH=$add_path + ./$ark_root/ark_js_runtime/ark_js_vm test.abc +elif [ "$1" = "all" ] +then + export LD_LIBRARY_PATH=$add_path + ./$ark_root/ark/es2abc test.js + ./$ark_root/ark_js_runtime/ark_js_vm test.abc +elif [ "$1" = "ark" ] +then + export SCRIPT_ROOT_DIR=$(cd $(dirname $0);pwd) #获取sh脚本绝对路径 + cp -r $SCRIPT_ROOT_DIR/* $SCRIPT_ROOT_DIR/.gn ./ + echo "cp -r build/compile_script/* ./" +else + $tools/gn gen out + cd out/ + $tools/ninja all + cd .. + echo + echo -e "\033[32m + c == clear out !\033[0m" + echo -e "\033[32m + . == execute test.abc !\033[0m" + echo -e "\033[32m + abc == get test.abc !\033[0m" + echo -e "\033[32m + all == all !\033[0m" + echo -e "\033[32m + ark == cp tools !\033[0m" +fi + +echo +echo "++++++++++++++++++++++++++++++++++++++++" +echo -e "\033[32m=====$@ successful=====\033[0m" + +date +%F' '%H:%M:%S +echo "++++++++++++++++++++++++++++++++++++++++" \ No newline at end of file diff --git a/build/compile_script/test.js b/build/compile_script/test.js new file mode 100644 index 00000000..b431aa41 --- /dev/null +++ b/build/compile_script/test.js @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +"use strict"; +print("Hello World !"); + diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn new file mode 100644 index 00000000..07964f1b --- /dev/null +++ b/build/config/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +config("complier_defaults") { + if (current_os == "linux") { + cflags = [ + "-fPIC", + "-pthread", + "-fno-rtti", + ] + } +} + +config("executable_ldconfig") { + if (!is_mac) { + ldflags = [ + "-Wl,-rpath=\$ORIGIN/", + "-Wl,-rpath-link=", + "-fPIE", + "-ldl", + "-lpthread", + "-lrt", + "-lc++", + "-latomic", + ] + } +} diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn new file mode 100644 index 00000000..10a7d3f8 --- /dev/null +++ b/build/config/BUILDCONFIG.gn @@ -0,0 +1,140 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +declare_args() { + another_path = true + ark_standalone_build = true + use_musl = false + build_root = "//toolchain/build" +} + +if (target_os == "") { + target_os = "ohos" #host_os# +} + +if (target_cpu == "") { + if (target_os == "ohos") { + target_cpu = "x64" + } else { + target_cpu = host_cpu + } +} + +if (current_cpu == "") { + current_cpu = host_cpu +} +if (current_os == "") { + current_os = host_os +} + +# different host platform tools directory. +if (host_os == "linux") { + host_platform_dir = "linux-x86_64" +} else { + assert(false, "Unsupported host_os: $host_os") +} + +declare_args() { + # Debug build. Enabling official builds automatically sets is_debug to false. + is_debug = false +} + +declare_args() { + host_toolchain = "" + custom_toolchain = "" + is_standard_system = false + + is_clang = current_os != "linux" || + (current_cpu != "s390x" && current_cpu != "s390" && + current_cpu != "ppc64" && current_cpu != "ppc" && + current_cpu != "mips" && current_cpu != "mips64") +} + +if (current_os == "ohos") { + is_ohos = true + is_linux = false + is_mac = false + is_posix = true + is_win = false + is_mingw = false +} else if (current_os == "linux") { + is_ohos = false + is_linux = true + is_mac = false + is_posix = true + is_win = false + is_mingw = false +} + +if (host_toolchain == "") { + # This should only happen in the top-level context. + # In a specific toolchain context, the toolchain_args() + # block should have propagated a value down. + + if (host_os == "linux") { + if (target_os != "linux") { + host_toolchain = "$build_root/toolchain/linux:clang_$host_cpu" + } else if (is_clang) { + host_toolchain = "$build_root/toolchain/linux:clang_$host_cpu" + } else { + host_toolchain = "$build_root/toolchain/linux:$host_cpu" + } + } else { + assert(false, "Unsupported host_os: $host_os") + } +} + +_default_toolchain = "" + +if (target_os == "ohos") { + assert(host_os == "linux" || host_os == "mac", + "ohos builds are only supported on Linux and Mac hosts.") + _default_toolchain = "$build_root/toolchain/ark:ark_clang_$target_cpu" +} else if (target_os == "linux") { + if (is_clang) { + _default_toolchain = "$build_root/toolchain/linux:clang_$target_cpu" + } else { + _default_toolchain = "$build_root/toolchain/linux:$target_cpu" + } +} else { + assert(false, "Unsupported target_os: $target_os") +} + +# If a custom toolchain has been set in the args, set it as default. Otherwise, +# set the default toolchain for the platform (if any). +if (custom_toolchain != "") { + set_default_toolchain(custom_toolchain) +} else if (_default_toolchain != "") { + set_default_toolchain(_default_toolchain) +} + +_shared_binary_target_configs = [ "$build_root/config:complier_defaults" ] + +default_compiler_configs = [] + +set_defaults("executable") { + configs = _shared_binary_target_configs + configs += [ "$build_root/config:executable_ldconfig" ] +} + +set_defaults("static_library") { + configs = _shared_binary_target_configs +} + +set_defaults("shared_library") { + configs = _shared_binary_target_configs +} + +set_defaults("source_set") { + configs = default_compiler_configs +} \ No newline at end of file diff --git a/build/config/clang/clang.gni b/build/config/clang/clang.gni new file mode 100644 index 00000000..5871b3d0 --- /dev/null +++ b/build/config/clang/clang.gni @@ -0,0 +1,20 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("$build_root/toolchain/toolchain.gni") + +default_clang_base_path = "//prebuilts/clang/ohos/${host_platform_dir}/llvm" + +declare_args() { + clang_base_path = default_clang_base_path +} diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn new file mode 100644 index 00000000..aeaaa73d --- /dev/null +++ b/build/config/compiler/BUILD.gn @@ -0,0 +1,48 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +config("rtti") { + if (is_win) { + cflags_cc = [ "/GR" ] + } else { + cflags_cc = [ "-frtti" ] + } +} + +config("exceptions") { + if (is_win) { + # Enables exceptions in the STL. + if (!use_custom_libcxx) { + defines = [ "_HAS_EXCEPTIONS=1" ] + } + cflags_cc = [ "/EHsc" ] + } else { + cflags_cc = [ "-fexceptions" ] + } +} + +config("no_exceptions") { + if (is_win) { + # Disables exceptions in the STL. + # libc++ uses the __has_feature macro to control whether to use exceptions, + # so defining this macro is unnecessary. Defining _HAS_EXCEPTIONS to 0 also + # breaks libc++ because it depends on MSVC headers that only provide certain + # declarations if _HAS_EXCEPTIONS is 1. Those MSVC headers do not use + # exceptions, despite being conditional on _HAS_EXCEPTIONS. + if (!use_custom_libcxx) { + defines = [ "_HAS_EXCEPTIONS=0" ] + } + } else { + cflags_cc = [ "-fno-exceptions" ] + } +} diff --git a/build/config/sanitizers/sanitizers.gni b/build/config/sanitizers/sanitizers.gni new file mode 100644 index 00000000..fb193d91 --- /dev/null +++ b/build/config/sanitizers/sanitizers.gni @@ -0,0 +1,312 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("$build_root/toolchain/toolchain.gni") + +declare_args() { + # Enable Clang's Source-based Code Coverage. + use_clang_coverage = false +} + +declare_args() { + # Compile for Address Sanitizer to find memory bugs. + is_asan = false + + # Compile for Leak Sanitizer to find leaks. + is_lsan = false + + # Compile for Memory Sanitizer to find uninitialized reads. + is_msan = false + + # Compile for Thread Sanitizer to find threading bugs. + is_tsan = false + + # Compile for Undefined Behavior Sanitizer to find various types of + # undefined behavior (excludes vptr checks). + is_ubsan = false + + # Halt the program if a problem is detected. + is_ubsan_no_recover = false + + # Compile for Undefined Behavior Sanitizer's null pointer checks. + is_ubsan_null = false + + # Compile for Undefined Behavior Sanitizer's vptr checks. + is_ubsan_vptr = false + + # Compile with SafeStack shadow stack support. + is_safestack = false + + # Track where uninitialized memory originates from. From fastest to slowest: + # 0 - no tracking, 1 - track only the initial allocation site, 2 - track the + # chain of stores leading from allocation site to use site. + msan_track_origins = 2 + + # Use dynamic libraries instrumented by one of the sanitizers instead of the + # standard system libraries. Set this flag to download prebuilt binaries from + # GCS. + use_prebuilt_instrumented_libraries = false + + # Use dynamic libraries instrumented by one of the sanitizers instead of the + # standard system libraries. Set this flag to build the libraries from source. + use_locally_built_instrumented_libraries = false + + # Compile with Control Flow Integrity to protect virtual calls and casts. + # See http://clang.llvm.org/docs/ControlFlowIntegrity.html + is_cfi = target_os == "linux" && !is_chromeos && target_cpu == "x64" && + is_official_build + + # Enable checks for bad casts: derived cast and unrelated cast. + use_cfi_cast = false + + # Enable checks for indirect function calls via a function pointer. + use_cfi_icall = target_os == "linux" && !is_chromeos && target_cpu == "x64" && + is_official_build + + # Print detailed diagnostics when Control Flow Integrity detects a violation. + use_cfi_diag = false + + # Let Control Flow Integrity continue execution instead of crashing when + # printing diagnostics (use_cfi_diag = true). + use_cfi_recover = false + + # Compile for fuzzing with LLVM LibFuzzer. + # See http://www.chromium.org/developers/testing/libfuzzer + use_libfuzzer = false + + # Compile for fuzzing with AFL. + use_afl = false + + # Enables core ubsan security features. Will later be removed once it matches + # is_ubsan. + is_ubsan_security = false + + # Compile for fuzzing with Dr. Fuzz + # See http://www.chromium.org/developers/testing/dr-fuzz + use_drfuzz = false + + # Helper variable for testing builds with disabled libfuzzer. + # Not for client use. + disable_libfuzzer = false + + # Optimize for coverage guided fuzzing (balance between speed and number of + # branches). Can be also used to remove non-determinism and other issues. + optimize_for_fuzzing = false + + # Value for -fsanitize-coverage flag. Setting this causes + # use_sanitizer_coverage to be enabled. + # This flag is not used for libFuzzer (use_libfuzzer=true) unless we are on + # Mac. Instead, we use: + # -fsanitize=fuzzer-no-link + # Default value when unset and use_fuzzing_engine=true: + # trace-pc-guard + # Default value when unset and use_sanitizer_coverage=true: + # trace-pc-guard,indirect-calls + sanitizer_coverage_flags = "" +} + +is_v8_host_toolchain = + current_toolchain == "$build_root/toolchain/linux:clang_x64_v8_arm64" || + current_toolchain == "$build_root/toolchain/linux:clang_x86_v8_arm" + +# Disable sanitizers for non-default toolchains. +if (current_toolchain == host_toolchain || is_v8_host_toolchain) { + is_asan = false + is_cfi = false + is_lsan = false + is_msan = false + is_tsan = false + is_ubsan = false + is_ubsan_null = false + is_ubsan_no_recover = false + is_ubsan_security = false + is_ubsan_vptr = false + msan_track_origins = 0 + sanitizer_coverage_flags = "" + use_afl = false + use_cfi_diag = false + use_cfi_recover = false + use_drfuzz = false + use_libfuzzer = false + use_prebuilt_instrumented_libraries = false + use_locally_built_instrumented_libraries = false + use_sanitizer_coverage = false +} + +# Whether we are doing a fuzzer build. Normally this should be checked instead +# of checking "use_libfuzzer || use_afl" because often developers forget to +# check for "use_afl". +use_fuzzing_engine = use_libfuzzer || use_afl + +# Args that are in turn dependent on other args must be in a separate +# declare_args block. User overrides are only applied at the end of a +# declare_args block. +declare_args() { + use_sanitizer_coverage = + !use_clang_coverage && + (use_fuzzing_engine || sanitizer_coverage_flags != "") + + # Detect overflow/underflow for global objects. + # + # Mac: http://crbug.com/352073 + asan_globals = !is_mac +} + +if (use_fuzzing_engine && sanitizer_coverage_flags == "") { + sanitizer_coverage_flags = "trace-pc-guard" +} else if (use_sanitizer_coverage && sanitizer_coverage_flags == "") { + sanitizer_coverage_flags = "trace-pc-guard,indirect-calls" +} + +# Whether we are linking against a debugging sanitizer runtime library. Among +# other things, this changes the default symbol level and other settings in +# order to prepare to create stack traces "live" using the sanitizer runtime. +using_sanitizer = + is_asan || is_lsan || is_tsan || is_msan || is_ubsan || is_ubsan_null || + is_ubsan_vptr || is_ubsan_security || use_sanitizer_coverage || use_cfi_diag + +if (!is_ohos) { + using_sanitizer = false +} + +assert(!using_sanitizer || is_clang, + "Sanitizers (is_*san) require setting is_clang = true in 'gn args'") + +assert(!is_cfi || is_clang, + "is_cfi requires setting is_clang = true in 'gn args'") + +assert(!is_safestack || is_clang, + "is_safestack requires setting is_clang = true in 'gn args'") + +prebuilt_instrumented_libraries_available = + is_msan && (msan_track_origins == 0 || msan_track_origins == 2) + +if (use_libfuzzer && is_linux) { + if (is_asan) { + # We do leak checking with libFuzzer on Linux. Set is_lsan for code that + # relies on LEAK_SANITIZER define to avoid false positives. + is_lsan = true + } + if (is_msan) { + use_prebuilt_instrumented_libraries = true + } +} + +# MSan only links Chrome properly in release builds (brettw -- 9/1/2015). The +# same is possibly true for the other non-ASan sanitizers. But regardless of +# whether it links, one would normally never run a sanitizer in debug mode. +# Running in debug mode probably indicates you forgot to set the "is_debug = +# false" flag in the build args. ASan seems to run fine in debug mode. +# +# If you find a use-case where you want to compile a sanitizer in debug mode +# and have verified it works, ask brettw and we can consider removing it from +# this condition. We may also be able to find another way to enable your case +# without having people accidentally get broken builds by compiling an +# unsupported or unadvisable configurations. +# +# For one-off testing, just comment this assertion out. +assert(!is_debug || !(is_msan || is_ubsan || is_ubsan_null || is_ubsan_vptr), + "Sanitizers should generally be used in release (set is_debug=false).") + +assert(!is_msan || (is_linux && current_cpu == "x64"), + "MSan currently only works on 64-bit Linux and ChromeOS builds.") + +assert(!is_lsan || is_asan, "is_lsan = true requires is_asan = true also.") + +# ASAN build on Windows is not working in debug mode. Intercepting memory +# allocation functions is hard on Windows and not yet implemented in LLVM. +assert(!is_win || !is_debug || !is_asan, + "ASan on Windows doesn't work in debug (set is_debug=false).") + +# Make sure that if we recover on detection (i.e. not crash), diagnostics are +# printed. +assert(!use_cfi_recover || use_cfi_diag, + "Only use CFI recovery together with diagnostics.") + +assert( + !(use_sanitizer_coverage && is_mac && target_os == "ios"), + "crbug.com/753445: use_sanitizer_coverage=true is not supported by the " + + "Chromium mac_clang_x64 toolchain on iOS distribution. Please set " + + "the argument value to false.") + +# Use these lists of configs to disable instrumenting code that is part of a +# fuzzer, but which isn't being targeted (such as libprotobuf-mutator, *.pb.cc +# and libprotobuf when they are built as part of a proto fuzzer). Adding or +# removing these lists does not have any effect if use_libfuzzer or use_afl are +# not passed as arguments to gn. +not_fuzzed_remove_configs = [] +not_fuzzed_remove_nonasan_configs = [] + +if (use_fuzzing_engine) { + # Removing coverage should always just work. + not_fuzzed_remove_configs += + [ "$build_root/config/coverage:default_coverage" ] + not_fuzzed_remove_nonasan_configs += + [ "$build_root/config/coverage:default_coverage" ] + + if (!is_msan) { + # Allow sanitizer instrumentation to be removed if we are not using MSan + # since binaries cannot be partially instrumented with MSan. + not_fuzzed_remove_configs += + [ "$build_root/config/sanitizers:default_sanitizer_flags" ] + + # Certain parts of binaries must be instrumented with ASan if the rest of + # the binary is. For these, only remove non-ASan sanitizer instrumentation. + if (!is_asan) { + not_fuzzed_remove_nonasan_configs += + [ "$build_root/config/sanitizers:default_sanitizer_flags" ] + assert(not_fuzzed_remove_nonasan_configs == not_fuzzed_remove_configs) + } + } +} + +template("ohos_sanitizer_config") { + config(target_name) { + forward_variables_from(invoker, + [ + "cfi", + "scs", + "scudo", + "ubsan", + "boundary_sanitize", + "integer_overflow_sanitize", + ]) + configs = [] + _cfi = defined(cfi) && cfi + if (_cfi) { + configs += [ "$build_root/config/sanitizers:cfi_config" ] + } + _scudo = defined(scudo) && scudo + if (_scudo) { + configs += [ "$build_root/config/sanitizers:scudo_config" ] + } + _ubsan = defined(ubsan) && ubsan + if (_ubsan) { + configs += + [ "$build_root/config/sanitizers:undefined_behavior_sanitize_config" ] + } + _integer_sanitize = + defined(integer_overflow_sanitize) && integer_overflow_sanitize + if (_integer_sanitize) { + configs += [ "$build_root/config/sanitizers:integer_overflow_config" ] + } + _scs = defined(scs) && scs + if (_scs) { + configs += [ "$build_root/config/sanitizers:shadow_call_stack_config" ] + } + _boundary_sanitize = defined(boundary_sanitize) && boundary_sanitize + if (_boundary_sanitize) { + configs += [ "$build_root/config/sanitizers:boundary_sanitize_config" ] + } + } +} diff --git a/build/core/gn/BUILD.gn b/build/core/gn/BUILD.gn new file mode 100644 index 00000000..fcf776fc --- /dev/null +++ b/build/core/gn/BUILD.gn @@ -0,0 +1,34 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("//ets_frontend/ts2panda/ts2abc_config.gni") +import("//ets_runtime/js_runtime_config.gni") + +print("root_out_dir=$root_out_dir") +print("root_build_dir=$root_build_dir") +print("root_gen_dir=$root_gen_dir") +print("current_toolchain=$current_toolchain") +print("host_toolchain=$host_toolchain") +print("current_os=$current_os, current_cpu=$current_cpu") +print("host_os=$host_os, host_cpu=$host_cpu") +print("target_os=$target_os, target_cpu=$target_cpu") + +print() + +group("ark_js_packages") { + deps = [ "//ets_runtime/ecmascript/js_vm:ark_js_vm" ] +} + +group("ark_es2abc") { + deps = [ "//ets_frontend/es2panda:es2panda" ] +} diff --git a/build/prebuilts_download/prebuilts_download.py b/build/prebuilts_download/prebuilts_download.py new file mode 100644 index 00000000..179d265c --- /dev/null +++ b/build/prebuilts_download/prebuilts_download.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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 os +import sys +import argparse +import subprocess +import tarfile +import zipfile +import ssl +import shutil +from multiprocessing import cpu_count +from concurrent.futures import ThreadPoolExecutor, as_completed +from functools import partial +from urllib.request import urlopen +import urllib.error +from rich.progress import ( + BarColumn, + DownloadColumn, + Progress, + TaskID, + TextColumn, + TimeRemainingColumn, + TransferSpeedColumn, +) +from util import read_json_file + +progress = Progress( + TextColumn("[bold blue]{task.fields[filename]}", justify="right"), + BarColumn(bar_width=None), + "[progress.percentage]{task.percentage:>3.1f}%", + "•", + DownloadColumn(), + "•", + TransferSpeedColumn(), + "•", + TimeRemainingColumn(), +) + +def _run_cmd(cmd): + res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + sout, serr = res.communicate() + return sout.rstrip().decode('utf-8'), serr, res.returncode + +def _check_sha256(check_url, local_file): + check_sha256_cmd = ''.join(['curl -s -k ', check_url, '.sha256']) + local_sha256_cmd = ''.join(['sha256sum ', local_file, "|cut -d ' ' -f1"]) + check_sha256, err, returncode = _run_cmd(check_sha256_cmd) + local_sha256, err, returncode = _run_cmd(local_sha256_cmd) + return check_sha256 == local_sha256 + +def _check_sha256_by_mark(args, check_url, code_dir, unzip_dir, unzip_filename): + check_sha256_cmd = ''.join(['curl -s -k ', check_url, '.sha256']) + check_sha256, err, returncode = _run_cmd(check_sha256_cmd) + mark_file_dir = os.path.join(code_dir, unzip_dir) + mark_file_name = ''.join([check_sha256, '.', unzip_filename, '.mark']) + mark_file_path = os.path.join(mark_file_dir, mark_file_name) + args.mark_file_path = mark_file_path + return os.path.exists(mark_file_path) + +def _config_parse(config, tool_repo): + unzip_dir = config.get('unzip_dir') + huaweicloud_url = ''.join([tool_repo, config.get('file_path')]) + unzip_filename = config.get('unzip_filename') + md5_huaweicloud_url_cmd = ''.join(['echo ', huaweicloud_url, "|md5sum|cut -d ' ' -f1"]) + md5_huaweicloud_url, err, returncode = _run_cmd(md5_huaweicloud_url_cmd) + bin_file = os.path.basename(huaweicloud_url) + return unzip_dir, huaweicloud_url, unzip_filename, md5_huaweicloud_url, bin_file + +def _uncompress(args, src_file, code_dir, unzip_dir, unzip_filename, mark_file_path): + dest_dir = os.path.join(code_dir, unzip_dir) + if src_file[-3:] == 'zip': + cmd = 'unzip -o {} -d {};echo 0 > {}'.format(src_file, dest_dir, mark_file_path) + elif src_file[-6:] == 'tar.gz': + cmd = 'tar -xvzf {} -C {};echo 0 > {}'.format(src_file, dest_dir, mark_file_path) + else: + cmd = 'tar -xvf {} -C {};echo 0 > {}'.format(src_file, dest_dir, mark_file_path) + _run_cmd(cmd) + + # npm install + if os.path.basename(unzip_dir) == 'nodejs': + _npm_install(args, code_dir, unzip_dir, unzip_filename) + +def _copy_url(args, task_id, url, local_file, code_dir, unzip_dir, unzip_filename, mark_file_path): + # download files + download_buffer_size = 32768 + progress.console.log('Requesting {}'.format(url)) + try: + response = urlopen(url) + except urllib.error.HTTPError as e: + progress.console.log("Failed to open {}, HTTPError: {}".format(url, e.code), style='red') + progress.update(task_id, total=int(response.info()["Content-length"])) + with open(local_file, "wb") as dest_file: + progress.start_task(task_id) + for data in iter(partial(response.read, download_buffer_size), b""): + dest_file.write(data) + progress.update(task_id, advance=len(data)) + progress.console.log("Downloaded {}".format(local_file)) + + # decompressing files + progress.console.log("Decompressing {}".format(local_file)) + _uncompress(args, local_file, code_dir, unzip_dir, unzip_filename, mark_file_path) + progress.console.log("Decompressed {}".format(local_file)) + +def _hwcloud_download(args, config, bin_dir, code_dir): + try: + cnt = cpu_count() + except: + cnt = 1 + with progress: + with ThreadPoolExecutor(max_workers=cnt) as pool: + tasks = dict() + for config_info in config: + unzip_dir, huaweicloud_url, unzip_filename, md5_huaweicloud_url, bin_file = _config_parse(config_info, + args.tool_repo) + abs_unzip_dir = os.path.join(code_dir, unzip_dir) + if not os.path.exists(abs_unzip_dir): + os.makedirs(abs_unzip_dir) + if _check_sha256_by_mark(args, huaweicloud_url, code_dir, unzip_dir, unzip_filename): + progress.console.log('{}, Sha256 markword check OK.'.format(huaweicloud_url), style='green') + if os.path.basename(abs_unzip_dir) == 'nodejs': + _npm_install(args, code_dir, unzip_dir, unzip_filename) + else: + _run_cmd(''.join(['rm -rf ', code_dir, '/', unzip_dir, '/*.', unzip_filename, '.mark'])) + _run_cmd(''.join(['rm -rf ', code_dir, '/', unzip_dir, '/', unzip_filename])) + local_file = os.path.join(bin_dir, ''.join([md5_huaweicloud_url, '.', bin_file])) + if os.path.exists(local_file): + if _check_sha256(huaweicloud_url, local_file): + progress.console.log('{}, Sha256 check download OK.'.format(local_file), style='green') + task = pool.submit(_uncompress, args, local_file, code_dir, unzip_dir, unzip_filename, + args.mark_file_path) + tasks[task] = os.path.basename(huaweicloud_url) + else: + os.remove(local_file) + else: + filename = huaweicloud_url.split("/")[-1] + task_id = progress.add_task("download", filename=filename, start=False) + task = pool.submit(_copy_url, args, task_id, huaweicloud_url, local_file, code_dir, unzip_dir, + unzip_filename, args.mark_file_path) + tasks[task] = os.path.basename(huaweicloud_url) + for task in as_completed(tasks): + progress.console.log('{}, download and decompress completed'.format(tasks.get(task)), style='green') + +def _npm_install(args, code_dir, unzip_dir, unzip_filename): + procs = [] + skip_ssl_cmd = '' + unsafe_perm_cmd = '' + os.environ['PATH'] = '{}/{}/{}/bin:{}'.format(code_dir, unzip_dir, unzip_filename, os.environ.get('PATH')) + for install_info in args.npm_install_config: + full_code_path = os.path.join(code_dir, install_info) + full_code_path = os.path.join(install_info) + if os.path.exists(full_code_path): + npm = '{}/{}/{}/bin/npm'.format(code_dir, unzip_dir, unzip_filename) + if args.skip_ssl: + skip_ssl_cmd = '{} config set strict-ssl false;'.format(npm) + if args.unsafe_perm: + unsafe_perm_cmd = '--unsafe-perm;' + cmd = 'cd {};{} config set registry {};{}{} cache clean -f;{} install {}'.format( + full_code_path, npm, args.npm_registry, skip_ssl_cmd, npm, npm, unsafe_perm_cmd) + proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + procs.append(proc) + else: + raise Exception("{} not exist, it shouldn't happen, pls check...".format(full_code_path)) + for proc in procs: + out, err = proc.communicate() + if proc.returncode: + raise Exception(err.decode()) + +def _node_modules_copy(config, code_dir): + for config_info in config: + src_dir = os.path.join(code_dir, config_info.get('src')) + dest_dir = os.path.join(code_dir, config_info.get('dest')) + use_symlink = config_info.get('use_symlink') + if os.path.exists(os.path.dirname(dest_dir)): + shutil.rmtree(os.path.dirname(dest_dir)) + if use_symlink == 'True': + os.makedirs(os.path.dirname(dest_dir)) + os.symlink(src_dir, dest_dir) + else: + shutil.copytree(src_dir, dest_dir, symlinks=True) + +def _file_handle(config, code_dir): + for config_info in config: + src_dir = ''.join([code_dir, config_info.get('src')]) + dest_dir = ''.join([code_dir, config_info.get('dest')]) + tmp_dir = config_info.get('tmp') + symlink_src = config_info.get('symlink_src') + symlink_dest = config_info.get('symlink_dest') + if os.path.exists(src_dir): + if tmp_dir: + tmp_dir = ''.join([code_dir, tmp_dir]) + shutil.move(src_dir, tmp_dir) + cmd = 'mv {}/*.mark {}'.format(dest_dir, tmp_dir) + _run_cmd(cmd) + if os.path.exists(dest_dir): + shutil.rmtree(dest_dir) + shutil.move(tmp_dir, dest_dir) + elif symlink_src and symlink_dest: + if os.path.exists(dest_dir): + shutil.rmtree(dest_dir) + shutil.move(src_dir, dest_dir) + os.symlink(''.join([dest_dir, symlink_src]), ''.join([dest_dir, symlink_dest])) + else: + _run_cmd('chmod 755 {} -R'.format(dest_dir)) + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--skip-ssl', action='store_true', help='skip ssl authentication') + parser.add_argument('--unsafe-perm', action='store_true', help='add "--unsafe-perm" for npm install') + parser.add_argument('--tool-repo', default='https://repo.huaweicloud.com', help='prebuilt file download source') + parser.add_argument('--npm-registry', default='https://repo.huaweicloud.com/repository/npm/', + help='npm download source') + parser.add_argument('--host-cpu', help='host cpu', required=True) + parser.add_argument('--host-platform', help='host platform', required=True) + args = parser.parse_args() + args.code_dir = os.path.abspath(os.path.join(os.getcwd())) + if args.skip_ssl: + ssl._create_default_https_context = ssl._create_unverified_context + + host_platform = args.host_platform + host_cpu = args.host_cpu + tool_repo = args.tool_repo + config_file = os.path.join(args.code_dir, 'toolchain/build/prebuilts_download/prebuilts_download_config.json') + config_info = read_json_file(config_file) + args.npm_install_config = config_info.get('npm_install_path') + node_modules_copy_config = config_info.get('node_modules_copy') + file_handle_config = config_info.get('file_handle_config') + + args.bin_dir = os.path.join(args.code_dir, config_info.get('prebuilts_download_dir')) + if not os.path.exists(args.bin_dir): + os.makedirs(args.bin_dir) + copy_config = config_info.get(host_platform).get(host_cpu).get('copy_config') + if host_platform == 'linux': + linux_copy_config = config_info.get(host_platform).get(host_cpu).get('linux_copy_config') + copy_config.extend(linux_copy_config) + elif host_platform == 'darwin': + darwin_copy_config = config_info.get(host_platform).get(host_cpu).get('darwin_copy_config') + copy_config.extend(darwin_copy_config) + _hwcloud_download(args, copy_config, args.bin_dir, args.code_dir) + _file_handle(file_handle_config, args.code_dir) + _node_modules_copy(node_modules_copy_config, args.code_dir) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/build/prebuilts_download/prebuilts_download.sh b/build/prebuilts_download/prebuilts_download.sh new file mode 100644 index 00000000..a64070ca --- /dev/null +++ b/build/prebuilts_download/prebuilts_download.sh @@ -0,0 +1,136 @@ +#!/bin/bash +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. +set -e +while [ $# -gt 0 ]; do + case "$1" in + -skip-ssl|--skip-ssl) # wget、npm skip ssl check, which will allow + # hacker to get and modify data stream between server and client! + SKIP_SSL=YES + ;; + -h|--help) + HELP=YES + ;; + --tool-repo) + TOOL_REPO="$2" + shift + ;; + --tool-repo=*) + TOOL_REPO="${1#--tool-repo=}" + ;; + --npm-registry) + NPM_REGISTRY="$2" + shift + ;; + --npm-registry=*) + NPM_REGISTRY="${1#--npm-registry=}" + ;; + --trusted-host) + TRUSTED_HOST="$2" + shift + ;; + --trusted-host=*) + TRUSTED_HOST="${1#--trusted-host=}" + ;; + --pypi-url) # python package index url + PYPI_URL="$2" + shift + ;; + --pypi-url=*) + PYPI_URL="${1#--pypi-url=}" + ;; + *) + echo "$0: Warning: unsupported parameter: $1" >&2 + ;; + esac + shift +done + +case $(uname -s) in + Linux) + + host_platform=linux + ;; + Darwin) + host_platform=darwin + ;; + *) + echo "Unsupported host platform: $(uname -s)" + exit 1 +esac + +case $(uname -m) in + arm64) + + host_cpu=arm64 + ;; + *) + host_cpu=x86_64 +esac + +if [ "X${SKIP_SSL}" == "XYES" ];then + wget_ssl_check="--skip-ssl" +else + wget_ssl_check='' +fi + +if [ "X${HELP}" == "XYES" ];then + help="-h" +else + help='' +fi + +if [ ! -z "$TOOL_REPO" ];then + tool_repo="--tool-repo $TOOL_REPO" +else + tool_repo='' +fi + +if [ ! -z "$NPM_REGISTRY" ];then + npm_registry="--npm-registry $NPM_REGISTRY" +else + npm_registry='' +fi + +if [ ! -z "$TRUSTED_HOST" ];then + trusted_host=$TRUSTED_HOST +elif [ ! -z "$PYPI_URL" ];then + trusted_host=${PYPI_URL/#*:\/\//} # remove prefix part such as http:// https:// etc. + trusted_host=${trusted_host/%[:\/]*/} # remove suffix part including the port number +else + trusted_host='repo.huaweicloud.com' +fi + +if [ ! -z "$PYPI_URL" ];then + pypi_url=$PYPI_URL +else + pypi_url='http://repo.huaweicloud.com/repository/pypi/simple' +fi + +if [ $UID -ne 0 ]; then + npm_para='' +else + npm_para='--unsafe-perm' +fi + +cpu="--host-cpu $host_cpu" +platform="--host-platform $host_platform" + +script_path=$(cd $(dirname $0);pwd) +code_dir=$(dirname ${script_path}) +pip3 install --trusted-host $trusted_host -i $pypi_url rich +echo "prebuilts_download start" +python3 "${code_dir}/prebuilts_download/prebuilts_download.py" $wget_ssl_check $tool_repo $npm_registry $help $cpu $platform $npm_para +echo "prebuilts_download end" + +echo -e "\n" diff --git a/build/prebuilts_download/prebuilts_download_config.json b/build/prebuilts_download/prebuilts_download_config.json new file mode 100644 index 00000000..83c57a34 --- /dev/null +++ b/build/prebuilts_download/prebuilts_download_config.json @@ -0,0 +1,53 @@ +{ + "prebuilts_download_dir": "../../OpenHarmony_canary_prebuilts", + "npm_install_path": ["ets_frontend/ts2panda"], + "node_modules_copy": [ + { + "src": "ets_frontend/ts2panda/node_modules", + "dest": "prebuilts/build-tools/common/ts2abc/node_modules", + "use_symlink": "True" + } + ], + "file_handle_config": [ + { + "src": "/prebuilts/clang/ohos/linux-x86_64/clang-971024-20220827", + "dest": "/prebuilts/clang/ohos/linux-x86_64/llvm", + "symlink_src": "/lib/clang/12.0.1", + "symlink_dest": "/lib/clang/current" + } + ], + "linux": { + "x86_64": { + "copy_config": [ + { + "unzip_dir": "prebuilts/build-tools/linux-x86/bin", + "file_path": "/openharmony/compiler/gn/1717/linux/gn-linux-x86-1717.tar.gz", + "unzip_filename": "gn" + }, + { + "unzip_dir": "prebuilts/build-tools/linux-x86/bin", + "file_path": "/openharmony/compiler/ninja/1.10.1/linux/ninja-linux-x86-1.10.1.tar.gz", + "unzip_filename": "ninja" + }, + { + "unzip_dir": "prebuilts/ark_tools", + "file_path": "/openharmony/compiler/llvm_prebuilt_libs/ark_js_prebuilts_20220815.tar.gz", + "unzip_filename": "ark_js_prebuilts" + }, + { + "unzip_dir": "prebuilts/build-tools/common/nodejs", + "file_path": "/nodejs/v12.18.4/node-v12.18.4-linux-x64.tar.gz", + "unzip_filename": "node-v12.18.4-linux-x64" + } + ], + "linux_copy_config": [ + { + "unzip_dir": "prebuilts/clang/ohos/linux-x86_64", + "file_path": "/openharmony/compiler/clang/12.0.1-971024/linux/clang-971024-linux-x86_64-20220827.tar.bz2", + "unzip_filename": "llvm" + } + ] + } + } +} + diff --git a/build/prebuilts_download/util.py b/build/prebuilts_download/util.py new file mode 100644 index 00000000..7f76be10 --- /dev/null +++ b/build/prebuilts_download/util.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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 json +import os +import subprocess +import hashlib + + +# Read json file data +def read_json_file(input_file): + if not os.path.exists(input_file): + print("file '{}' doesn't exist.".format(input_file)) + return None + + data = None + try: + with open(input_file, 'r') as input_f: + data = json.load(input_f) + except json.decoder.JSONDecodeError: + print("The file '{}' format is incorrect.".format(input_file)) + raise + except: # noqa E722 + print("read file '{}' failed.".format(input_file)) + raise + return data + + +# Read file by line +def read_file(input_file): + if not os.path.exists(input_file): + print("file '{}' doesn't exist.".format(input_file)) + return None + + data = [] + try: + with open(input_file, 'r') as file_obj: + for line in file_obj.readlines(): + data.append(line.rstrip('\n')) + except: # noqa E722 + print("read file '{}' failed".format(input_file)) + raise + return data + + +# Write json file data +def write_json_file(output_file, content, check_changes=False): + file_dir = os.path.dirname(os.path.abspath(output_file)) + if not os.path.exists(file_dir): + os.makedirs(file_dir, exist_ok=True) + + if check_changes is True: + changed = __check_changes(output_file, content) + else: + changed = True + if changed is True: + with open(output_file, 'w') as output_f: + json.dump(content, output_f, sort_keys=True, indent=2) + + +def __check_changes(output_file, content): + if os.path.exists(output_file) and os.path.isfile(output_file): + # file content md5 val + sha256_obj = hashlib.sha256() + sha256_obj.update(str(read_json_file(output_file)).encode()) + hash_value = sha256_obj.hexdigest() + # new content md5 val + sha256_obj_new = hashlib.sha256() + sha256_obj_new.update(str(content).encode()) + hash_value_new = sha256_obj_new.hexdigest() + if hash_value_new == hash_value: + return False + return True + + +# Write file data +def write_file(output_file, content): + file_dir = os.path.dirname(os.path.abspath(output_file)) + if not os.path.exists(file_dir): + os.makedirs(file_dir, exist_ok=True) + + with open(output_file, 'w') as output_f: + output_f.write(content) + if output_file.endswith('.gni') or output_file.endswith('.gn'): + # Call gn format to make the output gn file prettier. + cmd = ['gn', 'format'] + cmd.append(output_file) + subprocess.check_output(cmd) diff --git a/build/preconfig_ubuntu.md b/build/preconfig_ubuntu.md new file mode 100644 index 00000000..72613588 --- /dev/null +++ b/build/preconfig_ubuntu.md @@ -0,0 +1,32 @@ +# 获取源码及安装依赖工具 +## 推荐操作系统Ubuntu18及以上 +## 安装repo工具 + +安装码云repo工具,由于权限可切换到root用户下安装,安装后再切换个人用户目录操作 + +``` +curl https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > /usr/local/bin/repo +chmod a+x /usr/local/bin/repo +pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple requests +``` + +## 下载源码 +``` +repo init -u https://gitee.com/lordwithcc/manifest.git -b Ark_Standalone_Build +repo sync -c +repo forall -c 'git lfs pull' +``` + +## 编译环境准备 + +安装依赖工具 +``` +sudo apt-get update && sudo apt-get install binutils git git-lfs gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev genext2fs liblz4-tool libssl-dev libtinfo5 lib32z1-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 bc gnutls-bin python3.8 python3-pip ruby default-jdk u-boot-tools mtools mtd-utils scons gcc-arm-none-eabi gcc-arm-linux-gnueabi +``` + +安装编译器及二进制工具 +``` +cd arkcompiler +./toolchain/build/compile_script/gen.sh ark +./toolchain/build/prebuilts_download/prebuilts_download.sh +``` diff --git a/build/templates/cxx/cxx.gni b/build/templates/cxx/cxx.gni new file mode 100755 index 00000000..5c232d0a --- /dev/null +++ b/build/templates/cxx/cxx.gni @@ -0,0 +1,135 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +template("ohos_executable") { + executable(target_name) { + forward_variables_from(invoker, + "*", + [ + "configs", + "remove_configs", + "subsystem_name", + "install_enable", + "part_name", + "use_exceptions", + "static_link", + "output_dir", + ]) + if (defined(invoker.subsystem_name) && defined(invoker.part_name)) { + subsystem_name = invoker.subsystem_name + part_name = invoker.part_name + } else if (defined(invoker.part_name)) { + part_name = invoker.part_name + _part_subsystem_info_file = + "$root_build_dir/build_configs/parts_info/part_subsystem.json" + _arguments = [ + "--part-name", + part_name, + "--part-subsystem-info-file", + rebase_path(_part_subsystem_info_file, root_build_dir), + ] + get_subsystem_script = "//build/templates/common/get_subsystem_name.py" + subsystem_name = + exec_script(get_subsystem_script, _arguments, "trim string") + } else if (defined(invoker.subsystem_name)) { + subsystem_name = invoker.subsystem_name + part_name = subsystem_name + } else { + subsystem_name = "common" + part_name = subsystem_name + } + if (is_standard_system) { + output_dir = "${root_out_dir}/${subsystem_name}/${part_name}" + } else { + output_dir = "${root_out_dir}" + } + if (defined(invoker.configs)) { + configs += invoker.configs + } + + if (defined(invoker.remove_configs)) { + configs -= invoker.remove_configs + } + + if (defined(invoker.use_exceptions) && invoker.use_exceptions) { + configs += [ "//toolchain/build/config/compiler:exceptions" ] + } + } +} +template("ohos_static_library") { + static_library(target_name) { + forward_variables_from(invoker, + "*", + [ + "configs", + "remove_configs", + "subsystem_name", + "part_name", + "use_exceptions", + "external_deps", + ]) + if (defined(invoker.configs)) { + configs += invoker.configs + } + + if (defined(invoker.remove_configs)) { + configs -= invoker.remove_configs + } + + if (defined(invoker.use_exceptions) && invoker.use_exceptions) { + configs += [ "//toolchain/build/config/compiler:exceptions" ] + } + } +} +template("ohos_shared_library") { + shared_library(target_name) { + forward_variables_from(invoker, + "*", + [ + "relative_install_dir", + "subsystem_name", + "install_enable", + "part_name", + "install_images", + "use_exceptions", + "external_deps", + ]) + } +} + +template("ohos_copy") { + copy(target_name) { + forward_variables_from(invoker, + "*", + [ + "module_source_dir", + "module_install_name", + ]) + } +} + +template("ohos_source_set") { + source_set(target_name) { + forward_variables_from(invoker, + "*", + [ + "configs", + "remove_configs", + "no_default_deps", + "external_deps", + "license_file", + "license_as_sources", + "use_exceptions", + ]) + } +} diff --git a/build/third_party_gn/bounds_checking_function/BUILD.gn b/build/third_party_gn/bounds_checking_function/BUILD.gn new file mode 100644 index 00000000..8c26a0d4 --- /dev/null +++ b/build/third_party_gn/bounds_checking_function/BUILD.gn @@ -0,0 +1,34 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("//third_party/bounds_checking_function/libsec_src.gni") +import("$build_root/ark.gni") + +config("libsec_public_config") { + include_dirs = [ "//third_party/bounds_checking_function/include" ] + cflags_cc = [ "-fPIC" ] +} + +ohos_static_library("libsec_static") { + sources = libsec_sources + public_configs = [ ":libsec_public_config" ] + cflags = [ + "-D_INC_STRING_S", + "-D_INC_WCHAR_S", + "-D_SECIMP=//", + "-D_STDIO_S_DEFINED", + "-D_INC_STDIO_S", + "-D_INC_STDLIB_S", + "-D_INC_MEMORY_S", + ] +} diff --git a/build/third_party_gn/icu/icu4c/BUILD.gn b/build/third_party_gn/icu/icu4c/BUILD.gn new file mode 100644 index 00000000..2dcdd60f --- /dev/null +++ b/build/third_party_gn/icu/icu4c/BUILD.gn @@ -0,0 +1,659 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("$build_root/ark.gni") +config("icu_config") { + visibility = [ ":*" ] + include_dirs = [ + "//third_party/icu/icu4c/source/common", + "//third_party/icu/icu4c/source/i18n", + "//third_party/icu/icu4c/source", + ] + cflags_cc = [ "-fPIC" ] +} + +ohos_static_library("static_icustubdata") { + configs = [ + ":icu_config", + "$build_root/config/compiler:rtti", + ] + sources = [ "//third_party/icu/icu4c/source/stubdata/stubdata.cpp" ] + + cflags_cc = [ + "-O3", + "-W", + "-Wall", + "-pedantic", + "-Wpointer-arith", + "-Wwrite-strings", + "-std=c++11", + "-Wno-ignored-attributes", + ] + output_dir = "${root_out_dir}/third_party/icu/stubdata" + output_name = "stubdata" +} + +icu_common_source = [ + "//third_party/icu/icu4c/source/common/ubiditransform.cpp", + "//third_party/icu/icu4c/source/common/locutil.cpp", + "//third_party/icu/icu4c/source/common/cstring.cpp", + "//third_party/icu/icu4c/source/common/rbbiscan.cpp", + "//third_party/icu/icu4c/source/common/utrie.cpp", + "//third_party/icu/icu4c/source/common/cwchar.cpp", + "//third_party/icu/icu4c/source/common/bytestriebuilder.cpp", + "//third_party/icu/icu4c/source/common/umapfile.cpp", + "//third_party/icu/icu4c/source/common/uenum.cpp", + "//third_party/icu/icu4c/source/common/putil.cpp", + "//third_party/icu/icu4c/source/common/bytestrieiterator.cpp", + "//third_party/icu/icu4c/source/common/unifunct.cpp", + "//third_party/icu/icu4c/source/common/rbbistbl.cpp", + "//third_party/icu/icu4c/source/common/bytestrie.cpp", + "//third_party/icu/icu4c/source/common/ucptrie.cpp", + "//third_party/icu/icu4c/source/common/errorcode.cpp", + "//third_party/icu/icu4c/source/common/unames.cpp", + "//third_party/icu/icu4c/source/common/restrace.cpp", + "//third_party/icu/icu4c/source/common/util.cpp", + "//third_party/icu/icu4c/source/common/sharedobject.cpp", + "//third_party/icu/icu4c/source/common/bmpset.cpp", + "//third_party/icu/icu4c/source/common/servlk.cpp", + "//third_party/icu/icu4c/source/common/ustrcase_locale.cpp", + "//third_party/icu/icu4c/source/common/localeprioritylist.cpp", + "//third_party/icu/icu4c/source/common/ucnvbocu.cpp", + "//third_party/icu/icu4c/source/common/ucharstrieiterator.cpp", + "//third_party/icu/icu4c/source/common/unisetspan.cpp", + "//third_party/icu/icu4c/source/common/locavailable.cpp", + "//third_party/icu/icu4c/source/common/unistr.cpp", + "//third_party/icu/icu4c/source/common/ustr_wcs.cpp", + "//third_party/icu/icu4c/source/common/ucnv_err.cpp", + "//third_party/icu/icu4c/source/common/ucnv_lmb.cpp", + "//third_party/icu/icu4c/source/common/rbbidata.cpp", + "//third_party/icu/icu4c/source/common/uarrsort.cpp", + "//third_party/icu/icu4c/source/common/ucnv2022.cpp", + "//third_party/icu/icu4c/source/common/uresbund.cpp", + "//third_party/icu/icu4c/source/common/ucnvsel.cpp", + "//third_party/icu/icu4c/source/common/unistr_titlecase_brkiter.cpp", + "//third_party/icu/icu4c/source/common/loadednormalizer2impl.cpp", + "//third_party/icu/icu4c/source/common/ustring.cpp", + "//third_party/icu/icu4c/source/common/unifilt.cpp", + "//third_party/icu/icu4c/source/common/ubrk.cpp", + "//third_party/icu/icu4c/source/common/bytesinkutil.cpp", + "//third_party/icu/icu4c/source/common/localebuilder.cpp", + "//third_party/icu/icu4c/source/common/rbbi_cache.cpp", + "//third_party/icu/icu4c/source/common/ucnvhz.cpp", + "//third_party/icu/icu4c/source/common/uniset_closure.cpp", + "//third_party/icu/icu4c/source/common/uloc.cpp", + "//third_party/icu/icu4c/source/common/utypes.cpp", + "//third_party/icu/icu4c/source/common/ucnv_u16.cpp", + "//third_party/icu/icu4c/source/common/uniset_props.cpp", + "//third_party/icu/icu4c/source/common/locbased.cpp", + "//third_party/icu/icu4c/source/common/unistr_cnv.cpp", + "//third_party/icu/icu4c/source/common/ucnv_ct.cpp", + "//third_party/icu/icu4c/source/common/unormcmp.cpp", + "//third_party/icu/icu4c/source/common/wintz.cpp", + "//third_party/icu/icu4c/source/common/ruleiter.cpp", + "//third_party/icu/icu4c/source/common/utrie2.cpp", + "//third_party/icu/icu4c/source/common/locresdata.cpp", + "//third_party/icu/icu4c/source/common/ucnv_u8.cpp", + "//third_party/icu/icu4c/source/common/uscript_props.cpp", + "//third_party/icu/icu4c/source/common/locdspnm.cpp", + "//third_party/icu/icu4c/source/common/locid.cpp", + "//third_party/icu/icu4c/source/common/rbbitblb.cpp", + "//third_party/icu/icu4c/source/common/icudataver.cpp", + "//third_party/icu/icu4c/source/common/ubidi.cpp", + "//third_party/icu/icu4c/source/common/brkiter.cpp", + "//third_party/icu/icu4c/source/common/uvectr32.cpp", + "//third_party/icu/icu4c/source/common/usc_impl.cpp", + "//third_party/icu/icu4c/source/common/normlzr.cpp", + "//third_party/icu/icu4c/source/common/icuplug.cpp", + "//third_party/icu/icu4c/source/common/uvector.cpp", + "//third_party/icu/icu4c/source/common/ucnv_set.cpp", + "//third_party/icu/icu4c/source/common/udataswp.cpp", + "//third_party/icu/icu4c/source/common/uhash_us.cpp", + "//third_party/icu/icu4c/source/common/rbbisetb.cpp", + "//third_party/icu/icu4c/source/common/ubidi_props.cpp", + "//third_party/icu/icu4c/source/common/ucmndata.cpp", + "//third_party/icu/icu4c/source/common/locdistance.cpp", + "//third_party/icu/icu4c/source/common/serv.cpp", + "//third_party/icu/icu4c/source/common/utrie_swap.cpp", + "//third_party/icu/icu4c/source/common/uchar.cpp", + "//third_party/icu/icu4c/source/common/uloc_tag.cpp", + "//third_party/icu/icu4c/source/common/ustr_titlecase_brkiter.cpp", + "//third_party/icu/icu4c/source/common/pluralmap.cpp", + "//third_party/icu/icu4c/source/common/lsr.cpp", + "//third_party/icu/icu4c/source/common/uhash.cpp", + "//third_party/icu/icu4c/source/common/propname.cpp", + "//third_party/icu/icu4c/source/common/ucnvlat1.cpp", + "//third_party/icu/icu4c/source/common/ucnv_ext.cpp", + "//third_party/icu/icu4c/source/common/ubidiln.cpp", + "//third_party/icu/icu4c/source/common/ucnv_cb.cpp", + "//third_party/icu/icu4c/source/common/static_unicode_sets.cpp", + "//third_party/icu/icu4c/source/common/dictbe.cpp", + "//third_party/icu/icu4c/source/common/stringtriebuilder.cpp", + "//third_party/icu/icu4c/source/common/uvectr64.cpp", + "//third_party/icu/icu4c/source/common/patternprops.cpp", + "//third_party/icu/icu4c/source/common/propsvec.cpp", + "//third_party/icu/icu4c/source/common/ustrenum.cpp", + "//third_party/icu/icu4c/source/common/ucnv_u32.cpp", + "//third_party/icu/icu4c/source/common/ustr_cnv.cpp", + "//third_party/icu/icu4c/source/common/edits.cpp", + "//third_party/icu/icu4c/source/common/loclikely.cpp", + "//third_party/icu/icu4c/source/common/parsepos.cpp", + "//third_party/icu/icu4c/source/common/loclikelysubtags.cpp", + "//third_party/icu/icu4c/source/common/uloc_keytype.cpp", + "//third_party/icu/icu4c/source/common/appendable.cpp", + "//third_party/icu/icu4c/source/common/filteredbrk.cpp", + "//third_party/icu/icu4c/source/common/ucharstrie.cpp", + "//third_party/icu/icu4c/source/common/uiter.cpp", + "//third_party/icu/icu4c/source/common/messagepattern.cpp", + "//third_party/icu/icu4c/source/common/servrbf.cpp", + "//third_party/icu/icu4c/source/common/rbbirb.cpp", + "//third_party/icu/icu4c/source/common/uinit.cpp", + "//third_party/icu/icu4c/source/common/stringpiece.cpp", + "//third_party/icu/icu4c/source/common/normalizer2impl.cpp", + "//third_party/icu/icu4c/source/common/ucharstriebuilder.cpp", + "//third_party/icu/icu4c/source/common/uobject.cpp", + "//third_party/icu/icu4c/source/common/ushape.cpp", + "//third_party/icu/icu4c/source/common/ucasemap.cpp", + "//third_party/icu/icu4c/source/common/uinvchar.cpp", + "//third_party/icu/icu4c/source/common/utf_impl.cpp", + "//third_party/icu/icu4c/source/common/ustack.cpp", + "//third_party/icu/icu4c/source/common/characterproperties.cpp", + "//third_party/icu/icu4c/source/common/rbbi.cpp", + "//third_party/icu/icu4c/source/common/ucasemap_titlecase_brkiter.cpp", + "//third_party/icu/icu4c/source/common/caniter.cpp", + "//third_party/icu/icu4c/source/common/ucnv_bld.cpp", + "//third_party/icu/icu4c/source/common/ucln_cmn.cpp", + "//third_party/icu/icu4c/source/common/chariter.cpp", + "//third_party/icu/icu4c/source/common/punycode.cpp", + "//third_party/icu/icu4c/source/common/ustrtrns.cpp", + "//third_party/icu/icu4c/source/common/ucnvmbcs.cpp", + "//third_party/icu/icu4c/source/common/bytestream.cpp", + "//third_party/icu/icu4c/source/common/servlkf.cpp", + "//third_party/icu/icu4c/source/common/udatamem.cpp", + "//third_party/icu/icu4c/source/common/ucnv_io.cpp", + "//third_party/icu/icu4c/source/common/dtintrv.cpp", + "//third_party/icu/icu4c/source/common/cstr.cpp", + "//third_party/icu/icu4c/source/common/ulist.cpp", + "//third_party/icu/icu4c/source/common/ucnvisci.cpp", + "//third_party/icu/icu4c/source/common/brkeng.cpp", + "//third_party/icu/icu4c/source/common/localematcher.cpp", + "//third_party/icu/icu4c/source/common/umutablecptrie.cpp", + "//third_party/icu/icu4c/source/common/locdispnames.cpp", + "//third_party/icu/icu4c/source/common/uchriter.cpp", + "//third_party/icu/icu4c/source/common/uresdata.cpp", + "//third_party/icu/icu4c/source/common/unifiedcache.cpp", + "//third_party/icu/icu4c/source/common/dictionarydata.cpp", + "//third_party/icu/icu4c/source/common/uscript.cpp", + "//third_party/icu/icu4c/source/common/ucnv_u7.cpp", + "//third_party/icu/icu4c/source/common/unistr_case.cpp", + "//third_party/icu/icu4c/source/common/ucat.cpp", + "//third_party/icu/icu4c/source/common/resource.cpp", + "//third_party/icu/icu4c/source/common/usprep.cpp", + "//third_party/icu/icu4c/source/common/ucnvdisp.cpp", + "//third_party/icu/icu4c/source/common/uniset.cpp", + "//third_party/icu/icu4c/source/common/ucnv.cpp", + "//third_party/icu/icu4c/source/common/ucnvscsu.cpp", + "//third_party/icu/icu4c/source/common/uset_props.cpp", + "//third_party/icu/icu4c/source/common/umutex.cpp", + "//third_party/icu/icu4c/source/common/ucnv_cnv.cpp", + "//third_party/icu/icu4c/source/common/locmap.cpp", + "//third_party/icu/icu4c/source/common/resbund.cpp", + "//third_party/icu/icu4c/source/common/filterednormalizer2.cpp", + "//third_party/icu/icu4c/source/common/uprops.cpp", + "//third_party/icu/icu4c/source/common/schriter.cpp", + "//third_party/icu/icu4c/source/common/simpleformatter.cpp", + "//third_party/icu/icu4c/source/common/uts46.cpp", + "//third_party/icu/icu4c/source/common/ucol_swp.cpp", + "//third_party/icu/icu4c/source/common/udata.cpp", + "//third_party/icu/icu4c/source/common/ustrfmt.cpp", + "//third_party/icu/icu4c/source/common/servslkf.cpp", + "//third_party/icu/icu4c/source/common/servls.cpp", + "//third_party/icu/icu4c/source/common/unistr_props.cpp", + "//third_party/icu/icu4c/source/common/utrace.cpp", + "//third_party/icu/icu4c/source/common/utrie2_builder.cpp", + "//third_party/icu/icu4c/source/common/ucase.cpp", + "//third_party/icu/icu4c/source/common/cmemory.cpp", + "//third_party/icu/icu4c/source/common/uset.cpp", + "//third_party/icu/icu4c/source/common/unistr_case_locale.cpp", + "//third_party/icu/icu4c/source/common/ures_cnv.cpp", + "//third_party/icu/icu4c/source/common/charstr.cpp", + "//third_party/icu/icu4c/source/common/uidna.cpp", + "//third_party/icu/icu4c/source/common/normalizer2.cpp", + "//third_party/icu/icu4c/source/common/resbund_cnv.cpp", + "//third_party/icu/icu4c/source/common/umath.cpp", + "//third_party/icu/icu4c/source/common/utext.cpp", + "//third_party/icu/icu4c/source/common/ucurr.cpp", + "//third_party/icu/icu4c/source/common/util_props.cpp", + "//third_party/icu/icu4c/source/common/unorm.cpp", + "//third_party/icu/icu4c/source/common/ubidiwrt.cpp", + "//third_party/icu/icu4c/source/common/usetiter.cpp", + "//third_party/icu/icu4c/source/common/rbbinode.cpp", + "//third_party/icu/icu4c/source/common/ustrcase.cpp", + "//third_party/icu/icu4c/source/common/servnotf.cpp", + "//third_party/icu/icu4c/source/ohos/init_data.cpp", +] + +icu_i18n_source = [ + "//third_party/icu/icu4c/source/i18n/number_capi.cpp", + "//third_party/icu/icu4c/source/i18n/upluralrules.cpp", + "//third_party/icu/icu4c/source/i18n/numparse_currency.cpp", + "//third_party/icu/icu4c/source/i18n/ufieldpositer.cpp", + "//third_party/icu/icu4c/source/i18n/number_output.cpp", + "//third_party/icu/icu4c/source/i18n/number_currencysymbols.cpp", + "//third_party/icu/icu4c/source/i18n/curramt.cpp", + "//third_party/icu/icu4c/source/i18n/alphaindex.cpp", + "//third_party/icu/icu4c/source/i18n/indiancal.cpp", + "//third_party/icu/icu4c/source/i18n/dayperiodrules.cpp", + "//third_party/icu/icu4c/source/i18n/quantityformatter.cpp", + "//third_party/icu/icu4c/source/i18n/collationfastlatinbuilder.cpp", + "//third_party/icu/icu4c/source/i18n/csrucode.cpp", + "//third_party/icu/icu4c/source/i18n/measunit_extra.cpp", + "//third_party/icu/icu4c/source/i18n/ethpccal.cpp", + "//third_party/icu/icu4c/source/i18n/anytrans.cpp", + "//third_party/icu/icu4c/source/i18n/number_scientific.cpp", + "//third_party/icu/icu4c/source/i18n/cpdtrans.cpp", + "//third_party/icu/icu4c/source/i18n/regexst.cpp", + "//third_party/icu/icu4c/source/i18n/numfmt.cpp", + "//third_party/icu/icu4c/source/i18n/formattedvalue.cpp", + "//third_party/icu/icu4c/source/i18n/unesctrn.cpp", + "//third_party/icu/icu4c/source/i18n/ucoleitr.cpp", + "//third_party/icu/icu4c/source/i18n/tmutamt.cpp", + "//third_party/icu/icu4c/source/i18n/transreg.cpp", + "//third_party/icu/icu4c/source/i18n/unum.cpp", + "//third_party/icu/icu4c/source/i18n/number_longnames.cpp", + "//third_party/icu/icu4c/source/i18n/numparse_affixes.cpp", + "//third_party/icu/icu4c/source/i18n/plurrule.cpp", + "//third_party/icu/icu4c/source/i18n/zrule.cpp", + "//third_party/icu/icu4c/source/i18n/collationrootelements.cpp", + "//third_party/icu/icu4c/source/i18n/currunit.cpp", + "//third_party/icu/icu4c/source/i18n/funcrepl.cpp", + "//third_party/icu/icu4c/source/i18n/collationdatareader.cpp", + "//third_party/icu/icu4c/source/i18n/buddhcal.cpp", + "//third_party/icu/icu4c/source/i18n/number_decimalquantity.cpp", + "//third_party/icu/icu4c/source/i18n/scriptset.cpp", + "//third_party/icu/icu4c/source/i18n/fmtable.cpp", + "//third_party/icu/icu4c/source/i18n/regextxt.cpp", + "//third_party/icu/icu4c/source/i18n/bocsu.cpp", + "//third_party/icu/icu4c/source/i18n/olsontz.cpp", + "//third_party/icu/icu4c/source/i18n/utmscale.cpp", + "//third_party/icu/icu4c/source/i18n/ucol.cpp", + "//third_party/icu/icu4c/source/i18n/currfmt.cpp", + "//third_party/icu/icu4c/source/i18n/hebrwcal.cpp", + "//third_party/icu/icu4c/source/i18n/ucol_sit.cpp", + "//third_party/icu/icu4c/source/i18n/rbnf.cpp", + "//third_party/icu/icu4c/source/i18n/decContext.cpp", + "//third_party/icu/icu4c/source/i18n/collationdatawriter.cpp", + "//third_party/icu/icu4c/source/i18n/csr2022.cpp", + "//third_party/icu/icu4c/source/i18n/dtrule.cpp", + "//third_party/icu/icu4c/source/i18n/numparse_validators.cpp", + "//third_party/icu/icu4c/source/i18n/numparse_parsednumber.cpp", + "//third_party/icu/icu4c/source/i18n/double-conversion-fast-dtoa.cpp", + "//third_party/icu/icu4c/source/i18n/choicfmt.cpp", + "//third_party/icu/icu4c/source/i18n/format.cpp", + "//third_party/icu/icu4c/source/i18n/reldatefmt.cpp", + "//third_party/icu/icu4c/source/i18n/double-conversion-double-to-string.cpp", + "//third_party/icu/icu4c/source/i18n/rbt_data.cpp", + "//third_party/icu/icu4c/source/i18n/smpdtfmt.cpp", + "//third_party/icu/icu4c/source/i18n/double-conversion-bignum-dtoa.cpp", + "//third_party/icu/icu4c/source/i18n/number_padding.cpp", + "//third_party/icu/icu4c/source/i18n/vtzone.cpp", + "//third_party/icu/icu4c/source/i18n/region.cpp", + "//third_party/icu/icu4c/source/i18n/coptccal.cpp", + "//third_party/icu/icu4c/source/i18n/datefmt.cpp", + "//third_party/icu/icu4c/source/i18n/formatted_string_builder.cpp", + "//third_party/icu/icu4c/source/i18n/numparse_impl.cpp", + "//third_party/icu/icu4c/source/i18n/plurfmt.cpp", + "//third_party/icu/icu4c/source/i18n/rematch.cpp", + "//third_party/icu/icu4c/source/i18n/simpletz.cpp", + "//third_party/icu/icu4c/source/i18n/search.cpp", + "//third_party/icu/icu4c/source/i18n/number_mapper.cpp", + "//third_party/icu/icu4c/source/i18n/inputext.cpp", + "//third_party/icu/icu4c/source/i18n/dtptngen.cpp", + "//third_party/icu/icu4c/source/i18n/coleitr.cpp", + "//third_party/icu/icu4c/source/i18n/collationweights.cpp", + "//third_party/icu/icu4c/source/i18n/number_modifiers.cpp", + "//third_party/icu/icu4c/source/i18n/scientificnumberformatter.cpp", + "//third_party/icu/icu4c/source/i18n/vzone.cpp", + "//third_party/icu/icu4c/source/i18n/fphdlimp.cpp", + "//third_party/icu/icu4c/source/i18n/udatpg.cpp", + "//third_party/icu/icu4c/source/i18n/collationfcd.cpp", + "//third_party/icu/icu4c/source/i18n/tridpars.cpp", + "//third_party/icu/icu4c/source/i18n/csmatch.cpp", + "//third_party/icu/icu4c/source/i18n/dangical.cpp", + "//third_party/icu/icu4c/source/i18n/ulocdata.cpp", + "//third_party/icu/icu4c/source/i18n/double-conversion-strtod.cpp", + "//third_party/icu/icu4c/source/i18n/erarules.cpp", + "//third_party/icu/icu4c/source/i18n/numsys.cpp", + "//third_party/icu/icu4c/source/i18n/csdetect.cpp", + "//third_party/icu/icu4c/source/i18n/japancal.cpp", + "//third_party/icu/icu4c/source/i18n/collation.cpp", + "//third_party/icu/icu4c/source/i18n/uregex.cpp", + "//third_party/icu/icu4c/source/i18n/timezone.cpp", + "//third_party/icu/icu4c/source/i18n/strmatch.cpp", + "//third_party/icu/icu4c/source/i18n/decNumber.cpp", + "//third_party/icu/icu4c/source/i18n/nortrans.cpp", + "//third_party/icu/icu4c/source/i18n/sortkey.cpp", + "//third_party/icu/icu4c/source/i18n/ulistformatter.cpp", + "//third_party/icu/icu4c/source/i18n/tzgnames.cpp", + "//third_party/icu/icu4c/source/i18n/number_multiplier.cpp", + "//third_party/icu/icu4c/source/i18n/ztrans.cpp", + "//third_party/icu/icu4c/source/i18n/persncal.cpp", + "//third_party/icu/icu4c/source/i18n/number_utils.cpp", + "//third_party/icu/icu4c/source/i18n/csrmbcs.cpp", + "//third_party/icu/icu4c/source/i18n/taiwncal.cpp", + "//third_party/icu/icu4c/source/i18n/dtitvinf.cpp", + "//third_party/icu/icu4c/source/i18n/astro.cpp", + "//third_party/icu/icu4c/source/i18n/number_patternmodifier.cpp", + "//third_party/icu/icu4c/source/i18n/rulebasedcollator.cpp", + "//third_party/icu/icu4c/source/i18n/msgfmt.cpp", + "//third_party/icu/icu4c/source/i18n/stsearch.cpp", + "//third_party/icu/icu4c/source/i18n/number_affixutils.cpp", + "//third_party/icu/icu4c/source/i18n/quant.cpp", + "//third_party/icu/icu4c/source/i18n/calendar.cpp", + "//third_party/icu/icu4c/source/i18n/collationroot.cpp", + "//third_party/icu/icu4c/source/i18n/rbt_rule.cpp", + "//third_party/icu/icu4c/source/i18n/number_compact.cpp", + "//third_party/icu/icu4c/source/i18n/name2uni.cpp", + "//third_party/icu/icu4c/source/i18n/chnsecal.cpp", + "//third_party/icu/icu4c/source/i18n/csrutf8.cpp", + "//third_party/icu/icu4c/source/i18n/basictz.cpp", + "//third_party/icu/icu4c/source/i18n/reldtfmt.cpp", + "//third_party/icu/icu4c/source/i18n/nultrans.cpp", + "//third_party/icu/icu4c/source/i18n/number_grouping.cpp", + "//third_party/icu/icu4c/source/i18n/rbt_pars.cpp", + "//third_party/icu/icu4c/source/i18n/nounit.cpp", + "//third_party/icu/icu4c/source/i18n/winnmfmt.cpp", + "//third_party/icu/icu4c/source/i18n/uregexc.cpp", + "//third_party/icu/icu4c/source/i18n/fpositer.cpp", + "//third_party/icu/icu4c/source/i18n/tmutfmt.cpp", + "//third_party/icu/icu4c/source/i18n/compactdecimalformat.cpp", + "//third_party/icu/icu4c/source/i18n/numparse_decimal.cpp", + "//third_party/icu/icu4c/source/i18n/number_notation.cpp", + "//third_party/icu/icu4c/source/i18n/uspoof_conf.cpp", + "//third_party/icu/icu4c/source/i18n/utf16collationiterator.cpp", + "//third_party/icu/icu4c/source/i18n/udat.cpp", + "//third_party/icu/icu4c/source/i18n/number_skeletons.cpp", + "//third_party/icu/icu4c/source/i18n/utrans.cpp", + "//third_party/icu/icu4c/source/i18n/number_rounding.cpp", + "//third_party/icu/icu4c/source/i18n/double-conversion-bignum.cpp", + "//third_party/icu/icu4c/source/i18n/number_asformat.cpp", + "//third_party/icu/icu4c/source/i18n/double-conversion-string-to-double.cpp", + "//third_party/icu/icu4c/source/i18n/rbtz.cpp", + "//third_party/icu/icu4c/source/i18n/csrsbcs.cpp", + "//third_party/icu/icu4c/source/i18n/selfmt.cpp", + "//third_party/icu/icu4c/source/i18n/tztrans.cpp", + "//third_party/icu/icu4c/source/i18n/uspoof_impl.cpp", + "//third_party/icu/icu4c/source/i18n/regeximp.cpp", + "//third_party/icu/icu4c/source/i18n/measure.cpp", + "//third_party/icu/icu4c/source/i18n/fmtable_cnv.cpp", + "//third_party/icu/icu4c/source/i18n/uspoof.cpp", + "//third_party/icu/icu4c/source/i18n/gregoimp.cpp", + "//third_party/icu/icu4c/source/i18n/umsg.cpp", + "//third_party/icu/icu4c/source/i18n/numparse_symbols.cpp", + "//third_party/icu/icu4c/source/i18n/numrange_impl.cpp", + "//third_party/icu/icu4c/source/i18n/collationtailoring.cpp", + "//third_party/icu/icu4c/source/i18n/double-conversion-cached-powers.cpp", + "//third_party/icu/icu4c/source/i18n/udateintervalformat.cpp", + "//third_party/icu/icu4c/source/i18n/uni2name.cpp", + "//third_party/icu/icu4c/source/i18n/casetrn.cpp", + "//third_party/icu/icu4c/source/i18n/windtfmt.cpp", + "//third_party/icu/icu4c/source/i18n/listformatter.cpp", + "//third_party/icu/icu4c/source/i18n/uregion.cpp", + "//third_party/icu/icu4c/source/i18n/usearch.cpp", + "//third_party/icu/icu4c/source/i18n/brktrans.cpp", + "//third_party/icu/icu4c/source/i18n/gender.cpp", + "//third_party/icu/icu4c/source/i18n/collationruleparser.cpp", + "//third_party/icu/icu4c/source/i18n/rbt.cpp", + "//third_party/icu/icu4c/source/i18n/tzfmt.cpp", + "//third_party/icu/icu4c/source/i18n/dtfmtsym.cpp", + "//third_party/icu/icu4c/source/i18n/tolowtrn.cpp", + "//third_party/icu/icu4c/source/i18n/collationdatabuilder.cpp", + "//third_party/icu/icu4c/source/i18n/unumsys.cpp", + "//third_party/icu/icu4c/source/i18n/csrecog.cpp", + "//third_party/icu/icu4c/source/i18n/collationfastlatin.cpp", + "//third_party/icu/icu4c/source/i18n/esctrn.cpp", + "//third_party/icu/icu4c/source/i18n/collationdata.cpp", + "//third_party/icu/icu4c/source/i18n/titletrn.cpp", + "//third_party/icu/icu4c/source/i18n/ucal.cpp", + "//third_party/icu/icu4c/source/i18n/regexcmp.cpp", + "//third_party/icu/icu4c/source/i18n/wintzimpl.cpp", + "//third_party/icu/icu4c/source/i18n/decimfmt.cpp", + "//third_party/icu/icu4c/source/i18n/tmunit.cpp", + "//third_party/icu/icu4c/source/i18n/number_integerwidth.cpp", + "//third_party/icu/icu4c/source/i18n/ucsdet.cpp", + "//third_party/icu/icu4c/source/i18n/uspoof_build.cpp", + "//third_party/icu/icu4c/source/i18n/ucln_in.cpp", + "//third_party/icu/icu4c/source/i18n/measfmt.cpp", + "//third_party/icu/icu4c/source/i18n/formattedval_iterimpl.cpp", + "//third_party/icu/icu4c/source/i18n/toupptrn.cpp", + "//third_party/icu/icu4c/source/i18n/translit.cpp", + "//third_party/icu/icu4c/source/i18n/dtitvfmt.cpp", + "//third_party/icu/icu4c/source/i18n/dcfmtsym.cpp", + "//third_party/icu/icu4c/source/i18n/islamcal.cpp", + "//third_party/icu/icu4c/source/i18n/numrange_fluent.cpp", + "//third_party/icu/icu4c/source/i18n/gregocal.cpp", + "//third_party/icu/icu4c/source/i18n/zonemeta.cpp", + "//third_party/icu/icu4c/source/i18n/collationbuilder.cpp", + "//third_party/icu/icu4c/source/i18n/string_segment.cpp", + "//third_party/icu/icu4c/source/i18n/collationkeys.cpp", + "//third_party/icu/icu4c/source/i18n/coll.cpp", + "//third_party/icu/icu4c/source/i18n/uitercollationiterator.cpp", + "//third_party/icu/icu4c/source/i18n/nfsubs.cpp", + "//third_party/icu/icu4c/source/i18n/smpdtfst.cpp", + "//third_party/icu/icu4c/source/i18n/collationsettings.cpp", + "//third_party/icu/icu4c/source/i18n/formattedval_sbimpl.cpp", + "//third_party/icu/icu4c/source/i18n/strrepl.cpp", + "//third_party/icu/icu4c/source/i18n/standardplural.cpp", + "//third_party/icu/icu4c/source/i18n/ucol_res.cpp", + "//third_party/icu/icu4c/source/i18n/repattrn.cpp", + "//third_party/icu/icu4c/source/i18n/tznames_impl.cpp", + "//third_party/icu/icu4c/source/i18n/numparse_compositions.cpp", + "//third_party/icu/icu4c/source/i18n/rbt_set.cpp", + "//third_party/icu/icu4c/source/i18n/currpinf.cpp", + "//third_party/icu/icu4c/source/i18n/collationsets.cpp", + "//third_party/icu/icu4c/source/i18n/cecal.cpp", + "//third_party/icu/icu4c/source/i18n/tzrule.cpp", + "//third_party/icu/icu4c/source/i18n/collationiterator.cpp", + "//third_party/icu/icu4c/source/i18n/numparse_scientific.cpp", + "//third_party/icu/icu4c/source/i18n/number_patternstring.cpp", + "//third_party/icu/icu4c/source/i18n/utf8collationiterator.cpp", + "//third_party/icu/icu4c/source/i18n/sharedbreakiterator.cpp", + "//third_party/icu/icu4c/source/i18n/number_fluent.cpp", + "//third_party/icu/icu4c/source/i18n/measunit.cpp", + "//third_party/icu/icu4c/source/i18n/collationcompare.cpp", + "//third_party/icu/icu4c/source/i18n/number_formatimpl.cpp", + "//third_party/icu/icu4c/source/i18n/number_decimfmtprops.cpp", + "//third_party/icu/icu4c/source/i18n/nfrs.cpp", + "//third_party/icu/icu4c/source/i18n/tznames.cpp", + "//third_party/icu/icu4c/source/i18n/remtrans.cpp", + "//third_party/icu/icu4c/source/i18n/nfrule.cpp", +] + +ohos_shared_library("shared_icuuc") { + configs = [ + ":icu_config", + "$build_root/config/compiler:rtti", + ] + deps = [ ":static_icustubdata" ] + defines = [ + "U_ATTRIBUTE_DEPRECATED=", + "U_COMMON_IMPLEMENTATION", + "UPRV_BLOCK_MACRO_BEGIN=", + "UPRV_BLOCK_MACRO_END=", + "UCONFIG_USE_WINDOWS_LCID_MAPPING_API=0", + "_REENTRANT", + ] + sources = icu_common_source + cflags_cc = [ + "-O3", + "-W", + "-Wall", + "-pedantic", + "-Wpointer-arith", + "-Wwrite-strings", + "-Wno-error=unused-parameter", + "-Wno-error=unused-const-variable", + "-Wno-error=unneeded-internal-declaration", + "-std=c++11", + "-Wno-ignored-attributes", + ] + ldflags = [ + "-shared", + "-lm", + ] + output_name = "hmicuuc" +} + +ohos_shared_library("shared_icui18n") { + sources = icu_i18n_source + configs = [ + ":icu_config", + "$build_root/config/compiler:rtti", + ] + deps = [ ":shared_icuuc" ] + defines = [ + "U_ATTRIBUTE_DEPRECATED=", + "U_I18N_IMPLEMENTATION", + "UPRV_BLOCK_MACRO_BEGIN=", + "UPRV_BLOCK_MACRO_END=", + "_REENTRANT", + "PIC", + ] + cflags_cc = [ + "-O3", + "-W", + "-Wall", + "-pedantic", + "-Wpointer-arith", + "-Wno-error=unused-parameter", + "-Wno-error=unused-const-variable", + "-Wno-error=implicit-float-conversion", + "-Wno-error=unneeded-internal-declaration", + "-Wwrite-strings", + "-std=c++11", + "-Wno-ignored-attributes", + ] + ldflags = [ + "-shared", + "-lm", + ] + if (!is_mingw) { + cflags_cc += [ "-fPIC" ] + ldflags += [ "-ldl" ] + } + output_name = "hmicui18n" +} + +ohos_static_library("static_icuuc") { + configs = [ + ":icu_config", + "$build_root/config/compiler:rtti", + ] + deps = [ ":static_icustubdata" ] + defines = [ + "U_ATTRIBUTE_DEPRECATED=", + "U_COMMON_IMPLEMENTATION", + "U_STATIC_IMPLEMENTATION", + "UPRV_BLOCK_MACRO_BEGIN=", + "UPRV_BLOCK_MACRO_END=", + "UCONFIG_USE_WINDOWS_LCID_MAPPING_API=0", + "_REENTRANT", + ] + sources = icu_common_source + cflags_cc = [ + "-Os", + "-W", + "-Wall", + "-pedantic", + "-Wpointer-arith", + "-Wwrite-strings", + "-std=c++11", + "-Wno-error=unused-parameter", + "-Wno-error=unused-const-variable", + "-Wno-error=unneeded-internal-declaration", + "-fvisibility-inlines-hidden", + "-Wno-unused-function", + "-Wno-ignored-attributes", + ] + + cflags = [ + "-fvisibility=hidden", + "-fdata-sections", + "-ffunction-sections", + "-Os", + "-Wno-unused-function", + ] + + ldflags = [ + "-static", + "-ldl", + "-lm", + ] + + output_name = "hmicuuc" +} + +ohos_static_library("static_icui18n") { + sources = icu_i18n_source + configs = [ + ":icu_config", + "$build_root/config/compiler:rtti", + ] + deps = [ ":static_icuuc" ] + defines = [ + "U_ATTRIBUTE_DEPRECATED=", + "U_I18N_IMPLEMENTATION", + "U_STATIC_IMPLEMENTATION", + "UPRV_BLOCK_MACRO_BEGIN=", + "UPRV_BLOCK_MACRO_END=", + "_REENTRANT", + "PIC", + ] + + cflags_cc = [ + "-Os", + "-W", + "-Wall", + "-pedantic", + "-Wpointer-arith", + "-Wwrite-strings", + "-Wno-error=unused-parameter", + "-Wno-error=unused-const-variable", + "-Wno-error=implicit-float-conversion", + "-Wno-error=unneeded-internal-declaration", + "-std=c++11", + "-fvisibility-inlines-hidden", + "-fno-exceptions", + "-Wno-ignored-attributes", + ] + + if (is_mingw) { + cflags_cc += [ "-DWINVER=0x0601" ] + } else { + cflags_cc += [ "-fPIC" ] + } + + cflags = [ + "-fvisibility=hidden", + "-fdata-sections", + "-ffunction-sections", + "-Os", + ] + + ldflags = [ + "-static", + "-ldl", + "-lm", + ] + output_name = "hmicui18n" +} diff --git a/build/third_party_gn/protobuf/BUILD.gn b/build/third_party_gn/protobuf/BUILD.gn new file mode 100644 index 00000000..6c263fbc --- /dev/null +++ b/build/third_party_gn/protobuf/BUILD.gn @@ -0,0 +1,416 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +if (defined(ark_standalone_build)) { + import("//profiler//build/config.gni") + import("$build_root/ark.gni") +} else { + import("//build/ohos.gni") + import("//developtools/profiler/build/config.gni") +} + +protobuf_src_root = "//third_party/protobuf/src/" + +config("protobuf_config") { + include_dirs = [ "$protobuf_src_root" ] +} + +ohos_shared_library("protobuf_lite") { + sources = [ + "$protobuf_src_root/google/protobuf/any_lite.cc", + "$protobuf_src_root/google/protobuf/arena.cc", + "$protobuf_src_root/google/protobuf/extension_set.cc", + "$protobuf_src_root/google/protobuf/generated_enum_util.cc", + "$protobuf_src_root/google/protobuf/generated_message_table_driven_lite.cc", + "$protobuf_src_root/google/protobuf/generated_message_util.cc", + "$protobuf_src_root/google/protobuf/implicit_weak_message.cc", + "$protobuf_src_root/google/protobuf/io/coded_stream.cc", + "$protobuf_src_root/google/protobuf/io/io_win32.cc", + "$protobuf_src_root/google/protobuf/io/strtod.cc", + "$protobuf_src_root/google/protobuf/io/zero_copy_stream.cc", + "$protobuf_src_root/google/protobuf/io/zero_copy_stream_impl.cc", + "$protobuf_src_root/google/protobuf/io/zero_copy_stream_impl_lite.cc", + "$protobuf_src_root/google/protobuf/message_lite.cc", + "$protobuf_src_root/google/protobuf/parse_context.cc", + "$protobuf_src_root/google/protobuf/repeated_field.cc", + "$protobuf_src_root/google/protobuf/stubs/bytestream.cc", + "$protobuf_src_root/google/protobuf/stubs/common.cc", + "$protobuf_src_root/google/protobuf/stubs/int128.cc", + "$protobuf_src_root/google/protobuf/stubs/status.cc", + "$protobuf_src_root/google/protobuf/stubs/statusor.cc", + "$protobuf_src_root/google/protobuf/stubs/stringpiece.cc", + "$protobuf_src_root/google/protobuf/stubs/stringprintf.cc", + "$protobuf_src_root/google/protobuf/stubs/structurally_valid.cc", + "$protobuf_src_root/google/protobuf/stubs/strutil.cc", + "$protobuf_src_root/google/protobuf/stubs/time.cc", + "$protobuf_src_root/google/protobuf/wire_format_lite.cc", + ] + include_dirs = [ + "$protobuf_src_root/google/protobuf/**/*.h", + "$protobuf_src_root/google/protobuf/**/*.inc", + "$protobuf_src_root", + ] + if (!is_mingw) { + if (current_toolchain != host_toolchain) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } + } else { + defines = [ "_FILE_OFFSET_BITS_SET_LSEEK" ] + } + + cflags_cc = [ "-Wno-sign-compare" ] + cflags = [ + "-Wno-sign-compare", + "-D HAVE_PTHREAD", + ] + + public_configs = [ ":protobuf_config" ] + install_enable = true + subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}" + part_name = "${OHOS_PROFILER_PART_NAME}" +} + +ohos_static_library("protobuf_lite_static") { + sources = [ + "$protobuf_src_root/google/protobuf/any_lite.cc", + "$protobuf_src_root/google/protobuf/arena.cc", + "$protobuf_src_root/google/protobuf/extension_set.cc", + "$protobuf_src_root/google/protobuf/generated_enum_util.cc", + "$protobuf_src_root/google/protobuf/generated_message_table_driven_lite.cc", + "$protobuf_src_root/google/protobuf/generated_message_util.cc", + "$protobuf_src_root/google/protobuf/implicit_weak_message.cc", + "$protobuf_src_root/google/protobuf/io/coded_stream.cc", + "$protobuf_src_root/google/protobuf/io/io_win32.cc", + "$protobuf_src_root/google/protobuf/io/strtod.cc", + "$protobuf_src_root/google/protobuf/io/zero_copy_stream.cc", + "$protobuf_src_root/google/protobuf/io/zero_copy_stream_impl.cc", + "$protobuf_src_root/google/protobuf/io/zero_copy_stream_impl_lite.cc", + "$protobuf_src_root/google/protobuf/message_lite.cc", + "$protobuf_src_root/google/protobuf/parse_context.cc", + "$protobuf_src_root/google/protobuf/repeated_field.cc", + "$protobuf_src_root/google/protobuf/stubs/bytestream.cc", + "$protobuf_src_root/google/protobuf/stubs/common.cc", + "$protobuf_src_root/google/protobuf/stubs/int128.cc", + "$protobuf_src_root/google/protobuf/stubs/status.cc", + "$protobuf_src_root/google/protobuf/stubs/statusor.cc", + "$protobuf_src_root/google/protobuf/stubs/stringpiece.cc", + "$protobuf_src_root/google/protobuf/stubs/stringprintf.cc", + "$protobuf_src_root/google/protobuf/stubs/structurally_valid.cc", + "$protobuf_src_root/google/protobuf/stubs/strutil.cc", + "$protobuf_src_root/google/protobuf/stubs/time.cc", + "$protobuf_src_root/google/protobuf/wire_format_lite.cc", + ] + include_dirs = [ + "$protobuf_src_root/google/protobuf/**/*.h", + "$protobuf_src_root/google/protobuf/**/*.inc", + "$protobuf_src_root", + ] + if (!is_mingw) { + if (default_toolchain == current_toolchain) { + # target build, not host build + defines = [ "HAVE_HILOG" ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } + } else { + defines = [ "_FILE_OFFSET_BITS_SET_LSEEK" ] + } + + cflags_cc = [ "-Wno-sign-compare" ] + cflags = [ + "-Wno-sign-compare", + "-D HAVE_PTHREAD", + ] + if (is_mingw) { + # ../../third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc:60:9: error: 'lseek' macro redefined [-Werror,-Wmacro-redefined] + cflags += [ "-Wno-macro-redefined" ] + } + public_configs = [ ":protobuf_config" ] +} + +ohos_shared_library("protobuf") { + sources = [ + "$protobuf_src_root/google/protobuf/any.cc", + "$protobuf_src_root/google/protobuf/any.pb.cc", + "$protobuf_src_root/google/protobuf/api.pb.cc", + "$protobuf_src_root/google/protobuf/compiler/importer.cc", + "$protobuf_src_root/google/protobuf/compiler/parser.cc", + "$protobuf_src_root/google/protobuf/descriptor.cc", + "$protobuf_src_root/google/protobuf/descriptor.pb.cc", + "$protobuf_src_root/google/protobuf/descriptor_database.cc", + "$protobuf_src_root/google/protobuf/duration.pb.cc", + "$protobuf_src_root/google/protobuf/dynamic_message.cc", + "$protobuf_src_root/google/protobuf/empty.pb.cc", + "$protobuf_src_root/google/protobuf/extension_set_heavy.cc", + "$protobuf_src_root/google/protobuf/field_mask.pb.cc", + "$protobuf_src_root/google/protobuf/generated_message_reflection.cc", + "$protobuf_src_root/google/protobuf/generated_message_table_driven.cc", + "$protobuf_src_root/google/protobuf/io/gzip_stream.cc", + "$protobuf_src_root/google/protobuf/io/printer.cc", + "$protobuf_src_root/google/protobuf/io/tokenizer.cc", + "$protobuf_src_root/google/protobuf/map_field.cc", + "$protobuf_src_root/google/protobuf/message.cc", + "$protobuf_src_root/google/protobuf/reflection_ops.cc", + "$protobuf_src_root/google/protobuf/service.cc", + "$protobuf_src_root/google/protobuf/source_context.pb.cc", + "$protobuf_src_root/google/protobuf/struct.pb.cc", + "$protobuf_src_root/google/protobuf/stubs/substitute.cc", + "$protobuf_src_root/google/protobuf/text_format.cc", + "$protobuf_src_root/google/protobuf/timestamp.pb.cc", + "$protobuf_src_root/google/protobuf/type.pb.cc", + "$protobuf_src_root/google/protobuf/unknown_field_set.cc", + "$protobuf_src_root/google/protobuf/util/delimited_message_util.cc", + "$protobuf_src_root/google/protobuf/util/field_comparator.cc", + "$protobuf_src_root/google/protobuf/util/field_mask_util.cc", + "$protobuf_src_root/google/protobuf/util/internal/datapiece.cc", + "$protobuf_src_root/google/protobuf/util/internal/default_value_objectwriter.cc", + "$protobuf_src_root/google/protobuf/util/internal/error_listener.cc", + "$protobuf_src_root/google/protobuf/util/internal/field_mask_utility.cc", + "$protobuf_src_root/google/protobuf/util/internal/json_escaping.cc", + "$protobuf_src_root/google/protobuf/util/internal/json_objectwriter.cc", + "$protobuf_src_root/google/protobuf/util/internal/json_stream_parser.cc", + "$protobuf_src_root/google/protobuf/util/internal/object_writer.cc", + "$protobuf_src_root/google/protobuf/util/internal/proto_writer.cc", + "$protobuf_src_root/google/protobuf/util/internal/protostream_objectsource.cc", + "$protobuf_src_root/google/protobuf/util/internal/protostream_objectwriter.cc", + "$protobuf_src_root/google/protobuf/util/internal/type_info.cc", + "$protobuf_src_root/google/protobuf/util/internal/type_info_test_helper.cc", + "$protobuf_src_root/google/protobuf/util/internal/utility.cc", + "$protobuf_src_root/google/protobuf/util/json_util.cc", + "$protobuf_src_root/google/protobuf/util/message_differencer.cc", + "$protobuf_src_root/google/protobuf/util/time_util.cc", + "$protobuf_src_root/google/protobuf/util/type_resolver_util.cc", + "$protobuf_src_root/google/protobuf/wire_format.cc", + "$protobuf_src_root/google/protobuf/wrappers.pb.cc", + ] + include_dirs = [ + "$protobuf_src_root/google/protobuf/**/*.h", + "$protobuf_src_root/google/protobuf/**/*.inc", + "$protobuf_src_root", + ] + cflags_cc = [ "-Wno-sign-compare" ] + cflags = [ + "-Wno-sign-compare", + "-D HAVE_PTHREAD", + ] + + deps = [ ":protobuf_lite" ] + + public_configs = [ ":protobuf_config" ] + install_enable = true + subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}" + part_name = "${OHOS_PROFILER_PART_NAME}" +} + +ohos_static_library("protobuf_static") { + sources = [ + "$protobuf_src_root/google/protobuf/any.cc", + "$protobuf_src_root/google/protobuf/any.pb.cc", + "$protobuf_src_root/google/protobuf/api.pb.cc", + "$protobuf_src_root/google/protobuf/compiler/importer.cc", + "$protobuf_src_root/google/protobuf/compiler/parser.cc", + "$protobuf_src_root/google/protobuf/descriptor.cc", + "$protobuf_src_root/google/protobuf/descriptor.pb.cc", + "$protobuf_src_root/google/protobuf/descriptor_database.cc", + "$protobuf_src_root/google/protobuf/duration.pb.cc", + "$protobuf_src_root/google/protobuf/dynamic_message.cc", + "$protobuf_src_root/google/protobuf/empty.pb.cc", + "$protobuf_src_root/google/protobuf/extension_set_heavy.cc", + "$protobuf_src_root/google/protobuf/field_mask.pb.cc", + "$protobuf_src_root/google/protobuf/generated_message_reflection.cc", + "$protobuf_src_root/google/protobuf/generated_message_table_driven.cc", + "$protobuf_src_root/google/protobuf/io/gzip_stream.cc", + "$protobuf_src_root/google/protobuf/io/printer.cc", + "$protobuf_src_root/google/protobuf/io/tokenizer.cc", + "$protobuf_src_root/google/protobuf/map_field.cc", + "$protobuf_src_root/google/protobuf/message.cc", + "$protobuf_src_root/google/protobuf/reflection_ops.cc", + "$protobuf_src_root/google/protobuf/service.cc", + "$protobuf_src_root/google/protobuf/source_context.pb.cc", + "$protobuf_src_root/google/protobuf/struct.pb.cc", + "$protobuf_src_root/google/protobuf/stubs/substitute.cc", + "$protobuf_src_root/google/protobuf/text_format.cc", + "$protobuf_src_root/google/protobuf/timestamp.pb.cc", + "$protobuf_src_root/google/protobuf/type.pb.cc", + "$protobuf_src_root/google/protobuf/unknown_field_set.cc", + "$protobuf_src_root/google/protobuf/util/delimited_message_util.cc", + "$protobuf_src_root/google/protobuf/util/field_comparator.cc", + "$protobuf_src_root/google/protobuf/util/field_mask_util.cc", + "$protobuf_src_root/google/protobuf/util/internal/datapiece.cc", + "$protobuf_src_root/google/protobuf/util/internal/default_value_objectwriter.cc", + "$protobuf_src_root/google/protobuf/util/internal/error_listener.cc", + "$protobuf_src_root/google/protobuf/util/internal/field_mask_utility.cc", + "$protobuf_src_root/google/protobuf/util/internal/json_escaping.cc", + "$protobuf_src_root/google/protobuf/util/internal/json_objectwriter.cc", + "$protobuf_src_root/google/protobuf/util/internal/json_stream_parser.cc", + "$protobuf_src_root/google/protobuf/util/internal/object_writer.cc", + "$protobuf_src_root/google/protobuf/util/internal/proto_writer.cc", + "$protobuf_src_root/google/protobuf/util/internal/protostream_objectsource.cc", + "$protobuf_src_root/google/protobuf/util/internal/protostream_objectwriter.cc", + "$protobuf_src_root/google/protobuf/util/internal/type_info.cc", + "$protobuf_src_root/google/protobuf/util/internal/type_info_test_helper.cc", + "$protobuf_src_root/google/protobuf/util/internal/utility.cc", + "$protobuf_src_root/google/protobuf/util/json_util.cc", + "$protobuf_src_root/google/protobuf/util/message_differencer.cc", + "$protobuf_src_root/google/protobuf/util/time_util.cc", + "$protobuf_src_root/google/protobuf/util/type_resolver_util.cc", + "$protobuf_src_root/google/protobuf/wire_format.cc", + "$protobuf_src_root/google/protobuf/wrappers.pb.cc", + ] + include_dirs = [ + "$protobuf_src_root/google/protobuf/**/*.h", + "$protobuf_src_root/google/protobuf/**/*.inc", + "$protobuf_src_root", + ] + cflags_cc = [ "-Wno-sign-compare" ] + cflags = [ + "-Wno-sign-compare", + "-D HAVE_PTHREAD", + ] + + deps = [ ":protobuf_lite_static" ] + + public_configs = [ ":protobuf_config" ] +} + +if (current_toolchain == host_toolchain) { + ohos_shared_library("protoc_lib") { + sources = [ + "$protobuf_src_root/google/protobuf/compiler/code_generator.cc", + "$protobuf_src_root/google/protobuf/compiler/command_line_interface.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_enum.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_enum_field.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_extension.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_field.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_file.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_generator.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_helpers.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_map_field.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_message.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_message_field.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_primitive_field.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_service.cc", + "$protobuf_src_root/google/protobuf/compiler/cpp/cpp_string_field.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_doc_comment.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_enum.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_enum_field.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_field_base.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_generator.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_helpers.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_map_field.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_message.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_message_field.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_primitive_field.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_reflection_class.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_source_generator_base.cc", + "$protobuf_src_root/google/protobuf/compiler/csharp/csharp_wrapper_field.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_context.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_doc_comment.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_enum.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_enum_field.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_enum_field_lite.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_enum_lite.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_extension.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_extension_lite.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_field.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_file.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_generator.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_generator_factory.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_helpers.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_map_field.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_map_field_lite.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_message.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_message_builder.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_message_builder_lite.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_message_field.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_message_field_lite.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_message_lite.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_name_resolver.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_primitive_field.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_primitive_field_lite.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_service.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_shared_code_generator.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_string_field.cc", + "$protobuf_src_root/google/protobuf/compiler/java/java_string_field_lite.cc", + "$protobuf_src_root/google/protobuf/compiler/js/js_generator.cc", + "$protobuf_src_root/google/protobuf/compiler/js/well_known_types_embed.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_enum.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_enum_field.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_extension.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_field.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_file.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_generator.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_helpers.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_map_field.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_message.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_message_field.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_oneof.cc", + "$protobuf_src_root/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc", + "$protobuf_src_root/google/protobuf/compiler/php/php_generator.cc", + "$protobuf_src_root/google/protobuf/compiler/plugin.cc", + "$protobuf_src_root/google/protobuf/compiler/plugin.pb.cc", + "$protobuf_src_root/google/protobuf/compiler/python/python_generator.cc", + "$protobuf_src_root/google/protobuf/compiler/ruby/ruby_generator.cc", + "$protobuf_src_root/google/protobuf/compiler/subprocess.cc", + "$protobuf_src_root/google/protobuf/compiler/zip_writer.cc", + ] + include_dirs = [ + "$protobuf_src_root/google/protobuf/**/*.h", + "$protobuf_src_root/google/protobuf/**/*.inc", + "$protobuf_src_root", + ] + cflags_cc = [ + "-Wno-sign-compare", + "-Wno-unused-function", + "-Wno-unused-private-field", + ] + cflags = [ + "-Wno-sign-compare", + "-D HAVE_PTHREAD", + "-Wno-unused-function", + ] + + deps = [ + ":protobuf", + ":protobuf_lite", + ] + + public_configs = [ ":protobuf_config" ] + subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}" + part_name = "${OHOS_PROFILER_PART_NAME}" + } +} + +# Only compile the plugin for the host architecture. +if (current_toolchain == host_toolchain) { + ohos_executable("protoc") { + sources = [ "$protobuf_src_root/google/protobuf/compiler/main.cc" ] + include_dirs = [ + "$protobuf_src_root/google/protobuf/**/*.h", + "$protobuf_src_root/google/protobuf/**/*.inc", + "$protobuf_src_root", + ] + deps = [ ":protoc_lib" ] + cflags_cc = [ "-Wno-sign-compare" ] + cflags = [ + "-Wno-sign-compare", + "-D HAVE_PTHREAD", + ] + + subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}" + part_name = "${OHOS_PROFILER_PART_NAME}" + } +} diff --git a/build/third_party_gn/zlib/BUILD.gn b/build/third_party_gn/zlib/BUILD.gn new file mode 100644 index 00000000..f0b9f191 --- /dev/null +++ b/build/third_party_gn/zlib/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("$build_root/ark.gni") + +config("zlib_config") { + cflags = [ + "-Wno-incompatible-pointer-types", + "-Werror", + "-Wimplicit-function-declaration", + "-fPIC", + ] +} + +config("zlib_public_config") { + include_dirs = [ "." ] +} + +ohos_static_library("libz") { + sources = [ + "//third_party/zlib/adler32.c", + "//third_party/zlib/compress.c", + "//third_party/zlib/contrib/minizip/ioapi.c", + "//third_party/zlib/contrib/minizip/unzip.c", + "//third_party/zlib/contrib/minizip/zip.c", + "//third_party/zlib/crc32.c", + "//third_party/zlib/crc32.h", + "//third_party/zlib/deflate.c", + "//third_party/zlib/deflate.h", + "//third_party/zlib/gzclose.c", + "//third_party/zlib/gzguts.h", + "//third_party/zlib/gzlib.c", + "//third_party/zlib/gzread.c", + "//third_party/zlib/gzwrite.c", + "//third_party/zlib/infback.c", + "//third_party/zlib/inffast.c", + "//third_party/zlib/inffast.h", + "//third_party/zlib/inffixed.h", + "//third_party/zlib/inflate.c", + "//third_party/zlib/inflate.h", + "//third_party/zlib/inftrees.c", + "//third_party/zlib/inftrees.h", + "//third_party/zlib/trees.c", + "//third_party/zlib/trees.h", + "//third_party/zlib/uncompr.c", + "//third_party/zlib/zconf.h", + "//third_party/zlib/zlib.h", + "//third_party/zlib/zutil.c", + "//third_party/zlib/zutil.h", + ] + configs = [ ":zlib_config" ] + public_configs = [ ":zlib_public_config" ] +} diff --git a/build/toolchain/ark/BUILD.gn b/build/toolchain/ark/BUILD.gn new file mode 100755 index 00000000..05a62413 --- /dev/null +++ b/build/toolchain/ark/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("$build_root/toolchain/ark/ark_toolchain.gni") + +ark_clang_toolchain("ark_clang_arm") { + toolchain_args = { + current_cpu = "arm" + current_os = "ohos" + } +} + +ark_clang_toolchain("ark_clang_x64") { + toolchain_args = { + current_cpu = "x64" + current_os = "ohos" + } +} + +ark_clang_toolchain("ark_clang_android_arm") { + toolchain_args = { + current_cpu = "arm" + current_os = "android" + } +} + +ark_clang_toolchain("ark_clang_android_arm64") { + toolchain_args = { + current_cpu = "arm64" + current_os = "android" + } +} + +ark_clang_toolchain("ark_clang_ios_arm") { + toolchain_args = { + current_cpu = "arm64" + current_os = "ios" + } +} + +ark_clang_toolchain("ark_clang_arm64") { + toolchain_args = { + current_cpu = "arm64" + current_os = "ohos" + } +} diff --git a/build/toolchain/ark/ark_toolchain.gni b/build/toolchain/ark/ark_toolchain.gni new file mode 100755 index 00000000..56d707e1 --- /dev/null +++ b/build/toolchain/ark/ark_toolchain.gni @@ -0,0 +1,45 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("$build_root/toolchain/gcc_toolchain.gni") + +template("ark_clang_toolchain") { + gcc_toolchain(target_name) { + prefix = rebase_path("$clang_base_path/bin", root_build_dir) + cc = "$prefix/clang" + cxx = "$prefix/clang++" + ld = cxx + readelf = "$prefix/llvm-readobj" + ar = "${prefix}/llvm-ar" + nm = "$prefix/llvm-nm" + + forward_variables_from(invoker, + [ + "strip", + "is_clang_analysis_supported", + "enable_linker_map", + "use_unstripped_as_runtime_outputs", + ]) + + toolchain_args = { + if (defined(invoker.toolchain_args)) { + forward_variables_from(invoker.toolchain_args, "*") + } + is_clang = true + } + + if (defined(invoker.shlib_extension) && invoker.shlib_extension != "") { + shlib_extension = invoker.shlib_extension + } + } +} diff --git a/build/toolchain/cc_wrapper.gni b/build/toolchain/cc_wrapper.gni new file mode 100755 index 00000000..0c682700 --- /dev/null +++ b/build/toolchain/cc_wrapper.gni @@ -0,0 +1,51 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +# Defines the configuration of cc wrapper +# ccache: a c/c++ compiler cache which can greatly reduce recompilation times. +# icecc, distcc: it takes compile jobs from a build and distributes them among +# remote machines allowing a parallel build. +# +# TIPS +# +# 1) ccache +# Set clang_use_chrome_plugins=false if using ccache 3.1.9 or earlier, since +# these versions don't support -Xclang. (3.1.10 and later will silently +# ignore -Xclang, so it doesn't matter if you disable clang_use_chrome_plugins +# or not). +# +# Use ccache 3.2 or later to avoid clang unused argument warnings: +# https://bugzilla.samba.org/show_bug.cgi?id=8118 +# +# To avoid -Wparentheses-equality clang warnings, at some cost in terms of +# speed, you can do: +# export CCACHE_CPP2=yes +# +# 2) icecc +# Set clang_use_chrome_plugins=false because icecc cannot distribute custom +# clang libraries. +# +# To use icecc and ccache together, set cc_wrapper = "ccache" with +# export CCACHE_PREFIX=icecc + +_cc_wrapper = "" +_ccache_exec = getenv("CCACHE_EXEC") +_use_ccache = getenv("USE_CCACHE") +if (_use_ccache == "1" && _ccache_exec != "") { + _cc_wrapper = rebase_path(_ccache_exec) +} + +declare_args() { + # Set to "ccache", "icecc" or "distcc". Probably doesn't work on windows. + cc_wrapper = _cc_wrapper +} diff --git a/build/toolchain/clang_static_analyzer.gni b/build/toolchain/clang_static_analyzer.gni new file mode 100755 index 00000000..c92b4903 --- /dev/null +++ b/build/toolchain/clang_static_analyzer.gni @@ -0,0 +1,20 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +# Defines the configuration of Clang static analysis tools. +# See docs/clang_static_analyzer.md for more information. + +declare_args() { + # Uses the Clang static analysis tools during compilation. + use_clang_static_analyzer = false +} diff --git a/build/toolchain/gcc_link_wrapper.py b/build/toolchain/gcc_link_wrapper.py new file mode 100755 index 00000000..0a248d42 --- /dev/null +++ b/build/toolchain/gcc_link_wrapper.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Runs a linking command and optionally a strip command. + +This script exists to avoid using complex shell commands in +gcc_toolchain.gni's tool("link"), in case the host running the compiler +does not have a POSIX-like shell (e.g. Windows). +""" + +import argparse +import os +import subprocess +import sys + +import wrapper_utils + +# When running on a Windows host and using a toolchain whose tools are +# actually wrapper scripts (i.e. .bat files on Windows) rather than binary +# executables, the "command" to run has to be prefixed with this magic. +# The GN toolchain definitions take care of that for when GN/Ninja is +# running the tool directly. When that command is passed in to this +# script, it appears as a unitary string but needs to be split up so that +# just 'cmd' is the actual command given to Python's subprocess module. +BAT_PREFIX = 'cmd /c call ' + + +def command_to_run(command): + if command[0].startswith(BAT_PREFIX): + command = command[0].split(None, 3) + command[1:] + return command + + +def is_static_link(command): + if "-static" in command: + return True + else: + return False + + +""" since static link and dynamic link have different CRT files on ohos, +and we use dynamic link CRT files as default, so when link statically, +we need change the CRT files +""" + + +def update_crt(command): + for item in command: + if str(item).find("crtbegin_dynamic.o") >= 0: + index = command.index(item) + new_crtbegin = str(item).replace("crtbegin_dynamic.o", + "crtbegin_static.o") + command[index] = new_crtbegin + return command + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--strip', + help='The strip binary to run', + metavar='PATH') + parser.add_argument('--unstripped-file', + help='Executable file produced by linking command', + metavar='FILE') + parser.add_argument('--map-file', + help=('Use --Wl,-Map to generate a map file. Will be ' + 'gzipped if extension ends with .gz'), + metavar='FILE') + parser.add_argument('--output', + required=True, + help='Final output executable file', + metavar='FILE') + parser.add_argument('--clang_rt_dso_path', + help=('Clang asan runtime shared library')) + parser.add_argument('command', nargs='+', help='Linking command') + args = parser.parse_args() + + # Work-around for gold being slow-by-default. http://crbug.com/632230 + fast_env = dict(os.environ) + fast_env['LC_ALL'] = 'C' + if is_static_link(args.command): + command = update_crt(args.command) + if args.clang_rt_dso_path is not None: + return 0 + else: + command = args.command + result = wrapper_utils.run_link_with_optional_map_file( + command, env=fast_env, map_file=args.map_file) + if result != 0: + return result + + # Finally, strip the linked executable (if desired). + if args.strip: + result = subprocess.call( + command_to_run( + [args.strip, '-o', args.output, args.unstripped_file])) + + return result + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/build/toolchain/gcc_solink_wrapper.py b/build/toolchain/gcc_solink_wrapper.py new file mode 100755 index 00000000..7bf11798 --- /dev/null +++ b/build/toolchain/gcc_solink_wrapper.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Runs 'ld -shared' and generates a .TOC file that's untouched when unchanged. + +This script exists to avoid using complex shell commands in +gcc_toolchain.gni's tool("solink"), in case the host running the compiler +does not have a POSIX-like shell (e.g. Windows). +""" + +import argparse +import os +import subprocess +import sys +import shutil + +import wrapper_utils + + +def collect_soname(args): + """Replaces: readelf -d $sofile | grep SONAME""" + toc = '' + readelf = subprocess.Popen(wrapper_utils.command_to_run( + [args.readelf, '-d', args.sofile]), + stdout=subprocess.PIPE, + bufsize=-1) + for line in readelf.stdout: + if b'SONAME' in line: + toc += line.decode() + return readelf.wait(), toc + + +def collect_dyn_sym(args): + """Replaces: nm --format=posix -g -D $sofile | cut -f1-2 -d' '""" + toc = '' + _command = [args.nm] + if args.sofile.endswith('.dll'): + _command.append('--extern-only') + else: + _command.extend(['--format=posix', '-g', '-D']) + _command.append(args.sofile) + nm = subprocess.Popen(wrapper_utils.command_to_run(_command), + stdout=subprocess.PIPE, + bufsize=-1) + for line in nm.stdout: + toc += '{}\n'.format(' '.join(line.decode().split(' ', 2)[:2])) + return nm.wait(), toc + + +def collect_toc(args): + result, toc = collect_soname(args) + if result == 0: + result, dynsym = collect_dyn_sym(args) + toc += dynsym + return result, toc + + +def update_toc(tocfile, toc): + if os.path.exists(tocfile): + with open(tocfile, 'r') as f: + old_toc = f.read() + else: + old_toc = None + if toc != old_toc: + with open(tocfile, 'w') as fp: + fp.write(toc) + + +def reformat_rsp_file(rspfile): + """ Move all implibs from --whole-archive section""" + with open(rspfile, "r") as fi: + rspcontent = fi.read() + result = [] + implibs = [] + naflag = False + for arg in rspcontent.split(" "): + if naflag and arg.endswith(".lib"): + implibs.append(arg) + continue + result.append(arg) + if arg == "-Wl,--whole-archive": + naflag = True + continue + if arg == "-Wl,--no-whole-archive": + naflag = False + result.extend(implibs) + + with open(rspfile, "w") as fo: + fo.write(" ".join(result)) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--readelf', + required=True, + help='The readelf binary to run', + metavar='PATH') + parser.add_argument('--nm', + required=True, + help='The nm binary to run', + metavar='PATH') + parser.add_argument('--strip', + help='The strip binary to run', + metavar='PATH') + parser.add_argument('--sofile', + required=True, + help='Shared object file produced by linking command', + metavar='FILE') + parser.add_argument('--tocfile', + required=False, + help='Output table-of-contents file', + metavar='FILE') + parser.add_argument('--map-file', + help=('Use --Wl,-Map to generate a map file. Will be ' + 'gzipped if extension ends with .gz'), + metavar='FILE') + parser.add_argument('--output', + required=True, + help='Final output shared object file', + metavar='FILE') + parser.add_argument('--libfile', required=False, metavar='FILE') + parser.add_argument('command', nargs='+', help='Linking command') + args = parser.parse_args() + + if args.sofile.endswith(".dll"): + rspfile = None + for a in args.command: + if a[0] == "@": + rspfile = a[1:] + break + if rspfile: + reformat_rsp_file(rspfile) + # Work-around for gold being slow-by-default. http://crbug.com/632230 + fast_env = dict(os.environ) + fast_env['LC_ALL'] = 'C' + + # First, run the actual link. + command = wrapper_utils.command_to_run(args.command) + result = wrapper_utils.run_link_with_optional_map_file( + command, env=fast_env, map_file=args.map_file) + + if result != 0: + return result + + # Next, generate the contents of the TOC file. + result, toc = collect_toc(args) + if result != 0: + return result + + # If there is an existing TOC file with identical contents, leave it alone. + # Otherwise, write out the TOC file. + if args.tocfile: + update_toc(args.tocfile, toc) + + # Finally, strip the linked shared object file (if desired). + if args.strip: + result = subprocess.call( + wrapper_utils.command_to_run( + [args.strip, '-o', args.output, args.sofile])) + if args.libfile: + libfile_name = os.path.basename(args.libfile) + sofile_output_dir = os.path.dirname(args.sofile) + unstripped_libfile = os.path.join(sofile_output_dir, libfile_name) + shutil.copy2(unstripped_libfile, args.libfile) + + return result + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni new file mode 100755 index 00000000..ff75a507 --- /dev/null +++ b/build/toolchain/gcc_toolchain.gni @@ -0,0 +1,499 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("$build_root/config/clang/clang.gni") +import("$build_root/config/sanitizers/sanitizers.gni") +import("$build_root/toolchain/cc_wrapper.gni") +import("$build_root/toolchain/clang_static_analyzer.gni") +import("$build_root/toolchain/toolchain.gni") +template("gcc_toolchain") { + toolchain(target_name) { + assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value") + assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value") + assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value") + assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value") + + # This define changes when the toolchain changes, forcing a rebuild. + # Nothing should ever use this define. + if (defined(invoker.rebuild_define)) { + rebuild_string = "-D" + invoker.rebuild_define + " " + } else { + rebuild_string = "" + } + + # GN's syntax can't handle more than one scope dereference at once, like + # "invoker.toolchain_args.foo", so make a temporary to hold the toolchain + # args so we can do "invoker_toolchain_args.foo". + assert(defined(invoker.toolchain_args), + "Toolchains must specify toolchain_args") + invoker_toolchain_args = invoker.toolchain_args + assert(defined(invoker_toolchain_args.current_cpu), + "toolchain_args must specify a current_cpu") + assert(defined(invoker_toolchain_args.current_os), + "toolchain_args must specify a current_os") + + # When invoking this toolchain not as the default one, these args will be + # passed to the build. They are ignored when this is the default toolchain. + toolchain_args = { + # Populate toolchain args from the invoker. + forward_variables_from(invoker_toolchain_args, "*") + # The host toolchain value computed by the default toolchain's setup + # needs to be passed through unchanged to all secondary toolchains to + # ensure that it's always the same, regardless of the values that may be + # set on those toolchains. + } + + if (defined(toolchain_args.cc_wrapper)) { + toolchain_cc_wrapper = toolchain_args.cc_wrapper + } else { + toolchain_cc_wrapper = cc_wrapper + } + + if (is_clang && use_clang_static_analyzer && + (!defined(invoker.is_clang_analysis_supported) || + invoker.is_clang_analysis_supported)) { + compiler_prefix = "${analyzer_wrapper} " + asm = invoker.cc + } else { + compiler_prefix = "${toolchain_cc_wrapper} " + } + + cc = compiler_prefix + invoker.cc + cxx = compiler_prefix + invoker.cxx + ar = invoker.ar + ld = invoker.ld + if (!defined(asm)) { + asm = cc + } + if (defined(invoker.readelf)) { + readelf = invoker.readelf + } else { + readelf = "readelf" + } + if (defined(invoker.nm)) { + nm = invoker.nm + } else { + nm = "nm" + } + + if (defined(invoker.shlib_extension)) { + default_shlib_extension = invoker.shlib_extension + } else { + default_shlib_extension = shlib_extension + } + + if (defined(invoker.executable_extension)) { + default_executable_extension = invoker.executable_extension + } else { + default_executable_extension = "" + } + + # Bring these into our scope for string interpolation with default values. + if (defined(invoker.libs_section_prefix)) { + libs_section_prefix = invoker.libs_section_prefix + } else { + libs_section_prefix = "" + } + + if (defined(invoker.libs_section_postfix)) { + libs_section_postfix = invoker.libs_section_postfix + } else { + libs_section_postfix = "" + } + + if (defined(invoker.solink_libs_section_prefix)) { + solink_libs_section_prefix = invoker.solink_libs_section_prefix + } else { + solink_libs_section_prefix = "" + } + + if (defined(invoker.solink_libs_section_postfix)) { + solink_libs_section_postfix = invoker.solink_libs_section_postfix + } else { + solink_libs_section_postfix = "" + } + + if (defined(invoker.extra_cflags) && invoker.extra_cflags != "") { + extra_cflags = " " + invoker.extra_cflags + } else { + extra_cflags = "" + } + + if (defined(invoker.extra_cppflags) && invoker.extra_cppflags != "") { + extra_cppflags = " " + invoker.extra_cppflags + } else { + extra_cppflags = "" + } + + if (defined(invoker.extra_cxxflags) && invoker.extra_cxxflags != "") { + extra_cxxflags = " " + invoker.extra_cxxflags + } else { + extra_cxxflags = "" + } + + if (defined(invoker.extra_asmflags) && invoker.extra_asmflags != "") { + extra_asmflags = " " + invoker.extra_asmflags + } else { + extra_asmflags = "" + } + + if (defined(invoker.extra_ldflags) && invoker.extra_ldflags != "") { + extra_ldflags = " " + invoker.extra_ldflags + } else { + extra_ldflags = "" + } + + enable_linker_map = defined(invoker.enable_linker_map) && + invoker.enable_linker_map && generate_linker_map + + # These library switches can apply to all tools below. + lib_switch = "-l" + lib_dir_switch = "-L" + + # Object files go in this directory. + object_subdir = "{{source_out_dir}}/{{label_name}}" + + tool("cc") { + depfile = "{{output}}.d" + command = "$cc -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}${extra_cppflags}${extra_cflags} -c {{source}} -o {{output}}" + depsformat = "gcc" + description = "CC {{output}}" + outputs = [ "$object_subdir/{{source_name_part}}.o" ] + } + + tool("cxx") { + depfile = "{{output}}.d" + command = "$cxx -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}${extra_cppflags}${extra_cxxflags} -c {{source}} -o {{output}}" + depsformat = "gcc" + description = "CXX {{output}}" + outputs = [ "$object_subdir/{{source_name_part}}.o" ] + } + + tool("asm") { + # For GCC we can just use the C compiler to compile assembly. + depfile = "{{output}}.d" + command = "$asm -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{asmflags}}${extra_asmflags} -c {{source}} -o {{output}}" + depsformat = "gcc" + description = "ASM {{output}}" + outputs = [ "$object_subdir/{{source_name_part}}.o" ] + } + + tool("alink") { + if (current_os == "aix") { + # AIX does not support either -D (deterministic output) or response + # files. + command = "$ar -X64 {{arflags}} -r -c -s {{output}} {{inputs}}" + } else { + rspfile = "{{output}}.rsp" + rspfile_content = "{{inputs}}" + command = "\"$ar\" {{arflags}} -r -c -s -D {{output}} @\"$rspfile\"" + } + + # Remove the output file first so that ar doesn't try to modify the + # existing file. + if (host_os == "win") { + tool_wrapper_path = + rebase_path("$build_root/toolchain/win/tool_wrapper.py", + root_build_dir) + command = "cmd /c $python_path $tool_wrapper_path delete-file {{output}} && $command" + } else { + command = "rm -f {{output}} && $command" + } + + # Almost all targets build with //build/config/compiler:thin_archive which + # adds -T to arflags. + description = "AR {{output}}" + outputs = [ "{{output_dir}}/{{target_output_name}}{{output_extension}}" ] + + # Shared libraries go in the target out directory by default so we can + # generate different targets with the same name and not have them collide. + default_output_dir = "{{target_out_dir}}" + default_output_extension = ".a" + output_prefix = "lib" + } + + tool("solink") { + soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". + sofile = "{{output_dir}}/$soname" # Possibly including toolchain dir. + rspfile = sofile + ".rsp" + + is_mingw_link = false + if (invoker_toolchain_args.current_os == "mingw") { + is_mingw_link = true + libname = "{{target_output_name}}.lib" + libfile = "{{output_dir}}/$libname" + } + + if (defined(invoker.strip)) { + unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$sofile" + } else { + unstripped_sofile = sofile + } + + link_command = "$ld -shared {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" @\"$rspfile\"" + if (!is_mingw_link) { + link_command = "$link_command -Wl,-soname=\"$soname\"" + } else { + link_command = "$link_command -Wl,--out-implib,{{root_out_dir}}/lib.unstripped/$libfile" + } + + # Generate a map file to be used for binary size analysis. + # Map file adds ~10% to the link time on a z620. + map_switch = "" + if (enable_linker_map && is_official_build) { + map_file = "$unstripped_sofile.map.gz" + map_switch = " --map-file \"$map_file\"" + } + + assert(defined(readelf), "to solink you must have a readelf") + assert(defined(nm), "to solink you must have an nm") + strip_switch = "" + if (defined(invoker.strip)) { + strip_switch = "--strip=${invoker.strip} " + } + + # This needs a Python script to avoid using a complex shell command + # requiring sh control structures, pipelines, and POSIX utilities. + # The host might not have a POSIX shell and utilities (e.g. Windows). + solink_wrapper = + rebase_path("$build_root/toolchain/gcc_solink_wrapper.py", + root_build_dir) + command = "$python_path \"$solink_wrapper\" --readelf=\"$readelf\" --nm=\"$nm\" $strip_switch --sofile=\"$unstripped_sofile\" $map_switch --output=\"$sofile\"" + if (is_mingw_link) { + command = "$command --libfile=\"$libfile\"" + } + command = "$command -- $link_command" + + rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" + + description = "SOLINK $sofile" + + # Use this for {{output_extension}} expansions unless a target manually + # overrides it (in which case {{output_extension}} will be what the target + # specifies). + default_output_extension = default_shlib_extension + + default_output_dir = "{{root_out_dir}}" + + output_prefix = "lib" + + # Since the above commands only updates the .TOC file when it changes, ask + # Ninja to check if the timestamp actually changed to know if downstream + # dependencies should be recompiled. + restat = true + + # Tell GN about the output files. It will link to the sofile + outputs = [ sofile ] + if (sofile != unstripped_sofile) { + outputs += [ unstripped_sofile ] + if (defined(invoker.use_unstripped_as_runtime_outputs) && + invoker.use_unstripped_as_runtime_outputs) { + runtime_outputs = [ unstripped_sofile ] + } + } + if (defined(map_file)) { + outputs += [ map_file ] + } + + if (is_mingw_link) { + outputs += [ libfile ] + link_output = libfile + depend_output = libfile + } else { + link_output = sofile + depend_output = sofile + } + } + + tool("solink_module") { + soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". + sofile = "{{output_dir}}/$soname" + rspfile = sofile + ".rsp" + + if (defined(invoker.strip)) { + unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$sofile" + } else { + unstripped_sofile = sofile + } + + command = "$ld -shared {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" -Wl,-soname=\"$soname\" @\"$rspfile\"" + + if (defined(invoker.strip)) { + strip_command = "${invoker.strip} -o \"$sofile\" \"$unstripped_sofile\"" + command += " && " + strip_command + } + rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" + + description = "SOLINK_MODULE $sofile" + + # Use this for {{output_extension}} expansions unless a target manually + # overrides it (in which case {{output_extension}} will be what the target + # specifies). + if (defined(invoker.loadable_module_extension)) { + default_output_extension = invoker.loadable_module_extension + } else { + default_output_extension = default_shlib_extension + } + + default_output_dir = "{{root_out_dir}}" + + output_prefix = "lib" + + outputs = [ sofile ] + if (sofile != unstripped_sofile) { + outputs += [ unstripped_sofile ] + if (defined(invoker.use_unstripped_as_runtime_outputs) && + invoker.use_unstripped_as_runtime_outputs) { + runtime_outputs = [ unstripped_sofile ] + } + } + } + + tool("link") { + exename = "{{target_output_name}}{{output_extension}}" + outfile = "{{output_dir}}/$exename" + rspfile = "$outfile.rsp" + unstripped_outfile = outfile + + # Use this for {{output_extension}} expansions unless a target manually + # overrides it (in which case {{output_extension}} will be what the target + # specifies). + default_output_extension = default_executable_extension + + default_output_dir = "{{root_out_dir}}" + + if (defined(invoker.strip)) { + unstripped_outfile = "{{root_out_dir}}/exe.unstripped/$outfile" + } + + # Generate a map file to be used for binary size analysis. + # Map file adds ~10% to the link time on a z620. + map_switch = "" + if (enable_linker_map && is_official_build) { + map_file = "$unstripped_outfile.map.gz" + map_switch = " --map-file \"$map_file\"" + } + + start_group_flag = "" + end_group_flag = "" + if (current_os != "aix") { + # the "--start-group .. --end-group" feature isn't available on the aix ld. + start_group_flag = "-Wl,--start-group" + end_group_flag = "-Wl,--end-group " + } + _clang_rt_dso_full_path = "" + if (is_asan && invoker_toolchain_args.current_os == "ohos") { + if (invoker_toolchain_args.current_cpu == "arm64") { + _clang_rt_dso_full_path = rebase_path( + "$clang_base_path/lib/clang/$clang_version/lib/aarch64-linux-ohos/libclang_rt.asan.so", + root_build_dir) + } else { + _clang_rt_dso_full_path = rebase_path( + "$clang_base_path/lib/clang/$clang_version/lib/arm-linux-ohos/libclang_rt.asan.so", + root_build_dir) + } + } + link_command = "$ld {{ldflags}}${extra_ldflags} -o \"$unstripped_outfile\" $libs_section_prefix $start_group_flag $_clang_rt_dso_full_path @\"$rspfile\" {{solibs}} {{libs}} $end_group_flag $libs_section_postfix" + + strip_switch = "" + + if (defined(invoker.strip)) { + strip_switch = " --strip=\"${invoker.strip}\" --unstripped-file=\"$unstripped_outfile\"" + } + if (is_asan && invoker_toolchain_args.current_os == "ohos") { + strip_switch = + "$strip_switch --clang_rt_dso_path=\"$_clang_rt_dso_full_path\"" + } + + link_wrapper = rebase_path("$build_root/toolchain/gcc_link_wrapper.py", + root_build_dir) + command = "$python_path \"$link_wrapper\" --output=\"$outfile\"$strip_switch$map_switch -- $link_command" + description = "LINK $outfile" + rspfile_content = "{{inputs}}" + outputs = [ outfile ] + if (outfile != unstripped_outfile) { + outputs += [ unstripped_outfile ] + if (defined(invoker.use_unstripped_as_runtime_outputs) && + invoker.use_unstripped_as_runtime_outputs) { + runtime_outputs = [ unstripped_outfile ] + } + } + if (defined(invoker.link_outputs)) { + outputs += invoker.link_outputs + } + if (defined(map_file)) { + outputs += [ map_file ] + } + } + + # These two are really entirely generic, but have to be repeated in + # each toolchain because GN doesn't allow a template to be used here. + # See //build/toolchain/toolchain.gni for details. + tool("stamp") { + command = stamp_command + description = stamp_description + } + tool("copy") { + command = copy_command + description = copy_description + } + + forward_variables_from(invoker, [ "deps" ]) + } +} + +# This is a shorthand for gcc_toolchain instances based on the Chromium-built +# version of Clang. Only the toolchain_cpu and toolchain_os variables need to +# be specified by the invoker, and optionally toolprefix if it's a +# cross-compile case. Note that for a cross-compile case this toolchain +# requires a config to pass the appropriate -target option, or else it will +# actually just be doing a native compile. The invoker can optionally override +# use_gold too. +template("clang_toolchain") { + if (defined(invoker.toolprefix)) { + toolprefix = invoker.toolprefix + } else { + toolprefix = "" + } + + gcc_toolchain(target_name) { + prefix = rebase_path("$clang_base_path/bin", root_build_dir) + cc = "$prefix/clang" + cxx = "$prefix/clang++" + ld = cxx + readelf = "${toolprefix}readelf" + ar = "${prefix}/llvm-ar" + nm = "${toolprefix}nm" + + forward_variables_from(invoker, + [ + "strip", + "is_clang_analysis_supported", + "enable_linker_map", + "use_unstripped_as_runtime_outputs", + ]) + + toolchain_args = { + if (defined(invoker.toolchain_args)) { + forward_variables_from(invoker.toolchain_args, "*") + } + is_clang = true + } + + if (defined(invoker.shlib_extension) && invoker.shlib_extension != "") { + shlib_extension = invoker.shlib_extension + } + } +} diff --git a/build/toolchain/linux/BUILD.gn b/build/toolchain/linux/BUILD.gn new file mode 100755 index 00000000..c38b3082 --- /dev/null +++ b/build/toolchain/linux/BUILD.gn @@ -0,0 +1,125 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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("$build_root/toolchain/gcc_toolchain.gni") +clang_toolchain("clang_arm") { + toolprefix = "arm-linux-gnueabihf-" + toolchain_args = { + current_cpu = "arm" + current_os = "linux" + } +} + +clang_toolchain("clang_arm64") { + toolprefix = "aarch64-linux-gnu-" + toolchain_args = { + current_cpu = "arm64" + current_os = "linux" + } +} + +gcc_toolchain("arm64") { + toolprefix = "aarch64-linux-gnu-" + + cc = "${toolprefix}gcc" + cxx = "${toolprefix}g++" + + ar = "${toolprefix}ar" + ld = cxx + readelf = "${toolprefix}readelf" + nm = "${toolprefix}nm" + + toolchain_args = { + current_cpu = "arm64" + current_os = "linux" + is_clang = false + } +} + +gcc_toolchain("arm") { + toolprefix = "arm-linux-gnueabihf-" + + cc = "${toolprefix}gcc" + cxx = "${toolprefix}g++" + + ar = "${toolprefix}ar" + ld = cxx + readelf = "${toolprefix}readelf" + nm = "${toolprefix}nm" + + toolchain_args = { + current_cpu = "arm" + current_os = "linux" + is_clang = false + } +} + +clang_toolchain("clang_x86") { + # Output linker map files for binary size analysis. + enable_linker_map = true + + toolchain_args = { + current_cpu = "x86" + current_os = "linux" + } +} + +gcc_toolchain("x86") { + cc = "gcc" + cxx = "g++" + + readelf = "readelf" + nm = "nm" + ar = "ar" + ld = cxx + + # Output linker map files for binary size analysis. + enable_linker_map = true + + toolchain_args = { + current_cpu = "x86" + current_os = "linux" + is_clang = false + } +} + +clang_toolchain("clang_x64") { + # Output linker map files for binary size analysis. + enable_linker_map = true + + strip = rebase_path("${clang_base_path}/bin/llvm-strip", root_build_dir) + toolchain_args = { + current_cpu = "x64" + current_os = "linux" + } + shlib_extension = ".so" +} + +gcc_toolchain("x64") { + cc = "gcc" + cxx = "g++" + + readelf = "readelf" + nm = "nm" + ar = "ar" + ld = cxx + + # Output linker map files for binary size analysis. + enable_linker_map = true + + toolchain_args = { + current_cpu = "x64" + current_os = "linux" + is_clang = false + } +} diff --git a/build/toolchain/toolchain.gni b/build/toolchain/toolchain.gni new file mode 100755 index 00000000..0f051224 --- /dev/null +++ b/build/toolchain/toolchain.gni @@ -0,0 +1,111 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +# Toolchain-related configuration that may be needed outside the context of the +# toolchain() rules themselves. + +#import("//build/misc/overrides/build.gni") + +declare_args() { + # If this is set to true, or if LLVM_FORCE_HEAD_REVISION is set to 1 + # in the environment, we use the revision in the llvm repo to determine + # the CLANG_REVISION to use, instead of the version hard-coded into + # //tools/clang/scripts/update.py. This should only be used in + # conjunction with setting LLVM_FORCE_HEAD_REVISION in the + # environment when `gclient runhooks` is run as well. + llvm_force_head_revision = false + + # Compile with Xcode version of clang instead of hermetic version shipped + # with the build. Used on iOS to ship official builds (as they are built + # with the version of clang shipped with Xcode). + use_xcode_clang = false + + # Used for binary size analysis. + # Currently disabled on LLD because of a bug (fixed upstream). + # See https://crbug.com/716209. + generate_linker_map = is_ohos && is_official_build + + # Use absolute file paths in the compiler diagnostics and __FILE__ macro + # if needed. + msvc_use_absolute_paths = false +} + +if (generate_linker_map) { + assert( + is_official_build, + "Linker map files should only be generated when is_official_build = true") + assert(current_os == "ohos" || target_os == "linux", + "Linker map files should only be generated for ohos and Linux") +} + +# The path to the hermetic install of Xcode. Only relevant when +hermetic_xcode_path = + rebase_path("//build/${target_os}_files/Xcode.app", "", root_build_dir) + +declare_args() { + if (is_clang) { + # Clang compiler version. Clang files are placed at version-dependent paths. + clang_version = "10.0.1" + } + use_custom_clang = true +} + +# Check target_os here instead of is_ios as this file is loaded for secondary +# toolchain (host toolchain in particular) but the argument is the same for +# all toolchains. +assert(!use_xcode_clang || target_os == "ios", + "Using Xcode's clang is only supported in iOS builds") + +# Extension for shared library files (including leading dot). +executable_extension = "" +if (is_mac) { + shlib_extension = ".dylib" +} else if (is_ohos && is_component_build) { + # By appending .z, we prevent name collisions with libraries already loaded by the ohos. + shlib_extension = ".z.so" +} else if (is_mingw) { + shlib_extension = ".dll" + executable_extension = ".exe" +} else if (is_posix) { + shlib_extension = ".so" +} else if (is_win) { + shlib_extension = ".dll" +} else { + assert(false, "Platform not supported") +} + +# Prefix for shared library files. +if (is_posix) { + shlib_prefix = "lib" +} else { + shlib_prefix = "" +} + +# While other "tool"s in a toolchain are specific to the target of that +# toolchain, the "stamp" and "copy" tools are really generic to the host; +# but each toolchain must define them separately. GN doesn't allow a +# template instantiation inside a toolchain definition, so some boilerplate +# has to be repeated in each toolchain to define these two tools. These +# four variables reduce the duplication in that boilerplate. +stamp_description = "STAMP {{output}}" +copy_description = "COPY {{source}} {{output}}" +if (host_os == "win") { + _tool_wrapper_path = + rebase_path("//build/toolchain/win/tool_wrapper.py", root_build_dir) + stamp_command = "cmd /c type nul > \"{{output}}\"" + copy_command = + "$python_path $_tool_wrapper_path recursive-mirror {{source}} {{output}}" +} else { + stamp_command = "touch {{output}}" + copy_command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})" +} diff --git a/figures/zh-cn_image_arkcompiler.png b/figures/zh-cn_image_arkcompiler.png new file mode 100644 index 0000000000000000000000000000000000000000..4e34094c9c82cd80881078df9b5e5904dbe98a61 GIT binary patch literal 34397 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 E052%TEdT%j literal 0 HcmV?d00001 -- Gitee