Example #1
0
class Stage1Builder(base_builders.LLVMBuilder):
    name: str = 'stage1'
    install_dir: Path = paths.OUT_DIR / 'stage1-install'
    build_android_targets: bool = False
    config_list: List[configs.Config] = [configs.host_config()]

    @property
    def llvm_targets(self) -> Set[str]:
        if self.build_android_targets:
            return constants.HOST_TARGETS | constants.ANDROID_TARGETS
        else:
            return constants.HOST_TARGETS

    @property
    def llvm_projects(self) -> Set[str]:
        proj = {'clang', 'lld', 'libcxxabi', 'libcxx', 'compiler-rt'}
        if self.build_lldb:
            proj.add('lldb')
        return proj

    @property
    def ldflags(self) -> List[str]:
        ldflags = super().ldflags
        # Use -static-libstdc++ to statically link the c++ runtime [1].  This
        # avoids specifying self.toolchain.lib_dir in rpath to find libc++ at
        # runtime.
        # [1] libc++ in our case, despite the flag saying -static-libstdc++.
        ldflags.append('-static-libstdc++')
        return ldflags

    @property
    def cmake_defines(self) -> Dict[str, str]:
        defines = super().cmake_defines
        defines['CLANG_ENABLE_ARCMT'] = 'OFF'
        defines['CLANG_ENABLE_STATIC_ANALYZER'] = 'OFF'

        defines['LLVM_BUILD_TOOLS'] = 'ON'

        # Make libc++.so a symlink to libc++.so.x instead of a linker script that
        # also adds -lc++abi.  Statically link libc++abi to libc++ so it is not
        # necessary to pass -lc++abi explicitly.  This is needed only for Linux.
        if self._config.target_os.is_linux:
            defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF'
            defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON'

        # Do not build compiler-rt for Darwin.  We don't ship host (or any
        # prebuilt) runtimes for Darwin anyway.  Attempting to build these will
        # fail compilation of lib/builtins/atomic_*.c that only get built for
        # Darwin and fail compilation due to us using the bionic version of
        # stdatomic.h.
        if self._config.target_os.is_darwin:
            defines['LLVM_BUILD_EXTERNAL_COMPILER_RT'] = 'ON'

        # Don't build libfuzzer as part of the first stage build.
        defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF'

        return defines
Example #2
0
class LibNcursesBuilder(base_builders.AutoconfBuilder, base_builders.LibInfo):
    name: str = 'libncurses'
    src_dir: Path = paths.LIBNCURSES_SRC_DIR
    config_list: List[configs.Config] = [configs.host_config()]
    lib_version: str = '6'

    @property
    def config_flags(self) -> List[str]:
        return super().config_flags + [
            '--with-shared',
        ]

    @property
    def _lib_names(self) -> List[str]:
        return ['libncurses', 'libform', 'libpanel']
Example #3
0
class LibEditBuilder(base_builders.AutoconfBuilder):
    name: str = 'libedit'
    src_dir: Path = paths.LIBEDIT_SRC_DIR
    config_list: List[configs.Config] = [configs.host_config()]

    def install(self) -> None:
        super().install()
        if self._config.target_os.is_darwin:
            # Updates LC_ID_DYLIB so that users of libedit won't link with absolute path.
            libedit_path = paths.get_libedit_lib(self.install_dir,
                                                 self._config.target_os)
            cmd = [
                'install_name_tool', '-id', f'@rpath/{libedit_path.name}',
                str(libedit_path)
            ]
            utils.check_call(cmd)
Example #4
0
class LibXml2Builder(base_builders.CMakeBuilder, base_builders.LibInfo):
    name: str = 'libxml2'
    src_dir: Path = paths.LIBXML2_SRC_DIR
    config_list: List[configs.Config] = [configs.host_config()]
    lib_version: str = '2.9.10'

    @contextlib.contextmanager
    def _backup_file(self, file_to_backup: Path) -> Iterator[None]:
        backup_file = file_to_backup.parent / (file_to_backup.name + '.bak')
        if file_to_backup.exists():
            file_to_backup.rename(backup_file)
        try:
            yield
        finally:
            if backup_file.exists():
                backup_file.rename(file_to_backup)

    def build(self) -> None:
        # The src dir contains configure files for Android platform. Rename them
        # so that they will not be used during our build.
        # We don't delete them here because the same libxml2 may be used to build
        # Android platform later.
        with self._backup_file(self.src_dir / 'include' / 'libxml' /
                               'xmlversion.h'):
            with self._backup_file(self.src_dir / 'config.h'):
                super().build()

    @property
    def cmake_defines(self) -> Dict[str, str]:
        defines = super().cmake_defines
        defines['LIBXML2_WITH_PYTHON'] = 'OFF'
        defines['LIBXML2_WITH_PROGRAMS'] = 'OFF'
        defines['LIBXML2_WITH_LZMA'] = 'OFF'
        defines['LIBXML2_WITH_ICONV'] = 'OFF'
        defines['LIBXML2_WITH_ZLIB'] = 'OFF'
        return defines

    @property
    def include_dir(self) -> Path:
        return self.install_dir / 'include' / 'libxml2'

    @property
    def symlinks(self) -> List[Path]:
        if self._config.target_os.is_windows:
            return []
        ext = 'so' if self._config.target_os.is_linux else 'dylib'
        return [self.install_dir / 'lib' / f'libxml2.{ext}']
Example #5
0
class SwigBuilder(base_builders.AutoconfBuilder):
    name: str = 'swig'
    src_dir: Path = paths.SWIG_SRC_DIR
    config_list: List[configs.Config] = [configs.host_config()]

    @property
    def config_flags(self) -> List[str]:
        flags = super().config_flags
        flags.append('--without-pcre')
        return flags

    @property
    def ldflags(self) -> List[str]:
        ldflags = super().ldflags
        # Point to the libc++.so from the toolchain.
        ldflags.append(f'-Wl,-rpath,{self.toolchain.lib_dir}')
        return ldflags
Example #6
0
class LibEditBuilder(base_builders.AutoconfBuilder, base_builders.LibInfo):
    name: str = 'libedit'
    src_dir: Path = paths.LIBEDIT_SRC_DIR
    config_list: List[configs.Config] = [configs.host_config()]
    libncurses: base_builders.LibInfo
    lib_version: str = '0'

    @property
    def ldflags(self) -> List[str]:
        return [
            f'-L{self.libncurses.link_libraries[0].parent}',
        ] + super().ldflags

    @property
    def cflags(self) -> List[str]:
        flags = []
        flags.append('-I' + str(self.libncurses.include_dir))
        flags.append('-I' + str(self.libncurses.include_dir / 'ncurses'))
        return flags + super().cflags

    def build(self) -> None:
        files: List[Path] = []
        super().build()
Example #7
0
class XzBuilder(base_builders.CMakeBuilder, base_builders.LibInfo):
    name: str = 'liblzma'
    src_dir: Path = paths.XZ_SRC_DIR
    config_list: List[configs.Config] = [configs.host_config()]
    static_lib: bool = True
Example #8
0
class Stage2Builder(base_builders.LLVMBuilder):
    name: str = 'stage2'
    install_dir: Path = paths.OUT_DIR / 'stage2-install'
    config_list: List[configs.Config] = [configs.host_config()]
    remove_install_dir: bool = True
    debug_build: bool = False
    build_instrumented: bool = False
    profdata_file: Optional[Path] = None
    lto: bool = True

    @property
    def llvm_targets(self) -> Set[str]:
        return constants.ANDROID_TARGETS

    @property
    def llvm_projects(self) -> Set[str]:
        proj = {
            'clang', 'lld', 'libcxxabi', 'libcxx', 'compiler-rt',
            'clang-tools-extra', 'openmp', 'polly'
        }
        if self.build_lldb:
            proj.add('lldb')
        return proj

    @property
    def env(self) -> Dict[str, str]:
        env = super().env
        # Point CMake to the libc++ from stage1.  It is possible that once built,
        # the newly-built libc++ may override this because of the rpath pointing to
        # $ORIGIN/../lib64.  That'd be fine because both libraries are built from
        # the same sources.
        env['LD_LIBRARY_PATH'] = str(self.toolchain.lib_dir)
        return env

    @property
    def ldflags(self) -> List[str]:
        ldflags = super().ldflags
        if self.build_instrumented:
            # Building libcxx, libcxxabi with instrumentation causes linker errors
            # because these are built with -nodefaultlibs and prevent libc symbols
            # needed by libclang_rt.profile from being resolved.  Manually adding
            # the libclang_rt.profile to linker flags fixes the issue.
            resource_dir = self.toolchain.resource_dir
            ldflags.append(str(resource_dir / 'libclang_rt.profile-x86_64.a'))
        return ldflags

    @property
    def cflags(self) -> List[str]:
        cflags = super().cflags
        if self.profdata_file:
            cflags.append('-Wno-profile-instr-out-of-date')
            cflags.append('-Wno-profile-instr-unprofiled')
        return cflags

    @property
    def cmake_defines(self) -> Dict[str, str]:
        defines = super().cmake_defines
        defines['SANITIZER_ALLOW_CXXABI'] = 'OFF'
        defines['OPENMP_ENABLE_OMPT_TOOLS'] = 'FALSE'
        defines['LIBOMP_ENABLE_SHARED'] = 'FALSE'
        defines['CLANG_PYTHON_BINDINGS_VERSIONS'] = '3'

        if (self.lto and not self._config.target_os.is_darwin
                and not self.build_instrumented and not self.debug_build):
            defines['LLVM_ENABLE_LTO'] = 'Thin'

        # Build libFuzzer here to be exported for the host fuzzer builds. libFuzzer
        # is not currently supported on Darwin.
        if self._config.target_os.is_darwin:
            defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF'
        else:
            defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'ON'

        if self.debug_build:
            defines['CMAKE_BUILD_TYPE'] = 'Debug'

        if self.build_instrumented:
            defines['LLVM_BUILD_INSTRUMENTED'] = 'ON'

            # llvm-profdata is only needed to finish CMake configuration
            # (tools/clang/utils/perf-training/CMakeLists.txt) and not needed for
            # build
            llvm_profdata = self.toolchain.path / 'bin' / 'llvm-profdata'
            defines['LLVM_PROFDATA'] = str(llvm_profdata)
        elif self.profdata_file:
            defines['LLVM_PROFDATA_FILE'] = str(self.profdata_file)

        # Make libc++.so a symlink to libc++.so.x instead of a linker script that
        # also adds -lc++abi.  Statically link libc++abi to libc++ so it is not
        # necessary to pass -lc++abi explicitly.  This is needed only for Linux.
        if self._config.target_os.is_linux:
            defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON'
            defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF'

        # Do not build compiler-rt for Darwin.  We don't ship host (or any
        # prebuilt) runtimes for Darwin anyway.  Attempting to build these will
        # fail compilation of lib/builtins/atomic_*.c that only get built for
        # Darwin and fail compilation due to us using the bionic version of
        # stdatomic.h.
        if self._config.target_os.is_darwin:
            defines['LLVM_BUILD_EXTERNAL_COMPILER_RT'] = 'ON'

        return defines

    def install_config(self) -> None:
        super().install_config()
        lldb_wrapper_path = self.install_dir / 'bin' / 'lldb.sh'
        lib_path_env = 'LD_LIBRARY_PATH' if self._config.target_os.is_linux else 'DYLD_LIBRARY_PATH'
        lldb_wrapper_path.write_text(
            textwrap.dedent(f"""\
            #!/bin/bash
            CURDIR=$(cd $(dirname $0) && pwd)
            export PYTHONHOME="$CURDIR/../python3"
            export {lib_path_env}="$CURDIR/../python3/lib:${lib_path_env}"
            "$CURDIR/lldb" "$@"
        """))
        lldb_wrapper_path.chmod(0o755)
Example #9
0
class Stage1Builder(base_builders.LLVMBuilder):
    name: str = 'stage1'
    toolchain_name: str = 'prebuilt'
    install_dir: Path = paths.OUT_DIR / 'stage1-install'
    build_llvm_tools: bool = False
    build_android_targets: bool = False
    config_list: List[configs.Config] = [configs.host_config()]
    use_goma_for_stage1: bool = False

    @property
    def llvm_targets(self) -> Set[str]:
        if self.build_android_targets:
            return constants.HOST_TARGETS | constants.ANDROID_TARGETS
        else:
            return constants.HOST_TARGETS

    @property
    def llvm_projects(self) -> Set[str]:
        proj = {'clang', 'lld', 'libcxxabi', 'libcxx', 'compiler-rt'}
        if self.build_llvm_tools:
            # For lldb-tblgen. It will be used to build lldb-server and
            # windows lldb.
            proj.add('lldb')
        return proj

    @property
    def ldflags(self) -> List[str]:
        ldflags = super().ldflags
        # Point CMake to the libc++.so from the prebuilts.  Install an rpath
        # to prevent linking with the newly-built libc++.so
        ldflags.append(f'-Wl,-rpath,{self.toolchain.lib_dir}')
        return ldflags

    def set_lldb_flags(self, target: hosts.Host, defines: Dict[str,
                                                               str]) -> None:
        # Disable dependencies because we only need lldb-tblgen to be built.
        defines['LLDB_ENABLE_PYTHON'] = 'OFF'
        defines['LLDB_ENABLE_LIBEDIT'] = 'OFF'

    @property
    def cmake_defines(self) -> Dict[str, str]:
        defines = super().cmake_defines
        defines['CLANG_ENABLE_ARCMT'] = 'OFF'
        defines['CLANG_ENABLE_STATIC_ANALYZER'] = 'OFF'

        if self.build_llvm_tools:
            defines['LLVM_BUILD_TOOLS'] = 'ON'
        else:
            defines['LLVM_BUILD_TOOLS'] = 'OFF'

        # Make libc++.so a symlink to libc++.so.x instead of a linker script that
        # also adds -lc++abi.  Statically link libc++abi to libc++ so it is not
        # necessary to pass -lc++abi explicitly.  This is needed only for Linux.
        if self._config.target_os.is_linux:
            defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF'
            defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON'

        # Do not build compiler-rt for Darwin.  We don't ship host (or any
        # prebuilt) runtimes for Darwin anyway.  Attempting to build these will
        # fail compilation of lib/builtins/atomic_*.c that only get built for
        # Darwin and fail compilation due to us using the bionic version of
        # stdatomic.h.
        if self._config.target_os.is_darwin:
            defines['LLVM_BUILD_EXTERNAL_COMPILER_RT'] = 'ON'

        # Don't build libfuzzer as part of the first stage build.
        defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF'

        return defines

    @property
    def env(self) -> Dict[str, str]:
        env = super().env
        if self.use_goma_for_stage1:
            env['USE_GOMA'] = 'true'
        return env