Beispiel #1
0
    def _parse_command_line(self, argv):

        params = CMakeBuildUpdateAppParams()

        parser = argparse.ArgumentParser(usage=self._usage, epilog=self._epilog, formatter_class=argparse.RawDescriptionHelpFormatter)

        parser.add_argument("top_dir", action="store", nargs='?', default=None,
                            help="specifies a Git workspace to work on. By default the scripts installation path will be used to deduce the workspace.")

        util.app_args_add_log_level(parser)

        parser.add_argument("-t", "--tag", action="store", dest="cmakebuild_tag", metavar="TAG",
                            help="specifies a CMakeBuild tag to be used. If omitted the latest release tag will be used.")

        parser.add_argument("--cmakebuild-repo", action="store", dest="cmakebuild_repo", metavar="REPO", default=params.cmakebuild_repo,
                            help="specifies an alternative CMakeBuild repository overriding %(default)s." )

        parser.add_argument("--update", action="store_true", dest="update", default=False,
                            help="execute cmakebuild update, internal option reserved for the os.execv() machinery.")

        args = parser.parse_args(argv)

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

        if args.top_dir:
            params.top_dir = os.path.normpath(os.path.abspath(args.top_dir))
        if args.cmakebuild_tag:
            params.cmakebuild_tag = args.cmakebuild_tag
        if args.cmakebuild_repo:
            params.cmakebuild_repo = args.cmakebuild_repo
        if args.update:
            params.update_prepare = False

        return params
Beispiel #2
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))
    def _parse_command_line(self, argv):

        _usage = """
%(prog)s [options] [variant=debug,release,relwithdebinfo,minsizerel] [link=static,shared] [toolset=<toolset_spec>] [address-model=32]

%(prog)s is a script front end to cmake to simplify its usage on Linux,
Windows, MacOSX using cmake's generators "Unix Makefiles", "Xcode" and
"Visual Studio 15 - Visual Studio 10" and its compilers.

arguments:
  variant:          debug if not specified
  link:             static if not specified
  toolset:          default c++ compiler if not specified
                    examples/windows: msvc-19.12, msvc-19.0, msvc-18.0, msvc-17.0, msvc-16.0, intel
                    examples/linux:   gcc-4.9, gcc-5, gcc-6, clang, intel
  address-model=32: windows: builds 32 bit binaries instead of 64 bit binaries

"""
        _epilog = """
usage examples:

  # debug build, create the build tree if it does not exist.
  %(prog)s -b

  # release build, create the build tree if it does not exist.
  %(prog)s -b variant=release

  # release build using shared libraries, create the build tree if it does not exist.
  %(prog)s -b variant=release link=shared

  # create a build tree without building anything
  %(prog)s

  # create a build tree specifying a cmake cache entry without building anything
  %(prog)s -DENABLE_SOMETHING=1

"""
        parser = argparse.ArgumentParser(
            usage=_usage,
            epilog=_epilog,
            formatter_class=argparse.RawDescriptionHelpFormatter)

        parser.add_argument(
            "-g",
            "-G",
            action="store",
            dest="generator",
            choices=self._dict_generator_choice[self._sys_info.get_platform()],
            help="""specify a cmake generator the script has special support for.
                                    Supported generators: ninja, umake, mgwmake, vs15, vs14, vs12, vs11, vs10, xcode.
                                    The choices accepted are platform and installation dependent."""
        )

        parser.add_argument(
            "-D",
            action="append",
            dest="cache_entries",
            help=
            "specify a cmake cache entry. The option will be ignored if a build tree already exists."
        )

        parser.add_argument("-W",
                            action="append",
                            dest="warning_flags",
                            help="specify a cmake warning flag.")

        parser.add_argument(
            "-b",
            action="store_true",
            dest="build",
            default=False,
            help=
            """invokes cmake --build to build the default debug configuration unless overridden by additional arguments.
                                    If a build tree does not exist, it will be created."""
        )

        parser.add_argument(
            "-j",
            action="store",
            dest="build_jobs",
            type=int,
            nargs='?',
            default=1,
            const=str(self._get_optimal_number_cmake_jobs()),
            help=
            """specify the number of parallel build jobs. If you omit the numeric argument,
                                    cmake --build ... will be invoked with -j<number_of_processors>."""
        )

        parser.add_argument(
            "--target",
            action="store",
            dest="build_target",
            help="specify a build target overriding the default target.")

        parser.add_argument(
            "--clean-first",
            action="store_true",
            dest="clean_first",
            default=False,
            help="build target clean first, then build the active target.")

        parser.add_argument(
            "--verbosity",
            action="store",
            dest="build_verbosity",
            choices=['quiet', 'minimal', 'normal', 'detailed', 'diagnostic'],
            default='minimal',
            help="specify msbuild verbosity level [default: minimal].")

        parser.add_argument(
            "-i",
            action="store",
            dest="install_dir",
            nargs='?',
            const=os.path.join(self._sys_info.get_home_dir(), 'bin'),
            help=
            "install this script and exit. The default destination directory is $HOME/bin."
        )

        util.app_args_add_log_level(parser)

        # -j may be followed by a non-numeric argument which the parser is not able to handle.
        if '-j' in argv:
            i = argv.index('-j')
            # If the next argument is all numeric, attach it directly. In all other cases use the optimal number of parallel jobs.
            if i < (len(argv) - 1):
                if re.match(r'\d+$', argv[i + 1]):
                    argv_parsed = argv
                else:
                    # make a copy -> don't want to modify sys.argv.
                    argv_parsed = argv[:]
                    argv_parsed[i] = '-j' + str(
                        self._get_optimal_number_cmake_jobs())
            else:
                # make a copy -> don't want to modify sys.argv.
                argv_parsed = argv[:]
                argv_parsed[i] = '-j' + str(
                    self._get_optimal_number_cmake_jobs())
        else:
            argv_parsed = argv

        (cmake_py_options, args_left) = parser.parse_known_args(argv_parsed)

        # configure the python logger asap
        util.app_configure_logging(cmake_py_options.log_level)

        launcher_params = cmksupp.CMakeLauncherParams()
        cmake_args = []
        if cmake_py_options.install_dir:
            # print("-i found, install dir", cmake_py_options.install_dir)
            if os.path.isabs(cmake_py_options.install_dir):
                launcher_params.install_dir = cmake_py_options.install_dir
            else:
                launcher_params.install_dir = os.path.abspath(
                    cmake_py_options.install_dir)

        self._top_dir = os.getcwd()
        if cmake_py_options.install_dir:
            return launcher_params, cmake_args

        # if args_left:
        #    print("cmake args", args_left)

        # Assign cmake.py options to attributes of CMakeLauncherParams.
        launcher_params.cmk_build = cmake_py_options.build
        launcher_params.cmk_build_jobs = cmake_py_options.build_jobs
        launcher_params.clean_first = cmake_py_options.clean_first
        launcher_params.cmk_build_target = cmake_py_options.build_target
        launcher_params.cmk_build_verbosity = cmake_py_options.build_verbosity
        launcher_params.cmk_generator_alias = cmake_py_options.generator
        if cmake_py_options.cache_entries:
            launcher_params.cmk_cache_entries = [
                '-D' + x for x in cmake_py_options.cache_entries
            ]
        if cmake_py_options.warning_flags:
            launcher_params.cmk_warning_flags = [
                '-W' + x for x in cmake_py_options.warning_flags
            ]

        re_cmake_py_arg = re.compile(
            r'(toolset|variant|link|address-model)=(\S+)')
        for arg in args_left:
            # print("processing argument " + arg)
            re_match = re_cmake_py_arg.match(arg)
            if re_match:
                arg_key = re_match.group(1)
                arg_value = re_match.group(2)
                if arg_key == 'toolset':
                    if arg_value.endswith('.cmake'):
                        # A toolset=<something>.cmake expression is supposed to be a toolchain file to enable
                        # some kind of cross compilation.
                        if not os.path.exists(arg_value):
                            print("cmake.py: error: toolchain file=" +
                                  arg_value + " does not exist.")
                            sys.exit(1)
                        launcher_params.toolset_str = os.path.abspath(
                            arg_value)
                    else:
                        launcher_params.toolset_str = self._normalize_toolset_spec(
                            arg_value)
                elif arg_key == 'variant':
                    build_configs = arg_value.split(',')
                    for cfg in build_configs:
                        if cfg not in [
                                'release', 'debug', 'relwithdebinfo',
                                'minsizerel'
                        ]:
                            print("cmake.py: error: " + arg +
                                  " is not understood.")
                            sys.exit(1)
                    launcher_params.build_configs = build_configs
                elif arg_key == 'link':
                    link_variants = arg_value.split(',')
                    for lnk in link_variants:
                        if lnk not in ['static', 'shared']:
                            print("cmake.py: error: " + arg +
                                  " is not understood.")
                            sys.exit(1)
                    launcher_params.link_variants = link_variants
                elif arg_key == 'address-model':
                    if arg_value == '32':
                        launcher_params.target_arch = 'x86'
                    elif arg_value == '64':
                        launcher_params.target_arch = 'x86_64'
                    else:
                        print("cmake.py: error: " + arg +
                              " is not understood.")
                        sys.exit(1)
                else:
                    print("cmake.py: error: " + arg + " is not understood.")
                    sys.exit(1)
                continue
            if arg == '--':
                # Semantics seems to be tricky and I haven't seen a convincing use case yet.
                # In configuration mode all unknown arguments are passed verbatim to cmake and in build mode
                # all unknown arguments are really build tool arguments and are passed verbatim to the build tool.
                print(
                    "cmake.py: error: argument '--' encountered, this is not yet supported, please contact the maintainer."
                )
                sys.exit(1)
            # all other arguments are passed on to cmake verbatim.
            cmake_args.append(arg)
        return launcher_params, cmake_args
    def __call__(self):

        parser = argparse.ArgumentParser()
        util.app_args_add_log_level(parser)
        parser.add_argument(
            "-v",
            action="store",
            type=int,
            dest="verbosity_level",
            default=2,
            help=
            "change the default verbosity level of the python unit test framework."
        )
        parser.add_argument("--with-android",
                            action="store_true",
                            dest="with_android",
                            default=False,
                            help="include android tests.")
        parser.add_argument("--with-cuda",
                            action="store_true",
                            dest="with_cuda",
                            default=False,
                            help="include android tests.")
        parser.add_argument("--with-vlc",
                            action="store_true",
                            dest="with_vlc",
                            default=False,
                            help="include VLC tests.")
        parser.add_argument("--with-all",
                            action="store_true",
                            dest="with_all",
                            default=False,
                            help="include all optional tests.")
        parser.add_argument(
            "unit_tests",
            action="store",
            nargs='*',
            help=
            "specify one or more unit tests to run. By default all tests will be run."
        )
        args = parser.parse_args()

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

        # print("verbosity_level:", args.verbosity_level)

        # get the workspace
        top_dir = util.get_top_dir()
        # change to top_dir
        os.chdir(top_dir)

        # get the boost build script directory
        script_dir = util.get_script_dir()

        test_loader = unittest.TestLoader()

        # All unit tests live in the package bb.test
        test_package_prefix = 'pyhhi.build.test'

        py_module_nm_list = []
        if args.unit_tests:
            # One or more test modules are specified.
            for arg in args.unit_tests:
                if arg.startswith('test_'):
                    py_module_nm_list.append(arg)
                else:
                    py_module_nm_list.append('test_' + arg)
        else:
            # Construct the default test suite containing all test modules.
            # test_suite = test_loader.discover(test_package_prefix, 'test_*.py')
            for file in glob.glob(
                    os.path.join(script_dir, 'pyhhi', 'build', 'test',
                                 'test_*.py')):
                (py_module_nm, ext) = os.path.splitext(os.path.basename(file))
                py_module_nm_list.append(py_module_nm)
            for file in glob.glob(
                    os.path.join(script_dir, 'pyhhi', 'cmbuild', 'test',
                                 'test_*.py')):
                (py_module_nm, ext) = os.path.splitext(os.path.basename(file))
                py_module_nm_list.append(py_module_nm)
            py_module_nm_list = self._filter_module_list(
                args, py_module_nm_list)

        test_module_names = []
        for prefix in ['pyhhi.build.test', 'pyhhi.cmbuild.test']:
            #prefix_path = os.path.join(script_dir, prefix.split('.'))
            prefix_path = os.path.join(script_dir, prefix.replace('.', os.sep))
            for py_module_nm in py_module_nm_list:
                if os.path.exists(
                        os.path.join(prefix_path, py_module_nm + '.py')):
                    test_module_names.append(prefix + '.' + py_module_nm)
        #test_module_names = [test_package_prefix + '.' + x for x in py_module_nm_list]
        print("test module list: ", test_module_names)

        test_suite = test_loader.loadTestsFromNames(test_module_names)
        # and run tests ...
        test_runner = unittest.TextTestRunner(verbosity=args.verbosity_level)
        test_runner.run(test_suite)
    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())
Beispiel #6
0
    def _parse_command_line(self, argv):
        parser = argparse.ArgumentParser()
        parser.add_argument(
            "-m",
            action="append",
            dest="module_names",
            help=
            "specifies an extension module name, the option must be repeated for each extension module."
        )
        parser.add_argument("-R",
                            action="store_true",
                            dest="remove_all",
                            default=False,
                            help="remove all non-standard module sections.")
        parser.add_argument(
            "-r",
            action="store_true",
            dest="remove",
            default=False,
            help="remove a single non-standard module section.")
        parser.add_argument("-f",
                            action="store",
                            dest="rst_filenm",
                            required=True,
                            help="specifies the CMake RST file to be updated.")
        parser.add_argument("-o", action="store", dest="output_rst_filenm")
        parser.add_argument(
            "-s",
            action="store",
            dest="section_title",
            default="Extension Modules",
            help=
            "specifies the section to be updated [default: Extension Modules]")
        parser.add_argument("--dry-run",
                            action="store_true",
                            dest="dry_run",
                            default=False)

        util.app_args_add_log_level(parser)

        args = parser.parse_args(argv)

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

        params = cmkdoc.CMakeRstUtilParams()
        params.dry_run = args.dry_run
        params.rst_module_filenm = os.path.abspath(args.rst_filenm)

        if args.module_names:
            params.update_action = 'add'
            params.extension_module_names = args.module_names
        elif args.remove_all:
            params.update_action = 'remove_all'
        elif args.remove:
            params.update_action = 'remove'
        else:
            print("No update action specified, use -m, -R or -r.")
            sys.exit(1)
        if args.section_title:
            params.extension_section_title = args.section_title
        if args.output_rst_filenm:
            params.output_rst_filenm = os.path.abspath(args.output_rst_filenm)

        return params
Beispiel #7
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))
    def _parse_command_line(self, argv):
        _usage_header = "%(prog)s [options] [toolset=msvc-x.y|gcc|gcc-x[.y]|clang|intel[-msvc-x.y] [target-os=iphone|iphonesimulator]"
        _description = """

%(prog)s builds BOOST libraries from source, use option --boost-dir to specify the location of the BOOST SDK.
If the BOOST directory ends with -c++03, -c++11, -c++14, or -c++17, this suffix will be used as the c++ standard
unless option --std is specified. If neither condition is true, c++11 will be used. 

Notes on Intel Compiler Selection:
  - No support for side-by-side installation of multiple Intel compilers yet
  - No support for 32 bit builds on any platform
  - On Windows the latest MSVC runtime/IDE will be used unless overridden by a suffix -msvc-x.y". 
  
"""

        parser = argparse.ArgumentParser(usage=_usage_header, description=_description, formatter_class=argparse.RawDescriptionHelpFormatter)

        parser.add_argument("buildprops", action="store", nargs='*',
                            help="one or more build properties specified as key=value, e.g. toolset=msvc-12.0")

        parser.add_argument("--boost-dir", action="store", dest="boost_dir", required=True,
                            help="required option to specify the location of the BOOST SDK.")

        parser.add_argument("--std", action="store", dest="cxx_std", choices=['c++03', 'c++11', 'c++14', 'c++17'],
                            help="overrides the c++ standard which is deduced from the boost directory if it ends with "
                                 "one of the supported c++ standards prefixed by a hyphen.")

        parser.add_argument("--target", action="append", dest="targets",
                            help="override the toolset's default target. Typically used to build 32 bit libraries on Windows; "
                                 "example: --target x86 toolset=msvc-14.0")

        parser.add_argument("--rebuild", action="store_true", dest="rebuild_all", default=False,
                           help="force a rebuild of all boost libraries")

        group = parser.add_argument_group("MacOSX Options")

        g = group.add_mutually_exclusive_group()
        g.add_argument("--macosx-version-min", action="store", dest="macosx_version_min",
                           help="add backward compatibility down to the given MacOSX release.")

        g.add_argument("--ios-version-min", action="store", dest="macosx_version_min", metavar="IOS_VERSION_MIN",
                           help="add backward compatibility down to the given IOS release.")

        group = parser.add_argument_group("Advanced Options")

        group.add_argument("--c++-runtime", action="store", dest="cxx_runtime", choices=['shared', 'static', 'gnustl', 'libc++', 'libstdc++'],
                            help="overrides the default c++ runtime, supported for mingw, msvc, clang and Android.")

        group.add_argument("--with-mpi", action="store_true", dest="build_mpi", default=False,
                           help="enable Boost MPI (message passing interface) [default:off]")

        group.add_argument("--with-python", action="store_true", dest="build_python", default=False,
                           help="enable Boost Python [default:off]. If enabled, Boost MPI may not build.")

        group.add_argument("--use-user-config", action="store_true", dest="use_user_config", default=False,
                           help="enable the use of $HOME/user-config.jam [default:off].")

        util.app_args_add_log_level(group)

        group.add_argument("--dry-run", action="store_true", dest="dry_run", default=False,
                           help="check which libraries are missing, list the update actions but don't start the build.")

        group.add_argument("--debug-configuration", action="store_true", dest="debug_configuration", default=False,
                           help="invoke b2 with --debug-configuration, disables removal of temporary files.")

        group.add_argument("--jobs", action="store", type=int, dest="bjam_jobs",
                           help="specifies the number of parallel bjam jobs explicitly [default: number of processors]")

        args = parser.parse_args(argv)

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

        boost_build_params = boostbld.BoostBuildParams(self._sys_info)
        re_toolset = re.compile(r'toolset=(\S+)')
        re_address_model = re.compile(r'address-model=(\S+)')
        re_target_os = re.compile(r'target-os=(\S+)')
        for arg in args.buildprops:
            arg_parsed = False
            re_match = re_toolset.match(arg)
            if re_match:
                boost_build_params.toolset = re_match.group(1)
                if boost_build_params.toolset.startswith('msvc-'):
                    boost_build_params.toolset = self._msvc_dict.transform_cmake_to_bbuild(boost_build_params.toolset)
                elif boost_build_params.toolset.startswith('intel-'):
                    re_match_intel = re.match(r'intel-(msvc-\d+\.\d+)$', boost_build_params.toolset)
                    if re_match_intel:
                        boost_build_params.toolset = 'intel'
                        boost_build_params.msvc_rt = re_match_intel.group(1)
                    else:
                        print("boost_install.py: argument", arg, " not understood, try --help to get more usage information.")
                        sys.exit(1)
                arg_parsed = True
            re_match = re_address_model.match(arg)
            if re_match:
                arg_parsed = True
                if re_match.group(1) == '32':
                    args.targets = ['x86']
                elif re_match.group(1) == '64':
                    args.targets = ['x86_64']
                else:
                    print("boost_install.py: argument", arg, " not understood, try --help to get more usage information.")
                    sys.exit(1)
            re_match = re_target_os.match(arg)
            if re_match:
                arg_parsed = True
                if re_match.group(1) == 'iphone':
                    boost_build_params.platform_index = 1
                elif re_match.group(1) == 'iphonesimulator':
                    boost_build_params.platform_index = 2
                else:
                    print("boost_install.py: argument", arg, " not understood, try --help to get more usage information.")
                    sys.exit(1)
            if not arg_parsed:
                print("boost_install.py: argument", arg, " not understood, try --help to get more usage information.")
                sys.exit(1)

        boost_dir = None
        if args.boost_dir:
            # boost_dir must be transformed before changing cwd.
            boost_dir = util.normalize_path(os.path.abspath(args.boost_dir))

        boost_build_params.targets = self._set_build_targets(boost_build_params.toolset, args.targets)

        if args.cxx_std:
            cxx_std = args.cxx_std
        else:
            cxx_std = None
        if args.cxx_runtime:
            boost_build_params.cxx_runtime = args.cxx_runtime

        boost_build_params.dry_run = args.dry_run
        boost_build_params.debug_configuration = args.debug_configuration
        boost_build_params.build_mpi = args.build_mpi
        boost_build_params.build_python = args.build_python
        boost_build_params.bjam_jobs = args.bjam_jobs
        boost_build_params.custom_user_config = args.use_user_config

        # options to select what to build
        boost_build_params.rebuild_all = args.rebuild_all

        if self._sys_info.is_macosx():
            # handle --macosx-version-min option, it will apply to MacOSX and iOS
            if args.macosx_version_min is not None:
                boost_build_params.macosx_version_min = ver.version_tuple_from_str(args.macosx_version_min)

        return boost_build_params, boost_dir, cxx_std
Beispiel #9
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')