| # utils/SwiftBuildSupport.py - Utilities for Swift build scripts -*- python -*- |
| # |
| # This source file is part of the Swift.org open source project |
| # |
| # Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| # Licensed under Apache License v2.0 with Runtime Library Exception |
| # |
| # See https://swift.org/LICENSE.txt for license information |
| # See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| |
| from __future__ import print_function |
| |
| try: |
| # Python 2 |
| import ConfigParser |
| except ImportError: |
| # Python 3 |
| import configparser as ConfigParser |
| |
| import os |
| |
| from . import diagnostics |
| |
| |
| HOME = os.environ.get("HOME", "/") |
| |
| |
| def _get_default_source_root(): |
| result = "" |
| |
| # Are we in a Swift checkout? Start from this file and check its parent |
| # directories. |
| # |
| # $SWIFT_SOURCE_ROOT/swift/utils/swift_build_support/swift_build_support/SwiftBuildSupport.py |
| utils_path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) |
| (swift_path, parent_dirname) = os.path.split(utils_path) |
| if parent_dirname != "utils": |
| return result |
| if not os.path.exists(os.path.join(swift_path, 'CMakeLists.txt')): |
| return result |
| result = os.path.dirname(swift_path) |
| |
| # Are we in an LLVM checkout? Start from the Swift checkout and check /its/ |
| # parent directories. |
| # |
| # $SWIFT_SOURCE_ROOT/llvm/tools/swift/utils/swift_build_support/swift_build_support/SwiftBuildSupport.py |
| (llvm_path, parent_dirname) = os.path.split(result) |
| if parent_dirname != "tools": |
| return result |
| if not os.path.exists(os.path.join(llvm_path, 'CMakeLists.txt')): |
| return result |
| result = os.path.dirname(llvm_path) |
| |
| return result |
| |
| |
| # Set SWIFT_SOURCE_ROOT in your environment to control where the sources |
| # are found. |
| SWIFT_SOURCE_ROOT = os.environ.get( |
| "SWIFT_SOURCE_ROOT", _get_default_source_root()) |
| |
| # Set SWIFT_BUILD_ROOT to a directory that will contain a subdirectory |
| # for each build configuration |
| SWIFT_BUILD_ROOT = os.environ.get( |
| "SWIFT_BUILD_ROOT", os.path.join(SWIFT_SOURCE_ROOT, "build")) |
| |
| |
| def _get_default_swift_repo_name(): |
| result = "" |
| |
| # Are we in a Swift checkout? Start from this file and check its parent |
| # directories. |
| # |
| # $SWIFT_SOURCE_ROOT/$SWIFT_REPO_NAME/utils/swift_build_support/swift_build_support/SwiftBuildSupport.py |
| utils_path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) |
| (swift_path, parent_dirname) = os.path.split(utils_path) |
| if parent_dirname != "utils": |
| return result |
| if not os.path.exists(os.path.join(swift_path, 'CMakeLists.txt')): |
| return result |
| (_, swift_repo_name) = os.path.split(swift_path) |
| return swift_repo_name |
| |
| |
| # Set SWIFT_REPO_NAME in your environment to control the name of the swift |
| # directory name that is used. |
| SWIFT_REPO_NAME = os.environ.get( |
| "SWIFT_REPO_NAME", _get_default_swift_repo_name()) |
| |
| |
| def _load_preset_files_impl(preset_file_names, substitutions={}): |
| config = ConfigParser.SafeConfigParser(substitutions, allow_no_value=True) |
| if config.read(preset_file_names) == []: |
| diagnostics.fatal( |
| "preset file not found (tried " + str(preset_file_names) + ")") |
| return config |
| |
| |
| _PRESET_PREFIX = "preset: " |
| |
| |
| def _get_preset_options_impl(config, substitutions, preset_name): |
| section_name = _PRESET_PREFIX + preset_name |
| if section_name not in config.sections(): |
| return (None, None, None) |
| |
| build_script_opts = [] |
| build_script_impl_opts = [] |
| missing_opts = [] |
| dash_dash_seen = False |
| |
| for o in config.options(section_name): |
| try: |
| a = config.get(section_name, o) |
| except ConfigParser.InterpolationMissingOptionError as e: |
| # e.reference contains the correctly formatted option |
| missing_opts.append(e.reference) |
| continue |
| |
| if not a: |
| a = "" |
| |
| if o in substitutions: |
| continue |
| |
| opt = None |
| if o == "mixin-preset": |
| # Split on newlines and filter out empty lines. |
| mixins = filter(None, [m.strip() for m in a.splitlines()]) |
| for mixin in mixins: |
| (base_build_script_opts, |
| base_build_script_impl_opts, |
| base_missing_opts) = \ |
| _get_preset_options_impl(config, substitutions, mixin) |
| build_script_opts += base_build_script_opts |
| build_script_impl_opts += base_build_script_impl_opts |
| missing_opts += base_missing_opts |
| elif o == "dash-dash": |
| dash_dash_seen = True |
| elif a == "": |
| opt = "--" + o |
| else: |
| opt = "--" + o + "=" + a |
| |
| if opt: |
| if not dash_dash_seen: |
| build_script_opts.append(opt) |
| else: |
| build_script_impl_opts.append(opt) |
| |
| return (build_script_opts, build_script_impl_opts, missing_opts) |
| |
| |
| def get_preset_options(substitutions, preset_file_names, preset_name): |
| config = _load_preset_files_impl(preset_file_names, substitutions) |
| |
| (build_script_opts, build_script_impl_opts, missing_opts) = \ |
| _get_preset_options_impl(config, substitutions, preset_name) |
| if not build_script_opts and not build_script_impl_opts: |
| diagnostics.fatal("preset '" + preset_name + "' not found") |
| if missing_opts: |
| diagnostics.fatal("missing option(s) for preset '" + preset_name + |
| "': " + ", ".join(missing_opts)) |
| |
| # Migrate 'swift-sdks' parameter to 'stdlib-deployment-targets' |
| swift_sdks_opts = [opt for opt in build_script_impl_opts |
| if opt.startswith("--swift-sdks")] |
| try: |
| swift_sdks_opt = swift_sdks_opts[-1] |
| except IndexError: |
| swift_sdks_opt = None |
| |
| if swift_sdks_opt is not None: |
| sdks_to_configure = swift_sdks_opt.split("=")[1].split(";") |
| tgts = [] |
| # Expand SDKs in to their deployment targets |
| from swift_build_support.swift_build_support.targets \ |
| import StdlibDeploymentTarget |
| for sdk in sdks_to_configure: |
| if sdk == "OSX": |
| tgts += StdlibDeploymentTarget.OSX.targets |
| elif sdk == "IOS": |
| tgts += StdlibDeploymentTarget.iOS.targets |
| elif sdk == "IOS_SIMULATOR": |
| tgts += StdlibDeploymentTarget.iOSSimulator.targets |
| elif sdk == "TVOS": |
| tgts += StdlibDeploymentTarget.AppleTV.targets |
| elif sdk == "TVOS_SIMULATOR": |
| tgts += StdlibDeploymentTarget.AppleTVSimulator.targets |
| elif sdk == "WATCHOS": |
| tgts += StdlibDeploymentTarget.AppleWatch.targets |
| elif sdk == "WATCHOS_SIMULATOR": |
| tgts += StdlibDeploymentTarget.AppleWatchSimulator.targets |
| |
| build_script_opts.append("--stdlib-deployment-targets=" + |
| " ".join([tgt.name for tgt in tgts])) |
| |
| # Filter the swift-sdks parameter |
| build_script_impl_opts = [opt for opt in build_script_impl_opts |
| if not opt.startswith("--swift-sdks")] |
| |
| return build_script_opts + ["--"] + build_script_impl_opts |
| |
| |
| def get_all_preset_names(preset_file_names): |
| config = _load_preset_files_impl(preset_file_names) |
| return [name[len(_PRESET_PREFIX):] for name in config.sections() |
| if name.startswith(_PRESET_PREFIX)] |