#!/usr/bin/env python # This source file is part of the Swift.org open source project # # Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors # import sys import os import argparse import json import glob from lib.config import Configuration from lib.path import Path from lib.phases import CompileSources from lib.phases import CompileSwiftSources from lib.phases import CopyResources from lib.phases import CopyHeaders from lib.phases import SwiftExecutable from lib.product import DynamicLibrary from lib.product import Framework from lib.product import StaticLibrary from lib.product import StaticAndDynamicLibrary from lib.product import Application from lib.product import Executable from lib.pkg_config import PkgConfig from lib.script import Script from lib.target import ArchSubType from lib.target import ArchType from lib.target import EnvironmentType from lib.target import ObjectFormat from lib.target import OSType from lib.target import Target from lib.target import Vendor from lib.workspace import Workspace import sys def reconfigure(config, path): with open(path, 'r') as infile: info = json.load(infile) config.requires_pkg_config = info['requires_pkg_config'] if 'version' in info and info['version'] == config.version: if 'command' in info and info['command'] is not None: config.command = info['command'] if 'project' in info and info['project'] is not None: config.command = info['project'] if 'script_path' in info and info['script_path'] is not None: config.script_path = Path(info['script_path']) if 'build_script_path' in info and info['build_script_path'] is not None: config.build_script_path = Path(info['build_script_path']) if 'source_root' in info and info['source_root'] is not None: config.source_root = Path(info['source_root']) if 'target' in info and info['target'] is not None: config.target = Target(info['target']) if 'system_root' in info and info['system_root'] is not None: config.system_root = Path(info['system_root']) if 'toolchain' in info and info['toolchain'] is not None: config.toolchain = Path(info['toolchain']) if 'linker' in info and info['linker'] is not None: config.linker = info['linker'] elif config.target is not None: config.linker = config.target.linker if 'build_directory' in info and info['build_directory'] is not None: config.build_directory = Path(info['build_directory']) if 'intermediate_directory' in info and info['intermediate_directory'] is not None: config.intermediate_directory = Path(info['intermediate_directory']) if 'module_cache_directory' in info and info['module_cache_directory'] is not None: config.module_cache_directory = Path(info['module_cache_directory']) if 'install_directory' in info and info['install_directory'] is not None: config.install_directory = Path(info['install_directory']) if 'prefix' in info and info['prefix'] is not None: config.prefix = info['prefix'] if 'swift_install' in info and info['swift_install'] is not None: config.swift_install = info['swift_install'] if 'pkg_config' in info and info['pkg_config'] is not None: config.pkg_config = info['pkg_config'] if 'clang' in info and info['clang'] is not None: config.clang = info['clang'] if 'clangxx' in info and info['clangxx'] is not None: config.clangxx = info['clangxx'] if 'swift' in info and info['swift'] is not None: config.swift = info['swift'] if 'swiftc' in info and info['swiftc'] is not None: config.swiftc = info['swiftc'] if 'ar' in info and info['ar'] is not None: config.ar = info['ar'] if 'swift_sdk' in info and info['swift_sdk'] is not None: config.swift_sdk = info['swift_sdk'] if 'bootstrap_directory' in info and info['bootstrap_directory'] is not None: config.bootstrap_directory = Path(info['bootstrap_directory']) if 'verbose' in info and info['verbose'] is not None: config.verbose = info['verbose'] if 'extra_c_flags' in info and info['extra_c_flags'] is not None: config.extra_c_flags = info['extra_c_flags'] if 'extra_swift_flags' in info and info['extra_swift_flags'] is not None: config.extra_swift_flags = info['extra_swift_flags'] if 'extra_ld_flags' in info and info['extra_ld_flags'] is not None: config.extra_ld_flags = info['extra_ld_flags'] if 'build_mode' in info and info['build_mode'] is not None: config.build_mode = info['build_mode'] if 'variables' in info and info['variables'] is not None: config.variables = info['variables'] else: sys.exit("invalid version") def main(): config = Configuration() CWD = Path.path(os.getcwd()) config.build_directory = Path.path(os.getenv("BUILD_DIR", os.path.join(os.path.dirname(os.path.abspath(__file__)), "Build"))) config.module_cache_directory = Path.path(os.getenv("BUILD_DIR", config.build_directory.path_by_appending("ModuleCache"))) config.intermediate_directory = Path.path(os.getenv("INTERMEDIATE_DIR", config.build_directory.path_by_appending("Intermediates"))) config.install_directory = Path.path(os.getenv("DSTROOT", "/")) config.prefix = os.getenv("PREFIX", "/usr") config.clang = os.getenv("CLANG", "clang") config.clangxx = os.getenv("CLANGXX", "clang") config.swift = os.getenv("SWIFT", "swift") config.swiftc = os.getenv("SWIFTC", "swiftc") config.ar = os.getenv("AR", None) config.source_root = Path.path(os.getenv("SRCROOT", CWD)) config.extra_c_flags = os.getenv("CFLAGS", "") config.extra_swift_flags = os.getenv("SWIFTCFLAGS", "") config.extra_ld_flags = os.getenv("LDFLAGS", "") config.swift_sdk = os.getenv("SDKROOT", None) config.script_path = config.source_root.path_by_appending("build.py") config.build_script_path = config.source_root.path_by_appending("build.ninja") config.config_path = config.source_root.path_by_appending(".configuration") parser = argparse.ArgumentParser(description='Configure and emit ninja build scripts for building.') parser.add_argument('--target', dest='target', type=str, default=Target.default(), help="specify the deployment target") parser.add_argument('--sysroot', dest='sysroot', type=str, default=None, help="the system root directory for building") parser.add_argument('--toolchain', dest='toolchain', type=str, default=None, help="the base location for finding tools to compile") parser.add_argument('--linker', dest='linker', type=str, default=None, help="which linker program to use") parser.add_argument('--pkg-config', dest='pkg_config', type=str, default="pkg-config") parser.add_argument('--bootstrap', dest='bootstrap', type=str, default=os.path.join(os.path.dirname(os.path.abspath(__file__)), "bootstrap"), help="a directory for bootstrapping commonly used headers and libraries not associated directly with the target operating system") parser.add_argument('--reconfigure', dest='reconfigure', action="store_true", help="re-generate the build script given the previous configuration") parser.add_argument('-v', '--verbose', dest='verbose', action="store_true") args, extras = parser.parse_known_args() if args.reconfigure: reconfigure(config, config.config_path.absolute()) for arg in extras: if arg.lower() == 'debug': config.build_mode = Configuration.Debug elif arg.lower() == 'release': config.build_mode = Configuration.Release else: config.build_mode = Configuration.Debug # by default build in debug mode for arg in extras: if arg.lower() == 'debug': config.build_mode = Configuration.Debug elif arg.lower() == 'release': config.build_mode = Configuration.Release elif arg.startswith('-D'): # accept -DNAME=value as extra parameters to the configuration of the build.ninja key, val = arg[2:].split("=", 1) config.variables[key] = val config.command = [os.path.abspath(__file__)] + sys.argv[1:] config.target = Target(args.target) config.system_root = Path.path(args.sysroot) if config.target.sdk == OSType.MacOSX and config.system_root is None and Target(Target.default()).sdk == OSType.MacOSX: import subprocess config.system_root = Path.path(subprocess.Popen(['xcrun', '--show-sdk-path'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()[0]) swift_path = Path.path(subprocess.Popen(['xcrun', '--find', 'swift'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()[0]).parent().parent() config.swift_sdk = swift_path.absolute() elif config.swift_sdk is None: config.swift_sdk = "/usr" config.toolchain = Path.path(args.toolchain) config.pkg_config = args.pkg_config if args.linker is not None: config.linker = args.linker else: config.linker = config.target.linker config.bootstrap_directory = Path.path(args.bootstrap) config.verbose = args.verbose if config.toolchain is not None: ar_path = os.path.join(config.toolchain.relative(), "ar") if not os.path.exists(ar_path): ar_path = os.path.join(config.toolchain.relative(), "bin", "ar") config.ar = ar_path elif config.ar is None: config.ar = "ar" config.write(config.config_path.absolute()) Configuration.current = config exec(compile(open(config.script_path.absolute()).read(), config.script_path.absolute(), 'exec')) if __name__ == "__main__": main()