def run(self) -> None: self.compiler_choice.set_compiler( 'clang' if self.compiler_choice.use_only_clang() else 'gcc') if self.args.clean or self.args.clean_downloads: self.fs_layout.clean(self.selected_dependencies, self.args.clean_downloads) self.prepare_out_dirs() os.environ['PATH'] = ':'.join([ os.path.join(self.fs_layout.tp_installed_common_dir, 'bin'), os.path.join(self.fs_layout.tp_installed_llvm7_common_dir, 'bin'), os.environ['PATH'] ]) self.build_one_build_type(BUILD_TYPE_COMMON) build_types = [] if is_linux(): build_types.append(BUILD_TYPE_UNINSTRUMENTED) if self.compiler_choice.use_only_gcc(): if is_linux() and not self.compiler_choice.using_linuxbrew(): # Starting to support ASAN for GCC compilers # (not for the current GCC 5.5 build on Linuxbrew, though). build_types.append(BUILD_TYPE_ASAN) else: if self.compiler_choice.using_linuxbrew() or is_mac(): build_types.append(BUILD_TYPE_CLANG_UNINSTRUMENTED) if is_linux() and not self.args.skip_sanitizers: build_types.append(BUILD_TYPE_ASAN) build_types.append(BUILD_TYPE_TSAN) log(f"Full list of build types: {build_types}") for build_type in build_types: self.build_one_build_type(build_type)
def get_lib_tester() -> LibTestBase: if is_mac(): return LibTestMac() if is_linux(): return LibTestLinux() fatal(f"Unsupported platform: {platform.system()}")
def init_compiler_independent_flags(self, dep: Dependency) -> None: """ Initialize compiler and linker flags for a particular build type. We try to limit this function to flags that will work for most compilers we are using, which include various versions of GCC and Clang. """ self.preprocessor_flags = [] self.ld_flags = [] self.executable_only_ld_flags = [] self.compiler_flags = [] self.c_flags = [] self.cxx_flags = [] self.libs = [] self.add_linuxbrew_flags() for include_dir_component in set([BUILD_TYPE_COMMON, self.build_type]): self.add_include_path( os.path.join(self.fs_layout.tp_installed_dir, include_dir_component, 'include')) self.add_lib_dir_and_rpath( os.path.join(self.fs_layout.tp_installed_dir, include_dir_component, 'lib')) self.compiler_flags += self.preprocessor_flags # -fPIC is there to always generate position-independent code, even for static libraries. self.compiler_flags += [ '-fno-omit-frame-pointer', '-fPIC', '-O2', '-Wall' ] if is_linux(): # On Linux, ensure we set a long enough rpath so we can change it later with chrpath or # a similar tool. self.add_rpath(PLACEHOLDER_RPATH) self.dylib_suffix = "so" elif is_mac(): self.dylib_suffix = "dylib" # YugaByte builds with C++11, which on OS X requires using libc++ as the standard # library implementation. Some of the dependencies do not compile against libc++ by # default, so we specify it explicitly. self.cxx_flags.append("-stdlib=libc++") self.ld_flags += ["-lc++", "-lc++abi"] # Build for macOS Mojave or later. See https://bit.ly/37myHbk self.compiler_flags.append("-mmacosx-version-min=10.14") self.ld_flags.append("-Wl,-headerpad_max_install_names") else: fatal("Unsupported platform: {}".format(platform.system())) # The C++ standard must match CMAKE_CXX_STANDARD in the top-level CMakeLists.txt file in # the YugabyteDB source tree. self.cxx_flags.append('-std=c++14') self.cxx_flags.append('-frtti') if self.build_type == BUILD_TYPE_ASAN: self.compiler_flags += ASAN_FLAGS if self.build_type == BUILD_TYPE_TSAN: self.compiler_flags += TSAN_FLAGS
def detect_clang_version(self) -> None: """ Detects Clang version when the only compiler we are using is Clang. This is needed so we can use versions of components that are part of LLVM's repository that match the version of Clang. """ if is_linux() and self.single_compiler_type == 'clang': self.find_compiler_by_type(self.single_compiler_type) self._identify_compiler_version()
def detect_linuxbrew(self) -> None: self.linuxbrew_dir = None if not is_linux(): log("Not using Linuxbrew -- this is not Linux") return if self.single_compiler_type: log("Not using Linuxbrew, single_compiler_type is set to %s", self.single_compiler_type) return if self.compiler_suffix: log("Not using Linuxbrew, compiler_suffix is set to %s", self.compiler_suffix) return if self.compiler_prefix: compiler_prefix_basename = os.path.basename(self.compiler_prefix) if compiler_prefix_basename.startswith('linuxbrew'): self.linuxbrew_dir = self.compiler_prefix log("Setting Linuxbrew directory based on compiler prefix %s", self.compiler_prefix) if self.linuxbrew_dir is None: linuxbrew_dir_from_env = os.getenv('YB_LINUXBREW_DIR') if linuxbrew_dir_from_env: self.linuxbrew_dir = linuxbrew_dir_from_env log( "Setting Linuxbrew directory based on YB_LINUXBREW_DIR env var: %s", linuxbrew_dir_from_env) if self.linuxbrew_dir: log("Linuxbrew directory: %s", self.linuxbrew_dir) new_path_entry = os.path.join(self.linuxbrew_dir, 'bin') log("Adding PATH entry: %s", new_path_entry) add_path_entry(new_path_entry)
def get_build_types(self) -> List[str]: build_types: List[str] = list(BUILD_TYPES) if is_linux() and self.args.single_compiler_type is not None: build_types.remove(BUILD_TYPE_CLANG_UNINSTRUMENTED) return build_types
def populate_dependencies(self) -> None: # We have to use get_build_def_module to access submodules of build_definitions, # otherwise MyPy gets confused. self.dependencies = [ # Avoiding a name collision with the standard zlib module, hence "zlib_dependency". get_build_def_module('zlib_dependency').ZLibDependency(), get_build_def_module('lz4').LZ4Dependency(), get_build_def_module('openssl').OpenSSLDependency(), get_build_def_module('libev').LibEvDependency(), get_build_def_module('rapidjson').RapidJsonDependency(), get_build_def_module('squeasel').SqueaselDependency(), get_build_def_module('curl').CurlDependency(), get_build_def_module('hiredis').HiRedisDependency(), get_build_def_module('cqlsh').CQLShDependency(), get_build_def_module('redis_cli').RedisCliDependency(), get_build_def_module('flex').FlexDependency(), get_build_def_module('bison').BisonDependency(), get_build_def_module('libedit').LibEditDependency(), get_build_def_module('openldap').OpenLDAPDependency(), ] if is_linux(): self.dependencies += [ get_build_def_module('libuuid').LibUuidDependency(), ] if (not self.compiler_choice.use_only_gcc() and not self.compiler_choice.use_only_clang()): # Old LLVM. We will migrate away from this. self.dependencies += [ get_build_def_module('llvm7').LLVM7Dependency(), get_build_def_module( 'llvm7_libcxx').Llvm7LibCXXDependency(), ] if self.compiler_choice.use_only_clang(): if self.toolchain and self.toolchain.toolchain_type == 'llvm12rc1': # Still use libunwind/libcxxabi libraries from LLVM 11.0.1. TODO: upgrade. llvm_version_str = '11.0.1' else: llvm_version_str = self.compiler_choice.get_llvm_version_str( ) self.dependencies += [ # New LLVM. We will keep supporting new LLVM versions here. get_build_def_module('llvm1x_libunwind'). Llvm1xLibUnwindDependency(version=llvm_version_str), get_build_def_module('llvm1x_libcxx'). Llvm1xLibCxxAbiDependency(version=llvm_version_str), get_build_def_module( 'llvm1x_libcxx').Llvm1xLibCxxDependency( version=llvm_version_str), ] else: self.dependencies.append( get_build_def_module('libunwind').LibUnwindDependency()) self.dependencies.append( get_build_def_module('libbacktrace').LibBacktraceDependency()) self.dependencies += [ get_build_def_module('icu4c').Icu4cDependency(), get_build_def_module('protobuf').ProtobufDependency(), get_build_def_module('crypt_blowfish').CryptBlowfishDependency(), get_build_def_module('boost').BoostDependency(), get_build_def_module('gflags').GFlagsDependency(), get_build_def_module('glog').GLogDependency(), get_build_def_module('gperftools').GPerfToolsDependency(), get_build_def_module('gmock').GMockDependency(), get_build_def_module('snappy').SnappyDependency(), get_build_def_module('crcutil').CRCUtilDependency(), get_build_def_module('libcds').LibCDSDependency(), get_build_def_module('libuv').LibUvDependency(), get_build_def_module( 'cassandra_cpp_driver').CassandraCppDriverDependency(), ]