diff --git a/llvm-build/README.md b/llvm-build/README.md index 407b4b4c1871c8a6e602fbe357d1ea7e77433bef..469398843e41144ce9c47f2cbb8e4b41fdaf2e5c 100644 --- a/llvm-build/README.md +++ b/llvm-build/README.md @@ -75,7 +75,7 @@ build.py options: --build-instrumented # enable instrument pgo when build toolchain --xunit-xml-output # specify LLVM unit test XML report path --build-lldb-static # build statically lldb tool for ARM and AARCH64 ---build-python # build python (not using prebuilt one, currently effective for Windows) +--build-python # build python (not using prebuilt one, currently effective for Windows and OHOS) --build-ncurses # build ncurses tool for linux, Mac x86-64 or M1 --build-libedit # build libedit tool for linux, Mac x86-64 or M1 --build-libxml2 # build libxml2 tool for linux, windows, Mac x86_64 or M1 @@ -145,6 +145,10 @@ build-ohos-aarch64.py options: --enable-assertions # enable assertion when compiling --debug # build debug version llvm toolchain --strip # strip llvm toolchain binaries +--build-python # build python and enable script in debugger +--build-ncurses # build ncurses and enable ncurses in debugger +--build-libedit # build libedit and enable libedit in debugger +--build-libxml2 # build libxml2 and enable libxml in debugger ```
@@ -154,6 +158,33 @@ When build successfully completed, artifacts will be available in `out/ohos-aarc ## Function Introduction
+### Build process of Arm debugger + +First build toolchain on Linux. +Here is an example of starting build process on Linux: +``` +# build +python3 ./toolchain/llvm-project/llvm-build/build-ohos-arm.py +``` + +
+ +build-ohos-arm.py options: + +``` +--build-python # build python and enable script in debugger +--build-ncurses # build ncurses and enable ncurses in debugger +--build-libedit # build libedit and enable libedit in debugger +--build-libxml2 # build libxml2 and enable libxml in debugger +``` +
+ +When build successfully completed, artifacts will be available in `out/ohos-arm-install` directory, including lldb for arm. + + +## 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). diff --git a/llvm-build/build-ohos-aarch64.py b/llvm-build/build-ohos-aarch64.py index dd8fec1d54cc063e54a377764b86980e0badcb1d..bd4828ec51840b3b879dc3b5be506623b43b2876 100755 --- a/llvm-build/build-ohos-aarch64.py +++ b/llvm-build/build-ohos-aarch64.py @@ -14,163 +14,84 @@ # limitations under the License. import os +from ohos_toolchain_builder import OHOSToolchainBuilder + + +class Aarch64ToolchainBuilder(OHOSToolchainBuilder): + def __init__(self) -> None: + super().__init__("aarch64-linux-ohos") + + def _update_build_args(self): + self._cflags.extend( + [ + "-v", + "-funwind-tables", + "-no-canonical-prefixes", + "-D__MUSL__", + ] + ) + + cflags_debug = "-O0 -g -fno-limit-debug-info" + cflags_release = "-O2 -DNDEBUG" + + self._ldflags.extend(["-static-libstdc++"]) + + llvm_extra_env = {} + llvm_extra_env["LD_LIBRARY_PATH"] = os.path.join(self._llvm_root, "lib") + env = dict(self._build_config.ORIG_ENV) + if llvm_extra_env is not None: + env.update(llvm_extra_env) + + # We do not build runtimes, since they will be copied from main toolchain build + self._llvm_defines.update( + { + "CMAKE_C_FLAGS_DEBUG": cflags_debug, + "CMAKE_CXX_FLAGS_DEBUG": cflags_debug, + "CMAKE_ASM_FLAGS_DEBUG": cflags_debug, + "CMAKE_C_FLAGS_RELEASE": cflags_release, + "CMAKE_CXX_FLAGS_RELEASE": cflags_release, + "CMAKE_ASM_FLAGS_RELEASE": cflags_release, + "OPENMP_STANDALONE_BUILD": "ON", + "LLVM_DIR": os.path.join(self._llvm_root, "lib", "cmake", "llvm"), + "LLVM_ENABLE_FFI": "OFF", + "LLVM_BUILD_LLVM_DYLIB": "ON", + "CMAKE_LIBRARY_ARCHITECTURE": self._llvm_triple, + "LLVM_INCLUDE_BENCHMARKS": "OFF", + "LLVM_INCLUDE_EXAMPLES": "OFF", + "LLVM_INCLUDE_TESTS": "OFF", + "LLVM_BUILD_TOOLS": "ON", + "LLVM_INSTALL_UTILS": "ON", + "LLVM_ENABLE_ZLIB": "OFF", + "LLVM_ENABLE_PROJECTS": ";".join(self._build_config.host_projects), + "CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN": self._llvm_root, + "CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN": self._llvm_root, + "CMAKE_ASM_COMPILER_EXTERNAL_TOOLCHAIN": self._llvm_root, + "CMAKE_NM": os.path.join(self._llvm_root, "bin", "llvm-nm"), + "CMAKE_RANLIB": os.path.join(self._llvm_root, "bin", "llvm-ranlib"), + "CMAKE_OBJCOPY": os.path.join(self._llvm_root, "bin", "llvm-objcopy"), + "CMAKE_OBJDUMP": os.path.join(self._llvm_root, "bin", "llvm-objdump"), + "CMAKE_READELF": os.path.join(self._llvm_root, "bin", "llvm-readelf"), + "CMAKE_STRIP": os.path.join(self._llvm_root, "bin", "llvm-strip"), + "CMAKE_LINKER": os.path.join(self._llvm_root, "bin", "ld.lld"), + "CMAKE_POSITION_INDEPENDENT_CODE": "True", + "CMAKE_CXX_FLAGS": " ".join(self._cflags) + " -stdlib=libc++", + "CMAKE_ASM_FLAGS": " ".join(self._cflags), + "CMAKE_C_FLAGS": " ".join(self._cflags), + "CMAKE_SHARED_LINKER_FLAGS": " ".join(self._ldflags), + "CMAKE_MODULE_LINKER_FLAGS": " ".join(self._ldflags), + "CMAKE_EXE_LINKER_FLAGS": " ".join(self._ldflags) + + " -Wl,--gc-sections", + } + ) + + if self._build_config.enable_assertions: + self._llvm_defines["LLVM_ENABLE_ASSERTIONS"] = "ON" -from build import BuildConfig, BuildUtils def main(): - print('Start cross-compiling LLVM toolchain for OHOS AArch64 host on linux') - build_config = BuildConfig() - build_utils = BuildUtils(build_config) + print("Start cross-compiling LLVM toolchain for OHOS AArch64 host on linux") + Aarch64ToolchainBuilder().build() - llvm_project_path = os.path.abspath(os.path.join(build_config.LLVM_PROJECT_DIR, 'llvm')) - llvm_path = build_utils.merge_out_path('ohos-aarch64') - llvm_install = build_utils.merge_out_path('ohos-aarch64-install') - llvm_root = build_utils.merge_out_path('llvm-install') - sysroot = build_utils.merge_out_path('sysroot') - llvm_triple = 'aarch64-linux-ohos' - - cflags = [ '-v', - '-fstack-protector-strong', - '-fdata-sections', - '-ffunction-sections', - '-funwind-tables', - '-no-canonical-prefixes', - '-D__MUSL__', - '-target %s' % llvm_triple, - ] - - cflags_debug = '-O0 -g -fno-limit-debug-info' - cflags_release = '-O2 -DNDEBUG' - - ldflags = [ '-fuse-ld=lld', - '--rtlib=compiler-rt', - '-lunwind', - '-stdlib=libc++', - '-static-libstdc++', - '-pie', - '-Wl,--build-id=sha1', - '-Wl,-z,relro,-z,now', - ] - - if build_config.strip: - ldflags.append('-s') - - llvm_extra_env = {} - llvm_extra_env['LD_LIBRARY_PATH'] = os.path.join(llvm_root, 'lib') - env = dict(build_config.ORIG_ENV) - if llvm_extra_env is not None: - env.update(llvm_extra_env) - - llvm_defines = {} - llvm_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' - llvm_defines['CMAKE_CROSSCOMPILING'] = 'True' - llvm_defines['CMAKE_INSTALL_PREFIX'] = llvm_install - llvm_defines['CMAKE_SYSROOT'] = sysroot - llvm_defines['CMAKE_LIBRARY_ARCHITECTURE'] = llvm_triple - llvm_defines['LLVM_HOST_TRIPLE'] = llvm_triple - llvm_defines['LLVM_TARGETS_TO_BUILD'] = build_config.TARGETS - llvm_defines['LLVM_TARGET_ARCH'] = 'AArch64' - llvm_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple - llvm_defines['LLVM_BUILD_LLVM_DYLIB'] = 'ON' - llvm_defines['LLVM_ENABLE_FFI'] = 'OFF' - llvm_defines['LLVM_ENABLE_TERMINFO'] = 'OFF' - llvm_defines['LLVM_INCLUDE_BENCHMARKS'] = 'OFF' - llvm_defines['LLVM_INCLUDE_EXAMPLES'] = 'OFF' - llvm_defines['LLVM_INCLUDE_TESTS'] = 'OFF' - llvm_defines['LLVM_BUILD_TOOLS'] = 'ON' - llvm_defines['LLVM_INSTALL_UTILS'] = 'ON' - llvm_defines['LLVM_ENABLE_ZLIB'] = 'OFF' - llvm_defines['LLVM_ENABLE_PROJECTS'] = ';'.join(build_config.host_projects) - # We do not build runtimes, since they will be copied from main toolchain build - llvm_defines['LLVM_CONFIG_PATH'] = os.path.join(llvm_root, 'bin', 'llvm-config') - llvm_defines['LLVM_TABLEGEN'] = os.path.join(llvm_root, 'bin', 'llvm-tblgen') - llvm_defines['CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN'] = llvm_root - llvm_defines['CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN'] = llvm_root - llvm_defines['CMAKE_ASM_COMPILER_EXTERNAL_TOOLCHAIN'] = llvm_root - 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_NM'] = os.path.join(llvm_root, 'bin', 'llvm-nm') - llvm_defines['CMAKE_RANLIB'] = os.path.join(llvm_root, 'bin', 'llvm-ranlib') - llvm_defines['CMAKE_OBJCOPY'] = os.path.join(llvm_root, 'bin', 'llvm-objcopy') - llvm_defines['CMAKE_OBJDUMP'] = os.path.join(llvm_root, 'bin', 'llvm-objdump') - llvm_defines['CMAKE_READELF'] = os.path.join(llvm_root, 'bin', 'llvm-readelf') - llvm_defines['CMAKE_STRIP'] = os.path.join(llvm_root, 'bin', 'llvm-strip') - llvm_defines['CMAKE_LINKER'] = os.path.join(llvm_root, 'bin', 'ld.lld') - llvm_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) - llvm_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) - llvm_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + ' -stdlib=libc++' - llvm_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + ' -Wl,--gc-sections' - llvm_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) - llvm_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) - llvm_defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' - llvm_defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' - llvm_defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' - llvm_defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' - llvm_defines['CMAKE_POSITION_INDEPENDENT_CODE'] = 'True' - llvm_defines['Python3_EXECUTABLE'] = os.path.join(build_utils.get_python_dir(), 'bin', build_config.LLDB_PYTHON) - llvm_defines['CMAKE_C_FLAGS_DEBUG'] = cflags_debug - llvm_defines['CMAKE_CXX_FLAGS_DEBUG'] = cflags_debug - llvm_defines['CMAKE_ASM_FLAGS_DEBUG'] = cflags_debug - llvm_defines['CMAKE_C_FLAGS_RELEASE'] = cflags_release - llvm_defines['CMAKE_CXX_FLAGS_RELEASE'] = cflags_release - llvm_defines['CMAKE_ASM_FLAGS_RELEASE'] = cflags_release - llvm_defines['OPENMP_STANDALONE_BUILD'] = 'ON' - llvm_defines['LLVM_DIR'] = os.path.join(llvm_root, 'lib', 'cmake', 'llvm') - - lldb_defines = set_lldb_defines() - llvm_defines.update(lldb_defines) - - if build_config.enable_assertions: - llvm_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' - - if build_config.debug: - llvm_defines['CMAKE_BUILD_TYPE'] = 'Debug' - else: - llvm_defines['CMAKE_BUILD_TYPE'] = 'Release' - - build_utils.invoke_cmake(llvm_project_path, llvm_path, llvm_defines, env=env) - - build_utils.invoke_ninja(out_path=llvm_path, env=env, target=None, install=True) - - # Copy required aarch64-linux-ohos libs from main toolchain build. - arch_list = [build_utils.liteos_triple('arm'), build_utils.open_ohos_triple('arm'), - build_utils.open_ohos_triple('aarch64'), build_utils.open_ohos_triple('riscv64'), - build_utils.open_ohos_triple('mipsel'), build_utils.open_ohos_triple('x86_64')] - for arch in arch_list: - build_utils.check_copy_tree(os.path.join(llvm_root, 'lib', arch), - os.path.join(llvm_install, 'lib', arch)) - build_utils.check_copy_tree(os.path.join(llvm_root, 'lib', 'clang', '15.0.4', 'lib', arch), - os.path.join(llvm_install, 'lib', 'clang', '15.0.4', 'lib', arch)) - - #Copy required c++ headerfiles from main toolchain build. - build_utils.check_copy_tree(os.path.join(llvm_root, 'include', 'c++'), os.path.join(llvm_install, 'include', 'c++')) - build_utils.check_copy_tree(os.path.join(llvm_root, 'include', 'libcxx-ohos'), os.path.join(llvm_install, 'include', 'libcxx-ohos')) - - # Package ohos-aarch64 toolchain. - if build_config.do_package: - tarball_name = 'clang-%s-ohos-aarch64' % (build_config.build_name) - package_path = '%s%s' % (build_utils.merge_packages_path(tarball_name), build_config.ARCHIVE_EXTENSION) - build_utils.logger().info('Packaging %s', package_path) - args = ['tar', build_config.ARCHIVE_OPTION, '-h', '-C', build_config.OUT_PATH, '-f', package_path, 'ohos-aarch64-install'] - build_utils.check_create_dir(build_config.PACKAGES_PATH) - build_utils.check_call(args) - -def set_lldb_defines(): - lldb_defines = {} - lldb_defines['LLDB_INCLUDE_TESTS'] = 'OFF' - lldb_defines['LLDB_ENABLE_TIMEOUT'] = 'False' - # Optional Dependencies - lldb_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' - lldb_defines['LLDB_ENABLE_CURSE'] = 'OFF' - lldb_defines['LLDB_ENABLE_LIBXML2'] = 'OFF' - lldb_defines['LLDB_ENABLE_LZMA'] = 'OFF' - lldb_defines['LLDB_ENABLE_PYTHON'] = 'OFF' - # Debug & Tuning - lldb_defines['LLDB_ENABLE_PERFORMANCE'] = 'OFF' - - return lldb_defines - -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/llvm-build/build-ohos-arm.py b/llvm-build/build-ohos-arm.py new file mode 100755 index 0000000000000000000000000000000000000000..27931c07287d2951fe1f21049e727ba743546e53 --- /dev/null +++ b/llvm-build/build-ohos-arm.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +# Copyright (C) 2024 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 +from ohos_toolchain_builder import OHOSToolchainBuilder + + +class ArmToolchainBuilder(OHOSToolchainBuilder): + def __init__(self) -> None: + super().__init__("arm-linux-ohos") + self._llvm_prebuilt_path = self._build_utils.merge_out_path("llvm_make") + + def _update_build_args(self): + self._cflags.extend( + [ + "-march=armv7-a -mfloat-abi=soft", + ] + ) + + self._ldflags.extend( + [ + "-Wl,-rpath,'$ORIGIN/../lib'", + ] + ) + + self._llvm_defines.update( + { + "CMAKE_CXX_FLAGS": " ".join(self._cflags), + "CMAKE_ASM_FLAGS": " ".join(self._cflags), + "CMAKE_C_FLAGS": " ".join(self._cflags), + "CMAKE_SHARED_LINKER_FLAGS": " ".join(self._ldflags), + "CMAKE_MODULE_LINKER_FLAGS": " ".join(self._ldflags), + "CMAKE_EXE_LINKER_FLAGS": " ".join(self._ldflags), + "LLVM_ENABLE_ASSERTIONS": "OFF", + "LLVM_USE_NEWPM": "ON", + "LLVM_ENABLE_BINDINGS": "OFF", + "CLANG_REPOSITORY_STRING": "llvm-project", + "COMPILER_RT_BUILD_XRAY": "OFF", + "CMAKE_POSITION_INDEPENDENT_CODE": "ON", + "LLVM_ENABLE_PER_TARGET_RUNTIME_DIR": "ON", + "COMPILER_RT_USE_BUILTINS_LIBRARY": "ON", + "LLVM_ENABLE_LIBCXX": "ON", + "LLVM_ENABLE_PROJECTS": "clang;lldb", + "CLANG_TABLEGEN": os.path.join( + self._llvm_root, + "..", + self._llvm_prebuilt_path, + "bin", + "clang-tblgen", + ), + "LLDB_TABLEGEN": os.path.join( + self._llvm_root, + "..", + self._llvm_prebuilt_path, + "bin", + "lldb-tblgen", + ), + } + ) + + +def main(): + print("Start building LLDB tools for OHOS ARM host") + ArmToolchainBuilder().build(build_target=["lldb", "lldb-server"]) + + +if __name__ == "__main__": + main() diff --git a/llvm-build/build.py b/llvm-build/build.py index ee12969b8e24e5aed27446f043eecf5cbe131618..f6e465e41f14b4f8e0f9d44a4eebd2d370feede7 100755 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -216,7 +216,7 @@ class BuildConfig(): '--build-python', action='store_true', default=False, - help='Build Python (not using prebuilt one, currently effective for Windows)') + help='Build Python (not using prebuilt one, currently effective for Windows and OHOS)') parser.add_argument( '--build-ncurses', @@ -588,6 +588,18 @@ class BuildUtils(object): return None + def merge_ncurses_install_dir(self, platform_triple, *args): + return self.merge_out_path('third_party', 'ncurses', 'install', platform_triple, *args) + + def get_ncurses_dependence_libs(self, platform_triple): + ncurses_libs = ['libncurses', 'libpanel', 'libform'] + if self.use_platform() != platform_triple: + ncurses_libs.append('libtinfo') + return ncurses_libs + + def merge_ncurses_build_dir(self, platform_triple, *args): + return self.merge_out_path('third_party', 'ncurses', 'build', platform_triple, *args) + def get_libxml2_version(self): version_file = os.path.join(self.build_config.REPOROOT_DIR, 'third_party', 'libxml2', 'libxml2.spec') if os.path.isfile(version_file): @@ -604,14 +616,26 @@ class BuildUtils(object): return None - def get_libxml2_source_path(self): - return self.merge_out_path('third_party', 'libxml2', ('libxml2-' + self.build_config.LIBXML2_VERSION)) + def merge_libxml2_install_dir(self, platform_triple, *args): + return self.merge_out_path('third_party', 'libxml2', 'install', platform_triple, *args) - def get_libxml2_install_path(self, triple): - return self.merge_out_path('third_party', 'libxml2', 'install', triple) + def merge_libxml2_build_dir(self, platform_triple, *args): + return self.merge_out_path('third_party', 'libxml2', 'build', platform_triple, *args) - def get_libxml2_build_path(self, triple): - return self.merge_out_path('third_party', 'libxml2', 'build', triple) + def merge_libedit_install_dir(self, platform_triple, *args): + return self.merge_out_path('third_party', 'libedit', 'install', platform_triple, *args) + + def merge_libedit_build_dir(self, platform_triple, *args): + return self.merge_out_path('third_party', 'libedit', 'build', platform_triple, *args) + + def merge_python_install_dir(self, platform_triple, *args): + return self.merge_out_path('third_party', 'python', 'install', platform_triple, *args) + + def merge_python_build_dir(self, platform_triple, *args): + return self.merge_out_path('third_party', 'python', 'build', platform_triple, *args) + + def get_libxml2_source_path(self): + return self.merge_out_path('third_party', 'libxml2', ('libxml2-' + self.build_config.LIBXML2_VERSION)) class LlvmCore(BuildUtils): @@ -674,10 +698,11 @@ class LlvmCore(BuildUtils): llvm_defines['LLVM_ENABLE_ZSTD'] = 'OFF' llvm_defines['LLDB_PYTHON_EXT_SUFFIX'] = '.dylib' if self.build_config.build_ncurses: - libncurse = os.path.join(self.get_prebuilts_dir('ncurses'), 'lib', 'libncurses.6.dylib') - libpanel = os.path.join(self.get_prebuilts_dir('ncurses'), 'lib', 'libpanel.6.dylib') - libform = os.path.join(self.get_prebuilts_dir('ncurses'), 'lib', 'libform.6.dylib') - ncurses_libs = ';'.join([libncurse, libpanel, libform]) + ncurses_libs = ';'.join([ + self.merge_ncurses_install_dir( + self.use_platform(), + 'lib', + f'{lib_name}.6.dylib') for lib_name in self.get_ncurses_dependence_libs(self.use_platform())]) llvm_defines['CURSES_LIBRARIES'] = ncurses_libs llvm_defines['PANEL_LIBRARIES'] = ncurses_libs @@ -685,11 +710,12 @@ class LlvmCore(BuildUtils): llvm_defines['LIBLZMA_LIBRARIES'] = self.merge_out_path('lzma', 'lib', self.use_platform(), f'liblzma.{self.build_config.LZMA_VERSION}.dylib') if self.build_config.build_libedit: - llvm_defines['LibEdit_LIBRARIES'] = os.path.join(self.get_prebuilts_dir('libedit'), 'lib', 'libedit.0.dylib') + llvm_defines['LibEdit_LIBRARIES'] = \ + self.merge_libedit_install_dir(self.use_platform(), 'lib', 'libedit.0.dylib') if self.build_config.build_libxml2: - llvm_defines['LIBXML2_LIBRARIES'] = os.path.join(self.get_libxml2_install_path(self.use_platform()), 'lib', f'libxml2.{self.build_config.LIBXML2_VERSION}.dylib') - + llvm_defines['LIBXML2_LIBRARIES'] = \ + self.merge_libxml2_install_dir(self.use_platform(), 'lib', f'libxml2.{self.build_config.LIBXML2_VERSION}.dylib') def llvm_compile_linux_defines(self, llvm_defines, @@ -715,12 +741,18 @@ class LlvmCore(BuildUtils): llvm_defines['LLDB_PYTHON_EXT_SUFFIX'] = '.so' ncurses_version = self.get_ncurses_version() if self.build_config.build_ncurses and ncurses_version is not None: - ncurses_libs = [] - prebuilts_dir = self.get_prebuilts_dir('ncurses') - for library in ['libncurses', 'libpanel', 'libform']: - library_path = os.path.join(prebuilts_dir, 'lib', f'{library}.so.%s' % ncurses_version) - ncurses_libs.append(library_path) - ncurses_libs = ';'.join(ncurses_libs) + ncurses_libs = ";".join( + [ + self.merge_ncurses_install_dir( + self.use_platform(), + "lib", + f"{lib_name}.so.{ncurses_version}", + ) + for lib_name in self.get_ncurses_dependence_libs( + self.use_platform() + ) + ] + ) llvm_defines['CURSES_LIBRARIES'] = ncurses_libs llvm_defines['PANEL_LIBRARIES'] = ncurses_libs @@ -728,13 +760,15 @@ class LlvmCore(BuildUtils): llvm_defines['LIBLZMA_LIBRARIES'] = self.merge_out_path('lzma', 'lib', 'linux-x86_64', 'liblzma.so') if self.build_config.build_libedit: - llvm_defines['LibEdit_LIBRARIES'] = os.path.join(self.get_prebuilts_dir('libedit'), 'lib', 'libedit.so.0.0.68') + llvm_defines['LibEdit_LIBRARIES'] = \ + self.merge_libedit_install_dir(self.use_platform(), 'lib', 'libedit.so.0.0.68') if not build_instrumented and not no_lto and not debug_build: llvm_defines['LLVM_ENABLE_LTO'] = 'Thin' if self.build_config.build_libxml2: - llvm_defines['LIBXML2_LIBRARY'] = os.path.join(self.get_libxml2_install_path(self.use_platform()), 'lib', f'libxml2.so.{self.build_config.LIBXML2_VERSION}') + llvm_defines['LIBXML2_LIBRARY'] = \ + self.merge_libxml2_install_dir(self.use_platform(), 'lib', f'libxml2.so.{self.build_config.LIBXML2_VERSION}') def llvm_compile_llvm_defines(self, llvm_defines, llvm_root, cflags, ldflags): llvm_defines['LLVM_ENABLE_PROJECTS'] = ';'.join(self.build_config.host_projects) @@ -770,7 +804,7 @@ class LlvmCore(BuildUtils): if self.build_config.build_ncurses and self.get_ncurses_version() is not None: llvm_defines['LLDB_ENABLE_CURSES'] = 'ON' - llvm_defines['CURSES_INCLUDE_DIRS'] = os.path.join(self.get_prebuilts_dir('ncurses'), 'include') + llvm_defines['CURSES_INCLUDE_DIRS'] = self.merge_ncurses_install_dir(self.use_platform(), 'include') if self.build_config.enable_lzma_7zip: llvm_defines['LLDB_ENABLE_LZMA'] = 'ON' @@ -779,11 +813,11 @@ class LlvmCore(BuildUtils): if self.build_config.build_libedit: llvm_defines['LLDB_ENABLE_LIBEDIT'] = 'ON' - llvm_defines['LibEdit_INCLUDE_DIRS'] = os.path.join(self.get_prebuilts_dir('libedit'), 'include') + llvm_defines['LibEdit_INCLUDE_DIRS'] = self.merge_libedit_install_dir(self.use_platform(), 'include') if self.build_config.build_libxml2: llvm_defines['LLDB_ENABLE_LIBXML2'] = 'ON' - llvm_defines['LIBXML2_INCLUDE_DIR'] = os.path.join(self.get_libxml2_install_path(self.use_platform()), 'include', 'libxml2') + llvm_defines['LIBXML2_INCLUDE_DIR'] = self.merge_libxml2_install_dir(self.use_platform(), 'include', 'libxml2') if self.build_config.enable_monitoring: llvm_defines['LLDB_ENABLE_PERFORMANCE'] = 'ON' @@ -909,8 +943,8 @@ class LlvmCore(BuildUtils): if self.build_config.build_libxml2: windows_defines['LLDB_ENABLE_LIBXML2'] = 'ON' - windows_defines['LIBXML2_INCLUDE_DIR'] = os.path.join(self.get_libxml2_install_path('windows-x86_64'), 'include', 'libxml2') - windows_defines['LIBXML2_LIBRARY'] = os.path.join(self.get_libxml2_install_path('windows-x86_64'), 'lib', 'libxml2.dll.a') + windows_defines['LIBXML2_INCLUDE_DIR'] = self.merge_libxml2_install_dir('windows-x86_64', 'include', 'libxml2') + windows_defines['LIBXML2_LIBRARY'] = self.merge_libxml2_install_dir('windows-x86_64', 'lib', 'libxml2.dll.a') if self.build_config.enable_monitoring: windows_defines['LLDB_ENABLE_PERFORMANCE'] = 'ON' @@ -967,7 +1001,6 @@ class LlvmCore(BuildUtils): 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') @@ -984,7 +1017,6 @@ class LlvmCore(BuildUtils): 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, @@ -1695,11 +1727,10 @@ class LlvmLibs(BuildUtils): lldb_target.append('lldb') if self.build_config.build_libxml2: - self.build_libxml2(llvm_triple, None, llvm_install) + self.build_libxml2(llvm_triple, None, llvm_install, True) lldb_defines['LLDB_ENABLE_LIBXML2'] = 'ON' - libxml2_install_path = self.get_libxml2_install_path(llvm_triple) - lldb_defines['LIBXML2_INCLUDE_DIR'] = os.path.join(libxml2_install_path, 'include', 'libxml2') - lldb_defines['LIBXML2_LIBRARY'] = os.path.join(libxml2_install_path, 'lib', 'libxml2.a') + lldb_defines['LIBXML2_INCLUDE_DIR'] = self.merge_libxml2_install_dir(llvm_triple, 'include', 'libxml2') + lldb_defines['LIBXML2_LIBRARY'] = self.merge_libxml2_install_dir(llvm_triple, 'lib', 'libxml2.a') if self.build_config.lldb_timeout: lldb_defines['LLDB_ENABLE_TIMEOUT'] = 'True' @@ -1764,12 +1795,12 @@ class LlvmLibs(BuildUtils): env=dict(self.build_config.ORIG_ENV), install=True) - def build_ncurses(self, llvm_make, llvm_install): + def build_ncurses(self, llvm_make, llvm_install, platform_triple): self.logger().info('Building ncurses.') libncurses_src_dir = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'third_party', 'ncurses')) - libncurses_build_path = self.merge_out_path('ncurses') - libncurses_install_path = self.get_prebuilts_dir('ncurses') + libncurses_install_path = self.merge_ncurses_install_dir(platform_triple) + libncurses_build_path = self.merge_ncurses_build_dir(platform_triple) prebuilts_path = os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts') self.check_rm_tree(libncurses_build_path) @@ -1784,12 +1815,12 @@ class LlvmLibs(BuildUtils): ncurses_version = self.get_ncurses_version() if ncurses_version is not None: args = ['./build_ncurses.sh', libncurses_src_dir, libncurses_build_path, libncurses_install_path, - prebuilts_path, clang_version, ncurses_version] + prebuilts_path, clang_version, ncurses_version, platform_triple] self.check_call(args) os.chdir(cur_dir) - self.llvm_package.copy_ncurses_to_llvm(llvm_make) - self.llvm_package.copy_ncurses_to_llvm(llvm_install) + self.llvm_package.copy_ncurses_to_llvm(platform_triple, llvm_make) + self.llvm_package.copy_ncurses_to_llvm(platform_triple, llvm_install) def build_lzma(self, llvm_make, llvm_install): self.logger().info('Building lzma') @@ -1827,12 +1858,12 @@ class LlvmLibs(BuildUtils): self.check_create_dir(lib_dst_path) self.check_copy_file(lzma_file, lib_dst_path + '/liblzma' + shlib_ext) - def build_libedit(self, llvm_make, llvm_install): + def build_libedit(self, llvm_make, llvm_install, platform_triple): self.logger().info('Building libedit') libedit_src_dir = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'third_party', 'libedit')) - libedit_build_path = self.merge_out_path('libedit') - libedit_install_path = self.get_prebuilts_dir('libedit') + libedit_build_path = self.merge_libedit_build_dir(platform_triple) + libedit_install_path = self.merge_libedit_install_dir(platform_triple) prebuilts_path = os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts') self.check_rm_tree(libedit_build_path) @@ -1840,17 +1871,17 @@ class LlvmLibs(BuildUtils): self.check_rm_tree(libedit_install_path) self.rm_cmake_cache(libedit_install_path) - libncurses_path = self.get_prebuilts_dir('ncurses') + libncurses_path = self.merge_ncurses_install_dir(platform_triple) cur_dir = os.getcwd() os.chdir(self.build_config.LLVM_BUILD_DIR) clang_version = self.build_config.CLANG_VERSION - args = ['./build_libedit.sh', libedit_src_dir, libedit_build_path , libedit_install_path, libncurses_path, prebuilts_path, clang_version] + args = ['./build_libedit.sh', libedit_src_dir, libedit_build_path , libedit_install_path, libncurses_path, prebuilts_path, clang_version, platform_triple] self.check_call(args) os.chdir(cur_dir) - self.llvm_package.copy_libedit_to_llvm(llvm_make) - self.llvm_package.copy_libedit_to_llvm(llvm_install) + self.llvm_package.copy_libedit_to_llvm(platform_triple, llvm_make) + self.llvm_package.copy_libedit_to_llvm(platform_triple, llvm_install) def build_libxml2_defines(self): libxml2_defines = {} @@ -1862,7 +1893,7 @@ class LlvmLibs(BuildUtils): return libxml2_defines - def build_libxml2(self, triple, llvm_make, llvm_install): + def build_libxml2(self, triple, llvm_make, llvm_install, static = False): self.logger().info('Building libxml2 for %s', triple) cmake_path = self.get_libxml2_source_path() @@ -1873,31 +1904,23 @@ class LlvmLibs(BuildUtils): self.check_create_dir(untar_path) subprocess.run(['python3', untar_py, '--gen-dir', untar_path, '--source-file', package_path]) - build_path = self.get_libxml2_build_path(triple) - install_path = self.get_libxml2_install_path(triple) - self.check_rm_tree(build_path) + build_path = self.merge_libxml2_build_dir(triple) + install_path = self.merge_libxml2_install_dir(triple) self.check_rm_tree(install_path) defines = self.build_libxml2_defines() defines['CMAKE_INSTALL_PREFIX'] = install_path + if static: + defines['BUILD_SHARED_LIBS'] = 'OFF' - if triple != self.use_platform(): - configs_list, cc, cxx, ar, llvm_config = self.libs_argument(llvm_install) - for (arch, llvm_triple, extra_flags, multilib_suffix) in configs_list: - if llvm_triple != triple or multilib_suffix != '': - continue + if triple in ['arm-linux-ohos', 'aarch64-linux-ohos']: + defines['CMAKE_C_COMPILER'] = self.merge_out_path('llvm-install','bin','clang') + cflags = [f"--target={triple}"] + if triple == 'arm-linux-ohos': + cflags.append('-march=armv7-a -mfloat-abi=soft') + defines['CMAKE_C_FLAGS'] = ' '.join(cflags) - ldflags = [] - cflags = [] - self.build_libs_defines(triple, defines, cc, cxx, ar, llvm_config, ldflags, cflags, extra_flags) - defines['CMAKE_C_FLAGS'] = ' '.join(cflags) - defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) - defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) - defines['CMAKE_LINKER'] = os.path.join(llvm_install, 'bin', 'ld.lld') - defines['CMAKE_SYSTEM_NAME'] = 'OHOS' - defines['CMAKE_CROSSCOMPILING'] = 'True' - defines['BUILD_SHARED_LIBS'] = 'OFF' - break + self.rm_cmake_cache(build_path) self.invoke_cmake(cmake_path, build_path, @@ -1908,8 +1931,7 @@ class LlvmLibs(BuildUtils): dict(self.build_config.ORIG_ENV), None, True) - - if triple == self.use_platform(): + if not static: self.llvm_package.copy_libxml2_to_llvm(triple, llvm_make) self.llvm_package.copy_libxml2_to_llvm(triple, llvm_install) @@ -1918,8 +1940,8 @@ class LlvmLibs(BuildUtils): windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) windowstool_path = self.merge_out_path('llvm-install') - libxml2_build_path = self.get_libxml2_build_path('windows-x86_64') - libxml2_install_path = self.get_libxml2_install_path('windows-x86_64') + libxml2_build_path = self.merge_libxml2_build_dir('windows-x86_64') + libxml2_install_path = self.merge_libxml2_install_dir('windows-x86_64') cflags = ['--target=x86_64-pc-windows-gnu'] cflags.extend(('-I', os.path.join(windows_sysroot, 'include'))) @@ -2347,7 +2369,7 @@ class LlvmPackage(BuildUtils): if index_link != -1: subprocess.check_call(["install_name_tool", "-change", dependency, "@loader_path/../lib/%s" % lib_name, lib]) - def copy_ncurses_to_llvm(self, install_dir): + def copy_ncurses_to_llvm(self, platform_triple, install_dir): self.logger().info('copy_ncurses_to_llvm install_dir is %s', install_dir) if self.host_is_darwin(): @@ -2357,30 +2379,27 @@ class LlvmPackage(BuildUtils): lib_dst_path = os.path.join(install_dir, 'lib') - lib_src_path = self.merge_out_path('../prebuilts', 'ncurses', 'lib') - libncurses_src = os.path.join(lib_src_path, 'libncurses%s' % shlib_ext) - libpanel_src = os.path.join(lib_src_path, 'libpanel%s' % shlib_ext) - libform_src = os.path.join(lib_src_path, 'libform%s' % shlib_ext) - - libncurses_dst = os.path.join(lib_dst_path, 'libncurses%s' % shlib_ext) - libpanel_dst = os.path.join(lib_dst_path, 'libpanel%s' % shlib_ext) - libform_dst =os.path.join(lib_dst_path, 'libform%s' % shlib_ext) + lib_names = self.get_ncurses_dependence_libs(platform_triple) + lib_srcs = [self.merge_ncurses_install_dir(platform_triple, 'lib', + f'{name}{shlib_ext}') for name in lib_names] + lib_dsts = [os.path.join(install_dir, 'lib', + f'{name}{shlib_ext}') for name in lib_names] if not os.path.exists(lib_dst_path): os.makedirs(lib_dst_path) - for lib_file in (libncurses_src, libpanel_src, libform_src): - self.update_lib_id_link(lib_src_path, lib_file) + for lib_file in lib_srcs: + self.update_lib_id_link(self.merge_ncurses_install_dir(platform_triple, 'lib'), lib_file) # Clear historical libraries - for lib in (libncurses_dst, libpanel_dst, libform_dst): + for lib in lib_dsts: if os.path.exists(lib): os.remove(lib) - for lib_src in (libncurses_src, libpanel_src, libform_src): + for lib_src in lib_srcs: self.check_copy_file(lib_src, lib_dst_path) - def copy_libedit_to_llvm(self, install_dir): + def copy_libedit_to_llvm(self, platform_triple, install_dir): self.logger().info('LlvmPackage copy_libedit_to_llvm install_dir is %s', install_dir) if self.host_is_darwin(): @@ -2388,7 +2407,7 @@ class LlvmPackage(BuildUtils): if self.host_is_linux(): shlib_ext = '.so.0' - libedit_lib_path = self.merge_out_path('../prebuilts', 'libedit', 'lib') + libedit_lib_path = self.merge_libedit_install_dir(platform_triple, 'lib') libedit_src = os.path.join(libedit_lib_path, 'libedit%s' % shlib_ext) lib_dst_path = os.path.join(install_dir, 'lib') @@ -2413,7 +2432,7 @@ class LlvmPackage(BuildUtils): st = os.stat(os.path.join(bin_dir, sh_filename)) os.chmod(os.path.join(bin_dir, sh_filename), st.st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH) - def copy_libxml2_to_llvm(self, triple, install_dir): + def copy_libxml2_to_llvm(self, platform_triple, install_dir): self.logger().info('LlvmPackage copy_libxml2_to_llvm install_dir is %s', install_dir) libxml2_version = self.get_libxml2_version() @@ -2423,8 +2442,8 @@ class LlvmPackage(BuildUtils): if self.host_is_linux(): shlib_ext = f'.so.{libxml2_version}' - libxml2_lib_path = os.path.join(self.get_libxml2_install_path(triple), 'lib') - libxml2_src = os.path.join(libxml2_lib_path, 'libxml2%s' % shlib_ext) + lib_path = self.merge_libxml2_install_dir(platform_triple, 'lib') + libxml2_src = os.path.join(lib_path, 'libxml2%s' % shlib_ext) lib_dst_path = os.path.join(install_dir, 'lib') @@ -2433,7 +2452,7 @@ class LlvmPackage(BuildUtils): if not os.path.exists(lib_dst_path): os.makedirs(lib_dst_path) - self.update_lib_id_link(libxml2_lib_path, libxml2_src) + self.update_lib_id_link(lib_path, libxml2_src) # Clear historical library if os.path.isfile(libxml2_dst): @@ -2524,7 +2543,6 @@ class LlvmPackage(BuildUtils): return - def main(): build_config = BuildConfig() build_utils = BuildUtils(build_config) @@ -2560,13 +2578,13 @@ def main(): configs.append(('x86_64', build_utils.open_ohos_triple('x86_64'))) if build_config.build_ncurses: - llvm_libs.build_ncurses(llvm_make, llvm_install) + llvm_libs.build_ncurses(llvm_make, llvm_install, build_utils.use_platform()) if build_config.enable_lzma_7zip: llvm_libs.build_lzma(llvm_make, llvm_install) if build_config.build_libedit: - llvm_libs.build_libedit(llvm_make, llvm_install) + llvm_libs.build_libedit(llvm_make, llvm_install, build_utils.use_platform()) build_config.LIBXML2_VERSION = build_utils.get_libxml2_version() if build_config.LIBXML2_VERSION is None: diff --git a/llvm-build/build_libedit.sh b/llvm-build/build_libedit.sh index 5d046197a8874edd4ee453928fa8e68c72edd108..357ebea760221b1e61b5b526d8a3119ff7ffc72b 100755 --- a/llvm-build/build_libedit.sh +++ b/llvm-build/build_libedit.sh @@ -47,34 +47,57 @@ CXX_PATH=${PREBUILT_PATH}/clang/ohos/${host_platform}-${host_cpu}/clang-${CLANG_ libedit_package=${LIBEDIT_SRC_DIR}/libedit-${DATE}-${LIBEDIT_VERSION}.tar.gz if [ -e ${libedit_package} ]; then tar -xzvf ${libedit_package} --strip-components 1 -C ${LIBEDIT_SRC_DIR} + cd ${LIBEDIT_SRC_DIR} if [ ! -b ${LIBEDIT_BUILD_PATH} ]; then mkdir -p ${LIBEDIT_BUILD_PATH} fi + patches=($(grep -E '^Patch[0-9]+:' "${SPECFILE}" | sed 's/^[^:]*: *//')) + # Apply patches in order + for patch in "${patches[@]}" + do + patch -Np1 < $patch + done # build libedit cd ${LIBEDIT_BUILD_PATH} - ldflags="-L${NCURSES_PATH}/lib" - ncuses_flags="-I${NCURSES_PATH}/include" - if [ "${host_platform}" = "darwin" ]; then - ncurses_libs="-Wl,-rpath,@loader_path/../lib:${NCURSES_PATH}/lib" - SDKROOT=$(xcrun --sdk macosx --show-sdk-path) - sdk_flags="-I${SDKROOT}/usr/include" - export LDFLAGS="$LDFLAGS $sdk_flags $ldflags $ncurses_libs" - export CFLAGS="$CFLAGS -isysroot$SDKROOT $ncuses_flags" - fi + ohos_suffix='-ohos' + if [[ ${7} != *${ohos_suffix} ]]; then + ldflags="-L${NCURSES_PATH}/lib" + ncuses_flags="-I${NCURSES_PATH}/include" + if [ "${host_platform}" = "darwin" ]; then + ncurses_libs="-Wl,-rpath,@loader_path/../lib:${NCURSES_PATH}/lib" + SDKROOT=$(xcrun --sdk macosx --show-sdk-path) + sdk_flags="-I${SDKROOT}/usr/include" + export LDFLAGS="$LDFLAGS $sdk_flags $ldflags $ncurses_libs" + export CFLAGS="$CFLAGS -isysroot$SDKROOT $ncuses_flags" + fi - if [ "${host_platform}" = "linux" ]; then - ncurses_libs="-Wl,-rpath,\$$ORIGIN/../lib:${NCURSES_PATH}/lib" - export LDFLAGS="$LDFLAGS $ldflags $ncuses_flags $ncurses_libs" - export CFLAGS="$CFLAGS $ncuses_flags" - fi + if [ "${host_platform}" = "linux" ]; then + ncurses_libs="-Wl,-rpath,\$$ORIGIN/../lib:${NCURSES_PATH}/lib" + export LDFLAGS="$LDFLAGS $ldflags $ncuses_flags $ncurses_libs" + export CFLAGS="$CFLAGS $ncuses_flags" + fi - ${LIBEDIT_SRC_DIR}/configure \ - --prefix=${LIBEDIT_INSTALL_PATH} \ - CC=${CC_PATH} \ - CXX=${CXX_PATH} - make -j$(nproc --all) install | tee build_libedit.log + ${LIBEDIT_SRC_DIR}/configure \ + --prefix=${LIBEDIT_INSTALL_PATH} \ + CC=${CC_PATH} \ + CXX=${CXX_PATH} + make -j$(nproc --all) install | tee build_libedit.log + else + C_FLAGS="-I${NCURSES_PATH}/include/ -I${NCURSES_PATH}/include/ncurses -D__STDC_ISO_10646__=201103L -fPIC" + if [[ $7 =~ 'arm' ]]; then + C_FLAGS="$C_FLAGS -march=armv7-a -mfloat-abi=soft" + fi + ${LIBEDIT_SRC_DIR}/configure \ + --prefix=${LIBEDIT_INSTALL_PATH} \ + --host="$7" \ + CC="${PREBUILT_PATH}/../out/llvm-install/bin/clang --target=$7" \ + CFLAGS="${C_FLAGS}" \ + LDFLAGS="-L${NCURSES_PATH}/lib" + + make -j$(nproc --all) install | tee build_libedit_$7.log + fi fi diff --git a/llvm-build/build_ncurses.sh b/llvm-build/build_ncurses.sh index df4f7b1ed45cf568f7c9e49d325186f0aa16b77e..91a995440498543c27e115bdcaf5a64e92ea854b 100755 --- a/llvm-build/build_ncurses.sh +++ b/llvm-build/build_ncurses.sh @@ -60,31 +60,50 @@ if [ -e ${ncurses_package} ]; then fi cd ${NCURSES_BUILD_PATH} # build ncurses - if [ "${host_platform}" == "darwin" ]; then - export LDFLAGS="-Wl,-rpath,@loader_path/../lib" - SDKROOT=$(xcrun --sdk macosx --show-sdk-path) - flags="-Wl,-syslibroot,${SDKROOT}" - export CPPFLAGS="$CPPFALGS -I${SDKROOT}/usr/include -I${SDKROOT}/usr/include/i368" - export CFLAGS="$CFLAGS -isysroot${SDKROOT} $flags" + ohos_suffix='-ohos' + if [[ ${7} != *${ohos_suffix} ]]; then + if [ "${host_platform}" == "darwin" ]; then + export LDFLAGS="-Wl,-rpath,@loader_path/../lib" + SDKROOT=$(xcrun --sdk macosx --show-sdk-path) + flags="-Wl,-syslibroot,${SDKROOT}" + export CPPFLAGS="$CPPFALGS -I${SDKROOT}/usr/include -I${SDKROOT}/usr/include/i368" + export CFLAGS="$CFLAGS -isysroot${SDKROOT} $flags" + ${NCURSES_SRC_DIR}/configure \ + --with-shared \ + --with-default-terminfo-dir=/usr/lib/terminfo:/lib/terminfo:/usr/share/terminfo \ + --disable-mixed-case \ + --prefix=${NCURSES_INSTALL_PATH} \ + CC=${CC_PATH} \ + CXX=${CXX_PATH} + make -j$(nproc --all) install | tee build_ncurses.log + fi + if [ "${host_platform}" == "linux" ]; then + export LDFLAGS="-Wl,-rpath,\$$ORIGIN/../lib" + ${NCURSES_SRC_DIR}/configure \ + --with-shared \ + --with-default-terminfo-dir=/usr/lib/terminfo:/lib/terminfo:/usr/share/terminfo \ + --prefix=${NCURSES_INSTALL_PATH} \ + CC=${CC_PATH} \ + CXX=${CXX_PATH} + make -j$(nproc --all) install | tee build_ncurses.log + fi + else + C_FLAGS="--target=$7 -fPIC" + if [[ $7 =~ 'arm' ]]; then + C_FLAGS="$C_FLAGS -march=armv7-a -mfloat-abi=soft" + fi ${NCURSES_SRC_DIR}/configure \ + --host="$7" \ --with-shared \ - --with-default-terminfo-dir=/usr/lib/terminfo:/lib/terminfo:/usr/share/terminfo \ - --disable-mixed-case \ --prefix=${NCURSES_INSTALL_PATH} \ - CC=${CC_PATH} \ - CXX=${CXX_PATH} - make -j$(nproc --all) install | tee build_ncurses.log - fi - if [ "${host_platform}" == "linux" ]; then - export LDFLAGS="-Wl,-rpath,\$$ORIGIN/../lib" - ${NCURSES_SRC_DIR}/configure \ - --with-shared \ - --with-default-terminfo-dir=/usr/lib/terminfo:/lib/terminfo:/usr/share/terminfo \ - --prefix=${NCURSES_INSTALL_PATH} \ - CC=${CC_PATH} \ - CXX=${CXX_PATH} - make -j$(nproc --all) install | tee build_ncurses.log + --with-termlib \ + --without-manpages \ + --with-strip-program="${PREBUILT_PATH}/../out/llvm-install/bin/llvm-strip" \ + CC=${PREBUILT_PATH}/../out/llvm-install/bin/clang \ + CXX=${PREBUILT_PATH}/../out/llvm-install/bin/clang++ \ + CFLAGS="${C_FLAGS}" + make -j$(nproc --all) install | tee build_ncurses_$7.log fi fi diff --git a/llvm-build/ohos_toolchain_builder.py b/llvm-build/ohos_toolchain_builder.py new file mode 100644 index 0000000000000000000000000000000000000000..f8a586f90c9d71b30cd879ea811064cb19517cd0 --- /dev/null +++ b/llvm-build/ohos_toolchain_builder.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python3 +# Copyright (C) 2024 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 +from typing import List +from build import BuildConfig, BuildUtils, LlvmLibs, SysrootComposer, LlvmPackage +from python_builder import OHOSPythonBuilder + + +class OHOSToolchainBuilder: + def __init__(self, llvm_triple) -> None: + self._llvm_triple = llvm_triple + self._platform = llvm_triple.split("-")[0] + self._build_config = BuildConfig() + self._build_utils = BuildUtils(self._build_config) + self._sysroot_composer = SysrootComposer(self._build_config) + self._llvm_package = LlvmPackage(self._build_config) + self._llvm_libs = LlvmLibs( + self._build_config, self._sysroot_composer, self._llvm_package + ) + self._python_builder = OHOSPythonBuilder(self._build_utils, self._llvm_triple) + self._llvm_project_path = os.path.abspath( + os.path.join(self._build_config.LLVM_PROJECT_DIR, "llvm") + ) + self._llvm_path = self._build_utils.merge_out_path(f"ohos-{self._platform}") + self._llvm_install = self._build_utils.merge_out_path( + f"ohos-{self._platform}-install" + ) + self._llvm_root = self._build_utils.merge_out_path("llvm-install") + self._sysroot = self._build_utils.merge_out_path("sysroot") + + self._cflags = self._init_cflags() + self._ldflags = self._init_ldflags() + self._llvm_defines = self._init_llvm_defines() + + def _init_cflags(self) -> List[str]: + cflags = [ + "-fstack-protector-strong", + "--target=%s" % self._llvm_triple, + "-ffunction-sections", + "-fdata-sections", + ] + return cflags + + def _init_ldflags(self) -> List[str]: + ldflags = [ + "-fuse-ld=lld", + "-Wl,--gc-sections", + "-Wl,--build-id=sha1", + "--rtlib=compiler-rt", + "-stdlib=libc++", + "-Wl,-z,relro,-z,now", + "-pie", + "-lunwind", + ] + return ldflags + + def _init_llvm_defines(self): + llvm_defines = {} + llvm_defines["LLVM_TARGET_ARCH"] = self._platform + llvm_defines["OHOS"] = "1" + llvm_defines["CMAKE_SYSTEM_NAME"] = "OHOS" + llvm_defines["CMAKE_CROSSCOMPILING"] = "True" + llvm_defines["CMAKE_INSTALL_PREFIX"] = self._llvm_install + llvm_defines["CMAKE_SYSROOT"] = self._sysroot + llvm_defines["LLVM_HOST_TRIPLE"] = self._llvm_triple + llvm_defines["LLVM_TARGETS_TO_BUILD"] = self._build_config.TARGETS + llvm_defines["LLVM_DEFAULT_TARGET_TRIPLE"] = self._llvm_triple + llvm_defines["LLVM_ENABLE_TERMINFO"] = "OFF" + llvm_defines["LLVM_CONFIG_PATH"] = os.path.join( + self._llvm_root, "bin", "llvm-config" + ) + llvm_defines["LLVM_TABLEGEN"] = os.path.join( + self._llvm_root, "bin", "llvm-tblgen" + ) + llvm_defines["CMAKE_C_COMPILER"] = os.path.join(self._llvm_root, "bin", "clang") + llvm_defines["CMAKE_CXX_COMPILER"] = os.path.join( + self._llvm_root, "bin", "clang++" + ) + llvm_defines["CMAKE_AR"] = os.path.join(self._llvm_root, "bin", "llvm-ar") + llvm_defines["CMAKE_FIND_ROOT_PATH_MODE_INCLUDE"] = "ONLY" + llvm_defines["CMAKE_FIND_ROOT_PATH_MODE_LIBRARY"] = "ONLY" + llvm_defines["CMAKE_FIND_ROOT_PATH_MODE_PACKAGE"] = "ONLY" + llvm_defines["CMAKE_FIND_ROOT_PATH_MODE_PROGRAM"] = "NEVER" + llvm_defines["Python3_EXECUTABLE"] = os.path.join( + self._build_utils.get_python_dir(), "bin", self._build_config.LLDB_PYTHON + ) + + if self._build_config.debug: + llvm_defines["CMAKE_BUILD_TYPE"] = "Debug" + else: + llvm_defines["CMAKE_BUILD_TYPE"] = "Release" + + llvm_defines.update(self._init_lldb_defines()) + + return llvm_defines + + def _init_lldb_defines(self): + lldb_defines = {} + lldb_defines["LLDB_INCLUDE_TESTS"] = "OFF" + if self._build_config.lldb_timeout: + lldb_defines["LLDB_ENABLE_TIMEOUT"] = "True" + # Optional Dependencies + if self._build_config.build_ncurses: + lldb_defines["LLDB_ENABLE_CURSES"] = "ON" + lldb_defines["CURSES_INCLUDE_DIRS"] = ";".join( + [ + self._build_utils.merge_ncurses_install_dir( + self._llvm_triple, "include" + ), + self._build_utils.merge_ncurses_install_dir( + self._llvm_triple, "include", "ncurses" + ), + ] + ) + ncurses_libs = [] + for library in self._build_utils.get_ncurses_dependence_libs(self._llvm_triple): + library_path = self._build_utils.merge_ncurses_install_dir( + self._llvm_triple, + "lib", + f"{library}.so.%s" % self._build_utils.get_ncurses_version(), + ) + ncurses_libs.append(library_path) + lldb_defines["CURSES_LIBRARIES"] = ";".join(ncurses_libs) + lldb_defines["PANEL_LIBRARIES"] = ";".join(ncurses_libs) + + if self._build_config.build_libxml2: + self._build_config.LIBXML2_VERSION = self._build_utils.get_libxml2_version() + + lldb_defines["LLDB_ENABLE_LIBXML2"] = "ON" + lldb_defines["LIBXML2_INCLUDE_DIR"] = ( + self._build_utils.merge_libxml2_install_dir( + self._llvm_triple, "include", "libxml2" + ) + ) + lldb_defines["LIBXML2_LIBRARY"] = ( + self._build_utils.merge_libxml2_install_dir( + self._llvm_triple, + "lib", + "libxml2.so.%s" % self._build_utils.get_libxml2_version(), + ) + ) + + if self._build_config.build_libedit: + lldb_defines["LLDB_ENABLE_LIBEDIT"] = "ON" + lldb_defines["LibEdit_INCLUDE_DIRS"] = ( + self._build_utils.merge_libedit_install_dir( + self._llvm_triple, "include" + ) + ) + lldb_defines["LibEdit_LIBRARIES"] = ( + self._build_utils.merge_libedit_install_dir( + self._llvm_triple, "lib", "libedit.so.0.0.68" + ) + ) + + if self._build_config.build_python: + lldb_defines["LLDB_ENABLE_PYTHON"] = "ON" + lldb_defines["LLDB_EMBED_PYTHON_HOME"] = "ON" + lldb_defines["LLDB_PYTHON_HOME"] = f"../{self._build_config.LLDB_PYTHON}" + lldb_defines["LLDB_PYTHON_RELATIVE_PATH"] = "bin/python/lib/python%s" % ( + self._build_config.LLDB_PY_VERSION + ) + lldb_defines["LLDB_PYTHON_EXE_RELATIVE_PATH"] = "bin/python" + lldb_defines["LLDB_PYTHON_EXT_SUFFIX"] = ".so" + lldb_defines["Python3_INCLUDE_DIRS"] = ( + self._build_utils.merge_python_install_dir( + self._llvm_triple, + "include", + f"python{self._build_config.LLDB_PY_VERSION}", + ) + ) + lldb_defines["Python3_LIBRARIES"] = self._build_utils.merge_python_install_dir( + self._llvm_triple, + "lib", + "libpython%s.so" % self._build_config.LLDB_PY_VERSION, + ) + + lldb_defines["LLDB_ENABLE_LZMA"] = "OFF" + # Debug & Tuning + if self._build_config.enable_monitoring: + lldb_defines["LLDB_ENABLE_PERFORMANCE"] = "ON" + + return lldb_defines + + def _build_and_install(self, build_target): + if self._build_config.build_ncurses: + self._llvm_libs.build_ncurses("", self._llvm_install, self._llvm_triple) + if self._build_config.build_libxml2: + self._llvm_libs.build_libxml2(self._llvm_triple, "", self._llvm_install) + if self._build_config.build_libedit: + self._llvm_libs.build_libedit("", self._llvm_install, self._llvm_triple) + if self._build_config.build_python: + self._python_builder.build() + + self._build_utils.invoke_cmake( + self._llvm_project_path, + self._llvm_path, + self._llvm_defines, + env=dict(self._build_config.ORIG_ENV), + ) + + self._build_utils.invoke_ninja( + out_path=self._llvm_path, + env=dict(self._build_config.ORIG_ENV), + target=build_target, + install=True, + ) + + if self._build_config.build_python: + self._python_builder.copy_python_to_host(self._llvm_install) + + # Copy required arm-linux-ohos libs from main toolchain build. + arch_list = [ + self._build_utils.liteos_triple("arm"), + self._build_utils.open_ohos_triple("arm"), + self._build_utils.open_ohos_triple("aarch64"), + self._build_utils.open_ohos_triple("riscv64"), + self._build_utils.open_ohos_triple("mipsel"), + self._build_utils.open_ohos_triple("x86_64"), + ] + for arch in arch_list: + self._build_utils.check_copy_tree( + os.path.join(self._llvm_root, "lib", arch), + os.path.join(self._llvm_install, "lib", arch), + ) + self._build_utils.check_copy_tree( + os.path.join(self._llvm_root, "lib", "clang", "15.0.4", "lib", arch), + os.path.join(self._llvm_install, "lib", "clang", "15.0.4", "lib", arch), + ) + + # Copy required c++ headerfiles from main toolchain build. + self._build_utils.check_copy_tree( + os.path.join(self._llvm_root, "include", "c++"), + os.path.join(self._llvm_install, "include", "c++"), + ) + self._build_utils.check_copy_tree( + os.path.join(self._llvm_root, "include", "libcxx-ohos"), + os.path.join(self._llvm_install, "include", "libcxx-ohos"), + ) + + def _package_if_need(self): + if self._build_config.do_package: + tarball_name = ( + f"clang-{self._build_config.build_name}-ohos-{self._platform}" + ) + package_path = "%s%s" % ( + self._build_utils.merge_packages_path(tarball_name), + self._build_config.ARCHIVE_EXTENSION, + ) + self._build_utils.logger().info("Packaging %s", package_path) + args = [ + "tar", + self._build_config.ARCHIVE_OPTION, + "-h", + "-C", + self._build_config.OUT_PATH, + "-f", + package_path, + f"ohos-{self._platform}-install", + ] + self._build_utils.check_create_dir(self._build_config.PACKAGES_PATH) + self._build_utils.check_call(args) + + # virtual function + def _update_build_args(self): + return + + def build(self, build_target=None): + self._update_build_args() + + self._build_and_install(build_target) + + self._package_if_need() diff --git a/llvm-build/python_builder.py b/llvm-build/python_builder.py index 7ca5426987ee9b781fbc404ec7765ab1d7bb0337..1663b59168753e7aedeff266b9e073f77d427566 100755 --- a/llvm-build/python_builder.py +++ b/llvm-build/python_builder.py @@ -18,28 +18,22 @@ import shutil import subprocess from typing import List, Mapping -class MinGWPythonBuilder: - target_platform = "x86_64-w64-mingw32" +class PythonBuilder: + target_platform = "" + patches = [] def __init__(self, build_config) -> None: - repo_root = Path(build_config.REPOROOT_DIR).resolve() + self.repo_root = Path(build_config.REPOROOT_DIR).resolve() self._out_dir = Path(build_config.OUT_PATH).resolve() self._clang_toolchain_dir = self._out_dir / 'llvm-install' - self._mingw_install_dir = self._out_dir / 'mingw' / build_config.MINGW_TRIPLE - self._source_dir = repo_root / 'third_party' / 'python' - self._build_dir = self._out_dir / 'python-windows-build' - self._install_dir = self._out_dir / 'python-windows-install' self._version = build_config.LLDB_PY_DETAILED_VERSION version_parts = self._version.split('.') self._major_version = version_parts[0] + '.' + version_parts[1] - # This file is used to detect whether patches are applied - self._mingw_ignore_file = self._source_dir / 'mingw_ignorefile.txt' + self._source_dir = self.repo_root / 'third_party' / 'python' self._patch_dir = self._source_dir / 'patches' + self._install_dir = "" - for directory in (self._clang_toolchain_dir, self._mingw_install_dir, - self._source_dir): - if not directory.is_dir(): - raise ValueError(f'No such directory "{directory}"') + self._clean_patches() @property def _logger(self) -> logging.Logger: @@ -49,6 +43,14 @@ class MinGWPythonBuilder: def _cc(self) -> Path: return self._clang_toolchain_dir/ 'bin' / 'clang' + @property + def _cflags(self) -> List[str]: + return [] + + @property + def _ldflags(self) -> List[str]: + return [] + @property def _cxx(self) -> Path: return self._clang_toolchain_dir / 'bin' / 'clang++' @@ -57,33 +59,13 @@ class MinGWPythonBuilder: def _strip(self) -> Path: return self._clang_toolchain_dir / 'bin' / 'llvm-strip' - @property - def _cflags(self) -> List[str]: - cflags = [ - f'-target {self.target_platform}', - f'--sysroot={self._mingw_install_dir}', - ] - return cflags - @property def _cxxflags(self) -> List[str]: return self._cflags.copy() - @property - def _ldflags(self) -> List[str]: - ldflags = [ - f'--sysroot={self._mingw_install_dir}', - f'-rtlib=compiler-rt', - f'-target {self.target_platform}', - f'-lucrt', - f'-lucrtbase', - f'-fuse-ld=lld', - ] - return ldflags - @property def _rcflags(self) -> List[str]: - return [ f'-I{self._mingw_install_dir}/include' ] + return [] @property def _env(self) -> Mapping[str, str]: @@ -104,26 +86,19 @@ class MinGWPythonBuilder: 'CXXFLAGS': ' '.join(self._cxxflags), 'LDFLAGS': ' '.join(self._ldflags), 'RCFLAGS': ' '.join(self._rcflags), + 'CPPFLAGS': ' '.join(self._cflags), }) return env def _configure(self) -> None: - subprocess.check_call(['autoreconf', '-vfi'], cwd=self._source_dir) - build_platform = subprocess.check_output( - ['./config.guess'], cwd=self._source_dir).decode().strip() - config_flags = [ - f'--prefix={self._install_dir}', - f'--build={build_platform}', - f'--host={self.target_platform}', - '--enable-shared', - '--without-ensurepip', - '--enable-loadable-sqlite-extensions', - ] - cmd = [str(self._source_dir / 'configure')] + config_flags - subprocess.check_call(cmd, env=self._env, cwd=self._build_dir) + return + + def _clean_patches(self) -> None: + subprocess.check_call(['git', 'reset', '--hard', 'HEAD'], cwd=self._source_dir) + subprocess.check_call(['git', 'clean', '-df'], cwd=self._source_dir) def _pre_build(self) -> None: - if self._mingw_ignore_file.is_file(): + if self._patch_ignore_file.is_file(): self._logger.warning('Patches for Python have being applied, skip patching') return @@ -132,7 +107,7 @@ class MinGWPythonBuilder: return for patch in self._patch_dir.iterdir(): - if patch.is_file(): + if patch.is_file() and patch.name in self.patches: cmd = [ 'git', 'apply', str(patch) ] subprocess.check_call(cmd, cwd=self._source_dir) @@ -142,8 +117,8 @@ class MinGWPythonBuilder: shutil.rmtree(self._build_dir) if self._install_dir.exists(): shutil.rmtree(self._install_dir) - self._build_dir.mkdir() - self._install_dir.mkdir() + self._build_dir.mkdir(parents=True) + self._install_dir.mkdir(parents=True) self._configure() self._install() @@ -194,6 +169,70 @@ class MinGWPythonBuilder: for cache_dir in pycaches: shutil.rmtree(cache_dir) + @property + def install_dir(self) -> str: + return str(self._install_dir) + + +class MinGWPythonBuilder(PythonBuilder): + def __init__(self, build_config) -> None: + super().__init__(build_config) + + self.target_platform = "x86_64-w64-mingw32" + self.patches = ["cpython_mingw_v3.10.2.patch"] + + self._mingw_install_dir = self._out_dir / 'mingw' / build_config.MINGW_TRIPLE + self._build_dir = self._out_dir / 'python-windows-build' + self._install_dir = self._out_dir / 'python-windows-install' + + # This file is used to detect whether patches are applied + self._patch_ignore_file = self._source_dir / 'mingw_ignorefile.txt' + + + for directory in (self._clang_toolchain_dir, self._mingw_install_dir, + self._source_dir): + if not directory.is_dir(): + raise ValueError(f'No such directory "{directory}"') + + @property + def _cflags(self) -> List[str]: + cflags = [ + f'-target {self.target_platform}', + f'--sysroot={self._mingw_install_dir}', + ] + return cflags + + @property + def _ldflags(self) -> List[str]: + ldflags = [ + f'--sysroot={self._mingw_install_dir}', + f'-rtlib=compiler-rt', + f'-target {self.target_platform}', + f'-lucrt', + f'-lucrtbase', + f'-fuse-ld=lld', + ] + return ldflags + + @property + def _rcflags(self) -> List[str]: + return [ f'-I{self._mingw_install_dir}/include' ] + + def _configure(self) -> None: + subprocess.check_call(['autoreconf', '-vfi'], cwd=self._source_dir) + build_platform = subprocess.check_output( + ['./config.guess'], cwd=self._source_dir).decode().strip() + config_flags = [ + f'--prefix={self._install_dir}', + f'--build={build_platform}', + f'--host={self.target_platform}', + '--enable-shared', + '--without-ensurepip', + '--enable-loadable-sqlite-extensions', + ] + cmd = [str(self._source_dir / 'configure')] + config_flags + subprocess.check_call(cmd, env=self._env, cwd=self._build_dir) + def prepare_for_package(self) -> None: self._clean_bin_dir() self._clean_share_dir() @@ -215,6 +254,71 @@ class MinGWPythonBuilder: ] + [ f.name for f in self._install_dir.iterdir() ] subprocess.check_call(cmd, cwd=self._install_dir) + +class OHOSPythonBuilder(PythonBuilder): + def __init__(self, build_utils, target_platform) -> None: + super().__init__(build_utils.build_config) + + self.target_platform = target_platform + self.patches = ["cross_compile_support_ohos.patch"] + + self._build_dir = Path(build_utils.merge_python_build_dir(target_platform)) + self._install_dir = Path(build_utils.merge_python_install_dir(target_platform)) + + # This file is used to detect whether patches are applied + self._patch_ignore_file = self._source_dir / 'support_ohos_ignorefile.txt' + + self.build_utils = build_utils + return + @property - def install_dir(self) -> str: - return str(self._install_dir) + def _cflags(self) -> List[str]: + cflags = [ + f'--target={self.target_platform}', + '-nostdinc', + '-I%s' % str(self._out_dir / 'sysroot' / self.target_platform / 'usr' / 'include'), + ] + if str(self.target_platform).find("arm") > 0: + cflags.append('-march=armv7-a -mfloat-abi=soft') + return cflags + + @property + def _ldflags(self) -> List[str]: + ldflags = [ + f'-rtlib=compiler-rt', + f'--target={self.target_platform}', + f'-fuse-ld=lld', + '-L%s' % str(self._out_dir / 'sysroot' / self.target_platform / 'usr' / 'lib'), + '-lc', + '-Wl,-rpath,\\$$ORIGIN/../lib', + ] + return ldflags + + def _configure(self) -> None: + subprocess.check_call(['autoreconf', '-vfi'], cwd=self._source_dir) + build_platform = subprocess.check_output( + ['./config.guess'], cwd=self._source_dir).decode().strip() + config_flags = [ + f'--prefix={self._install_dir}', + f'--build={build_platform}', + f'--host={self.target_platform}', + '--enable-shared', + '--without-ensurepip', + '--enable-loadable-sqlite-extensions', + '--disable-ipv6', + 'ac_cv_file__dev_ptmx=no', + 'ac_cv_file__dev_ptc=no', + '--without-system-ffi', + '--enable-optimizations', + '--without-pydebug', + '--without-doc-strings', + '--without-dtrace', + ] + cmd = [str(self._source_dir / 'configure')] + config_flags + subprocess.check_call(cmd, env=self._env, cwd=self._build_dir) + + def copy_python_to_host(self, install_dir): + libpython = f'libpython{self.build_utils.build_config.LLDB_PY_VERSION}.so.1.0' + + shutil.copyfile(os.path.join(self._install_dir, "lib", libpython), os.path.join(install_dir, 'lib', libpython)) + self.build_utils.check_copy_tree(self._install_dir, os.path.join(install_dir, self.build_utils.build_config.LLDB_PYTHON))