From 8eaf205343df8292f0abb894d168d4b73489bd78 Mon Sep 17 00:00:00 2001 From: guzhihao4 Date: Mon, 15 May 2023 17:54:43 +0800 Subject: [PATCH] Test llvm-build Signed-off-by: guzhihao4 Change-Id: I91a5252255e4d167255e55ff837ba711dd6379fb --- llvm-build/Makefile | 230 ++++ llvm-build/OHOS.cmake | 22 + llvm-build/README.md | 126 ++ llvm-build/build.py | 1866 ++++++++++++++++++++++++++++ llvm-build/build_cpython-mingw.sh | 81 ++ llvm-build/build_musl.sh | 121 ++ llvm-build/data/llvm_build.png | Bin 0 -> 34465 bytes llvm-build/data/one_time_setup.png | Bin 0 -> 21555 bytes llvm-build/env_prepare.sh | 113 ++ llvm-build/mingw.py | 235 ++++ llvm-build/toolchain_readme.md | 26 + 11 files changed, 2820 insertions(+) create mode 100644 llvm-build/Makefile create mode 100644 llvm-build/OHOS.cmake create mode 100644 llvm-build/README.md create mode 100755 llvm-build/build.py create mode 100755 llvm-build/build_cpython-mingw.sh create mode 100755 llvm-build/build_musl.sh create mode 100644 llvm-build/data/llvm_build.png create mode 100644 llvm-build/data/one_time_setup.png create mode 100755 llvm-build/env_prepare.sh create mode 100755 llvm-build/mingw.py create mode 100644 llvm-build/toolchain_readme.md diff --git a/llvm-build/Makefile b/llvm-build/Makefile new file mode 100644 index 0000000000..011686dd41 --- /dev/null +++ b/llvm-build/Makefile @@ -0,0 +1,230 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +ARCH = arm +ifneq ($(GCC),) +TARGET = +CROSS_COMPILE = $(GCC:%gcc=%) +CC = $(GCC) $(ARCH_CFLAGS) +MULTILIB = $(patsubst %.,%,$(shell $(CC) -print-multi-directory)) +else +TARGET = $(ARCH)-liteos-ohos +CLANG ?= clang +CROSS_COMPILE = $(CLANG:%clang=%llvm-) +CC = $(CLANG) --target=$(TARGET) $(ARCH_CFLAGS) +BUILD=x86_64-linux-gnu +MULTILIB = $(patsubst $(dir $(shell $(filter-out $(ARCH_CFLAGS),$(CC)) -print-libgcc-file-name))%,/%,$(dir $(shell $(CC) -print-libgcc-file-name))) +endif +MUSLBUILDDIR = build_$(or $(TARGET),$(ARCH))$(subst /,_,$(MULTILIB:%/=%)) +HIDE = @ +BUILD_DEBUG = false +SED_ARGS = -e '/install-libs:/s/if/and/g' + +TOPDIR = $(shell pwd)/../../../.. +MUSLDIR = $(TOPDIR)/third_party/musl +LINUXKERNELDIR = $(TOPDIR)/third_party/Linux_Kernel +OPTRTDIR = $(TOPDIR)/third_party/optimized-routines +NUTTXDIR = $(TOPDIR)/third_party/NuttX +SYSROOTDIR = $(TOPDIR)/prebuilts/lite/sysroot +LITEOSADIR = $(TOPDIR)/kernel/liteos_a +LINUXDIR = $(TOPDIR)/kernel/linux/linux-5.10 + +TARGETS = $(if $(wildcard $(LITEOSADIR)),liteos_a_user,) +TARGETS += $(if $(wildcard $(LINUXDIR)),linux_user,) + +define LINUX_TYPES_H +#ifndef _LINUX_TYPES_H +#define _LINUX_TYPES_H +#include +typedef uint32_t __u32, __le32; +#endif +endef +export LINUX_TYPES_H + +ifeq ($(ARCH),arm) +ARCH_CFLAGS = -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 +else +ifeq ($(ARCH),aarch64) +ARCH_CFLAGS = +else +ifeq ($(ARCH),riscv64) +ARCH_CFLAGS = +else +ifeq ($(ARCH),mips) +ARCH_CFLAGS = +else +ifeq ($(ARCH),x86_64) +ARCH_CFLAGS = +else +$(warning *** warning: ARCH $(ARCH) has not been tested yet, use with cautions!) +ARCH_CFLAGS = +endif +endif +endif +endif +endif + +ifeq ($(ARCH),aarch64) +CFLAGS = -march=armv8 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +ifeq ($(ARCH),riscv64) +CFLAGS = -march=rv64gc -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +ifeq ($(ARCH),mips) +CFLAGS = -march=mips32r2 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +ifeq ($(ARCH),x86_64) +CFLAGS = -march=x86-64 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +CFLAGS = -march=armv7-a -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +endif +endif +endif +endif + +CFLAGS += -Wno-int-conversion + +.PHONY: $(TARGETS:%=musl_copy_for_%) +.PHONY: $(TARGETS:%=musl_patch_for_%) +.PHONY: $(TARGETS:%=musl_install_for_%) +.PHONY: $(TARGETS:%=musl_header_install_for_%) +.PHONY: $(TARGETS:%=linux_header_install_for_%) +.PHONY: $(TARGETS:%=nuttx_header_install_for_%) +.PHONY: $(TARGETS:%=optimized_routines_install_for_%) +.PHONY: all clean distclean + +all: $(TARGETS:%=musl_install_for_%) + +$(TARGETS:%=musl_copy_for_%): + $(HIDE) mkdir -p $@ + $(HIDE) cp -rfu $(MUSLDIR)/[!p]* $@ + +optimized_routines_install_for_liteos_a_user: musl_copy_for_liteos_a_user +ifneq ($(ARCH),) + $(HIDE) cp -rfp $(OPTRTDIR)/string/$(ARCH)/* $> $ $ $/dev/null && \ + make -sj install-headers + +musl_install_for_liteos_a_user: musl_patch_for_liteos_a_user + $(HIDE) cd musl_copy_for_liteos_a_user && mkdir -p $(MUSLBUILDDIR) && cd $(MUSLBUILDDIR) && \ + ../configure --prefix=$(SYSROOTDIR)/$(TARGET)/usr --target=$(TARGET) \ + --includedir=$(SYSROOTDIR)/$(TARGET)/usr/include \ + --libdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --syslibdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --build=$(BUILD) \ + $(if $(LDFLAGS),LDFLAGS="$(LDFLAGS)",) \ + CC="$(CC)" CROSS_COMPILE="$(CROSS_COMPILE)" CFLAGS="$(CFLAGS)" >/dev/null && \ + make -sj install + +musl_patch_for_linux_user: musl_copy_for_linux_user + $(HIDE) cp -rfp $(MUSLDIR)/porting/linux/user/* $/dev/null && \ + make -sj install-headers + +musl_install_for_linux_user: musl_patch_for_linux_user + $(HIDE) cd musl_copy_for_linux_user && mkdir -p $(MUSLBUILDDIR) && cd $(MUSLBUILDDIR) && \ + ../configure --prefix=$(SYSROOTDIR)/$(TARGET)/usr --target=$(TARGET) \ + --includedir=$(SYSROOTDIR)/$(TARGET)/usr/include \ + --libdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --syslibdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --build=$(BUILD) \ + CC="$(CC)" CROSS_COMPILE="$(CROSS_COMPILE)" CFLAGS="$(CFLAGS)" >/dev/null && \ + make -sj install + +clean: + $(HIDE) rm -rf musl_copy_for_* linux_header_install_for_* + +distclean: clean + $(HIDE) rm -rf $(SYSROOTDIR)/lib $(SYSROOTDIR)/usr diff --git a/llvm-build/OHOS.cmake b/llvm-build/OHOS.cmake new file mode 100644 index 0000000000..df2c08ce41 --- /dev/null +++ b/llvm-build/OHOS.cmake @@ -0,0 +1,22 @@ +# Copyright (C) 2021 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. + +include(Platform/Linux) + +# OHOS has soname, but binary names must end in ".so" so we cannot append +# a version number. Also we cannot portably represent symlinks on the host. +set(CMAKE_PLATFORM_NO_VERSIONED_SONAME 1) + +# OHOS reportedly ignores RPATH, and we cannot predict the install +# location anyway. +set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") diff --git a/llvm-build/README.md b/llvm-build/README.md new file mode 100644 index 0000000000..2d0b99adde --- /dev/null +++ b/llvm-build/README.md @@ -0,0 +1,126 @@ +## Overview + +This readme briefly describes the functionality of our LLVM toolchain and how to build it + +1. [Build WIKI](#build_wiki) +2. [Function Introduction](#function_introduction) + + +## Build WIKI +
+ +### System Requirements for Toolchain BUild + +Ubuntu >= 16.04 +MacOS X >= 10.15.4 + +
+ +### Get Code +``` +repo init -u https://gitee.com/OpenHarmony/manifest.git -b master -m llvm-toolchain.xml +repo sync -c +repo forall -c 'git lfs pull' +``` +
+ +### Toolchain build process + +Here is an example of starting build process on Linux or MacOS: +``` +# update prebuilts, no need to run each time +./toolchain/llvm-project/llvm-build/env_prepare.sh +# build +python3 ./toolchain/llvm-project/llvm-build/build.py +``` + +1. env_prepare (one time only) +![输入图片说明](data/one_time_setup.png) + +2. build +![输入图片说明](data/llvm_build.png) + +
+ +### Options + +build.py options: + +``` +--skip-build # skip compile and goto package step +--skip-package # do compile without package step +--enable-assertions # enable assertion when compiling +--build-name # specify release package name +--debug # build debug version llvm toolchain +--strip # strip llvm toolchain binaries +--no-build-arm # skip triplet arm +--no-build-aarch64 # skip triplet arm64 +--no-build-x86_64 # skip triplet x86_64 +--no-lto # disable LTO optimization when build toolchain +--build-instrumented # enable instrument pgo when build toolchain +--xunit-xml-output # specify LLVM unit test XML report path +--no-build # optional, skip some targets + windows + libs + lldb-mi + lldb-server + linux + check-api +``` +
+ +### Output Layout + +When build successfully completed. following artifacts will be available in `out` directory + +`sysroot` -> sysroots for OHOS targets +`install` -> toolchain build +`*.tar.bz2` -> archived versions of toolchain and sysroots +
+ +### OHOS Archive + +1. llvm +``` +contains: +1. toolchain which provides clang compiler, lldb(-mi), clang-tidy etc. tools +2. libc++/clang_rt/asan/fuzzer libs for target device + +OHOS sync from: https://mirrors.huaweicloud.com/openharmony/compiler/clang/ +Which is the same as: out/clang-dev-${platform}-${arch}.tar.bz2 +OHOS archive to: prebuilts/clang/ohos//${platform}/llvm + +License: Apache License v2.0 with LLVM Exceptions +``` + +2. libcxx-ndk +``` +contains: provide libc++ for ndk in target device + +OHOS fetch prebuilts from: https://mirrors.huaweicloud.com/openharmony/compiler/clang/ and archive it to prebuilts/clang/ohos//${platform}/libcxx-ndk. This tar is + +License: Apache License v2.0 with LLVM Exceptions +``` + + +## Function Introduction +
+ +### Functionality + +The LLVM toolchain is built based on LLVM 15.0.4. It is used to provide capability of building ohos image. For detailed information about LLVM 15.0.4, please refer to [LLVM 15.0.4](https://discourse.llvm.org/t/llvm-15-0-4-released/66337). +
+ +### Specifically Included Triplets + +Despite all the components provided by LLVM community, we included several triplets for different types of ohos devices to our LLVM toochain, listed as below. For specification, liteos is a newly included OS name which indicate the simplified linux kernel. + +| Triplet Name | Architecture | System Kernel | System | +| ---------------------- | ------------ | ------------- | --------------- | +| arm-liteos-ohos | ARM 32bits | LiteOS | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Standard system | +| aarch64-linux-ohos | ARM 64bits | Linux | Standard system | + +For detailed definition of Small System and Standard System, please refer to [System Types](https://gitee.com/openharmony/docs/blob/master/en/device-dev/Readme-EN.md). + diff --git a/llvm-build/build.py b/llvm-build/build.py new file mode 100755 index 0000000000..a009e2541c --- /dev/null +++ b/llvm-build/build.py @@ -0,0 +1,1866 @@ +#!/usr/bin/env python3 +# Copyright (C) 2021 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. +# 2021.3.15 build for OHOS LLVM. +# Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + +import os +import platform +import re +import datetime +import logging +import glob +import subprocess +import shutil +import argparse +import mingw +import stat + + +class BuildConfig(): + # Defines public methods and functions and obtains script parameters. + + def __init__(self): + args = self.parse_args() + self.do_build = not args.skip_build + self.do_package = not args.skip_package + self.build_name = args.build_name + self.debug = args.debug + self.strip = args.strip + self.no_lto = args.no_lto + self.build_instrumented = args.build_instrumented + self.xunit_xml_output = args.xunit_xml_output + self.enable_assertions = args.enable_assertions + self.need_libs = self.do_build and 'libs' not in args.no_build + self.need_lldb_mi = self.do_build and 'lldb-mi' not in args.no_build + self.need_lldb_server = self.do_build and 'lldb-server' not in args.no_build + + self.no_build_arm = args.skip_build or args.no_build_arm + self.no_build_aarch64 = args.skip_build or args.no_build_aarch64 + self.no_build_riscv64 = args.skip_build or args.no_build_riscv64 + self.no_build_mipsel = args.skip_build or args.no_build_mipsel + self.no_build_x86_64 = args.skip_build or args.no_build_x86_64 + + self.discover_paths() + + self.TARGETS = 'AArch64;ARM;BPF;Mips;RISCV;X86' + self.ORIG_ENV = dict(os.environ) + self.VERSION = None # autodetected + + self.OPENHOS_SFX = '-linux-ohos' + self.LITEOS_SFX = '-liteos-ohos' + self.LLDB_PY_VERSION = '3.10' + self.CLANG_VERSION = '10.0.1' + self.MINGW_TRIPLE = 'x86_64-windows-gnu' + logging.basicConfig(level=logging.INFO) + + def discover_paths(self): + # Location of llvm-build directory + self.LLVM_BUILD_DIR = os.path.abspath(os.path.dirname(__file__)) + + parent_of_llvm_build = os.path.basename(os.path.dirname(self.LLVM_BUILD_DIR)) + if parent_of_llvm_build == 'toolchain': + self.REPOROOT_DIR = os.path.abspath(os.path.join(self.LLVM_BUILD_DIR, '../..')) + else: + assert parent_of_llvm_build == 'llvm-project' + self.REPOROOT_DIR = os.path.abspath(os.path.join(self.LLVM_BUILD_DIR, '../../..')) + + self.LLVM_PROJECT_DIR = os.path.join(self.REPOROOT_DIR, 'toolchain', 'llvm-project') + self.OUT_PATH = os.path.join(self.REPOROOT_DIR, 'out') + + @staticmethod + def parse_add_argument(parser): + + parser.add_argument( + '--enable-assertions', + action='store_true', + default=False, + help='Apply assertions, some parameters are affected.') + + parser.add_argument( + '--build-name', + default='dev', + help='Release name for the package.') + + parser.add_argument( + '--debug', + action='store_true', + default=False, + help='Building Clang and LLVM Tools for Debugging (only affects stage2)') + + parser.add_argument( + '--strip', + action='store_true', + default=False, + help='Strip final LLVM binaries.') + + parser.add_argument( + '--no-build-arm', + action='store_true', + default=False, + help='Omit build os target: arm.') + + parser.add_argument( + '--no-build-aarch64', + action='store_true', + default=False, + help='Omit build os target: aarch64.') + + parser.add_argument( + '--no-build-riscv64', + action='store_true', + default=False, + help='Omit build os target: 64-bit RISC-V.') + + parser.add_argument( + '--no-build-mipsel', + action='store_true', + default=False, + help='Omit build os target: mipsel.') + + parser.add_argument( + '--no-build-x86_64', + action='store_true', + default=False, + help='Omit build os target: x86_64.') + + parser.add_argument( + '--no-lto', + action='store_true', + default=False, + help='Accelerate builds by disabling LTO (only affects llvm product)') + + parser.add_argument( + '--build-instrumented', + action='store_true', + default=False, + help='Using the PGO instrumentation to build LLVM tool') + + parser.add_argument( + '--xunit-xml-output', + default=None, + help='Output path for LLVM unit tests XML report') + + def parse_args(self): + + parser = argparse.ArgumentParser(description='Process some integers.') + + # Options to skip build or packaging, can't skip two + build_package_group = parser.add_mutually_exclusive_group() + build_package_group.add_argument( + '--skip-build', + '-sb', + action='store_true', + default=False, + help='Omit the build, perform the packaging step directly.') + + build_package_group.add_argument( + '--skip-package', + '-sp', + action='store_true', + default=False, + help='Omit the packaging, perform the packaging step directly.') + + self.parse_add_argument(parser) + + known_platforms = ('windows', 'libs', 'lldb-mi', 'lldb-server', 'linux', 'check-api') + known_platforms_str = ', '.join(known_platforms) + + class SeparatedListByCommaAction(argparse.Action): + def __call__(self, parser, namespace, vals, option_string): + for val in vals.split(','): + if val in known_platforms: + continue + else: + error = '\'{}\' invalid. Choose from {}'.format(val, known_platforms) + raise argparse.ArgumentError(self, error) + setattr(namespace, self.dest, vals.split(',')) + + parser.add_argument( + '--no-build', + action=SeparatedListByCommaAction, + default=list(), + help='Don\'t build toolchain for specified platforms. Choices: ' + known_platforms_str) + + return parser.parse_args() + + +class ClangVersion(object): + """Parse and save clang version from version file.""" + + def __init__(self, version_file): + self._parse_version_file(version_file) + + @staticmethod + def _parse(text, key): + return re.findall(r'%s\s+(\d+)' % key, text)[0] + + def _parse_version_file(self, version_file): + with open(version_file, 'r') as fp: + text = fp.read() + self.major = self._parse(text, 'CLANG_VERSION_MAJOR') + self.minor = self._parse(text, 'CLANG_VERSION_MINOR') + self.patch = self._parse(text, 'CLANG_VERSION_PATCHLEVEL') + + def long_version(self): + return '.'.join([self.major, self.minor, self.patch]) + + def short_version(self): + return '.'.join([self.major, self.minor]) + + def major_version(self): + return self.major + + +class BuildUtils(object): + + def __init__(self, build_config): + self.build_config = build_config + + self.CMAKE_BIN_DIR = os.path.abspath( + os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts/cmake', self.platform_prefix(), 'bin')) + + def open_ohos_triple(self, arch): + return arch + self.build_config.OPENHOS_SFX + + def liteos_triple(self, arch): + return arch + self.build_config.LITEOS_SFX + + def set_clang_version(self, install_dir): + self.build_config.VERSION = self.get_clang_version(install_dir).long_version() + + def invoke_ninja(self, + out_path, + env, + target=None, + install=True, + build_threads=False): + + ninja_bin_path = os.path.join(self.CMAKE_BIN_DIR, 'ninja') + + ninja_list = ['-l{}'.format(build_threads)] if build_threads else [] + + ninja_target = [target] if target else [] + + self.check_call([ninja_bin_path] + ninja_list + ninja_target, cwd=out_path, env=env) + if install: + self.check_call([ninja_bin_path, 'install'], cwd=out_path, env=env) + + def invoke_cmake(self, + cmake_path, + out_path, + invoke_defines, + env): + + cmake_bin_path = os.path.join(self.CMAKE_BIN_DIR, 'cmake') + flags = ['-G', 'Ninja'] + flags += ['-DCMAKE_PREFIX_PATH=%s' % self.CMAKE_BIN_DIR] + + for key in invoke_defines: + newdef = ''.join(['-D', key, '=', invoke_defines[key]]) + flags += [newdef] + + flags += [cmake_path] + self.check_create_dir(out_path) + + self.check_call([cmake_bin_path] + flags, cwd=out_path, env=env) + + @staticmethod + def logger(): + """Returns the module level logger.""" + return logging.getLogger(__name__) + + @staticmethod + def get_clang_version(llvm_install): + version_file = os.path.join(llvm_install, 'include', 'clang', 'Basic', + 'Version.inc') + return ClangVersion(version_file) + + def check_create_dir(self, path): + if not os.path.exists(path): + """Proxy for os.makedirs with logging and dry-run support.""" + self.logger().info('makedirs %s', path) + os.makedirs(path) + + def check_rm_tree(self, tree_dir): + """Removes directory tree.""" + def chmod_and_retry(func, path, _): + if not os.access(path, os.W_OK): + os.chmod(path, stat.S_IWUSR) + return func(path) + raise IOError("rmtree on %s failed" % path) + + if os.path.exists(tree_dir): + self.logger().info('shutil rmtree %s', tree_dir) + shutil.rmtree(tree_dir, onerror=chmod_and_retry) + + def check_copy_tree(self, src_dir, dst_dir): + self.check_rm_tree(dst_dir) + """Proxy for shutil.copytree with logging and dry-run support.""" + self.logger().info('copytree %s %s', src_dir, dst_dir) + shutil.copytree(src_dir, dst_dir, symlinks=True) + + def check_copy_file(self, src_file, dst_file): + if os.path.exists(src_file): + """Proxy for shutil.copy2 with logging and dry-run support.""" + self.logger().info('copy %s %s', src_file, dst_file) + shutil.copy2(src_file, dst_file) + + def check_call(self, cmd, *args, **kwargs): + """subprocess.check_call with logging.""" + self.logger().info('check_call:%s %s', + datetime.datetime.now().strftime("%H:%M:%S"), subprocess.list2cmdline(cmd)) + + subprocess.check_call(cmd, *args, **kwargs) + + def merge_out_path(self, *args): + return os.path.abspath(os.path.join(self.build_config.OUT_PATH, *args)) + + @staticmethod + def use_platform(): + sysstr = platform.system().lower() + arch = platform.machine() + return "%s-%s" % (sysstr, arch) + + def platform_prefix(self): + prefix = self.use_platform() + if (prefix.endswith('x86_64')): + return prefix[:-3] + return prefix + + def host_is_linux(self): + return self.use_platform().startswith('linux-') + + def host_is_darwin(self): + return self.use_platform().startswith('darwin-') + + def rm_cmake_cache(self, cache_dir): + for dirpath, dirs, files in os.walk(cache_dir): + if 'CMakeCache.txt' in files: + self.logger().info('rm CMakeCache.txt on %s', cache_dir) + os.remove(os.path.join(dirpath, 'CMakeCache.txt')) + if 'CMakeFiles' in dirs: + self.logger().info('rm CMakeFiles on %s', cache_dir) + self.check_rm_tree(os.path.join(dirpath, 'CMakeFiles')) + + @staticmethod + def find_program(name): + # FIXME: Do we need Windows support here? + return os.popen('which ' + name).read().strip() + + # Base cmake options such as build type that are common across all invocations + def base_cmake_defines(self): + mac_min_version = '10.9' + defines = {} + + defines['CMAKE_BUILD_TYPE'] = 'Release' + defines['LLVM_ENABLE_ASSERTIONS'] = 'OFF' + defines['LLVM_ENABLE_TERMINFO'] = 'OFF' + defines['LLVM_ENABLE_THREADS'] = 'ON' + defines['LLVM_USE_NEWPM'] = 'ON' + defines['LLVM_ENABLE_BINDINGS'] = 'OFF' + defines['CLANG_REPOSITORY_STRING'] = 'llvm-project' + + if self.host_is_darwin(): + defines['CMAKE_OSX_DEPLOYMENT_TARGET'] = mac_min_version + defines['LLDB_INCLUDE_TESTS'] = 'OFF' + defines['LIBCXX_INCLUDE_TESTS'] = 'OFF' + + defines['COMPILER_RT_BUILD_XRAY'] = 'OFF' + return defines + + +class LlvmCore(BuildUtils): + + def __init__(self, build_config): + super(LlvmCore, self).__init__(build_config) + + def build_llvm(self, + targets, + build_dir, + install_dir, + build_name, + extra_defines=None, + extra_env=None): + + common_defines = self.base_cmake_defines() + common_defines['CMAKE_INSTALL_PREFIX'] = install_dir + common_defines['LLVM_INSTALL_UTILS'] = 'ON' + common_defines['LLVM_TARGETS_TO_BUILD'] = targets + common_defines['LLVM_BUILD_LLVM_DYLIB'] = 'ON' + + build_number = '' + if re.match(r'\d+-.\D*$', build_name): + build_number, build_name = build_name.split('-', 1) + elif re.match(r'^\d+$', build_name): + build_number = build_name + build_name = '' + elif re.match(r'^\D+$', build_name): + build_name = build_name + else: + raise Exception('Warning! Build name is invalid, because it must not contain digits. ' + 'If you want to pass digit version, please, use follow template: {NUMBER}-{SUFFIX} ' + 'or just pass number. Otherwise unit tests will fail with assertions') + + common_defines['CLANG_VENDOR'] = 'OHOS (%s) ' % build_name + common_defines['CLANG_VENDOR_BUILD_VERSION'] = build_number + common_defines.update(extra_defines) + + env = dict(self.build_config.ORIG_ENV) + if extra_env is not None: + env.update(extra_env) + + llvm_project_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'llvm')) + + self.invoke_cmake(llvm_project_path, + build_dir, + common_defines, + env=env) + + self.invoke_ninja(out_path=build_dir, + env=env, + target=None, + install=True) + + + def llvm_compile_darwin_defines(self, llvm_defines): + if self.host_is_darwin(): + llvm_defines['LIBUNWIND_ENABLE_SHARED'] = 'OFF' + llvm_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + llvm_defines['LLDB_NO_DEBUGSERVER'] = 'ON' + llvm_defines['LLDB_ENABLE_PYTHON'] = 'OFF' + llvm_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + llvm_defines['LLVM_BUILD_EXTERNAL_COMPILER_RT'] = 'ON' + llvm_defines['LLVM_ENABLE_ZSTD'] = 'OFF' + + def llvm_compile_linux_defines(self, + llvm_defines, + debug_build=False, + no_lto=False, + build_instrumented=False): + if self.host_is_linux(): + llvm_defines['LLVM_ENABLE_LLD'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'ON' + llvm_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + llvm_defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF' + llvm_defines['LIBCXX_USE_COMPILER_RT'] = 'ON' + llvm_defines['LIBCXXABI_USE_LLVM_UNWINDER'] = 'ON' + llvm_defines['LIBCXXABI_ENABLE_STATIC_UNWINDER'] = 'ON' + llvm_defines['LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY'] = 'YES' + llvm_defines['LIBCXXABI_USE_COMPILER_RT'] = 'ON' + llvm_defines['COMPILER_RT_USE_LLVM_UNWINDER'] = 'ON' + llvm_defines['COMPILER_RT_ENABLE_STATIC_UNWINDER'] = 'ON' + llvm_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_ORC'] = 'OFF' + llvm_defines['LIBUNWIND_USE_COMPILER_RT'] = 'ON' + llvm_defines['LLVM_BINUTILS_INCDIR'] = '/usr/include' + llvm_defines['LLDB_ENABLE_PYTHON'] = 'OFF' + + if not build_instrumented and not no_lto and not debug_build: + llvm_defines['LLVM_ENABLE_LTO'] = 'Thin' + + @staticmethod + def llvm_compile_llvm_defines(llvm_defines, llvm_root, cflags, ldflags): + llvm_defines['LLVM_ENABLE_PROJECTS'] = 'clang;lld;clang-tools-extra;openmp;lldb' + llvm_defines['LLVM_ENABLE_RUNTIMES'] = 'libunwind;libcxxabi;libcxx;compiler-rt' + llvm_defines['LLVM_ENABLE_BINDINGS'] = 'OFF' + llvm_defines['CMAKE_C_COMPILER'] = os.path.join(llvm_root, 'bin', 'clang') + llvm_defines['CMAKE_CXX_COMPILER'] = os.path.join(llvm_root, 'bin', 'clang++') + llvm_defines['CMAKE_AR'] = os.path.join(llvm_root, 'bin', 'llvm-ar') + llvm_defines['CMAKE_RANLIB'] = os.path.join(llvm_root, 'bin', 'llvm-ranlib') + llvm_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + llvm_defines['SANITIZER_ALLOW_CXXABI'] = 'OFF' + llvm_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE' + llvm_defines['OPENMP_TEST_FLAGS'] = '-Wl,-ldl' + llvm_defines['CLANG_BUILD_EXAMPLES'] = 'OFF' + llvm_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + llvm_defines['COMPILER_RT_BUILD_SANITIZERS'] = 'OFF' + llvm_defines['COMPILER_RT_BUILD_MEMPROF'] = 'OFF' + llvm_defines['CMAKE_ASM_FLAGS'] = cflags + llvm_defines['CMAKE_C_FLAGS'] = cflags + llvm_defines['CMAKE_CXX_FLAGS'] = '%s -stdlib=libc++' % cflags + llvm_defines['CMAKE_EXE_LINKER_FLAGS'] = ldflags + llvm_defines['CMAKE_SHARED_LINKER_FLAGS'] = ldflags + llvm_defines['CMAKE_MODULE_LINKER_FLAGS'] = ldflags + + def llvm_compile(self, + build_name, + out_dir, + debug_build=False, + no_lto=False, + build_instrumented=False, + xunit_xml_output=None): + + llvm_clang_install = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'prebuilts/clang/ohos', self.use_platform(), + 'clang-%s' % self.build_config.CLANG_VERSION)) + llvm_path = self.merge_out_path('llvm_make') + llvm_profdata = os.path.join(llvm_clang_install, 'bin', 'llvm-profdata') + + if self.host_is_darwin(): + ldflags = '' + else: + ldflags = '-fuse-ld=lld' + ldflags = '%s -L%s' % (ldflags, os.path.join(llvm_clang_install, 'lib')) + + llvm_extra_env = {} + llvm_extra_env['LD_LIBRARY_PATH'] = os.path.join(llvm_clang_install, 'lib') + + llvm_defines = {} + + self.llvm_compile_darwin_defines(llvm_defines) + self.llvm_compile_linux_defines(llvm_defines, debug_build, no_lto, build_instrumented) + + if self.host_is_linux(): + ldflags += ' -l:libunwind.a -l:libc++abi.a --rtlib=compiler-rt -stdlib=libc++ -static-libstdc++' + + if xunit_xml_output: + llvm_defines['LLVM_LIT_ARGS'] = "--xunit-xml-output={} -sv".format(xunit_xml_output) + + if self.build_config.enable_assertions: + llvm_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + if debug_build: + llvm_defines['CMAKE_BUILD_TYPE'] = 'Debug' + + if build_instrumented: + llvm_defines['LLVM_BUILD_INSTRUMENTED'] = 'ON' + llvm_defines['LLVM_PROFDATA'] = llvm_profdata + + resource_dir = "lib/clang/10.0.1/lib/linux/libclang_rt.profile-x86_64.a" + ldflags += ' %s' % os.path.join(llvm_clang_install, resource_dir) + + cflags = '-fstack-protector-strong -fPIE' + if not self.host_is_darwin(): + ldflags += ' -Wl,-z,relro,-z,now -pie' + if self.build_config.strip: + ldflags += ' -s' + + self.llvm_compile_llvm_defines(llvm_defines, llvm_clang_install, cflags, ldflags) + + linker_path = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts', 'clang', + 'ohos', 'linux-x86_64', 'llvm', 'bin', 'ld.lld')) + llvm_defines['CMAKE_LINKER'] = linker_path + + self.build_llvm(targets=self.build_config.TARGETS, + build_dir=llvm_path, + install_dir=out_dir, + build_name=build_name, + extra_defines=llvm_defines, + extra_env=llvm_extra_env) + + def llvm_compile_windows_defines(self, + windows_defines, + cc, + cxx, + windows_sysroot): + + if self.build_config.enable_assertions: + + windows_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + windows_defines['LLDB_RELOCATABLE_PYTHON'] = 'OFF' + win_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) + windows_defines['LLDB_ENABLE_PYTHON'] = 'ON' + windows_defines['LLDB_PYTHON_HOME'] = 'python' + windows_defines['LLDB_PYTHON_RELATIVE_PATH'] = \ + 'bin/python/lib/python%s' % (self.build_config.LLDB_PY_VERSION) + windows_defines['LLDB_PYTHON_EXE_RELATIVE_PATH'] = 'bin/python' + windows_defines['LLDB_PYTHON_EXT_SUFFIX'] = '.pys' + windows_defines['PYTHON_INCLUDE_DIRS'] = os.path.join(win_sysroot, + 'include', 'python%s' % self.build_config.LLDB_PY_VERSION) + windows_defines['PYTHON_LIBRARIES'] = os.path.join(win_sysroot, 'lib', 'libpython%s.dll.a' + % self.build_config.LLDB_PY_VERSION) + windows_defines['SWIG_EXECUTABLE'] = self.find_program('swig') + windows_defines['PYTHON_EXECUTABLE'] = self.find_program('python3') + + windows_defines['CMAKE_C_COMPILER'] = cc + windows_defines['CMAKE_CXX_COMPILER'] = cxx + windows_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + windows_defines['CMAKE_BUILD_TYPE'] = 'Release' + windows_defines['LLVM_BUILD_RUNTIME'] = 'OFF' + windows_defines['LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD'] = 'ON' + windows_defines['LLVM_TOOL_OPENMP_BUILD'] = 'OFF' + windows_defines['LLVM_INCLUDE_TESTS'] = 'OFF' + windows_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + windows_defines['LLVM_ENABLE_PROJECTS'] = 'clang;clang-tools-extra;lld;lldb' + windows_defines['LLVM_BUILD_LLVM_DYLIB'] = 'OFF' + windows_defines['CLANG_BUILD_EXAMPLES'] = 'OFF' + windows_defines['CMAKE_SYSROOT'] = windows_sysroot + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + windows_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + windows_defines['LLDB_RELOCATABLE_PYTHON'] = 'OFF' + + def llvm_compile_windows_flags(self, + windows_defines, + windowstool_path, + windows64_install, + ldflags, + cflags): + + windows_defines['CROSS_TOOLCHAIN_FLAGS_NATIVE'] = ';'.join([ + '-DCMAKE_PREFIX_PATH=%s' % self.CMAKE_BIN_DIR, + '-DCOMPILER_RT_BUILD_LIBFUZZER=OFF', + '-DLLVM_ENABLE_LIBCXX=ON', + '-DCMAKE_BUILD_WITH_INSTALL_RPATH=TRUE', + '-DCMAKE_INSTALL_RPATH=%s' % os.path.join(windowstool_path, 'lib')] + ) + + ldflag = ['-fuse-ld=lld', + '-stdlib=libc++', + '--rtlib=compiler-rt', + '-lunwind', '-Wl,--dynamicbase', + '-Wl,--nxcompat', + '-lucrt', + '-lucrtbase', + '-L', + os.path.join(windows64_install, 'lib'), + '-Wl,--high-entropy-va'] + ldflags.extend(ldflag) + + cflag = ['-stdlib=libc++', + '--target=x86_64-pc-windows-gnu', + '-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', + '-D_WIN32_WINNT=0x0600', + '-DWINVER=0x0600', + '-D__MSVCRT_VERSION__=0x1400', + '-DMS_WIN64'] + cflags.extend(cflag) + + def llvm_compile_windows_cmake(self, + cflags, + cxxflags, + ldflags, + windows_defines): + + + zlib_path = self.merge_out_path('../', 'prebuilts', 'clang', 'host', 'windows-x86', 'toolchain-prebuilts', + 'zlib') + zlib_inc = os.path.join(zlib_path, 'include') + zlib_lib = os.path.join(zlib_path, 'lib') + + cflags.extend(['-I', zlib_inc]) + cxxflags.extend(['-I', zlib_inc]) + ldflags.extend(['-L', zlib_lib]) + + windows_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + windows_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + windows_defines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + windows_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + windows_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + windows_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + + def llvm_compile_for_windows(self, + targets, + enable_assertions, + build_name): + + self.logger().info('Building llvm for windows.') + + build_dir = self.merge_out_path("windows-x86_64") + windowstool_path = self.merge_out_path('llvm-install') + windows64_install = self.merge_out_path('windows-x86_64-install') + windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) + + self.check_create_dir(build_dir) + + # Write a NATIVE.cmake in windows_path that contains the compilers used + # to build native tools such as llvm-tblgen and llvm-config. This is + # used below via the CMake variable CROSS_TOOLCHAIN_FLAGS_NATIVE. + cc = os.path.join(windowstool_path, 'bin', 'clang') + cxx = os.path.join(windowstool_path, 'bin', 'clang++') + + # Extra cmake defines to use while building for Windows + windows_defines = {} + self.llvm_compile_windows_defines(windows_defines, cc, cxx, windows_sysroot) + + # Set CMake path, toolchain file for native compilation (to build tablegen + # etc). Also disable libfuzzer build during native compilation. + + ldflags = [] + cflags = [] + + self.llvm_compile_windows_flags(windows_defines, + windowstool_path, windows64_install, ldflags, cflags) + + cxxflags = list(cflags) + + windows_extra_env = dict() + + cxxflags.append('-fuse-cxa-atexit') + cxxflags.extend(('-I', os.path.join(windows64_install, 'include', 'c++', 'v1'))) + + self.llvm_compile_windows_cmake(cflags, cxxflags, ldflags, windows_defines) + + self.build_llvm(self.build_config.TARGETS, + build_dir, + windows64_install, + build_name, + extra_defines=windows_defines, + extra_env=windows_extra_env) + + +class SysrootComposer(BuildUtils): + + def __init__(self, build_config): + super(SysrootComposer, self).__init__(build_config) + + def setup_cmake_platform(self, llvm_install): + + # OHOS.cmake already exsit on cmake prebuilts, + # but it didn't contain these two lines, so we still need OHOS.cmake. + ohos_cmake = 'OHOS.cmake' + dst_dir = self.merge_out_path( + '../prebuilts/cmake/%s/share/cmake-3.16/Modules/Platform' % self.platform_prefix()) + src_file = '%s/%s' % (self.build_config.LLVM_BUILD_DIR, ohos_cmake) + if os.path.exists(os.path.join(dst_dir, ohos_cmake)): + os.remove(os.path.join(dst_dir, ohos_cmake)) + shutil.copy2(src_file, dst_dir) + + + def build_musl(self, llvm_install, target, *extra_args): + cur_dir = os.getcwd() + os.chdir(self.build_config.LLVM_BUILD_DIR) + self.logger().info('build musl %s', self.merge_out_path('install')) + args = ['./build_musl.sh', '-t', target, + '-c', self.merge_out_path(llvm_install, 'bin'), + '-o', self.merge_out_path(), + '-T', self.build_config.REPOROOT_DIR] + list(extra_args) + self.check_call(args) + os.chdir(cur_dir) + + def install_linux_headers(self, arch, target): + dir_suffix = arch + if arch == 'x86_64': + dir_suffix = 'x86' + elif arch == 'mipsel': + dir_suffix = 'mips' + linux_kernel_dir = os.path.join('kernel_linux_patches', 'linux-5.10') + linux_kernel_path = os.path.join(self.build_config.OUT_PATH, '..', linux_kernel_dir) + ohosmusl_sysroot_dst = self.merge_out_path('sysroot', target, 'usr') + headers_tmp_dir = os.path.join(linux_kernel_path, 'prebuilts', 'usr', 'include') + self.check_copy_tree(os.path.join(headers_tmp_dir, 'linux'), + os.path.join(ohosmusl_sysroot_dst, 'include/linux')) + self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-%s' % dir_suffix,'asm'), + os.path.join(ohosmusl_sysroot_dst, 'include', 'asm')) + self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-generic'), + os.path.join(ohosmusl_sysroot_dst, 'include/asm-generic')) + + def copy_libz_to_sysroot(self, libz_path, llvm_triple): + # Install to sysroot + dest_usr = self.merge_out_path('sysroot', llvm_triple, 'usr') + dest_usr_include = os.path.join(dest_usr, 'include') + + # Copy over usr/include. + zlib_h = self.merge_out_path('../third_party/zlib', 'zlib.h') + self.check_copy_file(zlib_h, dest_usr_include) + + zconf_h = os.path.join(libz_path, 'zconf.h') + self.check_copy_file(zconf_h, dest_usr_include) + + # Copy over usr/lib. + dest_usr_lib = os.path.join(dest_usr, 'lib') + static_zlib = os.path.join(libz_path, 'libz.a') + self.check_copy_file(static_zlib, dest_usr_lib) + + +class LlvmLibs(BuildUtils): + + def __init__(self, build_config, sysroot_composer, llvm_package): + super(LlvmLibs, self).__init__(build_config) + self.sysroot_composer = sysroot_composer + self.llvm_package = llvm_package + + def build_crt_libs(self, configs, llvm_install, need_lldb_server): + for (arch, target) in configs: + self.sysroot_composer.build_musl(llvm_install, target) + if target.endswith(self.build_config.OPENHOS_SFX): + self.sysroot_composer.install_linux_headers(arch, target) + self.build_libs(need_lldb_server, + llvm_install, + target, + precompilation=True) + self.sysroot_composer.build_musl(llvm_install, target, '-l') + + def build_libs_defines(self, + llvm_triple, + defines, + cc, + cxx, + ar, + llvm_config, + ldflags, + cflags, + extra_flags): + + sysroot = self.merge_out_path('sysroot') + + defines['CMAKE_C_COMPILER'] = cc + defines['CMAKE_CXX_COMPILER'] = cxx + defines['CMAKE_AR'] = ar + defines['LLVM_CONFIG_PATH'] = llvm_config + defines['CMAKE_SYSROOT'] = sysroot + defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + + ldflag = [ + '-fuse-ld=lld', + '-Wl,--gc-sections', + '-Wl,--build-id=sha1', + '--rtlib=compiler-rt', + '-stdlib=libc++', ] + + if not self.host_is_darwin(): + ldflag.append('-Wl,-z,relro,-z,now -pie') + if self.build_config.strip: + ldflag.append('-s') + + ldflags.extend(ldflag) + + cflag = [ + '-fstack-protector-strong', + '-fPIE', + '--target=%s' % llvm_triple, + '-ffunction-sections', + '-fdata-sections', + extra_flags, ] + + cflags.extend(cflag) + + def build_libs(self, need_lldb_server, llvm_install, llvm_build, precompilation=False): + configs_list = [ + ('arm', self.liteos_triple('arm'), '-march=armv7-a -mfloat-abi=soft', ''), + ('arm', self.liteos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft', 'a7_soft'), + ('arm', self.liteos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4', 'a7_softfp_neon-vfpv4'), + ('arm', self.liteos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), + + ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mfloat-abi=soft', ''), + ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft', 'a7_soft'), + ('arm', self.open_ohos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4', 'a7_softfp_neon-vfpv4'), + ('arm', self.open_ohos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), + ('aarch64', self.open_ohos_triple('aarch64'), '', ''), + ('riscv64', self.open_ohos_triple('riscv64'), '', ''), + ('mipsel', self.open_ohos_triple('mipsel'), '', ''), + ('mipsel', self.open_ohos_triple('mipsel'), '-mnan=legacy', 'nanlegacy'), + ('x86_64', self.open_ohos_triple('x86_64'), '', ''),] + + cc = os.path.join(llvm_install, 'bin', 'clang') + cxx = os.path.join(llvm_install, 'bin', 'clang++') + ar = os.path.join(llvm_install, 'bin', 'llvm-ar') + llvm_config = os.path.join(llvm_install, 'bin', 'llvm-config') + seen_arch_list = [self.liteos_triple('arm')] + + self.set_clang_version(llvm_install) + for (arch, llvm_triple, extra_flags, multilib_suffix) in configs_list: + if llvm_build != llvm_triple: + continue + + has_lldb_server = arch not in ['riscv64', 'mipsel'] + + defines = {} + ldflags = [] + cflags = [] + self.logger().info('Build libs for %s', llvm_triple) + self.build_libs_defines(llvm_triple, defines, cc, cxx, ar, llvm_config, ldflags, cflags, extra_flags) + if arch == 'mipsel': + ldflags.append('-Wl,-z,notext') + ldflags.append('-Wl,--no-check-dynamic-relocations') + + llvm_path = self.merge_out_path('llvm_make') + arch_list = [self.liteos_triple('arm'), self.open_ohos_triple('arm'), + self.open_ohos_triple('aarch64'), self.open_ohos_triple('riscv64'), + self.open_ohos_triple('mipsel'), self.open_ohos_triple('x86_64')] + if precompilation: + self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) + continue + # libunwind is added to linker command line by OHOS toolchain, so we have to use two step build + self.build_runtimes(llvm_install, "libunwind", ldflags, cflags, llvm_triple, arch, multilib_suffix, defines) + self.build_runtimes(llvm_install, "libunwind;libcxxabi;libcxx", ldflags, cflags, llvm_triple, arch, multilib_suffix, defines) + + libcxx_ndk_install = self.merge_out_path('libcxx-ndk') + self.check_create_dir(libcxx_ndk_install) + self.build_runtimes(libcxx_ndk_install, "libunwind;libcxxabi;libcxx", ldflags, cflags, llvm_triple, + arch, multilib_suffix, defines, True) + + self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines, + first_time=False) + + if llvm_triple in arch_list: + if need_lldb_server and has_lldb_server and llvm_triple not in seen_arch_list: + self.build_lldb_server(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, + defines) + seen_arch_list.append(llvm_triple) + continue + + self.build_libomp(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) + self.build_libz(arch, llvm_triple, cflags, ldflags, defines) + if need_lldb_server and has_lldb_server and llvm_triple not in seen_arch_list: + self.build_lldb_server(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, defines) + seen_arch_list.append(llvm_triple) + + def build_runtimes(self, + llvm_install, + rt_list, + ldflags, + cflags, + llvm_triple, + arch, + multilib_suffix, + defines, + is_libcxx_ndk_install=False): + + self.logger().info('Building runtimes(%s) for %s', rt_list, arch) + + ndk_suffix = '-ndk' if is_libcxx_ndk_install else '' + out_path = self.merge_out_path('lib', rt_list.replace(';', '-') + ndk_suffix + '-' + str(llvm_triple)) + + libcxx_install_include_path = self.merge_out_path(llvm_install, 'include', 'libcxx-ohos', 'include', 'c++', 'v1') + + rt_cflags = list(cflags) + rt_cflags.append('-fstack-protector-strong') + rt_cflags.append('-funwind-tables') + rt_cflags.append('-fno-omit-frame-pointer') + + rt_defines = defines.copy() + rt_defines['OHOS'] = '1' + rt_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + rt_defines['LLVM_TARGET_MULTILIB_SUFFIX'] = multilib_suffix + rt_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple + rt_defines['LLVM_ENABLE_RUNTIMES'] = rt_list + rt_defines['LIBUNWIND_USE_COMPILER_RT'] = 'ON' + rt_defines['LIBUNWIND_ENABLE_SHARED'] = 'OFF' + rt_defines['LIBCXXABI_USE_COMPILER_RT'] = 'ON' + rt_defines['LIBCXXABI_USE_LLVM_UNWINDER'] = 'ON' + rt_defines['LIBCXXABI_ENABLE_STATIC_UNWINDER'] = 'ON' + rt_defines['LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY'] = 'OFF' + rt_defines['LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL'] = 'OFF' + rt_defines['LIBCXXABI_ENABLE_SHARED'] = 'OFF' + rt_defines['LIBCXXABI_LIBCXX_INCLUDES'] = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'libcxx', 'include')) + rt_defines['LIBCXXABI_INSTALL_INCLUDE_DIR'] = libcxx_install_include_path + rt_defines['LIBCXX_USE_COMPILER_RT'] = 'ON' + rt_defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF' + rt_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + rt_defines['LIBCXX_INSTALL_INCLUDE_DIR'] = libcxx_install_include_path + rt_defines['LIBCXX_INSTALL_INCLUDE_TARGET_DIR'] = libcxx_install_include_path + rt_defines['CMAKE_ASM_FLAGS'] = ' '.join(rt_cflags) + rt_defines['CMAKE_C_FLAGS'] = ' '.join(rt_cflags) + rt_defines['CMAKE_CXX_FLAGS'] = ' '.join(rt_cflags) + rt_defines['CMAKE_BUILD_TYPE'] = 'Release' + rt_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + rt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + rt_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + rt_defines['CMAKE_CROSSCOMPILING'] = 'True' + rt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + if is_libcxx_ndk_install: + rt_defines['LIBCXX_ABI_NAMESPACE'] = '__n1' + rt_defines['LIBCXX_OUTPUT_NAME'] = 'c++_shared' + rt_defines['LIBCXX_OUTPUT_STATIC_NAME'] = 'c++_static' + rt_defines['LIBCXXABI_INSTALL_LIBRARY'] = 'OFF' + rt_defines['LIBUNWIND_INSTALL_LIBRARY'] = 'OFF' + else: + rt_defines['LIBCXX_ABI_NAMESPACE'] = '__h' + + self.check_rm_tree(out_path) + cmake_rt = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'runtimes')) + + self.invoke_cmake(cmake_rt, + out_path, + rt_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=out_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_crts(self, + llvm_install, + arch, + llvm_triple, + cflags, + ldflags, + multilib_suffix, + defines, + first_time=True): + + self.logger().info('Building compiler-rt for %s', arch) + + suffix = '-' + multilib_suffix if multilib_suffix else '' + crt_path = self.merge_out_path('lib', 'clangrt-%s%s' % (llvm_triple, suffix)) + crt_install = os.path.join(llvm_install, 'lib', 'clang', self.build_config.VERSION) + + crt_extra_flags = [] + if not self.build_config.debug: + # Remove absolute paths from compiler-rt debug info emitted with -gline-tables-only + crt_extra_flags = ['-ffile-prefix-map=%s=.' % self.build_config.REPOROOT_DIR] + + crt_defines = defines.copy() + crt_defines.update(self.base_cmake_defines()) + crt_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_C_FLAGS'] = ' '.join(cflags + crt_extra_flags) + crt_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags + crt_extra_flags) + crt_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags + crt_extra_flags) + crt_defines['COMPILER_RT_TEST_COMPILER_CFLAGS'] = ' '.join(cflags) + crt_defines['OHOS'] = '1' + crt_defines['COMPILER_RT_TEST_TARGET_TRIPLE'] = llvm_triple + crt_defines['COMPILER_RT_TEST_STANDALONE_BUILD_LIBS'] = 'OFF' + crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'ON' + crt_defines['CMAKE_INSTALL_PREFIX'] = crt_install + crt_defines['LLVM_TARGET_MULTILIB_SUFFIX'] = multilib_suffix + if first_time or llvm_triple == self.liteos_triple('arm'): + crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + else: + crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'ON' + crt_defines['COMPILER_RT_BUILD_ORC'] = 'OFF' + crt_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + crt_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + crt_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + crt_defines['CMAKE_CROSSCOMPILING'] = 'True' + crt_defines['SANITIZER_CXX_ABI'] = 'libcxxabi' + crt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + crt_defines['COMPILER_RT_HWASAN_WITH_INTERCEPTORS'] = 'OFF' + crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = \ + 'OFF' if llvm_triple == self.liteos_triple('arm') or first_time else 'ON' + crt_defines['COMPILER_RT_DEFAULT_TARGET_TRIPLE'] = llvm_triple + crt_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'compiler-rt')) + self.rm_cmake_cache(crt_path) + + self.invoke_cmake(crt_cmake_path, + crt_path, + crt_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=crt_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_libomp(self, + llvm_install, + arch, + llvm_triple, + cflags, + ldflags, + multilib_suffix, + defines): + + self.logger().info('Building libomp for %s', arch) + + libomp_path = self.merge_out_path('lib', 'libomp-%s' % llvm_triple) + out_dir = os.path.join(libomp_path, 'lib') + + libomp_cflags = list(cflags) + libomp_cflags.append('-fPIC') + + libomp_defines = defines.copy() + libomp_defines.update(self.base_cmake_defines()) + libomp_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + libomp_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + libomp_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + libomp_defines['OHOS'] = '1' + libomp_defines['CMAKE_ASM_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['CMAKE_C_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['CMAKE_CXX_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['OPENMP_ENABLE_LIBOMPTARGET'] = 'FALSE' + + libomp_defines['OPENMP_LIBDIR_SUFFIX'] = os.path.join(os.sep, llvm_triple, multilib_suffix) + libomp_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE' + libomp_defines['CMAKE_POLICY_DEFAULT_CMP0056'] = 'NEW' + libomp_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + libomp_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + libomp_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + libomp_defines['CMAKE_CROSSCOMPILING'] = 'True' + libomp_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + libomp_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + libomp_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, 'openmp') + self.rm_cmake_cache(libomp_path) + + self.invoke_cmake(libomp_cmake_path, + libomp_path, + libomp_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=libomp_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_libz(self, + arch, + llvm_triple, + cflags, + ldflags, + defines): + + self.logger().info('Building libz for %s ', arch) + + libz_path = self.merge_out_path('lib', 'libz-%s' % llvm_triple) + if llvm_triple == self.hos_triple('arm'): + ldflags.append('-lunwind') + + libz_cflags = list(cflags) + libz_cflags.append('-fPIC') + + libz_defines = defines.copy() + libz_defines.update(self.base_cmake_defines()) + libz_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['OHOS'] = '1' + libz_defines['CMAKE_ASM_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_C_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_CXX_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + libz_cmake_path = os.path.join(self.build_config.REPOROOT_DIR, 'third_party/zlib') + self.rm_cmake_cache(libz_path) + + self.invoke_cmake(libz_cmake_path, + libz_path, + libz_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=libz_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=False) + + self.sysroot_composer.copy_libz_to_sysroot(libz_path, llvm_triple) + + def build_lldb_server(self, + llvm_install, + llvm_path, + arch, + llvm_triple, + cflags, + ldflags, + defines): + + self.logger().info('Building lldb for %s', arch) + + lldb_path = self.merge_out_path('lib', 'lldb-server-%s' % llvm_triple) + crt_install = os.path.join(llvm_install, 'lib', 'clang', self.build_config.VERSION) + out_dir = os.path.join(lldb_path, 'bin') + + lldb_ldflags = list(ldflags) + lldb_cflags = list(cflags) + + lldb_ldflags.append('-lunwind') + lldb_ldflags.append('-static') + + lldb_defines = defines.copy() + lldb_defines.update(self.base_cmake_defines()) + + lldb_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + lldb_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + lldb_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + + lldb_defines['OHOS'] = '1' + lldb_defines['CMAKE_C_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_ASM_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_CXX_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_INSTALL_PREFIX'] = crt_install + lldb_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + lldb_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + lldb_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + lldb_defines['CMAKE_CROSSCOMPILING'] = 'True' + lldb_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple + lldb_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_defines['LLVM_ENABLE_PROJECTS'] = 'clang;lldb' + lldb_defines['LLVM_TABLEGEN'] = os.path.join(llvm_install, 'bin', 'llvm-tblgen') + lldb_defines['CLANG_TABLEGEN'] = os.path.join(llvm_install, '..', llvm_path, 'bin', 'clang-tblgen') + lldb_defines['LLDB_TABLEGEN'] = os.path.join(llvm_install, '..', llvm_path, 'bin', 'lldb-tblgen') + lldb_defines['LLVM_HOST_TRIPLE'] = llvm_triple + lldb_defines['LLVM_TARGET_ARCH'] = arch + lldb_defines['LLVM_TARGETS_TO_BUILD'] = self.build_config.TARGETS + + lldb_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, 'llvm') + + self.invoke_cmake(lldb_cmake_path, + lldb_path, + lldb_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=lldb_path, + env=dict(self.build_config.ORIG_ENV), + target='lldb-server', + install=False) + + self.llvm_package.copy_lldb_server_to_llvm_install(lldb_path, crt_install, llvm_triple) + + + def build_runtimes_for_windows(self, enable_assertions): + + self.logger().info('Building libs for windows.') + toolchain_dir = self.merge_out_path('llvm-install') + install_dir = self.merge_out_path('windows-x86_64-install') + windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) + + cflags = ['-stdlib=libc++', '--target=x86_64-pc-windows-gnu', '-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', '-D_WIN32_WINNT=0x0600', '-DWINVER=0x0600', '-D__MSVCRT_VERSION__=0x1400'] + + cmake_defines = {} + cmake_defines['CMAKE_C_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang') + cmake_defines['CMAKE_CXX_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang++') + cmake_defines['CMAKE_CROSSCOMPILING'] = 'True' + cmake_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + cmake_defines['CMAKE_SYSROOT'] = windows_sysroot + cmake_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_BUILD_TYPE'] = 'Release' + cmake_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + cmake_defines['CMAKE_INSTALL_PREFIX'] = install_dir + cmake_defines['LLVM_CONFIG_PATH'] = os.path.join(toolchain_dir, 'bin', 'llvm-config') + cmake_defines['LIBCXX_ENABLE_SHARED'] = 'OFF' + cmake_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + cmake_defines['LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS'] = 'ON' + cmake_defines['LIBCXXABI_ENABLE_SHARED'] = 'OFF' + cmake_defines['LIBUNWIND_ENABLE_SHARED'] = 'OFF' + cmake_defines['LIBCXXABI_USE_LLVM_UNWINDER'] = 'ON' + cmake_defines['LLVM_ENABLE_RUNTIMES'] = 'libunwind;libcxxabi;libcxx' + cmake_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' if enable_assertions else 'OFF' + + out_path = self.merge_out_path('lib', 'windows-runtimes') + cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'runtimes')) + + self.invoke_cmake(cmake_path, + out_path, + cmake_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path, + env=dict(self.build_config.ORIG_ENV), + install=True) + + + +class LldbMi(BuildUtils): + + def __init__(self, build_config, llvm_package): + super(LldbMi, self).__init__(build_config) + self.llvm_package = llvm_package + + def build_lldb_mi(self, llvm_install): + self.logger().info('Building lldb-mi for linux.') + + llvm_path = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'prebuilts/clang/ohos', self.use_platform(), 'clang-%s' % self.build_config.CLANG_VERSION)) + lldb_mi_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, '../lldb-mi') + lldb_mi_path = self.merge_out_path('lldb_mi_build') + + self.check_rm_tree(lldb_mi_path) + self.rm_cmake_cache(lldb_mi_path) + + if self.host_is_darwin(): + cflags = [] + cxxflags =[] + ldflags = ['-Wl,-rpath,%s' % '@loader_path/../lib'] + else: + cflags = [] + cxxflags =[] + ldflags = ['-fuse-ld=lld', '-Wl,-rpath,%s' % '\$ORIGIN/../lib'] + ldflags.append('-Wl,-z,relro,-z,now -pie') + if self.build_config.strip: + ldflags.append('-s') + + ldflags.append('-L%s' % os.path.join(llvm_path, 'lib')) + cxxflags.append('-std=c++14') + cxxflags.append('-fstack-protector-strong -fPIE') + cflags.append('-fstack-protector-strong -fPIE') + + lldb_mi_defines = {} + lldb_mi_defines['CMAKE_C_COMPILER'] = os.path.join(llvm_path, 'bin', 'clang') + lldb_mi_defines['CMAKE_CXX_COMPILER'] = os.path.join(llvm_path, 'bin', 'clang++') + lldb_mi_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + lldb_mi_defines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + lldb_mi_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['LLVM_DIR'] = os.path.join(llvm_install, 'lib/cmake/llvm/') + lldb_mi_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_mi_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + + self.invoke_cmake(lldb_mi_cmake_path, + lldb_mi_path, + lldb_mi_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(lldb_mi_path, + env=dict(self.build_config.ORIG_ENV), + install=False) + + self.llvm_package.copy_lldb_mi_to_llvm_install(lldb_mi_path, llvm_install) + + @staticmethod + def ldflags_lists_define(): + ldflags_lists = ['-Wl,--dynamicbase', + '-Wl,--nxcompat', + '-lucrt', + '-lucrtbase', + '-L', ] + return ldflags_lists + + @staticmethod + def cflags_lists_define(): + cflags_lists = ['-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', + '-D_WIN32_WINNT=0x0600', + '-DWINVER=0x0600', + '-D__MSVCRT_VERSION__=0x1400', + '-DMS_WIN64', ] + return cflags_lists + + # Extra cmake defines to use while building for Windows + def lldb_mi_windefines_dictionary(self, cc, cxx, windows_sysroot, cflags, cxxflags, ldflags): + lldb_mi_windefines = {} + lldb_mi_windefines['CMAKE_C_COMPILER'] = cc + lldb_mi_windefines['CMAKE_CXX_COMPILER'] = cxx + lldb_mi_windefines['CMAKE_C_COMPILER_WORKS'] = '1' + lldb_mi_windefines['CMAKE_CXX_COMPILER_WORKS'] = '1' + lldb_mi_windefines['CMAKE_SYSTEM_NAME'] = 'Windows' + lldb_mi_windefines['CMAKE_SYSTEM_PROCESSOR'] = 'x86_64' + lldb_mi_windefines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_mi_windefines['CMAKE_SYSROOT'] = windows_sysroot + lldb_mi_windefines['LLVM_INSTALL_PREFIX'] = self.merge_out_path('windows-x86_64-install') + lldb_mi_windefines['LLVM_DIR'] = self.merge_out_path('windows-x86_64-install/lib/cmake/llvm/') + lldb_mi_windefines['CMAKE_C_FLAGS'] = ' '.join(cflags) + lldb_mi_windefines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + lldb_mi_windefines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_windefines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_windefines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + if self.build_config.enable_assertions: + lldb_mi_windefines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + return lldb_mi_windefines + + + def build_lldb_mi_for_windows(self): + self.logger().info('Building lldb-mi for windows.') + + build_dir = self.merge_out_path('llvm-install') + lldb_mi_windows64_path = self.merge_out_path('windows-x86_64-lldb-mi') + lldb_mi_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, '../lldb-mi')) + windows64_install = self.merge_out_path('windows-x86_64-install') + cc = os.path.join(build_dir, 'bin', 'clang') + cxx = os.path.join(build_dir, 'bin', 'clang++') + + windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) + self.check_create_dir(lldb_mi_windows64_path) + + ldflags = ['-fuse-ld=lld', + '--rtlib=compiler-rt', + '-lunwind', + '-L%s' % os.path.join(windows64_install, 'lib'), + ] + ldflags.extend(self.ldflags_lists_define()) + ldflags.append(os.path.join(windows64_install, 'lib')) + ldflags.append('-Wl,--high-entropy-va') + + + cflags = ['-stdlib=libc++', + '--target=x86_64-pc-windows-gnu', + ] + cflags.extend(self.cflags_lists_define()) + cflags.append('-fno-exceptions') + cflags.append('-fno-rtti') + + cxxflags = list(cflags) + cxxflags.extend(('-I', os.path.join(windows64_install, 'include', 'c++', 'v1'))) + + zlib_path = os.path.abspath( + os.path.join('../../', 'prebuilts', 'clang', 'host', 'windows-x86', 'toolchain-prebuilts', 'zlib')) + zlib_inc = os.path.join(zlib_path, 'include') + zlib_lib = os.path.join(zlib_path, 'lib') + + cflags.extend(['-I', zlib_inc]) + cxxflags.extend(['-I', zlib_inc]) + ldflags.extend(['-L', zlib_lib]) + + + lldb_mi_env = dict(self.build_config.ORIG_ENV) + lldb_mi_env['LD_LIBRARY_PATH'] = os.path.join(build_dir, 'lib') + self.rm_cmake_cache(lldb_mi_windows64_path) + + self.invoke_cmake(lldb_mi_cmake_path, + lldb_mi_windows64_path, + self.lldb_mi_windefines_dictionary(cc, cxx, windows_sysroot, cflags, cxxflags, ldflags), + env=lldb_mi_env) + + self.invoke_ninja(lldb_mi_windows64_path, + env=lldb_mi_env, + install=False) + + self.llvm_package.copy_lldb_mi_to_windows(windows64_install, lldb_mi_windows64_path) + + +class LlvmPackage(BuildUtils): + + def __init__(self, build_config): + super(LlvmPackage, self).__init__(build_config) + + def copy_lldb_server_to_llvm_install(self, lldb_path, crt_install, llvm_triple): + # Copy lldb-server + libname = 'lldb-server' + src_lib = os.path.join(lldb_path, 'bin', libname) + dst_dir = os.path.join(crt_install, 'bin', llvm_triple) + self.check_create_dir(dst_dir) + self.check_copy_file(src_lib, os.path.join(dst_dir, libname)) + + def copy_lldb_mi_to_llvm_install(self, lldb_mi_path, llvm_install): + # Copy lldb-mi + lldb_mi_dst = os.path.join(llvm_install, 'bin', 'lldb-mi') + lldb_mi_src = os.path.join(lldb_mi_path, 'src', 'lldb-mi') + + if os.path.exists(lldb_mi_dst): + os.remove(lldb_mi_dst) + self.check_copy_file(lldb_mi_src, lldb_mi_dst) + + def copy_lldb_mi_to_windows(self, windows64_install, lldb_mi_windows64_path): + # Copy lldb-mi for windows + lldb_mi_dst = os.path.join(windows64_install, 'bin', 'lldb-mi.exe') + lldb_mi_src = os.path.join(lldb_mi_windows64_path, 'src', 'lldb-mi.exe') + if os.path.exists(lldb_mi_dst): + os.remove(lldb_mi_dst) + self.check_copy_file(lldb_mi_src, lldb_mi_dst) + + def package_libcxx(self): + libcxx_ndk_install=self.merge_out_path('libcxx-ndk') + libcxx_ndk_install_include=self.merge_out_path(libcxx_ndk_install, 'include', 'libcxx-ohos', 'include', 'c++', 'v1') + hosts_list=['linux-x86_64', 'darwin-x86_64', 'windows-x86_64', 'darwin-arm64'] + + if os.path.exists(libcxx_ndk_install): + for headerfile in os.listdir(libcxx_ndk_install_include): + if headerfile not in ['__config', '__config_site']: + if os.path.isdir(os.path.join(libcxx_ndk_install_include, headerfile)): + shutil.rmtree(os.path.join(libcxx_ndk_install_include, headerfile)) + else: + os.remove(os.path.join(libcxx_ndk_install_include, headerfile)) + + #Package libcxx-ndk + for host in hosts_list: + tarball_name = 'libcxx-ndk-%s-%s' % (self.build_config.build_name, host) + package_path = '%s%s' % (self.merge_out_path(tarball_name), '.tar.bz2') + self.logger().info('Packaging %s', package_path) + args = ['tar', '-chjC', self.build_config.OUT_PATH, '-f', package_path, 'libcxx-ndk'] + self.check_call(args) + self.check_rm_tree(libcxx_ndk_install) + + @staticmethod + def merge_tree(src_dir, dst_dir): + for item in os.listdir(src_dir): + src_path = os.path.join(src_dir, item) + dst_path = os.path.join(dst_dir, item) + if os.path.isfile(src_path): + shutil.copyfile(src_path, dst_path) + else: + shutil.copytree(src_path, dst_path) + + + def install_mingw_python(self, install_dir): + py_root = self.merge_out_path('../third_party', 'mingw-w64', 'mingw-w64-python', + self.build_config.LLDB_PY_VERSION) + bin_root = os.path.join(install_dir, 'bin') + py_dll = 'libpython' + self.build_config.LLDB_PY_VERSION + '.dll' + shutil.copyfile(os.path.join(py_root, py_dll), os.path.join(bin_root, py_dll)) + self.merge_tree(os.path.join(py_root, 'lib'), + os.path.join(bin_root, 'python', 'lib', 'python%s' % self.build_config.LLDB_PY_VERSION)) + + + + + + def windows_lib_files_operation(self, lib_files, lib_dir, install_dir): + + # Remove unnecessary Windows lib files. + windows_necessary_lib_files = ['libc++.a', 'libc++abi.a'] + + for lib_file in lib_files: + if lib_file.endswith('.a') and lib_file not in windows_necessary_lib_files: + static_library = os.path.join(lib_dir, lib_file) + os.remove(static_library) + + for necessary_lib_file in windows_necessary_lib_files: + if not os.path.isfile(os.path.join(lib_dir, necessary_lib_file)): + raise RuntimeError('Did not find %s under %s' % (necessary_lib_file, lib_dir)) + self.install_mingw_python(install_dir) + + + def darwin_stripped_xargs(self, bin_dir, necessary_bin_files, script_bins, need_x_bins_darwin): + for bin_filename in os.listdir(bin_dir): + binary = os.path.join(bin_dir, bin_filename) + if not os.path.isfile(binary): + continue + if bin_filename not in necessary_bin_files: + os.remove(binary) + elif bin_filename not in script_bins and self.build_config.strip: + if bin_filename not in need_x_bins_darwin and self.host_is_darwin(): + self.check_call(['strip', '-x', binary]) + else: + self.check_call(['strip', binary]) + + + def strip_lldb_server(self, host, install_dir): + clang_version_bin_dir = os.path.join(install_dir, 'lib', 'clang', self.build_config.CLANG_VERSION, 'bin') + + if not host.startswith('linux') or not os.path.exists(clang_version_bin_dir) or not self.build_config.strip: + return + llvm_strip = os.path.join(install_dir, 'bin', 'llvm-strip') + for llvm_triple_dir in os.listdir(clang_version_bin_dir): + llvm_triple_bin_dir = os.path.join(clang_version_bin_dir, llvm_triple_dir) + + if not os.path.isdir(llvm_triple_bin_dir): + continue + + for bin_filename in os.listdir(llvm_triple_bin_dir): + binary = os.path.join(llvm_triple_bin_dir, bin_filename) + if os.path.isfile(binary): + self.check_call([llvm_strip, binary]) + + + def notice_prebuilts_file(self, host, projects, install_dir): + + # Fetch all the LICENSE.* files under our projects and append them into a + # Single NOTICE file for the resulting prebuilts. + notices = [] + for project in projects: + license_pattern = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, project, 'LICENSE.*')) + for license_file in glob.glob(license_pattern): + with open(license_file) as notice_file: + notices.append(notice_file.read()) + + zlib_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'third_party/zlib/LICENSE')) + with open(zlib_license_file) as notice_file: + notices.append(notice_file.read()) + + if host.startswith('windows'): + mingw_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'third_party/mingw-w64/COPYING')) + with open(mingw_license_file) as notice_file: + notices.append(notice_file.read()) + + with open(os.path.join(install_dir, 'NOTICE'), 'w') as notice_file: + notice_file.write('\n'.join(notices)) + + + def package_clang_bin_file(self, necessary_bin_files, ext): + necessary_bin_file = [ + 'clang%s' % ext, + 'clang++%s' % ext, + 'clang-cpp%s' % ext, + 'clang-%s%s' % (self.build_config.VERSION.split('.')[0], ext), + 'clang-check%s' % ext, + 'clang-cl%s' % ext, + 'clang-format%s' % ext, + 'clang-tidy%s' % ext, + 'clangd%s' % ext, + 'count%s' % ext, + 'llc%s' % ext, + 'opt%s' % ext, + + ] + + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_lldb_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'dsymutil%s' % ext, + 'FileCheck%s' % ext, + 'git-clang-format', + 'ld.lld%s' % ext, + 'ld64.lld%s' % ext, + 'lld%s' % ext, + 'lld-link%s' % ext, + 'lldb%s' % ext, + 'lldb-argdumper%s' % ext, + 'lldb-server%s' % ext, + 'lldb-vscode%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_llvm_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'llvm-addr2line%s' % ext, + 'llvm-ar%s' % ext, + 'llvm-as%s' % ext, + 'llvm-cfi-verify%s' % ext, + 'llvm-config%s' % ext, + 'llvm-cov%s' % ext, + 'llvm-cxxfilt%s' % ext, + 'llvm-dis%s' % ext, + 'llvm-lib%s' % ext, + 'llvm-link%s' % ext, + 'llvm-modextract%s' % ext, + 'llvm-nm%s' % ext, + 'llvm-objcopy%s' % ext, + 'llvm-objdump%s' % ext, + 'llvm-profdata%s' % ext, + 'llvm-ranlib%s' % ext, + 'llvm-readelf%s' % ext, + 'llvm-readobj%s' % ext, + 'llvm-rc%s' % ext, + 'llvm-size%s' % ext, + 'llvm-strings%s' % ext, + 'llvm-strip%s' % ext, + 'llvm-symbolizer%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_scan_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'not%s' % ext, + 'sancov%s' % ext, + 'sanstats%s' % ext, + 'scan-build%s' % ext, + 'scan-view%s' % ext, + 'yaml2obj%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_license_project_tuple(): + # Install license files as NOTICE in the toolchain install dir. + projects = ( + 'llvm', + 'compiler-rt', + 'libcxx', + 'libcxxabi', + 'openmp', + 'clang', + 'clang-tools-extra', + 'lld', + 'lldb', + 'libunwind', + ) + return projects + + def remove_unnecessary_bin(self, necessary_bin_files, host, lib_dir, install_dir, ext, shlib_ext): + + lib_files = [] + if os.path.isdir(lib_dir): + lib_files = os.listdir(lib_dir) + if host.startswith('windows'): + vers_major = int(self.build_config.VERSION.split('.')[0]) + # Redefining necessary bin files for Windows. + windows_forbidden_list_bin_files = ['clang-%s%s' % (vers_major, ext), 'scan-build%s' % ext, + 'scan-view%s' % ext] + windows_additional_bin_files = ['liblldb%s' % shlib_ext, 'libpython3.10%s' % shlib_ext] + + new_necessary_bin_files = list(set(necessary_bin_files) - set(windows_forbidden_list_bin_files)) + new_necessary_bin_files.extend(windows_additional_bin_files) + del necessary_bin_files[:] + necessary_bin_files.extend(new_necessary_bin_files) + + self.windows_lib_files_operation(lib_files, lib_dir, install_dir) + else: + # Remove unnecessary static libraries. + for lib_file in lib_files: + if lib_file.endswith('.a'): + static_library = os.path.join(lib_dir, lib_file) + os.remove(static_library) + + def package_up_resulting(self, package_name, host, install_host_dir): + # Package up the resulting trimmed install/ directory. + tarball_name = '%s-%s' % (package_name, host) + package_path = '%s%s' % (self.merge_out_path(tarball_name), '.tar.bz2') + self.logger().info('Packaging %s', package_path) + args = ['tar', '-cjC', install_host_dir, '-f', package_path, package_name] + if host.startswith('windows'): + # windows do not support symlinks, + # replace them with file copies + args.insert(1, '--dereference') + + self.check_call(args) + + # Package ohos NDK + if os.path.exists(self.merge_out_path('sysroot')): + tarball_ndk_name = 'ohos-sysroot-%s' % self.build_config.build_name + package_ndk_path = '%s%s' % (self.merge_out_path(tarball_ndk_name), '.tar.bz2') + self.logger().info('Packaging %s', package_ndk_path) + args = ['tar', '-chjC', self.build_config.OUT_PATH, '-f', package_ndk_path, 'sysroot'] + self.check_call(args) + + # Packing Operation. + + def package_operation(self, build_dir, host): + + self.logger().info('Packaging for other environments.') + package_name = 'clang-%s' % self.build_config.build_name + self.set_clang_version(build_dir) + + if host.startswith('windows'): + ext = '.exe' + shlib_ext = '.dll' + elif host.startswith('linux'): + ext = '' + shlib_ext = '.so' + else: + ext = '' + shlib_ext = '.dylib' + + install_dir = self.merge_out_path('install', host, package_name) + bin_dir = os.path.join(install_dir, 'bin') + lib_dir = os.path.join(install_dir, 'lib') + install_host_dir = os.path.abspath(os.path.join(install_dir, '../')) + self.check_rm_tree(install_host_dir) + self.check_copy_tree(build_dir, install_dir) + # copy readme file to install_dir + shutil.copyfile(os.path.join(self.build_config.LLVM_BUILD_DIR, "toolchain_readme.md"), + os.path.join(install_dir, "README.md")) + + # Generate manifest in install_dir + manifest = os.path.join(install_dir, 'manifest.xml') + repo_tool = os.path.join(self.build_config.REPOROOT_DIR, '.repo', 'repo', 'repo') + if os.path.isfile(repo_tool): + self.logger().info('Generating manifest.') + subprocess.run([repo_tool, 'manifest', '-r', '-o', manifest], shell=False, + stdout=subprocess.PIPE, cwd=self.build_config.REPOROOT_DIR) + else: + self.logger().error('Cannot generate manifest, repo tool not found.') + + # Remove unnecessary binaries. + necessary_bin_files = [] + self.package_clang_bin_file(necessary_bin_files, ext) + self.package_lldb_bin_file(necessary_bin_files, ext) + self.package_llvm_bin_file(necessary_bin_files, ext) + self.package_scan_bin_file(necessary_bin_files, ext) + + if self.build_config.need_lldb_mi: + necessary_bin_files.append('lldb-mi%s' % ext) + self.remove_unnecessary_bin(necessary_bin_files, host, lib_dir, install_dir, ext, shlib_ext) + + # Scripts that should not be stripped + script_bins = ['git-clang-format', 'scan-build', 'scan-view'] + need_x_bins_darwin = ['clang', 'clang++', 'clang-9', 'clang-cl', 'clang-cpp'] + + # Bin file in the list should be stripped with -x args when host=darwin + self.darwin_stripped_xargs(bin_dir, necessary_bin_files, script_bins, need_x_bins_darwin) + + # Strip lldb-server + self.strip_lldb_server(host, install_dir) + + for necessary_bin_file in necessary_bin_files: + if not os.path.isfile(os.path.join(bin_dir, necessary_bin_file)): + print('Did not find %s in %s' % (necessary_bin_file, bin_dir)) + raise RuntimeError('Did not find %s in %s' % (necessary_bin_file, bin_dir)) + + cmake_dir = os.path.join(lib_dir, 'cmake') + self.check_rm_tree(cmake_dir) + + self.notice_prebuilts_file(host, self.package_license_project_tuple(), install_dir) + + create_tar = True + if create_tar: + self.package_up_resulting(package_name, host, install_host_dir) + + return + + + +def main(): + build_config = BuildConfig() + build_utils = BuildUtils(build_config) + sysroot_composer = SysrootComposer(build_config) + llvm_core = LlvmCore(build_config) + llvm_package = LlvmPackage(build_config) + lldb_mi = LldbMi(build_config, llvm_package) + llvm_libs = LlvmLibs(build_config, sysroot_composer, llvm_package) + + args = build_config.parse_args() + need_host = build_utils.host_is_darwin() or ('linux' not in args.no_build) + need_windows = build_utils.host_is_linux() and \ + ('windows' not in args.no_build) + + llvm_install = build_utils.merge_out_path('llvm-install') + windows64_install = build_utils.merge_out_path('windows-x86_64-install') + + configs = [] + if not build_config.no_build_arm: + configs.append(('arm', build_utils.liteos_triple('arm'))) + configs.append(('arm', build_utils.open_ohos_triple('arm'))) + + if not build_config.no_build_aarch64: + configs.append(('arm64', build_utils.open_ohos_triple('aarch64'))) + + if not build_config.no_build_riscv64: + configs.append(('riscv', build_utils.open_ohos_triple('riscv64'))) + + if not build_config.no_build_mipsel: + configs.append(('mipsel', build_utils.open_ohos_triple('mipsel'))) + + if not build_config.no_build_x86_64: + configs.append(('x86_64', build_utils.open_ohos_triple('x86_64'))) + + + if build_config.do_build and need_host: + llvm_core.llvm_compile( + build_config.build_name, + llvm_install, + build_config.debug, + build_config.no_lto, + build_config.build_instrumented, + build_config.xunit_xml_output) + + llvm_core.set_clang_version(llvm_install) + + if build_config.do_build and build_utils.host_is_linux(): + sysroot_composer.setup_cmake_platform(llvm_install) + llvm_libs.build_crt_libs(configs, llvm_install, build_config.need_lldb_server) + + if build_config.need_libs: + for (arch, target) in configs: + llvm_libs.build_libs(build_config.need_lldb_server, llvm_install, target) + + if build_config.do_build and need_windows: + mingw.main(build_config.VERSION) + llvm_libs.build_runtimes_for_windows(build_config.enable_assertions) + llvm_core.llvm_compile_for_windows(build_config.TARGETS, + build_config.enable_assertions, + build_config.build_name) + + if build_config.need_lldb_mi: + lldb_mi.build_lldb_mi_for_windows() + + if build_config.do_build and build_config.need_lldb_mi and need_host: + lldb_mi.build_lldb_mi(llvm_install) + + if build_config.do_package: + if build_utils.host_is_linux(): + llvm_package.package_libcxx() + llvm_package.package_operation(llvm_install, build_utils.use_platform()) + if build_config.do_package and need_windows: + llvm_package.package_operation(windows64_install, 'windows-x86_64') + +if __name__ == '__main__': + main() diff --git a/llvm-build/build_cpython-mingw.sh b/llvm-build/build_cpython-mingw.sh new file mode 100755 index 0000000000..7419458cc7 --- /dev/null +++ b/llvm-build/build_cpython-mingw.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +PROJECT_ROOT=$(pwd) +CPYTHON_MINGW_SRC=${PROJECT_ROOT}/third_party/python +MINGW_W64_SRC=${PROJECT_ROOT}/third_party/mingw-w64 + +# prepare SYSROOT for cpython-mingw build +CLANG_MINGW_BUILD=${PROJECT_ROOT}/out/clang_mingw +python3 ${PROJECT_ROOT}/toolchain/llvm-build/mingw.py + +# refreash cpython-mingw config +cd ${CPYTHON_MINGW_SRC} +cat ./patchs/cpython_mingw_v3.10.2.patch | patch -d ./ -p1 -E +rm -rf ${CPYTHON_MINGW_SRC}/configure +autoconf ${CPYTHON_MINGW_SRC}/configure.ac > ${CPYTHON_MINGW_SRC}/configure +chmod 777 ${CPYTHON_MINGW_SRC}/configure +./configure + +# # prepare build config and build libpython for cpython-mingw +CPYTHON_MINGW_BUILD=${PROJECT_ROOT}/out/cpython-mingw-build +mkdir -p ${CPYTHON_MINGW_BUILD} +cd ${CPYTHON_MINGW_BUILD} +MINGW_PREFIX=${CPYTHON_MINGW_BUILD}/mingw64 +MINGW_CHOST=x86_64-w64-mingw32 +MINGW_BUILD=x86_64-unknown-linux-gnu +CLANG_VERSION=clang-10.0.1 +TOOLCHAIN_ROOT=${CLANG_MINGW_BUILD}/${CLANG_VERSION}/bin +SYSROOT=${CLANG_MINGW_BUILD}/${CLANG_VERSION}/x86_64-w64-mingw32 +mkdir $MINGW_BUILD + +export CC=$TOOLCHAIN_ROOT/clang +export CXX=$TOOLCHAIN_ROOT/clang++ +export CFLAGS="-target ${MINGW_CHOST} --sysroot=$SYSROOT" +export LDFLAGS="--sysroot=$SYSROOT -rtlib=compiler-rt -target ${MINGW_CHOST} -lucrt -lucrtbase -fuse-ld=lld" + +${CPYTHON_MINGW_SRC}/configure \ + --prefix=${MINGW_PREFIX} \ + --host=${MINGW_CHOST} \ + --build=${MINGW_BUILD} \ + --enable-shared \ + --enable-static \ + --without-ensurepip \ + --without-c-locale-coercion \ + --enable-loadable-sqlite-extensions + +make -j4 + +# copy build result to mingw-w64 +cp ${CPYTHON_MINGW_BUILD}/libpython3.10.dll.a ${MINGW_W64_SRC}/mingw-w64-crt/lib64 +cp ${CPYTHON_MINGW_BUILD}/libpython3.10.dll ${MINGW_W64_SRC}/mingw-w64-python/3.10 +cd ../.. + +# example steps to install autoconf 2.71 +# wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.gz +# export PATH=/mnt/disk2/liwentao/workspace/tools/autoconf/autoconf-2.71/bin:$PATH +# sudo cp -r /mnt/disk2/liwentao/workspace/tools/autoconf/autoconf-2.71/lib /usr/local/share/autoconf + +# refreash configure and Makefile for mingw-w64 +# you need autoconf (2.69 for Ubuntu 20.04 LTS apt install, to support mingw-w64 9.x and later version, please install autoconf 2.71 http://ftp.gnu.org/gnu/autoconf/) +# and automake (1.16.1 for Ubuntu 20.04 LTS apt install) +cd ${MINGW_W64_SRC}/mingw-w64-crt +rm -rf configure +autoconf configure.ac > configure +chmod 777 configure + +aclocal +automake + +cd ${MINGW_W64_SRC}/mingw-w64-headers +rm -rf configure +autoconf configure.ac > configure +chmod 777 configure + +aclocal +automake + +# move cpython-mingw build result and python header file to mingw-w64 +cp -r ${CPYTHON_MINGW_SRC}/Include ${MINGW_W64_SRC}/mingw-w64-headers/include/python3.10 +cp ${CPYTHON_MINGW_SRC}/pyconfig.h ${MINGW_W64_SRC}/mingw-w64-headers/include/python3.10 +mkdir -p ${MINGW_W64_SRC}/mingw-w64-python/3.10 +cp -r ${CPYTHON_MINGW_SRC}/Lib ${MINGW_W64_SRC}/mingw-w64-python/3.10/lib \ No newline at end of file diff --git a/llvm-build/build_musl.sh b/llvm-build/build_musl.sh new file mode 100755 index 0000000000..123da9a1ee --- /dev/null +++ b/llvm-build/build_musl.sh @@ -0,0 +1,121 @@ +#!/bin/bash +# Copyright (C) 2021 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 + +# This script is used to create musl's libc.so. + +#default variables +CLANG_BIN_ROOT="${PWD}/../../out/install/linux-x86_64/clang-dev/bin/" +TARGET_TRIPLE="" +TOPDIR="${PWD}/../.." +OUT="${PWD}/../../out" +make_libs=0 + +#argument parser +while getopts "c:t:T:o:lh" arg +do + case "${arg}" in + "c") + CLANG_BIN_ROOT=${OPTARG} + ;; + "t") + TARGET_TRIPLE=${OPTARG} + ;; + "T") + TOPDIR=${OPTARG} + ;; + "o") + OUT=${OPTARG} + ;; + "l") + make_libs=1 + ;; + "h") + echo "Usage: ./build_musl.sh [OPTION]" + echo " Build C/C++ dynamic libs and runtime object" + echo " Options are:" + echo " -c Specify clang bin path" + echo " -t Specify target tripple" + echo " -T Specify top of repo tree" + echo " -o Specify the build output directory" + echo " -l Install libs" + exit 0 + ;; + ?) + echo "unkown argument" + exit 1 + ;; + esac +done + +if [ -z "${TARGET_TRIPLE}" ] +then + echo "[ERROR] Empty target triple in build_musl.sh" + exit 1 +fi + +# Canonicalize paths +CLANG_BIN_ROOT=$(readlink -f ${CLANG_BIN_ROOT}) + +CFLAGS_FOR_TARGET=("-mfloat-abi=soft" "-mfloat-abi=soft -mcpu=cortex-a7" +"-mfloat-abi=softfp -mfpu=neon-vfpv4 -mcpu=cortex-a7" "-mfloat-abi=hard -mfpu=neon-vfpv4 -mcpu=cortex-a7") + +if [ $TARGET_TRIPLE == "arm-liteos-ohos" ]; then + TARGET_USER="liteos_a_user" + TARGETS_PREFIX="arm" +elif [ $TARGET_TRIPLE == "arm-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="arm" +elif [ $TARGET_TRIPLE == "mipsel-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="mips" + CFLAGS_FOR_TARGET=(" " "-mnan=legacy") +elif [ $TARGET_TRIPLE == "riscv64-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="riscv64" +elif [ $TARGET_TRIPLE == "x86_64-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="x86_64" +else + TARGET_USER="linux_user" + TARGETS_PREFIX="aarch64" +fi + +echo "CLANG_BIN_ROOT=${CLANG_BIN_ROOT}" +echo "ARCH=${TARGETS_PREFIX}" +echo "TARGET=${TARGET_TRIPLE}" +echo "TOPDIR=${TOPDIR}" +echo "TARGETS=${TARGET_USER}" +echo "OUT=${OUT}" +echo "SYSROOTDIR=${OUT}/sysroot" + +# build musl_headers +make musl_header_install_for_${TARGET_USER} CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${TOPDIR} \ + SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER} TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} -f Makefile + +# build musl_libs +if ((make_libs == 1)); then + if [ $TARGET_TRIPLE == "aarch64-linux-ohos" ] || [ $TARGET_TRIPLE == "riscv64-linux-ohos" ] || \ + [ $TARGET_TRIPLE == "x86_64-linux-ohos" ]; then + make CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${TOPDIR} SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER}\ + TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} -f Makefile + else + for ARCH_CFLAG in "${CFLAGS_FOR_TARGET[@]}" + do + make CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${TOPDIR} SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER}\ + TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} ARCH_CFLAGS="${ARCH_CFLAG}" -f Makefile + done + fi +fi +make distclean -f Makefile diff --git a/llvm-build/data/llvm_build.png b/llvm-build/data/llvm_build.png new file mode 100644 index 0000000000000000000000000000000000000000..a7f0bdb0c100cf88771a169dc06772109799650d GIT binary patch literal 34465 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
    a@q@LIokbhw)h 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 literal 0 HcmV?d00001 diff --git a/llvm-build/data/one_time_setup.png b/llvm-build/data/one_time_setup.png new file mode 100644 index 0000000000000000000000000000000000000000..5d7573173460eedb09eef86edbf8562c687c40f4 GIT binary patch literal 21555 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 + + +## Specifically Included Triplets + +Despite all the components provided by LLVM community, we included several triplets for different types of ohos devices to our LLVM toochain, listed as below. For specification, liteos is a newly included OS name which indicate the simplified linux kernel. + +| Triplet Name | Architecture | System Kernel | System | +| ---------------------- | ------------ | ------------- | --------------- | +| arm-liteos-ohos | ARM 32bits | LiteOS | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Standard system | +| aarch64-linux-ohos | ARM 64bits | Linux | Standard system | + +For detailed definition of Small System and Standard System, please refer to [System Types](https://gitee.com/openharmony/docs/blob/master/en/device-dev/Readme-EN.md). + +### Specify the triplet + +To build images for different types of platform, you can configure the triplet in the build scripts by setting "--target=xxx" using cflags, xxx should be replaced with a specific triplet name. -- Gitee