Example #1
0
 def _get_default_cmake_generator(self):
     if 'DEFAULT_CMAKE_GENERATOR' in os.environ:
         generator_alias = os.environ['DEFAULT_CMAKE_GENERATOR']
         if generator_alias not in self._dict_to_cmake_generator:
             raise Exception(
                 "CMake generator " + generator_alias +
                 " defined by environment variable DEFAULT_CMAKE_GENERATOR is unsupported."
             )
         return generator_alias
     if self._sys_info.get_platform() == 'linux':
         generator_alias = 'umake'
     elif self._sys_info.get_platform() == 'macosx':
         generator_alias = 'xcode'
     elif self._sys_info.get_platform() == 'windows':
         # e.g. 14.2, 14.1, 14.0, 12.0 etc.
         bb_vs_latest_version = self._msvc_registry.get_latest_version()
         if ver.version_compare(bb_vs_latest_version, (14, 2)) == 0:
             generator_alias = 'vs16'
         elif ver.version_compare(bb_vs_latest_version, (14, 1)) == 0:
             generator_alias = 'vs15'
         else:
             generator_alias = 'vs' + str(bb_vs_latest_version[0])
     else:
         assert False
     return generator_alias
Example #2
0
 def _add_cmake_build_jobs_option(self, cmake_argv, generator_alias,
                                  build_jobs):
     cmake_version = self._cmake_finder.get_cmake_version()
     if ver.version_compare(cmake_version, (3, 12)) >= 0:
         assert len(cmake_argv) >= 2
         if build_jobs >= 2:
             if generator_alias.startswith('vs'):
                 self._add_cmake_build_tool_options(
                     cmake_argv, ['/maxcpucount:' + str(build_jobs)])
             else:
                 cmake_argv.insert(2, str(build_jobs))
                 cmake_argv.insert(2, '--parallel')
         elif build_jobs == 0:
             # Use the build engine's native number of jobs.
             cmake_argv.insert(2, '--parallel')
     elif build_jobs >= 2:
         if generator_alias in ['umake', 'ninja']:
             self._add_cmake_build_tool_options(cmake_argv,
                                                ['-j' + str(build_jobs)])
         elif generator_alias.startswith('vs'):
             self._add_cmake_build_tool_options(
                 cmake_argv, ['/maxcpucount:' + str(build_jobs)])
         elif generator_alias == 'xcode':
             self._add_cmake_build_tool_options(
                 cmake_argv,
                 ['-parallelizeTargets', '-jobs',
                  str(build_jobs)])
Example #3
0
 def get_subprocess_devnull(self):
     if ver.version_compare(self._python_version, (3, 3)) >= 0:
         devnull = subprocess.DEVNULL
     else:
         self._logger.debug(
             "attribute subprocess.DEVNULL not available (python < 3.3), using os.devnull instead"
         )
         devnull = self._get_devnull()
     return devnull
 def test_version_compare(self):
     self.assertEqual(
         0,
         ver.version_compare(ver.version_tuple_from_str('10.7.4'),
                             ver.version_tuple_from_str('10.7.4')))
     self.assertEqual(
         1,
         ver.version_compare(ver.version_tuple_from_str('10.7.4'),
                             ver.version_tuple_from_str('10.6.4')))
     self.assertEqual(
         -1,
         ver.version_compare(ver.version_tuple_from_str('10.6.4'),
                             ver.version_tuple_from_str('10.7.4')))
     self.assertEqual(
         -1,
         ver.version_compare(ver.version_tuple_from_str('10.7'),
                             ver.version_tuple_from_str('10.7.4')))
     self.assertEqual(
         1,
         ver.version_compare(ver.version_tuple_from_str('10.7.4'),
                             ver.version_tuple_from_str('10.7')))
     self.assertEqual(
         0,
         ver.version_compare(ver.version_tuple_from_str('10.7.0'),
                             ver.version_tuple_from_str('10.7')))
Example #5
0
 def _get_default_cmake_generator(self):
     if self._sys_info.get_platform() == 'linux':
         generator_alias = 'umake'
     elif self._sys_info.get_platform() == 'macosx':
         generator_alias = 'xcode'
     elif self._sys_info.get_platform() == 'windows':
         # e.g. 14.1, 14.0, 12.0 etc.
         bb_vs_latest_version = self._msvc_registry.get_latest_version()
         if ver.version_compare(bb_vs_latest_version, (14, 1)) == 0:
             generator_alias = 'vs15'
         else:
             generator_alias = 'vs' + str(bb_vs_latest_version[0])
     else:
         assert False
     return generator_alias
Example #6
0
 def _is_vs_64bit_native_toolset_supported(self, generator_alias):
     re_vs_generator = re.compile(r'vs(\d+)$')
     re_match = re_vs_generator.match(generator_alias)
     if not re_match:
         return False
     if not self._prefer_vs_native_toolsets:
         # Visual Studio native 64bit toolchains are disabled
         return False
     if self._sys_info.get_os_arch() != 'x86_64':
         return False
     if int(re_match.group(1), 10) < 12:
         # Visual Studio 11 2012 or earlier don't have native 64 bit toolchains.
         return False
     if ver.version_compare(self._cmake_finder.get_cmake_version(), (3, 8, 0)) < 0:
         # cmake too old to support vs native toolchains.
         return False
     return True
Example #7
0
 def _add_cmake_build_verbosity_option(self, cmake_argv, generator_alias,
                                       verbosity_level):
     if verbosity_level == 'cmake':
         cmake_version = self._cmake_finder.get_cmake_version()
         if ver.version_compare(cmake_version, (3, 14)) >= 0:
             # self._add_cmake_build_tool_options(cmake_argv, ['-v'])
             # -v is a cmake option and not a build tool option and therefore
             # it has to be inserted left of '--'
             if '--' in cmake_argv:
                 index = cmake_argv.index('--')
                 cmake_argv.insert(index, '-v')
             else:
                 cmake_argv.append('-v')
     else:
         if generator_alias.startswith('vs'):
             self._add_cmake_build_tool_options(
                 cmake_argv, ['/verbosity:' + verbosity_level])
 def _create_mk_toolchain_script(self, ndk_root, hash_bang_missing):
     if ver.version_compare(self._ndk_version, (12, 0)) >= 0:
         mk_toolchain_script_basename = 'make_standalone_toolchain.py'
     else:
         mk_toolchain_script_basename = 'make-standalone-toolchain.sh'
     mk_toolchain_script = os.path.join(ndk_root, 'build', 'tools',
                                        mk_toolchain_script_basename)
     # print("mk_toolchain_script: " + mk_toolchain_script)
     assert os.path.exists(mk_toolchain_script)
     if hash_bang_missing:
         mk_toolchain_script_tmp = os.path.join(
             ndk_root, 'build', 'tools', 'make-standalone-toolchain.bash')
         self._add_bash_hash_bang(mk_toolchain_script,
                                  mk_toolchain_script_tmp)
     else:
         mk_toolchain_script_tmp = mk_toolchain_script
     return mk_toolchain_script_tmp
Example #9
0
 def _update_build_params(self, toolset, build_params):
     platform_info = toolset.get_platform_info(build_params.platform_index)
     # modify the build parameters based on the toolset properties
     if platform_info.get_target_os() == 'android':
         if (toolset.get_toolset()
                 == 'gcc') and (ver.version_compare(toolset.get_version(),
                                                    (4, 8)) < 0):
             raise Exception(
                 "This gcc version is not supported on android, use gcc 4.8 or higher to get decent c++11 support."
             )
         build_params.cxx_std = 'c++11'
         if not build_params.boost_with_list:
             # use the standard boost library set for android
             build_params.boost_with_list = self._boost_libs_android
             # TODO: evaluate boost version and add some more libraries
     elif (platform_info.get_target_os()
           == 'iphone') or (platform_info.get_target_os()
                            == 'iphonesimulator'):
         build_params.cxx_std = 'c++11'
         if not build_params.boost_with_list:
             # use the standard boost library set for ios
             build_params.boost_with_list = self._boost_libs_ios
Example #10
0
    def main(self, argv):

        _description = """
This script creates a standalone NDK toolchain to be used with Boost.Build or another build system
outside of the Android SDK/NDK build environment.

        """

        _epilog = """
Examples:

    # create a default set of standalone toolchains
    %(prog)s
    
    # override the default API level
    %(prog)s --api-level=21      
        """
        parser = argparse.ArgumentParser(
            description=_description,
            epilog=_epilog,
            formatter_class=argparse.RawDescriptionHelpFormatter)

        util.app_args_add_log_level(parser)
        parser.add_argument(
            "--unified-headers",
            action="store_true",
            dest="unified_headers",
            default=False,
            help=
            "enable unified headers [valid for NDK r14 and higher, enabled for NDK r15]."
        )
        parser.add_argument(
            "--api-level",
            action="store",
            dest="api_level",
            type=int,
            help="override the default Android API level [default: latest].")
        parser.add_argument(
            "--stl",
            action="store",
            dest="stl",
            choices=['gnustl', 'libc++'],
            default='gnustl',
            help=
            "--stl=libc++ overrides the default c++ runtime, [default: gnustl to be compatible with Qt]."
        )
        parser.add_argument(
            "--inst-dir",
            action="store",
            dest="inst_dir",
            help=
            "specify the directory to save the toolchain, [default: $HOME/bin/ndksa]."
        )
        parser.add_argument(
            "toolchain",
            action="store",
            nargs='?',
            help=
            "specify the NDK toolchain to be converted into a standalone toolchain."
            " Use default to create toolchains for all supported architectures."
        )

        args = parser.parse_args(argv)

        # configure the python logger
        util.app_configure_logging(args.log_level)
        # create the NDK finder
        ndk_finder = pyhhi.build.common.android.NdkFinder()
        ndk_version = ndk_finder.get_ndk_version()
        if ver.version_compare(ndk_version, (15, 0)) >= 0:
            args.unified_headers = True
        if (args.toolchain is None) or (args.toolchain == 'default'):
            for toolchain in [
                    'arm-linux-androideabi-4.9', 'aarch64-linux-android-4.9',
                    'x86-4.9', 'x86_64-4.9'
            ]:
                ndk_finder.create_ndksa_toolchain(
                    toolchain,
                    api_level=args.api_level,
                    ndk_stl=args.stl,
                    inst_dir=args.inst_dir,
                    unified_headers=args.unified_headers)
        else:
            # create the NDK standalone toolchain
            ndk_finder.create_ndksa_toolchain(
                args.toolchain,
                api_level=args.api_level,
                ndk_stl=args.stl,
                inst_dir=args.inst_dir,
                unified_headers=args.unified_headers)

        # list available toolchains
        print('%-42s %s' % (' ', 'Summary'))
        if args.inst_dir is None:
            print('%-42s %s' %
                  ('NDK-SA root:', ndk_finder.get_ndksa_root(None)))
        ndksa_toolchains = ndk_finder.get_ndksa_toolchains(args.stl)
        if ndksa_toolchains:
            print('%-42s %s' % ('Avail. standalone toolchains using ' +
                                args.stl + ':', ' '.join(ndksa_toolchains)))
            if ver.version_compare(ndk_version, (11, 0)) >= 0:
                compiler_flavor = 'clang++'
            else:
                compiler_flavor = 'g++'
            if args.inst_dir is None:
                print('\nExample: boost_install.py toolset=' +
                      ndksa_toolchains[0] + '-' + compiler_flavor)
            else:
                print('\nExample: boost_install.py toolset=' +
                      os.path.join(args.inst_dir, 'bin', ndksa_toolchains[0] +
                                   '-' + compiler_flavor))
            print('\n')
Example #11
0
    def cmakebuild_update(self, params):

        initial_work_dir = os.getcwd()
        # (Re)create GitHelper in case the log level has been changed.
        self._git_helper = vcsutil.GitHelper()
        params = self._check_params(params)
        if params.top_dir is None:
            params.top_dir = util.get_top_dir()
        self._summary_lines = []
        if params.update_prepare:
            print("{}: preparing CMakeBuild update ...".format(self._prog_name))

            cmakebuild_version_current = self._get_current_cmakebuild_version(params.top_dir)
            if cmakebuild_version_current is None:
                print("{}: no existing CMakeBuild version found.".format(params.top_dir))

            if not self._is_workspace_clean(params.top_dir):
                return

            if params.cmakebuild_tag is None:
                cmakebuild_tag = self._git_helper.get_latest_cmakebuild_tag(params.cmakebuild_repo)

                if cmakebuild_version_current and (ver.version_compare(cmakebuild_version_current, ver.version_tuple_from_str(cmakebuild_tag)) == 0):
                    print("{}: CMakeBuild is up to date, nothing to be done.".format(params.top_dir))
                    return
            else:
                # Validate CMakeBuild tag
                cmakebuild_tags = self._git_helper.get_remote_tags(params.cmakebuild_repo)
                if params.cmakebuild_tag not in cmakebuild_tags:
                    raise InvalidInputParameterError("requested tag {0} does not exists in {1}.".format(params.cmakebuild_tag, params.cmakebuild_repo))
                cmakebuild_tag = params.cmakebuild_tag
                if cmakebuild_version_current and (ver.version_compare(ver.version_tuple_from_str(cmakebuild_tag), cmakebuild_version_current) <= 0):
                    print("{}: CMakeBuild is up to date, nothing to be done.".format(params.top_dir))
                    return

            install_dir = os.path.join(params.top_dir, 'build', 'cmakebuild_update')
            self._install_self(install_dir)

            update_script = os.path.join(install_dir, self._prog_name)
            # Prepare execv argument vector to call self with different arguments using the current python executable.
            if self._sys_info.is_windows():
                child_args = [self._sys_info.get_short_path(self._sys_info.get_python_executable())]
            else:
                child_args = [self._sys_info.get_python_executable()]
            child_args.extend([update_script, '--update'])
            if cmakebuild_tag:
                child_args.extend(['-t', cmakebuild_tag])
            if params.cmakebuild_repo:
                child_args.extend(['--cmakebuild-repo', params.cmakebuild_repo])

            # Add currrent log option to child_args[] to propagate the current log option to the child process.
            log_level = self._logger.getEffectiveLevel()
            log_level_str = None
            if log_level == logging.DEBUG:
                log_level_str = 'debug'
            elif log_level == logging.INFO:
                log_level_str = 'info'
            elif log_level == logging.WARNING:
                log_level_str = 'warning'
            elif log_level == logging.ERROR:
                log_level_str = 'error'
            elif log_level == logging.CRITICAL:
                log_level_str = 'critical'
            if log_level_str is not None:
                child_args.append('--log={}'.format(log_level_str))

            child_args.append(params.top_dir)
            os.chdir(params.top_dir)
            if self._sys_info.is_windows():
                # Unfortunately, there are issues with os.execv() on Windows and therefore a subprocess call is used instead.
                util.subproc_check_call_flushed(child_args)
            else:
                # execv() is preferred as the child is likely to remove python files just being executed
                # by the current python process.
                os.execv(child_args[0], child_args)
        else:
            try:
                print("{}: updating CMakeBuild in {} to {}".format(self._prog_name, params.top_dir, params.cmakebuild_tag))
                os.chdir(params.top_dir)
                if not self._is_workspace_clean():
                    return

                self._append_item_to_summary("Git workspace:", params.top_dir)
                if self._list_summary:
                    cmakebuild_version_current = self._get_current_cmakebuild_version(params.top_dir)
                    if cmakebuild_version_current is not None:
                        self._append_item_to_summary("Current CMakeBuild version:", "{}-{:d}".format(ver.version_tuple_to_str(cmakebuild_version_current[:3]), cmakebuild_version_current[-1]))
                    self._append_item_to_summary("New CMakeBuild version:", params.cmakebuild_tag)

                # Inventory of CMakeBuild to remember existing directories to be removed later on.
                (git_cmakebuild_dirs, cmakebuild_dirs) = self._get_git_cmakebuild_dirs(params.top_dir)
                if params.cmakebuild_tag in git_cmakebuild_dirs:
                    git_cmakebuild_dirs.remove(params.cmakebuild_tag)
                if params.cmakebuild_tag in cmakebuild_dirs:
                    cmakebuild_dirs.remove(params.cmakebuild_tag)
                # print("found existing Git CMakeBuild subdirs:", git_cmakebuild_dirs)
                # print("found existing CMakeBuild subdirs:", cmakebuild_dirs)

                # Add new CMakeBuild subtree
                self._add_cmakebuild_to_git_repo(params.cmakebuild_tag, params.cmakebuild_repo)

                # Update .svnimportprops in case is does exist.
                svnimportprops_file = os.path.join(params.top_dir, '.svnimportprops')
                svnimportprops_modified = self._update_svnimportprops(svnimportprops_file, params.cmakebuild_tag)

                for dname in git_cmakebuild_dirs:
                    git_argv = [self._git_executable, 'rm', '-r', os.path.join('CMakeBuild', dname)]
                    util.subproc_check_call_flushed(git_argv)
                if svnimportprops_modified or git_cmakebuild_dirs:
                    # Need a git commit if '.svnimportprops' has been updated or git rm -r has been launched.
                    git_comment = []
                    if git_cmakebuild_dirs:
                        git_comment.append("rm -r CMakeBuild/{}".format(','.join(git_cmakebuild_dirs)))
                    if svnimportprops_modified:
                        git_comment.append("modifying {}".format('.svnimportprops'))
                    git_argv = [self._git_executable, 'commit', '-am', '{}: {}'.format(self._prog_name, ', '.join(git_comment))]
                    util.subproc_check_call_flushed(git_argv)

                # Check again to get rid of any python cache files
                cmakebuild_dirs.extend(git_cmakebuild_dirs)
                for dname in cmakebuild_dirs:
                    dname_path = os.path.join(params.top_dir, 'CMakeBuild', dname)
                    if os.path.exists(dname_path):
                        util.rmtree(dname_path)

                print("{}: finished updating CMakeBuild in {} to {}".format(self._prog_name, params.top_dir, params.cmakebuild_tag))

                if self._list_summary:
                    print("\n{0:^80}".format("Summary"))
                    print("{0:^80}".format("======="))
                    for line in self._summary_lines:
                        print(line)
            finally:
                pass
        os.chdir(initial_work_dir)
Example #12
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 #13
0
    def launch_config(self, compiler_info, generator_alias, build_configs,
                      lnk_variant, cmake_argv_optional):
        cur_dir = os.getcwd()
        cmake_argv = []
        if self._is_multi_configuration_generator():
            tmp_build_configs = [build_configs[0]]
        else:
            tmp_build_configs = build_configs
        for cfg in tmp_build_configs:
            b_dir = self._build_tree_info.get_build_dir(cfg, lnk_variant)
            if not os.path.exists(b_dir):
                os.makedirs(b_dir)
            if generator_alias.startswith('vs'):
                if compiler_info.compiler_family == 'msvc':
                    if self._is_vs_64bit_native_toolset_supported(
                            generator_alias):
                        vs_toolset = self._dict_to_vs_platform_toolset[
                            'msvc-' + ver.version_tuple_to_str(
                                compiler_info.version_major_minor
                            )] + ',host=x64'
                    else:
                        vs_toolset = self._dict_to_vs_platform_toolset[
                            'msvc-' + ver.version_tuple_to_str(
                                compiler_info.version_major_minor)]
                elif compiler_info.compiler_family == 'intel':
                    vs_toolset = "Intel C++ Compiler %d.%d" % (
                        compiler_info.version_major_minor[0],
                        compiler_info.version_major_minor[1])
                else:
                    assert False
                cmake_argv = [
                    '-G', self._dict_to_cmake_generator[generator_alias]
                ]
                if generator_alias == 'vs16':
                    if ver.version_compare(compiler_info.version_major_minor,
                                           (19, 20)) < 0:
                        cmake_argv.extend([
                            '-T', self._dict_to_vs_platform_toolset[
                                'msvc-' + ver.version_tuple_to_str(
                                    compiler_info.version_major_minor)]
                        ])
                    if compiler_info.target_arch != 'x86_64':
                        cmake_argv.extend([
                            '-A', self._dict_to_vs_platform_name[
                                compiler_info.target_arch]
                        ])
                else:
                    cmake_argv.extend([
                        '-T', vs_toolset, '-A', self._dict_to_vs_platform_name[
                            compiler_info.target_arch]
                    ])

            elif generator_alias == 'xcode':
                cmake_argv = [
                    '-G', self._dict_to_cmake_generator[generator_alias]
                ]
            elif generator_alias in ['umake', 'mgwmake', 'ninja']:
                cmake_argv = [
                    '-G', self._dict_to_cmake_generator[generator_alias],
                    '-DCMAKE_BUILD_TYPE:STRING=' +
                    self._dict_to_cmake_config[cfg]
                ]
                if compiler_info.is_cross_compiler():
                    cmake_argv.append('-DCMAKE_TOOLCHAIN_FILE:FILEPATH=' +
                                      compiler_info.cmake_toolchain_file)
                else:
                    if compiler_info.cmake_cxx_compiler:
                        cmake_argv.append('-DCMAKE_CXX_COMPILER:FILEPATH=' +
                                          compiler_info.cmake_cxx_compiler)
                    if compiler_info.cmake_c_compiler:
                        cmake_argv.append('-DCMAKE_C_COMPILER:FILEPATH=' +
                                          compiler_info.cmake_c_compiler)
            if cmake_argv_optional:
                # Add any additional arguments to the cmake command line.
                cmake_argv.extend(cmake_argv_optional)
            if lnk_variant == 'shared':
                cmake_argv.append('-DBUILD_SHARED_LIBS:BOOL=ON')
            if self._is_multi_configuration_generator():
                cmake_config_types = [
                    self._dict_to_cmake_config[x]
                    for x in self._default_config_types
                ]
                for b_cfg in build_configs:
                    if b_cfg not in self._default_config_types:
                        cmake_config_types.append(
                            self._dict_to_cmake_config[b_cfg])
                cmake_argv.append('-DCMAKE_CONFIGURATION_TYPES:STRING=' +
                                  ';'.join(cmake_config_types))
            # cmake_argv.append(self._top_dir)
            # print("launch_config(): cmake_args", cmake_argv)
            # print("build dir:", b_dir)
            # print("top dir:", self._top_dir)
            if ver.version_compare(self._cmake_finder.get_cmake_version(),
                                   (3, 13, 0)) >= 0:
                cmake_argv.extend(['-S', self._top_dir, '-B', b_dir])
                retv = self.launch_cmake(cmake_argv)
            else:
                os.chdir(b_dir)
                cmake_argv.append(os.path.relpath(self._top_dir))
                retv = self.launch_cmake(cmake_argv)
                os.chdir(cur_dir)
            if retv != 0:
                sys.exit(1)
    def create_ndksa_toolchain(self,
                               ndk_toolchain,
                               api_level=None,
                               unified_headers=False,
                               ndk_stl='gnustl',
                               ndk_llvm_version=None,
                               inst_dir=None):
        # whether bash scripts have proper hash bang lines or not.
        hash_bang_missing = False
        if ver.version_compare(self._ndk_version, (11, 0)) < 0:
            hash_bang_missing = True
        # ndk_toolchain := arm-linux-androideabi-4.9, arm-linux-androideabi-clang3.6, arm-linux-androideabi
        #               := arm-linux-androideabi-4.9 aarch64-linux-android-4.9 x86-4.9 x86_64-4.9
        ndk_toolchain_parts = ndk_toolchain.split('-')
        if re.match('(clang)?[0-9.]+$', ndk_toolchain_parts[-1]):
            joiner = '-'
            ndk_toolchain_prefix = joiner.join(ndk_toolchain_parts[:-1])
        else:
            ndk_toolchain_prefix = ndk_toolchain
        if ndk_toolchain_prefix in self._ndk_toolchain_dict:
            if inst_dir is None:
                ndksa_inst_dir = os.path.join(
                    self.get_ndksa_root(ndk_stl),
                    self._ndk_toolchain_dict[ndk_toolchain_prefix])
            else:
                ndksa_inst_dir = os.path.join(
                    inst_dir, ndk_stl,
                    self._ndk_toolchain_dict[ndk_toolchain_prefix])
        else:
            raise Exception("The NDK toolchain " + ndk_toolchain +
                            " is not supported.")
        # Create a possibly patched version of the original script which can be invoked from python.
        mk_toolchain_script = self._create_mk_toolchain_script(
            self._ndk_root, hash_bang_missing)
        # build the argument vector
        mk_toolchain_args = [mk_toolchain_script]
        if api_level is None:
            api_level = self.get_api_level_from_platform(
                self._ndk_platforms[-1])

        if (ver.version_compare(self._ndk_version,
                                (14, 0)) >= 0) and (ver.version_compare(
                                    self._ndk_version, (16, 0)) < 0):
            if unified_headers:
                mk_toolchain_args.append('--unified-headers')
        if ver.version_compare(self._ndk_version, (12, 0)) >= 0:
            # NDK 12 comes with a new python script expecting different command line options
            if ndk_toolchain_parts[0] == 'aarch64':
                ndk_arch = 'arm64'
            else:
                ndk_arch = ndk_toolchain_parts[0]
            mk_toolchain_args.append('--arch=' + ndk_arch)
            mk_toolchain_args.append('--api=' + str(api_level))
            # --force -> remove destination directory if it exists.
            mk_toolchain_args.append('--force')
        else:
            ndk_platform = 'android-%d' % api_level
            mk_toolchain_args.append('--platform=' + ndk_platform)
            mk_toolchain_args.append('--toolchain=' + ndk_toolchain)
            if ver.version_compare(self._ndk_version, (11, 0)) < 0:
                if ndk_llvm_version is not None:
                    mk_toolchain_args.append('--llvm-version=' +
                                             ndk_llvm_version)
            else:
                # enable clang by default
                mk_toolchain_args.append('--use-llvm')

        if ndk_stl is not None:
            mk_toolchain_args.append('--stl=' + ndk_stl)
        mk_toolchain_args.append('--install-dir=' + ndksa_inst_dir)
        #print("create_ndksa_toolchain:", mk_toolchain_args)
        #return

        # prepare the destination directory
        if os.path.exists(ndksa_inst_dir):
            shutil.rmtree(ndksa_inst_dir)
        if not os.path.exists(self._ndksa_root):
            os.makedirs(self._ndksa_root)

        print("Launching: " + ' '.join(mk_toolchain_args))
        # and launch the script to create the new toolchain
        subprocess.check_call(mk_toolchain_args)

        if hash_bang_missing:
            if os.path.exists(mk_toolchain_script):
                os.remove(mk_toolchain_script)
            # patch the clang++ shell wrapper to have a hash bang
            self._patch_clang_shell_script(
                os.path.join(
                    ndksa_inst_dir, 'bin',
                    self._ndk_toolchain_dict[ndk_toolchain_prefix] +
                    '-clang++'))
            self._patch_clang_shell_script(
                os.path.join(
                    ndksa_inst_dir, 'bin',
                    self._ndk_toolchain_dict[ndk_toolchain_prefix] + '-clang'))

        # update the list of available toolchains.
        self._ndksa_toolchains[ndk_stl] = self._query_ndksa_toolchains(
            os.path.join(ndksa_inst_dir, '..'))
Example #15
0
    def _build_libs(self, boost_version, toolset, build_params):

        bjam_builder = None
        tmp_dirs = []
        remove_user_config = True

        user_config = os.path.join(self._sys_info.get_home_dir(),
                                   'user-config.jam')
        # check for $HOME/user-config.jam
        if build_params.custom_user_config:
            remove_user_config = False
        else:
            if os.path.exists(user_config):
                raise Exception(
                    "$HOME/user-config.jam exists and may conflict with the current configured toolset to be used to compile the boost libraries."
                )

        platform_info = toolset.get_platform_info(build_params.platform_index)
        try:
            #print("Listing toolset attributes ...")
            #print(toolset)

            # If we don't have a bjam program at this point, it's clear we must build it from the boost source.
            # On windows the boost version matters because vc11 can only be used to build bjam for 1.50.0 or higher.
            bjam_builder = bjambld.BjamBuilder(self._sys_info,
                                               top_dir=build_params.boost_dir,
                                               bb_version=self._boost_version)
            if build_params.dry_run:
                print("dry run: a temporary bjam has to be built from source.")
                # just for the message summary and command lines
                bjam_prog = "b2"
            else:
                bjam_target_arch = 'x86_64'
                if self._sys_info.is_windows() and (ver.version_compare(
                        boost_version, (1, 64, 0)) >= 0):
                    # Boost 1.64.0 and higher comes with build.bat which does not support building a 64 bit b2.
                    bjam_target_arch = 'x86'
                bjam_prog = bjam_builder.build(bjam_target_arch)
                # print("created temporary bjam:", bjam_prog)

                tmp_dirs.append(os.path.join(build_params.boost_dir, 'bin.v2'))
                # The next temporary directory exists in 1.58.0 but not in earlier versions.
                tmp_dirs.append(
                    os.path.join(build_params.boost_dir, 'libs', 'config',
                                 'checks', 'architecture', 'bin'))
                tmp_dirs.append(os.path.join(build_params.boost_dir, 'tmp'))

            # Remove temporary build trees, they might exist if a previous build was terminated by ctrl-c or the user tried a manual build.
            for dir in tmp_dirs[:2]:
                if os.path.exists(dir):
                    print("Removing '" + dir + "' ...")
                    shutil.rmtree(dir)

            bjam_launcher = bjambld.BjamLauncher(self._sys_info)

            if build_params.bjam_jobs is None:
                build_params.bjam_jobs = bjam_launcher.get_optimal_number_bjam_jobs(
                )

            # save the bjam command lines as a single string for logging
            self._bjam_cmd_lines = []
            os.chdir(build_params.boost_dir)

            for target in build_params.targets:
                (bjam_arg_list, user_config_content, setup_cmd_file,
                 setup_cmd_content) = self._compose_bjam_arg_list(
                     bjam_prog, toolset, build_params, target)
                # Remember the complete command line to be included in the final summary message.
                self._bjam_cmd_lines.append(' '.join(bjam_arg_list))
                if user_config_content:
                    if not build_params.dry_run:
                        self._write_tmp_user_config(user_config,
                                                    user_config_content,
                                                    setup_cmd_file,
                                                    setup_cmd_content)
                    self._bjam_cmd_lines.append('<user-config.jam>')
                    self._bjam_cmd_lines.extend(user_config_content)
                    self._bjam_cmd_lines.append('</user-config.jam>')
                    if setup_cmd_file:
                        self._bjam_cmd_lines.append('<' + setup_cmd_file + '>')
                        self._bjam_cmd_lines.extend(setup_cmd_content)
                        self._bjam_cmd_lines.append('</' + setup_cmd_file +
                                                    '>')
                if not build_params.dry_run:
                    bjam_launcher.launch(bjam_arg_list)
                    if platform_info.get_target_os() == 'windows':
                        bin_dir = self.get_boost_bin_dir(
                            build_params.boost_dir, toolset,
                            build_params.platform_index, target)
                        lib_dir = self.get_boost_lib_dir(
                            build_params.boost_dir, toolset,
                            build_params.platform_index, target)
                        self._move_boost_dlls(lib_dir, bin_dir, tmp_dirs[0])
                    # Get rid of the binaries in case multiple targets are selected which may use the same build tree and config check tree.
                    for d in tmp_dirs[:2]:
                        if os.path.exists(d):
                            print("Removing '" + d + "' ...")
                            shutil.rmtree(d)
                if os.path.exists(user_config) and remove_user_config:
                    os.remove(user_config)
        finally:
            if remove_user_config:
                if os.path.exists(user_config):
                    os.remove(user_config)
                if setup_cmd_file and os.path.exists(setup_cmd_file):
                    os.remove(setup_cmd_file)
            if not build_params.debug_configuration:
                for dir in tmp_dirs:
                    if os.path.exists(dir):
                        print("Removing '" + dir + "' ...")
                        shutil.rmtree(dir)
            if bjam_builder is not None:
                # get rid of the temporary bjam executable
                bjam_builder.remove_tmp_files()
Example #16
0
    def _compose_bjam_arg_list(self, bjam_prog, toolset, build_params,
                               target_arch):
        platform_info = toolset.get_platform_info(build_params.platform_index)
        if platform_info.get_target_os() == 'android':
            is_android = True
        else:
            is_android = False
        cflags_list = []
        cxxflags_list = []
        linkflags_list = []

        bjam_common_args = [bjam_prog]

        if build_params.bjam_jobs > 1:
            bjam_common_args.append('-j' + str(build_params.bjam_jobs))
        if build_params.debug_configuration:
            bjam_common_args.append('--debug-configuration')
        bjam_common_args.append('--layout=versioned')
        bjam_common_args.append('--prefix=tmp/dist')
        #if toolset.get_toolset() == 'clang':
        #    if ver.version_compare(toolset.get_version(), (3, 2) ) >= 0:
        #        cxxflags_list.append('-ftemplate-depth=256')
        if platform_info.get_target_os() in [
                'macosx', 'iphone', 'iphonesimulator'
        ]:
            if build_params.max_install_names:
                # macosx specific flag to help the install_name_tool
                linkflags_list.append('-headerpad_max_install_names')
            if build_params.macosx_version_min:
                version_str = ver.version_tuple_to_str(
                    build_params.macosx_version_min)
            else:
                version_str = None
                target_os_ver = platform_info.get_target_os_version()
                if platform_info.get_target_os() == 'macosx':
                    # deployment target cannot be larger than the macosx SDK version.
                    if ver.version_compare(
                            target_os_ver,
                            self._sys_info.get_os_version()) < 0:
                        version_str = ver.version_tuple_to_str(target_os_ver)
                else:
                    # a version hint is required for all portable platforms.
                    version_str = ver.version_tuple_to_str(target_os_ver)
            if version_str:
                if platform_info.get_target_os() == 'macosx':
                    cflags_list.append('-mmacosx-version-min=' + version_str)
                    linkflags_list.append('-mmacosx-version-min=' +
                                          version_str)
                elif platform_info.get_target_os() == 'iphone':
                    cflags_list.append('-miphoneos-version-min=' + version_str)
                    linkflags_list.append('-miphoneos-version-min=' +
                                          version_str)
                elif platform_info.get_target_os() == 'iphonesimulator':
                    cflags_list.append('-mios-simulator-version-min=' +
                                       version_str)
                    linkflags_list.append('-mios-simulator-version-min=' +
                                          version_str)
                else:
                    assert False

        if toolset.get_toolset() == 'clang':
            # For backward compatibility the user may have overridden the default c++ runtime on macosx which is only
            # sensible in c++03 mode.
            # On linux libc++ overrides the default c++ runtime.
            if self._sys_info.is_linux() and build_params.cxx_runtime in [
                    'libc++'
            ]:
                cxxflags_list.append('-stdlib=' + build_params.cxx_runtime)
                linkflags_list.append('-stdlib=' + build_params.cxx_runtime)
            elif self._sys_info.is_macosx() and build_params.cxx_runtime in [
                    'libstdc++'
            ]:
                cxxflags_list.append('-stdlib=' + build_params.cxx_runtime)
                linkflags_list.append('-stdlib=' + build_params.cxx_runtime)

        if toolset.is_mingw():
            if build_params.cxx_runtime == 'shared':
                linkflags_list.append('-shared-libstdc++')
                linkflags_list.append('-shared-libgcc')
            elif build_params.cxx_runtime == 'static':
                linkflags_list.append('-static-libstdc++')
                linkflags_list.append('-static-libgcc')

        bjam_common_args.append('variant=release,debug')
        if is_android:
            bjam_common_args.append('link=static')
        elif platform_info.get_target_os() in ['iphone', 'iphonesimulator']:
            bjam_common_args.append('link=static')
        else:
            if (toolset.get_toolset() == 'msvc') and (build_params.cxx_runtime
                                                      == 'static'):
                # Experimental feature to build the static boost libraries with dependency on the static MSVC runtime.
                bjam_common_args.append('link=static')
                bjam_common_args.append('runtime-link=static')
            else:
                bjam_common_args.append('link=static,shared')
        bjam_common_args.append('install')

        if build_params.boost_with_list:
            boost_with_list = list(build_params.boost_with_list)
        else:
            boost_with_list = []
        bjam_arg_list = []
        bjam_arg_list.extend(bjam_common_args)

        if toolset.get_toolset() == 'msvc':
            # On windows msvc-x.y selects the VS compiler.
            bjam_arg_list.append('toolset=' + toolset.get_toolset_versioned())
        else:
            bjam_arg_list.append('toolset=' + toolset.get_toolset())

        boost_lib_dir = self.get_boost_lib_dir(build_params.boost_dir, toolset,
                                               build_params.platform_index,
                                               target_arch)
        boost_lib_dir = os.path.relpath(boost_lib_dir, build_params.boost_dir)
        bjam_arg_list.append('--libdir=' + boost_lib_dir)
        if is_android:
            # The NDK cross compilers generate position independent code by default, some do -fpic and others -fPIC.
            bjam_arg_list.append('target-os=android')
        elif self._sys_info.is_linux():
            if toolset.get_toolset() == 'gcc':
                if toolset.is_mingw():
                    if ver.version_compare(self.get_boost_version(),
                                           (1, 66, 0)) >= 0:
                        # Boost 1.66.0 and higher
                        if target_arch == 'x86_64':
                            bjam_arg_list.append('address-model=64')
                        elif target_arch == 'x86':
                            bjam_arg_list.append('address-model=32')
                    bjam_arg_list.append('target-os=windows')
                    bjam_arg_list.append('threadapi=win32')
                elif platform_info.get_target_arch(0) in ['arm', 'aarch64']:
                    # is this really supported by every arm compiler?
                    cflags_list.append('-fPIC')
                else:
                    cflags_list.append('-fPIC')
                    assert self._sys_info.get_os_arch() == target_arch
            elif toolset.get_toolset() == 'clang':
                cflags_list.append('-fPIC')
            elif toolset.get_toolset() == 'intel':
                cflags_list.append('-fPIC')
            else:
                assert False
        elif self._sys_info.is_windows():
            if ver.version_compare(self.get_boost_version(), (1, 66, 0)) >= 0:
                # Boost 1.66.0 and higher
                if target_arch == 'x86_64':
                    bjam_arg_list.append('address-model=64')
                elif target_arch == 'x86':
                    bjam_arg_list.append('address-model=32')
            else:
                if toolset.is_mingw():
                    if (target_arch == 'x86') and (
                            target_arch != platform_info.get_target_arch(0)):
                        bjam_arg_list.append('address-model=32')
                elif toolset.get_toolset() == 'msvc':
                    # Assume this compiler is a msvc-x.y variant.
                    if target_arch == 'x86_64':
                        bjam_arg_list.append('address-model=64')
        elif self._sys_info.is_macosx():
            # target-os=iphonesimulator is undefined in Boost.Build inside the BOOST SDK tree.
            # target-os=iphone does not define dylib as the shared library suffix inside the BOOST SDK tree.
            #if platform_info.get_target_os() == 'iphone':
            #    bjam_arg_list.append('target-os=' + platform_info.get_target_os())
            pass
        else:
            assert False

        if build_params.cxx_std is not None:
            re_std = re.compile(r'c\+\+(\d+)$')
            re_match = re_std.match(build_params.cxx_std)
            if not re_match:
                raise Exception("C++ standard specification " +
                                build_params.cxx_std + " is not supported.")
            if toolset.get_toolset() in ['gcc', 'clang', 'intel']:
                if ver.version_compare(self._boost_version, (1, 66, 0)) >= 0:
                    bjam_arg_list.append('cxxstd=' + re_match.group(1))
                else:
                    cxxflags_list.append('-std=' + build_params.cxx_std)
        build_boost_python = False
        if build_params.build_python:
            build_boost_python = self._is_boost_python_enabled(
                toolset, build_params.platform_index, target_arch)
        if boost_with_list:
            for item in boost_with_list:
                bjam_arg_list.append('--with-' + item)
        else:
            # add --without-xxx arguments which cannot be combined with --with-xxx
            if toolset.is_mingw():
                bjam_arg_list.append('--without-locale')
            if not build_boost_python:
                bjam_arg_list.append('--without-python')
            if not build_params.build_mpi:
                bjam_arg_list.append('--without-mpi')
        if build_params.custom_user_config:
            user_config_content = []
            setup_cmd_file = None
            setup_cmd_content = []
        else:
            (user_config_content, setup_cmd_file,
             setup_cmd_content) = self._create_user_config_content(
                 toolset,
                 build_params.platform_index,
                 target_arch,
                 build_params.build_mpi,
                 build_boost_python,
                 cppflags=cxxflags_list,
                 cflags=cflags_list,
                 lflags=linkflags_list,
                 msvc_rt=build_params.msvc_rt)
        return bjam_arg_list, user_config_content, setup_cmd_file, setup_cmd_content
    def build(self, target_arch='x86_64'):
        """Builds the b2 executable from source and returns the full path to the executable."""
        assert self._bjam_src_dir is not None
        if self._sys_info.is_windows() and (ver.version_compare(
                self._bb_version, (1, 66, 0)) >= 0):
            target_arch = 'x86'
        # create a new list of temporary directories to be removed after the bjam executable has been installed.
        self._tmp_dirs = []

        bjam_bin_dir = os.path.join(self._bjam_src_dir,
                                    self._get_bjam_bin_dir_folder(target_arch))
        self._tmp_dirs.append(bjam_bin_dir)

        b2_prog_path = os.path.join(bjam_bin_dir, self._bjam_names[0])
        bjam_prog_path = os.path.join(bjam_bin_dir, self._bjam_names[1])

        bootstrap_dir = os.path.join(self._bjam_src_dir, 'bootstrap')
        self._tmp_dirs.append(bootstrap_dir)

        if os.path.exists(bootstrap_dir):
            # in case a previous build failed to remove the temporary files, remove bootstrap completely.
            shutil.rmtree(bootstrap_dir)

        cur_dir = os.getcwd()
        os.chdir(self._bjam_src_dir)

        print("========================================================")
        print("Start building bjam in", self._bjam_src_dir, "...")
        print("========================================================")

        build_script_args = []
        if self._sys_info.is_windows():
            build_script = os.path.join(self._bjam_src_dir, 'build.bat')
            build_script_args.append(build_script)
            bjam_toolset_arg = self._toolset.get_bjam_toolset(
                build_script_format=True)
            build_script_args.append(bjam_toolset_arg)

            if target_arch == 'x86_64':
                # build.bat builds a 32 bit b2 executable by default but we prefer a native b2.
                if bjam_toolset_arg in ['vc141', 'vc14']:
                    build_script_args.append('amd64')
                else:
                    build_script_args.append('x86_amd64')
        else:
            build_script = os.path.join(self._bjam_src_dir, 'build.sh')
            build_script_args.append(build_script)

        retv = subprocess.call(build_script_args)
        if retv != 0:
            raise Exception(
                "Building bjam failed. Please contact technical support.")

        # restore the previous current working directory
        os.chdir(cur_dir)

        if os.path.exists(b2_prog_path):
            return b2_prog_path
        elif os.path.exists(bjam_prog_path):
            return bjam_prog_path
        else:
            assert False
            return None
Example #18
0
 def is_python3(self):
     return ver.version_compare(self._python_version, (3, 0)) >= 0