/ configure
configure
  1  #!/usr/bin/env python
  2  
  3  # This source file is part of the Swift.org open source project
  4  #
  5  # Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
  6  # Licensed under Apache License v2.0 with Runtime Library Exception
  7  #
  8  # See http://swift.org/LICENSE.txt for license information
  9  # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 10  #
 11  
 12  import sys
 13  import os
 14  import argparse
 15  import json
 16  import glob
 17  
 18  from lib.config import Configuration
 19  
 20  from lib.path import Path
 21  
 22  from lib.phases import CompileSources
 23  from lib.phases import CompileSwiftSources
 24  from lib.phases import CopyResources
 25  from lib.phases import CopyHeaders
 26  from lib.phases import SwiftExecutable
 27  
 28  from lib.product import DynamicLibrary
 29  from lib.product import Framework
 30  from lib.product import StaticLibrary
 31  from lib.product import StaticAndDynamicLibrary
 32  from lib.product import Application
 33  from lib.product import Executable
 34  
 35  from lib.pkg_config import PkgConfig
 36  
 37  from lib.script import Script
 38  
 39  from lib.target import ArchSubType
 40  from lib.target import ArchType
 41  from lib.target import EnvironmentType
 42  from lib.target import ObjectFormat
 43  from lib.target import OSType
 44  from lib.target import Target
 45  from lib.target import Vendor
 46  
 47  from lib.workspace import Workspace
 48  
 49  import sys
 50  
 51  def reconfigure(config, path):
 52      with open(path, 'r') as infile:
 53          info = json.load(infile)
 54          config.requires_pkg_config = info['requires_pkg_config']
 55          if 'version' in info and info['version'] == config.version:
 56              if 'command' in info and info['command'] is not None:
 57                  config.command = info['command']
 58              if 'project' in info and info['project'] is not None:
 59                  config.command = info['project']
 60              if 'script_path' in info and info['script_path'] is not None:
 61                  config.script_path = Path(info['script_path'])
 62              if 'build_script_path' in info and info['build_script_path'] is not None:
 63                  config.build_script_path = Path(info['build_script_path'])
 64              if 'source_root' in info and info['source_root'] is not None:
 65                  config.source_root = Path(info['source_root'])
 66              if 'target' in info and info['target'] is not None:
 67                  config.target = Target(info['target'])
 68              if 'system_root' in info and info['system_root'] is not None:
 69                  config.system_root = Path(info['system_root'])
 70              if 'toolchain' in info and info['toolchain'] is not None:
 71                  config.toolchain = Path(info['toolchain'])
 72              if 'linker' in info and info['linker'] is not None:
 73                  config.linker = info['linker']
 74              elif config.target is not None:
 75                  config.linker = config.target.linker
 76              if 'build_directory' in info and info['build_directory'] is not None:
 77                  config.build_directory = Path(info['build_directory'])
 78              if 'intermediate_directory' in info and info['intermediate_directory'] is not None:
 79                  config.intermediate_directory = Path(info['intermediate_directory'])
 80              if 'module_cache_directory' in info and info['module_cache_directory'] is not None:
 81                  config.module_cache_directory = Path(info['module_cache_directory'])
 82              if 'install_directory' in info and info['install_directory'] is not None:
 83                  config.install_directory = Path(info['install_directory'])
 84              if 'prefix' in info and info['prefix'] is not None:
 85                  config.prefix = info['prefix']
 86              if 'swift_install' in info and info['swift_install'] is not None:
 87                  config.swift_install = info['swift_install']
 88              if 'pkg_config' in info and info['pkg_config'] is not None:
 89                  config.pkg_config = info['pkg_config']
 90              if 'clang' in info and info['clang'] is not None:
 91                  config.clang = info['clang']
 92              if 'clangxx' in info and info['clangxx'] is not None:
 93                  config.clangxx = info['clangxx']
 94              if 'swift' in info and info['swift'] is not None:
 95                  config.swift = info['swift']
 96              if 'swiftc' in info and info['swiftc'] is not None:
 97                  config.swiftc = info['swiftc']
 98              if 'ar' in info and info['ar'] is not None:
 99                  config.ar = info['ar']
100              if 'swift_sdk' in info and info['swift_sdk'] is not None:
101                  config.swift_sdk = info['swift_sdk']
102              if 'bootstrap_directory' in info and info['bootstrap_directory'] is not None:
103                  config.bootstrap_directory = Path(info['bootstrap_directory'])
104              if 'verbose' in info and info['verbose'] is not None:
105                  config.verbose = info['verbose']
106              if 'extra_c_flags' in info and info['extra_c_flags'] is not None:
107                  config.extra_c_flags = info['extra_c_flags']
108              if 'extra_swift_flags' in info and info['extra_swift_flags'] is not None:
109                  config.extra_swift_flags = info['extra_swift_flags']
110              if 'extra_ld_flags' in info and info['extra_ld_flags'] is not None:
111                  config.extra_ld_flags = info['extra_ld_flags']
112              if 'build_mode' in info and info['build_mode'] is not None:
113                  config.build_mode = info['build_mode']
114              if 'variables' in info and info['variables'] is not None:
115                  config.variables = info['variables']
116          else:
117              sys.exit("invalid version")
118  
119  
120  def main():
121      config = Configuration()
122      CWD                           = Path.path(os.getcwd())
123      config.build_directory        = Path.path(os.getenv("BUILD_DIR", os.path.join(os.path.dirname(os.path.abspath(__file__)), "Build")))
124      config.module_cache_directory = Path.path(os.getenv("BUILD_DIR", config.build_directory.path_by_appending("ModuleCache")))
125      config.intermediate_directory = Path.path(os.getenv("INTERMEDIATE_DIR", config.build_directory.path_by_appending("Intermediates")))
126      config.install_directory      = Path.path(os.getenv("DSTROOT", "/"))
127      config.prefix                 = os.getenv("PREFIX", "/usr")
128      config.clang                  = os.getenv("CLANG", "clang")
129      config.clangxx                = os.getenv("CLANGXX", "clang")
130      config.swift                  = os.getenv("SWIFT", "swift")
131      config.swiftc                 = os.getenv("SWIFTC", "swiftc")
132      config.ar                     = os.getenv("AR", None)
133      config.source_root            = Path.path(os.getenv("SRCROOT", CWD))
134      config.extra_c_flags          = os.getenv("CFLAGS", "")
135      config.extra_swift_flags      = os.getenv("SWIFTCFLAGS", "")
136      config.extra_ld_flags         = os.getenv("LDFLAGS", "")
137      config.swift_sdk              = os.getenv("SDKROOT", None)
138      config.script_path            = config.source_root.path_by_appending("build.py")
139      config.build_script_path      = config.source_root.path_by_appending("build.ninja")
140      config.config_path            = config.source_root.path_by_appending(".configuration")
141  
142      parser = argparse.ArgumentParser(description='Configure and emit ninja build scripts for building.')
143      parser.add_argument('--target', dest='target', type=str, default=Target.default(), help="specify the deployment target")
144      parser.add_argument('--sysroot', dest='sysroot', type=str, default=None, help="the system root directory for building")
145      parser.add_argument('--toolchain', dest='toolchain', type=str, default=None, help="the base location for finding tools to compile")
146      parser.add_argument('--linker', dest='linker', type=str, default=None, help="which linker program to use")
147      parser.add_argument('--pkg-config', dest='pkg_config', type=str, default="pkg-config")
148      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")
149      parser.add_argument('--reconfigure', dest='reconfigure', action="store_true", help="re-generate the build script given the previous configuration")
150      parser.add_argument('-v', '--verbose', dest='verbose', action="store_true")
151      args, extras = parser.parse_known_args()
152      
153      if args.reconfigure:
154          reconfigure(config, config.config_path.absolute())
155          for arg in extras:
156              if arg.lower() == 'debug':
157                  config.build_mode = Configuration.Debug
158              elif arg.lower() == 'release':
159                  config.build_mode = Configuration.Release
160      else:
161          config.build_mode = Configuration.Debug # by default build in debug mode
162  
163          for arg in extras:
164              if arg.lower() == 'debug':
165                  config.build_mode = Configuration.Debug
166              elif arg.lower() == 'release':
167                  config.build_mode = Configuration.Release
168              elif arg.startswith('-D'): # accept -DNAME=value as extra parameters to the configuration of the build.ninja
169                  key, val = arg[2:].split("=", 1)
170                  config.variables[key] = val
171  
172          config.command = [os.path.abspath(__file__)] + sys.argv[1:]
173  
174          config.target = Target(args.target)
175  
176          config.system_root = Path.path(args.sysroot)
177          if config.target.sdk == OSType.MacOSX and config.system_root is None and Target(Target.default()).sdk == OSType.MacOSX:
178              import subprocess
179              config.system_root = Path.path(subprocess.Popen(['xcrun', '--show-sdk-path'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()[0])
180              swift_path = Path.path(subprocess.Popen(['xcrun', '--find', 'swift'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()[0]).parent().parent()
181              config.swift_sdk = swift_path.absolute()
182          elif config.swift_sdk is None:
183              config.swift_sdk = "/usr"
184          config.toolchain = Path.path(args.toolchain)
185          config.pkg_config = args.pkg_config
186          if args.linker is not None:
187              config.linker = args.linker
188          else:
189              config.linker = config.target.linker
190          config.bootstrap_directory = Path.path(args.bootstrap)
191          config.verbose = args.verbose
192          if config.toolchain is not None:
193              ar_path = os.path.join(config.toolchain.relative(), "ar")
194              if not os.path.exists(ar_path):
195                  ar_path = os.path.join(config.toolchain.relative(), "bin", "ar")
196              config.ar = ar_path
197          elif config.ar is None:
198              config.ar = "ar"
199  
200      config.write(config.config_path.absolute())
201      Configuration.current = config
202  
203      exec(compile(open(config.script_path.absolute()).read(), config.script_path.absolute(), 'exec'))
204  
205  
206  if __name__ == "__main__":
207      main()
208