예제 #1
0
 def _create_build_dir_dict(self, compiler_info, generator_alias, build_configs):
     build_dir_dict = {}
     if compiler_info.is_cross_compiler():
         assert generator_alias == 'umake'
         build_root = self._create_cross_compile_build_dir(self._build_root, compiler_info.cmake_toolchain_file, generator_alias)
         print("cross compile build root: " + build_root)
         if generator_alias == 'umake':
             for cfg in build_configs:
                 build_dir_dict[cfg + '.' + 'static'] = os.path.join(build_root, cfg)
                 build_dir_dict[cfg + '.' + 'shared'] = os.path.join(build_root, cfg + '-shared')
     else:
         target_arch = compiler_info.target_arch
         if compiler_info.mingw:
             toolset_dir = "{}-mingw-{}".format(compiler_info.compiler_family, ver.version_tuple_to_str(compiler_info.version_major_minor))
         else:
             toolset_dir = "{}-{}".format(compiler_info.compiler_family, ver.version_tuple_to_str(compiler_info.version_major_minor))
         if self.is_multi_configuration_generator():
             for cfg in build_configs:
                 build_dir_dict[cfg + '.' + 'static'] = os.path.join(self._build_root, generator_alias, toolset_dir, target_arch)
                 build_dir_dict[cfg + '.' + 'shared'] = os.path.join(self._build_root, generator_alias, toolset_dir, target_arch + '-shared')
         else:
             for cfg in build_configs:
                 build_dir_dict[cfg + '.' + 'static'] = os.path.join(self._build_root, generator_alias, toolset_dir, target_arch, cfg)
                 build_dir_dict[cfg + '.' + 'shared'] = os.path.join(self._build_root, generator_alias, toolset_dir, target_arch, cfg + '-shared')
     return build_dir_dict
예제 #2
0
    def __init__(self, verbosity=1):
        self._logger = logging.getLogger(__name__)
        self._sys_info = SystemInfo()
        self._verbosity_level = verbosity
        self._cmake_finder = CMakeFinder(self._sys_info)
        self._top_dir = None
        self._build_root = None
        self._build_tree_create_if_not_exists = True
        self._build_tree_info = None
        self._deploy_dir = None
        self._script_name = os.path.basename(sys.argv[0])
        self._cmk_cache_file = 'CMakeCache.txt'
        # cache entries the user cannot override via -Dxxx
        self._cmk_reserved_cache_vars = ['BUILD_SHARED_LIBS',
                                         'CMAKE_BUILD_TYPE',
                                         'CMAKE_CONFIGURATION_TYPES',
                                         'CMAKE_CXX_COMPILER',
                                         'CMAKE_C_COMPILER',
                                         'CMAKE_TOOLCHAIN_FILE']
        self._dict_to_cmake_generator = {'umake': 'Unix Makefiles',
                                         'mgwmake': 'MinGW Makefiles',
                                         'ninja': 'Ninja',
                                         'xcode': 'Xcode',
                                         'vs15': 'Visual Studio 15 2017',
                                         'vs14': 'Visual Studio 14 2015',
                                         'vs12': 'Visual Studio 12 2013',
                                         'vs11': 'Visual Studio 11 2012',
                                         'vs10': 'Visual Studio 10 2010'}

        # list of default configuration types for multiconfiguration generators.
        self._default_config_types = ['debug', 'release']
        # self._default_config_types = ['debug', 'release', 'relwithdebinfo']

        self._dict_to_cmake_config = {'debug': 'Debug', 'release': 'Release', 'relwithdebinfo': 'RelWithDebInfo', 'minsizerel': 'MinSizeRel'}
        self._dict_to_vs_platform_name = {'x86_64': 'x64', 'x86': 'Win32'}
        self._prefer_vs_native_toolsets = True
        if self._sys_info.is_windows():
            self._msvc_registry = bldtools.MsvcRegistry()
            self._dict_to_vs_platform_toolset = {'msvc-19.0': 'v140',
                                                 'msvc-18.0': 'v120',
                                                 'msvc-17.0': 'v110',
                                                 'msvc-16.0': 'v100'}
            self._dict_generator_alias_to_msvc_toolsets = {'vs14': ['msvc-19.0', 'msvc-18.0', 'msvc-17.0', 'msvc-16.0'],
                                                           'vs12': ['msvc-18.0', 'msvc-17.0', 'msvc-16.0'],
                                                           'vs11': ['msvc-17.0', 'msvc-16.0'],
                                                           'vs10': ['msvc-16.0']}
            # vs15 has not a fixed compiler version and therefore the mapping is generated dynamically.
            if self._msvc_registry.is_version_installed((14, 1)):
                cl_version = self._msvc_registry.get_compiler_version((14, 1))
                msvc_str = 'msvc-' + ver.version_tuple_to_str(cl_version[:2])
                if cl_version[1] < 20:
                    self._dict_to_vs_platform_toolset[msvc_str] = 'v141'
                    self._dict_generator_alias_to_msvc_toolsets['vs15'] = [msvc_str, 'msvc-19.0', 'msvc-18.0', 'msvc-17.0', 'msvc-16.0']
                else:
                    assert False
예제 #3
0
 def __str__(self):
     if self.cmake_toolchain_file:
         s = "toolchain file: %s\n" % self.cmake_toolchain_file
     else:
         s = "compiler family: %s\n" % self.compiler_family
         s += "compiler version (major.minor): %s\n" % ver.version_tuple_to_str(self.version_major_minor)
         if self.target_arch:
             s += "target arch: %s\n" % self.target_arch
         if self.cmake_cxx_compiler:
             s += "cmake cxx compiler: %s\n" % self.cmake_cxx_compiler
             s += "cmake c compiler:   %s\n" % self.cmake_c_compiler
     return s
예제 #4
0
    def cm_import(self, svn_url):
        assert self._cm_version is not None
        dst_dir_base = os.path.join(self._svn_import_dir,
                                    ver.version_tuple_to_str(self._cm_version))

        # remove the destination directory to get rid of any existing files
        if os.path.exists(dst_dir_base):
            shutil.rmtree(dst_dir_base)
        os.makedirs(dst_dir_base)

        for file_info in self._pkg_file_list:
            # print("Copying " + file_info.cm_file + " -> " + file_info.dst_dir)
            dst_dir = os.path.join(dst_dir_base, file_info.dst_dir)
            if not os.path.exists(dst_dir):
                os.makedirs(dst_dir)
            print("Copying " + os.path.basename(file_info.cm_file) + " -> " +
                  dst_dir)
            shutil.copy(file_info.cm_file, dst_dir)

        svn_import_args = ['svn', 'import', '--no-ignore', '-m']
        # add a standard import comment
        svn_import_args.append(
            "cmsvn_import.py: importing CodeMeter software " +
            ver.version_tuple_to_str(self._cm_version))
        svn_import_args.append(self._svn_import_dir)
        svn_import_args.append(svn_url)

        # print("svn import command:", svn_import_args)
        # print("cmsvn_import.py: starting the import ... ")
        if self._dry_run:
            print("\n*** DRY RUN ***\n" + ' '.join(svn_import_args) + "\n")
        else:
            retv = subprocess.call(svn_import_args)
            if retv != 0:
                raise Exception(
                    "svn import failed, please contact technical support.")

            if os.path.exists(self._svn_import_dir):
                shutil.rmtree(self._svn_import_dir)
예제 #5
0
    def __call__(self):
        parser = argparse.ArgumentParser()

        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."
        )
        parser.add_argument(
            "--ignore-env-vars",
            action="store_false",
            dest="use_env",
            default=True,
            help=
            "disable environment variable ANDROID_NDK_ROOT in finding the desired NDK."
        )

        util.app_args_add_log_level(parser)

        args = parser.parse_args()

        # configure the python logger
        util.app_configure_logging(args.log_level)

        ndk_finder = pyhhi.build.common.android.NdkFinder(args.use_env)
        if args.verbose:
            print('%-42s %s' % ('NDK root:', ndk_finder.get_ndk_root()))
            print('%-42s %s' %
                  ('NDK version:',
                   ver.version_tuple_to_str(ndk_finder.get_ndk_version())))
            print('%-42s %s' %
                  ('NDK-SA root:', ndk_finder.get_ndksa_root(None)))
            print('%-42s %s' %
                  ('Avail. platforms:', ndk_finder.get_ndk_platforms()))
            toolchains = ndk_finder.get_ndksa_toolchains('gnustl')
            if toolchains:
                print(
                    '%-42s %s' %
                    ('Avail. standalone toolchains using gnustl:', toolchains))
            toolchains = ndk_finder.get_ndksa_toolchains('libc++')
            if toolchains:
                print(
                    '%-42s %s' %
                    ('Avail. standalone toolchains using libc++:', toolchains))
예제 #6
0
 def _get_current_cmakebuild_version(self, top_dir):
     assert os.path.exists(top_dir)
     cmakebuild_top_dir = os.path.join(top_dir, 'CMakeBuild')
     if not os.path.exists(cmakebuild_top_dir):
         return None
     re_version_dir = re.compile(r'^\d+[0-9.]+-\d+$')
     version_list = []
     for fname in os.listdir(cmakebuild_top_dir):
         if os.path.isdir(os.path.join(cmakebuild_top_dir, fname)):
             if re_version_dir.match(fname) and os.path.exists(os.path.join(cmakebuild_top_dir, fname, 'CMakeBuild', 'bin', 'cmake.py')):
                 version_list.append(ver.version_tuple_from_str(fname))
     if not version_list:
         return None
     if len(version_list) > 1:
         raise InvalidInputParameterError("Workspace {} contains multiple CMakeBuild versions, please update manually.".format(top_dir))
     self._logger.debug("found CMakeBuild {} in {}".format(ver.version_tuple_to_str(version_list[0]), top_dir))
     return version_list[0]
 def _query_platforms(self, ndk_root):
     platforms_dir = os.path.join(ndk_root, 'platforms')
     assert os.path.exists(platforms_dir)
     re_platform = re.compile('android-(\d+)$')
     # enumerate installed platforms in ascending order.
     version_list = [
         ver.version_tuple_from_str(re_platform.match(d).group(1))
         for d in os.listdir(platforms_dir) if re_platform.match(d)
     ]
     if version_list:
         version_list = ver.version_list_sort(version_list)
         ndk_platforms = [
             'android-' + ver.version_tuple_to_str(version)
             for version in version_list
         ]
         return ndk_platforms
     else:
         assert False
예제 #8
0
 def _is_boost_python_enabled(self, toolset, platform_index, target):
     build_python = False
     platform_info = toolset.get_platform_info(platform_index)
     if toolset.is_mingw() or (platform_info.get_target_os() == 'android'):
         return build_python
     python_version = self._sys_info.get_python_version()
     if platform_info.get_target_os() == 'linux':
         # This is neither mingw or android
         if target in ['x86_64', 'x86']:
             python_header_file = os.path.join(
                 '/usr/include',
                 'python' + ver.version_tuple_to_str(python_version[:2]),
                 'Python.h')
             if os.path.exists(python_header_file):
                 build_python = True
     elif platform_info.get_target_os() == 'macosx':
         #python_header_file = os.path.join('/usr/include', 'python' + ver.version_tuple_to_str(python_version[:2]), 'Python.h')
         #if os.path.exists(python_header_file):
         build_python = True
     elif toolset.get_toolset() == 'msvc':
         # This implies msvc and target either x86 or x86_64.
         if self._sys_info.get_python_arch() == target:
             build_python = True
     return build_python
예제 #9
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], '-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=' + self._dict_to_cmake_config[cfg]
             ]
             if compiler_info.is_cross_compiler():
                 cmake_argv.append('-DCMAKE_TOOLCHAIN_FILE=' +
                                   compiler_info.cmake_toolchain_file)
             else:
                 if compiler_info.cmake_cxx_compiler:
                     cmake_argv.append('-DCMAKE_CXX_COMPILER=' +
                                       compiler_info.cmake_cxx_compiler)
                 if compiler_info.cmake_c_compiler:
                     cmake_argv.append('-DCMAKE_C_COMPILER=' +
                                       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=1')
         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=' +
                               ';'.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)
         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)
예제 #10
0
 def test_cmake_version_parser(self):
     cmk_finder = cmksupp.CMakeFinder()
     for ver_tuple in self._cmk_version_test_set:
         cmk_version = cmk_finder._parse_cmake_version_retv(ver_tuple[0])
         self.assertEqual(ver_tuple[1],
                          ver.version_tuple_to_str(cmk_version))
예제 #11
0
    def main(self, argv):
        parser = argparse.ArgumentParser()
        parser.add_argument(
            "-v",
            "--verbose",
            action="store_true",
            dest="verbose",
            help=
            "enable verbose output suitable for humans. The default format is intended for scripting frameworks like Boost.Build/bjam."
        )
        parser.add_argument("--print-env",
                            action="store_true",
                            dest="print_env",
                            help="print environment variables")

        util.app_args_add_log_level(parser)
        args = parser.parse_args(argv)
        # configure the python logger
        util.app_configure_logging(args.log_level)
        # creates the system info object and performs python version checks
        sys_info = pyhhi.build.common.system.SystemInfo(True)

        if args.verbose:
            print('%-30s %s' %
                  ('python version:',
                   ver.version_tuple_to_str(sys_info.get_python_version())))
            print('%-30s %s' %
                  ('python executable:', sys_info.get_python_executable()))
            if sys_info.is_windows():
                print('%-30s %s' % ('python executable (short path):',
                                    sys_info.get_short_path(
                                        sys_info.get_python_executable())))
                print('%-30s %s' %
                      ('python launcher:', sys_info.get_python_launcher()))
            print('%-30s %s' % ('python implementation:',
                                sys_info.get_python_implementation()))
            print('%-30s %s' %
                  ('python architecture:', sys_info.get_python_arch()))
            if sys_info.is_windows():
                print('%-30s %s' % ('python module win32api?:',
                                    str(sys_info.is_win32api_installed())))
            print('%-30s %s' % ('platform:', sys_info.get_platform_long()))
            print('%-30s %s' % ('os distro:', sys_info.get_os_distro()))
            if sys_info.is_linux():
                print('%-30s %s' % ('debian?:', str(sys_info.is_debian())))
                print('%-30s %s' % ('redhat?:', str(sys_info.is_redhat())))
                print('%-30s %s' % ('suse?:', str(sys_info.is_suse())))
                print('%-30s %s' % ('package format:', sys_info.get_pkg_fmt()))
                print('%-30s %s' %
                      ('package architecture:', sys_info.get_pkg_arch()))
            elif sys_info.is_windows():
                print('%-30s %s' % ('windows8?:', str(sys_info.is_windows8())))
            print('%-30s %s' % ('os codename:', sys_info.get_os_codename()))
            print('%-30s %s' %
                  ('os version:',
                   ver.version_tuple_to_str(sys_info.get_os_version())))
            print('%-30s %s' % ('os architecture:', sys_info.get_os_arch()))
            print('%-30s %s' %
                  ('locale.prefencoding:', locale.getpreferredencoding(False)))
            print('%-30s %s' %
                  ('number of processors:', sys_info.get_number_processors()))
            print('%-30s %s' % ('home directory:', sys_info.get_home_dir()))
            desktop_dir = sys_info.get_desktop_dir()
            if desktop_dir is not None:
                print('%-30s %s' % ('desktop:', desktop_dir))
            # get_program_dir(self, target_arch):
            if sys_info.is_windows():
                program_dir = sys_info.get_program_dir(sys_info.get_os_arch())
                print('%-30s %s' % ('program dir:', program_dir))
                if sys_info.get_os_arch() == 'x86_64':
                    program_dir = sys_info.get_program_dir('x86')
                    print('%-30s %s' % ('program dir x86:', program_dir))
            label = 'path:'
            for d in sys_info.get_path():
                print('%-30s %s' % (label, d))
                label = ' '
        elif args.print_env:
            env_var_list = []
            for env_var in os.environ:
                env_var_list.append(env_var)
            env_var_list.sort()
            for env_var in env_var_list:
                print(env_var + '=' + os.getenv(env_var))
        else:
            print(sys_info.get_system_info_full_str())
예제 #12
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))
예제 #13
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)
예제 #14
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.")
예제 #15
0
    def main(self, argv):
        (boost_build_params, boost_dir, cxx_std) = self._parse_command_line(argv)
        # Change the current working directory to the top level directory in case the caller has moved
        # into CMakeBuild or bin to invoke boost_install.py.
        top_dir = util.get_top_dir()
        os.chdir(top_dir)
        msg_list_summary = []
        msg_list_summary.append('%-25s %s' % ('python version:', ver.version_tuple_to_str(self._sys_info.get_python_version())))
        msg_list_summary.append('%-25s %s' % ('python executable:', self._sys_info.get_python_executable()))
        msg_list_summary.append('%-25s %s' % ('platform:', self._sys_info.get_platform_long()))
        msg_list_todo = []
        self._sys_info.check_os_detection(msg_list_todo)

        if boost_dir is None:
            print("boost_install.py: no boost directory specified, use option --boost-dir.")
            sys.exit(1)
        else:
            boost_build_params.boost_dir = boost_dir

        if boost_build_params.boost_dir.startswith('/usr/include'):
            # system layout -> don't try to build the boost SDK and just extract the boost version
            msg_list_summary.append('%-25s %s' % ('boost version:', ver.version_tuple_to_str(boostbld.get_boost_version(boost_build_params.boost_dir))))
        else:
            # create the BoostBuilder
            boost_builder = boostbld.BoostBuilder(self._sys_info)

            if cxx_std:
                boost_build_params.cxx_std = cxx_std
            else:
                re_match = re.match(r'.*-(c\+\+[0-9]+)$', boost_dir)
                if re_match:
                    boost_build_params.cxx_std = re_match.group(1)
                else:
                    boost_build_params.cxx_std = 'c++11'

            # launch Boost building with the current set of build options.
            boost_builder.build_boost(boost_build_params)

            # compose the summary
            msg_list_summary.append('%-25s %s' % ('boost root:', boost_dir))
            msg_list_summary.append('%-25s %s' % ('boost version:', ver.version_tuple_to_str(boost_builder.get_boost_version())))
            if boost_build_params.targets:
                msg_list_summary.append('%-25s %s' % ('boost toolset:', boost_builder.get_toolset().get_toolset_info_short(boost_build_params.targets[0])))
            bjam_cmd_lines = boost_builder.get_bjam_cmd_lines()
            if bjam_cmd_lines:
                msg_list_summary.append('bjam command(s):')
                msg_list_summary.extend(boost_builder.get_bjam_cmd_lines())

        if msg_list_summary:
            print()
            print("                      SUMMARY                           ")
            print("                      =======                           ")
            print()
            for msg in msg_list_summary:
                print(msg)
            print()

        if msg_list_todo:
            print("\nTODO List:")
            for msg in msg_list_todo:
                print(msg)
            print()
        print("boost_install.py finished successfully.\n")
 def test_version_tuple_to_str(self):
     self.assertEqual('10', ver.version_tuple_to_str(tuple([10])))
     self.assertEqual('10.2', ver.version_tuple_to_str((10, 2)))
예제 #17
0
    def _create_user_config_content(self,
                                    toolset,
                                    platform_index,
                                    target,
                                    build_boost_mpi,
                                    build_boost_python,
                                    cppflags=None,
                                    cflags=None,
                                    lflags=None,
                                    msvc_rt=None):
        """Check the toolset attributes and determine whether a temporary user-config.jam is needed or not."""
        lines = []
        platform_info = toolset.get_platform_info(platform_index)
        toolset_str = toolset.get_toolset()
        toolset_version_str = ver.version_tuple_to_str(
            toolset.get_version()[:2])
        cxxflags = []
        compileflags = []
        linkflags = []
        rc = []
        using_line = None
        setup_cmd_content = []
        setup_cmd = None

        if cppflags:
            cxxflags.extend(cppflags)
        if cflags:
            compileflags.extend(cflags)
        if lflags:
            linkflags.extend(lflags)

        extra_cflags = platform_info.get_target_cflags(target)
        if extra_cflags:
            compileflags.extend(extra_cflags)

        if toolset_str == 'gcc':
            using_line = "using %s : %s : %s" % (
                toolset_str, toolset_version_str,
                toolset.get_compiler_command())
            if toolset.is_mingw():
                if self._sys_info.is_linux():
                    # mingw on linux is always a prefixed compiler and it does not figure out the path to windres by default.
                    compiler_dir = os.path.dirname(
                        toolset.get_compiler_command())
                    windres = os.path.join(
                        compiler_dir,
                        toolset.get_compiler_prefix() + '-windres')
                    rc.append(windres)
        elif toolset_str == 'clang':
            if platform_info.get_target_os() in ['android', 'linux']:
                using_line = "using %s : %s : %s" % (
                    toolset_str, toolset_version_str,
                    toolset.get_compiler_command())
            elif platform_info.get_target_os() in [
                    'macosx', 'iphone', 'iphonesimulator'
            ]:
                using_line = "using %s : : %s" % (
                    toolset_str, toolset.get_compiler_command())

                isysroot = platform_info.get_isysroot()
                assert isysroot is not None
                compileflags.extend(['-isysroot', isysroot])
                if platform_info.get_target_os() == 'macosx':
                    # Add 3rd party native frameworks folder
                    compileflags.append('-F/Library/Frameworks')
                    linkflags.append('-F/Library/Frameworks')
                else:
                    arch_flags = None
                    if platform_info.get_target_os() == 'iphone':
                        if target in ['armv7', 'arm64']:
                            arch_flags = ['-arch', target]
                        elif target == 'combined':
                            arch_flags = ['-arch', 'armv7', '-arch', 'arm64']
                        else:
                            assert False
                    elif platform_info.get_target_os() == 'iphonesimulator':
                        if target == 'x86_64':
                            # Assume -arch x86_64 is the default
                            pass
                        elif target == 'x86':
                            arch_flags = ['-arch', 'i386']
                        elif target == 'combined':
                            arch_flags = ['-arch', 'x86_64', '-arch', 'i386']
                        else:
                            assert False
                    else:
                        assert False
                    if arch_flags:
                        compileflags.extend(arch_flags)
                        linkflags.extend(arch_flags)
            else:
                assert False
        elif toolset_str == 'intel':
            if self._sys_info.is_linux() or self._sys_info.is_macosx():
                using_line = "using %s : %s : %s" % (
                    toolset_str, toolset_version_str,
                    toolset.get_compiler_command())
            elif self._sys_info.is_windows():
                compiler_cmd = os.path.normpath(toolset.get_compiler_command())
                compiler_cmd_escaped = compiler_cmd.replace("\\", "\\\\")
                assert msvc_rt is not None
                re_match = re.match(r'msvc-(\d+\.\d+)$', msvc_rt)
                if re_match:
                    msvc_version_str = re_match.group(1)
                else:
                    assert False
                using_line = 'using %s : %s : "%s" :' % (
                    toolset_str, toolset_version_str, compiler_cmd_escaped)
                #using_line += ' <rewrite-setup-scripts>off'
                using_line += ' <compatibility>vc' + msvc_version_str
            else:
                assert False
        elif toolset_str == 'msvc':
            if toolset_version_str in ['14.0']:
                msvc_registry = bldtools.MsvcRegistry()
                if msvc_registry.is_vs2017_toolset(
                        ver.version_tuple_from_str(toolset_version_str)):
                    # target ...
                    setup_cmd = os.path.normpath(
                        os.path.join(self._sys_info.get_home_dir(),
                                     'setup_vs2017_vc140.bat'))
                    # replace single backslashes with double backslashes
                    setup_cmd_escaped = setup_cmd.replace("\\", "\\\\")
                    using_line = 'using %s : %s : : <setup>"%s"' % (
                        toolset_str, toolset_version_str, setup_cmd_escaped)
                    using_line += ' <rewrite-setup-scripts>off'

                    # call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvarsall.bat" amd64 -vcvars_ver=14.0
                    if target == 'x86_64':
                        setup_cmd_target = 'amd64'
                    elif target == 'x86':
                        setup_cmd_target = 'amd64_x86'
                    else:
                        assert False
                    setup_cmd_content.append(
                        'call "%s" %s -vcvars_ver=14.0' %
                        (toolset.get_compiler_command(), setup_cmd_target))

        if cxxflags or compileflags or linkflags or rc:
            assert using_line is not None
            using_line += " :"
            if cxxflags:
                using_line += ' <cxxflags>"%s"' % ' '.join(cxxflags)
            if compileflags:
                using_line += ' <compileflags>"%s"' % ' '.join(compileflags)
            if linkflags:
                using_line += ' <linkflags>"%s"' % ' '.join(linkflags)
            if rc:
                using_line += ' <rc>"%s"' % ' '.join(rc)

        if using_line:
            lines.append(using_line + " ;")

        if build_boost_python:
            python_config_file = os.path.join(self._sys_info.get_home_dir(),
                                              'user-config-python.jam')
            if os.path.exists(python_config_file):
                with open(python_config_file) as f:
                    for line in f:
                        lines.append(line.rstrip())
            else:
                python_version = self._sys_info.get_python_version()
                if platform_info.get_target_os() == 'windows':
                    python_executable_short_path = self._sys_info.get_short_path_win(
                        self._sys_info.get_python_executable())
                    python_executable_cstring = python_executable_short_path.replace(
                        "\\", "\\\\")
                    lines.append('using python : %d.%d : "%s" ;' %
                                 (python_version[0], python_version[1],
                                  python_executable_cstring))
                elif platform_info.get_target_os() == 'macosx':
                    lines.append('using python : %d.%d : %s ;' %
                                 (python_version[0], python_version[1],
                                  self._sys_info.get_python_executable()))
                elif platform_info.get_target_os() == 'linux':
                    lines.append('using python : %d.%d : %s ;' %
                                 (python_version[0], python_version[1],
                                  self._sys_info.get_python_executable()))

        if build_boost_mpi:
            mpi_config_file = os.path.join(self._sys_info.get_home_dir(),
                                           'user-config-mpi.jam')
            if os.path.exists(mpi_config_file):
                with open(mpi_config_file) as f:
                    for line in f:
                        lines.append(line.rstrip())
            else:
                lines.append("using mpi ;")

        return lines, setup_cmd, setup_cmd_content
예제 #18
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