def test_normalize_toolset_spec(self): # create a default toolset to be able to test _normalize_toolset_spec(). ts = bldtools.Toolset(self._sys_info) self.assertEqual(ts._normalize_toolset_spec('clang++'), 'clang') self.assertEqual(ts._normalize_toolset_spec('clang++-3.5'), 'clang-3.5') self.assertEqual(ts._normalize_toolset_spec('g++'), 'gcc') self.assertEqual(ts._normalize_toolset_spec('g++-4.9'), 'gcc-4.9')
def _create_compiler_info(self, toolset_str, target_arch): if self._sys_info.is_cray(): return self._create_cray_compiler_info(target_arch) compiler_info = CMakeCompilerInfo() if toolset_str and (toolset_str.endswith('.cmake')): # toolchain file specified -> no need to add any furter compiler details compiler_info.cmake_toolchain_file = toolset_str return compiler_info # native compiler selected or assumed, figure out details to create the build tree folder. compiler_info.target_arch = target_arch re_msvc_version = re.compile(r'msvc-(\d+\.\d+)$') re_match = re_msvc_version.match(toolset_str) if re_match: compiler_info.compiler_family = 'msvc' compiler_info.version_major_minor = ver.version_tuple_from_str(re_match.group(1)) return compiler_info else: assert not toolset_str.startswith('msvc') bb_toolset_info = bldtools.Toolset(self._sys_info, toolset_str) compiler_info.compiler_family = bb_toolset_info.get_toolset() compiler_info.version_major_minor = bb_toolset_info.get_version()[:2] # re_toolset_versioned = re.compile('([a-z]+)-(\d+\.\d+)$') if self._sys_info.get_platform() == 'linux': if toolset_str != 'gcc': compiler_info.cmake_cxx_compiler = bb_toolset_info.get_compiler_command() cxx_basename = os.path.basename(compiler_info.cmake_cxx_compiler) # print("cxx_basename: ", cxx_basename) if compiler_info.compiler_family == 'gcc': gcc_basename = cxx_basename.replace('g++', 'gcc') compiler_info.cmake_c_compiler = os.path.join(os.path.dirname(compiler_info.cmake_cxx_compiler), gcc_basename) elif compiler_info.compiler_family == 'clang': clang_basename = cxx_basename.replace('++', '') compiler_info.cmake_c_compiler = os.path.join(os.path.dirname(compiler_info.cmake_cxx_compiler), clang_basename) elif compiler_info.compiler_family == 'intel': compiler_info.cmake_c_compiler = os.path.join(os.path.dirname(compiler_info.cmake_cxx_compiler), 'icc') elif self._sys_info.get_platform() == 'macosx': # assert compiler_info.compiler_family == 'clang' if compiler_info.compiler_family == 'clang': pass elif compiler_info.compiler_family == 'intel': compiler_info.cmake_cxx_compiler = bb_toolset_info.get_compiler_command() compiler_info.cmake_c_compiler = os.path.join(os.path.dirname(compiler_info.cmake_cxx_compiler), 'icc') else: assert False elif self._sys_info.get_platform() == 'windows': if compiler_info.compiler_family == 'msvc': pass elif compiler_info.compiler_family == 'gcc': # MinGW as native compiler: 64 bit and 32 bit default targets are possible. compiler_info.mingw = bb_toolset_info.is_mingw() compiler_info.target_arch = bb_toolset_info.get_platform_info(0).get_target_arch(0) elif compiler_info.compiler_family == 'intel': compiler_info.target_arch = bb_toolset_info.get_platform_info(0).get_target_arch(0) else: assert False return compiler_info
def test_gcc_thread_model(self): if self._sys_info.is_linux(): ts = bldtools.Toolset(self._sys_info) mingw_cmd = os.path.join('/usr', 'bin', 'x86_64-w64-mingw32-g++-win32') if os.path.exists(mingw_cmd): self.assertEqual(ts._get_gcc_thread_model(mingw_cmd), 'win32') mingw_cmd = os.path.join('/usr', 'bin', 'x86_64-w64-mingw32-g++-posix') if os.path.exists(mingw_cmd): self.assertEqual(ts._get_gcc_thread_model(mingw_cmd), 'posix') else: mingw_cmd = os.path.join('/usr', 'bin', 'x86_64-w64-mingw32-g++') if os.path.exists(mingw_cmd): self.assertEqual(ts._get_gcc_thread_model(mingw_cmd), 'posix')
def build_boost(self, build_params): #print("BoostBuilder.build_boost() starting ...") # extract the boost version boost_version = get_boost_version(build_params.boost_dir) self._boost_version = boost_version # print("BoostBuilder: boost version:", boost_version) # check the boost version against the minimal version we support if ver.version_compare(boost_version, self._min_boost_version) < 0: raise Exception( "The boost version " + ver.version_tuple_to_str(boost_version) + " is not supported anymore, please contact technical support.") # construct a new toolset toolset = bldtools.Toolset(self._sys_info, build_params.toolset, build_params.cxx_runtime) self._toolset = toolset if toolset.get_toolset() == 'intel': if self._sys_info.is_windows(): # Update MSVC environment to be used with the Intel compiler if build_params.msvc_rt is None: # Use latest MSVC by default msvc_registry = bldtools.MsvcRegistry() msvc_version = msvc_registry.get_latest_version() build_params.msvc_rt = "msvc-%d.%d" % (msvc_version[0], msvc_version[1]) # self._intel_msvc_suffix = self._intel_msvc_suffix_dict[ build_params.msvc_rt] elif self._sys_info.is_macosx(): if ver.version_compare(boost_version, (1, 66, 0)) == 0: # Is intel-darwin.jam patched? intel_darwin_boost = os.path.join(build_params.boost_dir, 'tools', 'build', 'src', 'tools', 'intel-darwin.jam') intel_darwin_patched = os.path.join( util.get_top_dir(), 'CMakeBuild', 'patches', 'Boost', ver.version_tuple_to_str(boost_version), 'tools', 'build', 'src', 'tools', 'intel-darwin.jam') assert os.path.exists(intel_darwin_boost) assert os.path.exists(intel_darwin_patched) if not filecmp.cmp(intel_darwin_boost, intel_darwin_patched, shallow=False): raise Exception( """intel-darwin.jam requires a patch. Consider a manual update: cp %s %s or contact technical support. """ % (intel_darwin_patched, intel_darwin_boost)) platform_info = toolset.get_platform_info(build_params.platform_index) if (platform_info.get_target_os() == 'macosx') and (build_params.macosx_version_min is None): # At times Xcode ships with OSX SDK version > macosx version, this is not permitted by default. if ver.version_compare(platform_info.get_sdk_version(), self._sys_info.get_os_version()) > 0: build_params.macosx_version_min = self._sys_info.get_os_version( )[:2] # check the optional target if build_params.targets: for target in build_params.targets: if target not in platform_info.get_target_arch(): raise Exception( "The target " + target + " is not supported. Please check target and toolset.") else: # no target(s) specified, use the defaults if toolset.get_toolset() == 'msvc': build_params.targets = list(platform_info.get_target_arch()) elif platform_info.get_target_os() in [ 'iphone', 'iphonesimulator' ]: if build_params.macosx_version_min: target_os_version = build_params.macosx_version_min else: target_os_version = platform_info.get_target_os_version() if ver.version_compare(target_os_version, (11, 0)) >= 0: # No support for 32 bit IOS targets anymore. if platform_info.get_target_os() == 'iphone': build_params.targets = ['arm64'] elif platform_info.get_target_os() == 'iphonesimulator': build_params.targets = ['x86_64'] else: assert False else: if platform_info.get_target_os() == 'iphone': build_params.targets = ['arm64', 'armv7'] elif platform_info.get_target_os() == 'iphonesimulator': build_params.targets = ['x86_64', 'x86'] else: assert False else: build_params.targets = [platform_info.get_target_arch(0)] # update the build parameters given the attributes of the toolset. self._update_build_params(toolset, build_params) #print(build_params) #return boost_lib_files_missing = False lib_dir_list = [] if build_params.rebuild_all: boost_lib_files_missing = True if not build_params.dry_run: for target in build_params.targets: if platform_info.get_target_os() == 'windows': bin_dir = self.get_boost_bin_dir( build_params.boost_dir, toolset, build_params.platform_index, target) if os.path.exists(bin_dir): shutil.rmtree(bin_dir) lib_dir = self.get_boost_lib_dir( build_params.boost_dir, toolset, build_params.platform_index, target) lib_dir_list.append(lib_dir) if os.path.exists(lib_dir): shutil.rmtree(lib_dir) else: for target in build_params.targets: lib_dir = self.get_boost_lib_dir(build_params.boost_dir, toolset, build_params.platform_index, target) lib_dir_list.append(lib_dir) if not os.path.exists(lib_dir): boost_lib_files_missing = True if boost_lib_files_missing: self._build_libs(boost_version, toolset, build_params) if not build_params.dry_run: if self._sys_info.is_macosx(): if len(build_params.targets) > 1: # create a fat binary/universal library file fat_binary_tool = bldtools.FatBinaryTool() platform_info = toolset.get_platform_info( build_params.platform_index) assert ((platform_info.get_target_os() == 'iphone') or (platform_info.get_target_os() == 'iphonesimulator')) src_lib_dirs = [] for target in build_params.targets: lib_dir = self.get_boost_lib_dir( build_params.boost_dir, toolset, build_params.platform_index, target) src_lib_dirs.append(lib_dir) dst_lib_dir = self.get_boost_lib_dir( build_params.boost_dir, toolset, build_params.platform_index, 'combined') if os.path.exists(dst_lib_dir): shutil.rmtree(dst_lib_dir) fat_binary_tool.createLibs(src_lib_dirs, dst_lib_dir) # if ver.version_compare( (1, 59, 0), self._boost_version) > 0: platform_info = toolset.get_platform_info( build_params.platform_index) if platform_info.get_target_os() == 'macosx': lib_dir = self.get_boost_lib_dir( build_params.boost_dir, toolset, build_params.platform_index, build_params.targets[0]) print( "Checking install names and dependencies in " + lib_dir) dylib_list = glob.glob(lib_dir + '/*.dylib') inst_name_inspector = bldtools.DyLibInstallNameInfoInspector( ) for dylib in dylib_list: inst_name_info = inst_name_inspector.create_install_name_info( dylib) if not inst_name_info.inst_name.startswith( '@rpath/'): inst_name_inspector.modify_install_name( dylib, os.path.join('@rpath', inst_name_info.basename)) # Walk the dependency list and change all boost libraries from libboost_NNN.dylib to @rpath/libboost_NNN.dylib. depends_dict = {} for libname in inst_name_info.depends_list: if libname.startswith('libboost_'): depends_dict[ libname] = os.path.join( '@rpath', libname) if depends_dict: print("Changing dependencies of " + os.path.basename(dylib)) inst_name_inspector.modify_depends( dylib, depends_dict) print("\n") print( "-------------------- Post build phase --------------------" ) for lib_dir in lib_dir_list: self._list_boost_components(lib_dir) print( "----------------------------------------------------------" ) else: print( "No boost library directories are missing, skipping library build step." ) print("Use --rebuild if you intend to rebuild all libraries.")
def __call__(self): def lowercase_arg(string): return string.lower() _usage = """%(prog)s [options] [toolset] This script lists the toolset properties in a single line separated by a ';'. The description can be easily parsed by Boost.Build jam code to simplify toolset setup. Examples: %(prog)s gcc %(prog)s msvc-12.0 %(prog)s gcc-4.9 %(prog)s --target-os=iphone clang %(prog)s --target-os=iphone --target-arch=armv7 clang %(prog)s --target-os=iphonesimulator clang %(prog)s arm-linux-androideabi-g++ %(prog)s --api-level=19 arm-linux-androideabi-g++ %(prog)s aarch64-linux-android-g++ %(prog)s i686-linux-android-g++ %(prog)s x86_64-linux-android-g++ """ parser = argparse.ArgumentParser(usage=_usage) parser.add_argument( "toolset", action="store", nargs='?', help="optional argument to override the default toolset.") util.app_args_add_log_level(parser) parser.add_argument( "-v", action="store_true", dest="verbose", default=False, help= "enable verbose output suitable for humans. The default format is intended for scripting frameworks like Boost.Build/b2." ) parser.add_argument( "--internal-version", action="store_true", dest="internal_version", default=False, help="list toolset's internal version, supported by msvc-x.y.") parser.add_argument( "--api-level", action="store", dest="api_level", type=int, help= "override the default Android API level, the default is either the latest or fixed when the toolchain has been created." ) parser.add_argument( "--target-os", action="store", dest="target_os", type=lowercase_arg, help= "add a target OS filter, by default all toolset information is emitted." ) parser.add_argument( "--target-arch", action="store", dest="target_arch", type=lowercase_arg, help= "add a target ARCH filter, by default the complete toolset information is emitted." ) parser.add_argument( "--short-path-name", action="store_true", dest="short_path_name", default=False, help="translate the compiler path into a short path on windows.") args = parser.parse_args() # configure the python logger util.app_configure_logging(args.log_level) if args.toolset: ts = bldtools.Toolset(self._sys_info, args.toolset) else: ts = bldtools.Toolset(self._sys_info) if args.api_level: # Override the default Android API level for platform_info in ts.get_platform_info(): platform_info.set_api_level(args.api_level) if args.verbose: print(ts, "\n") #print("Summary: " + ts.get_toolset_info_short()) elif args.internal_version: if ts.get_internal_version(): print(ver.version_tuple_to_str(ts.get_internal_version())) else: if self._sys_info.is_windows() and args.short_path_name: compiler_command = self._sys_info.get_short_path( ts.get_compiler_command()) else: compiler_command = ts.get_compiler_command() if ts.get_toolset() == 'msvc': tvl = list(ts.get_version()) tvl.extend(ts.get_internal_version()) toolset_version = tuple(tvl) else: toolset_version = ts.get_version() toolset_info_list = [ ts.get_toolset(), ver.version_tuple_to_str(toolset_version), compiler_command ] compiler_prefix = ts.get_compiler_prefix() if compiler_prefix is None: toolset_info_list.append('none') else: toolset_info_list.append(compiler_prefix) target_os_arch_list = [] target_os_rtl_list = [] for platform_info in ts.get_platform_info(): target_os = platform_info.get_target_os() if args.target_os and (target_os != args.target_os): # filter out platforms by target_os; e.g. return just the iphone toolset information. continue isysroot = platform_info.get_isysroot() for target_arch in platform_info.get_target_arch(): if args.target_arch and (target_arch != args.target_arch): # filter out target architectures if provided. continue if isysroot: assert self._sys_info.is_macosx() target_os_arch_list.append(target_os + '%' + target_arch + '%' + isysroot) else: if target_os == 'android': target_os_arch_list.append( '%s-%d%%%s' % (target_os, platform_info.get_api_level(), target_arch)) else: target_os_arch_list.append(target_os + '%' + target_arch) if (target_os == 'windows') and (ts.get_toolset() == 'gcc'): # mingw: add runtime library information if available. runtime_libs = platform_info.get_target_runtime_libs( target_arch) if runtime_libs: target_os_rtl_list.append(target_arch + '%' + '@'.join(runtime_libs)) toolset_info_list.append('!'.join(target_os_arch_list)) if target_os_rtl_list: toolset_info_list.append('!'.join(target_os_rtl_list)) else: toolset_info_list.append('none') toolset_info_list.append(ts.get_compiler_tag()) toolset_info_list.append(ts.get_boost_compiler_tag()) print(";".join(toolset_info_list))