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')
Example #2
0
    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')
Example #4
0
    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.")
Example #5
0
    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))