/ lib / script.py
script.py
  1  # This source file is part of the Swift.org open source project
  2  #
  3  # Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
  4  # Licensed under Apache License v2.0 with Runtime Library Exception
  5  #
  6  # See http://swift.org/LICENSE.txt for license information
  7  # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
  8  #
  9  
 10  from .config import Configuration
 11  import os
 12  
 13  class Script:
 14      products = []
 15      workspaces = []
 16      extra = ""
 17  
 18      def __init__(self):
 19          pass
 20  
 21      def add_product(self, product):
 22          self.workspaces = None
 23          self.products.append(product)
 24  
 25      def add_workspace(self, workspace):
 26          self.products = None
 27          self.workspaces.append(workspace)
 28  
 29      def add_text(self, text):
 30          self.extra += text + "\n\n"
 31  
 32      def generate_products(self):
 33          variables = ""
 34          for key, val in Configuration.current.variables.items():
 35              variables += key + "=" + val
 36              variables += "\n"
 37          verbose_flags = """
 38  VERBOSE_FLAGS = """ 
 39          if Configuration.current.verbose:
 40              verbose_flags += "-v"
 41          verbose_flags += "\n"
 42          swift_triple = Configuration.current.target.swift_triple
 43          base_flags = """
 44  TARGET                = """ + Configuration.current.target.triple + """
 45  DSTROOT               = """ + Configuration.current.install_directory.absolute() + """
 46  """
 47          if swift_triple is not None:
 48              base_flags += """
 49  SWIFT_TARGET          = """ + Configuration.current.target.swift_triple + """
 50  SWIFT_ARCH            = """ + Configuration.current.target.swift_arch + """
 51  """
 52          base_flags += """
 53  MODULE_CACHE_PATH     = """ + Configuration.current.module_cache_directory.relative() + """
 54  BUILD_DIR             = """ + Configuration.current.build_directory.relative() + """
 55  INTERMEDIATE_DIR      = """ + Configuration.current.intermediate_directory.relative() + """
 56  CLANG                 = """ + Configuration.current.clang + """
 57  CLANGXX               = """ + Configuration.current.clangxx + """
 58  SWIFT                 = """ + Configuration.current.swift + """
 59  SWIFTC                = """ + Configuration.current.swiftc + """
 60  SDKROOT               = """ + Configuration.current.swift_sdk + """
 61  AR                    = """ + Configuration.current.ar + """
 62  OS                    = """ + Configuration.current.target.swift_sdk_name + """
 63  ARCH                  = """ + Configuration.current.target.swift_arch + """
 64  DYLIB_PREFIX          = """ + Configuration.current.target.dynamic_library_prefix + """
 65  DYLIB_SUFFIX          = """ + Configuration.current.target.dynamic_library_suffix + """
 66  STATICLIB_PREFIX      = """ + Configuration.current.target.static_library_prefix + """
 67  STATICLIB_SUFFIX      = """ + Configuration.current.target.static_library_suffix + """
 68  PREFIX                = """ + Configuration.current.prefix + """
 69  """
 70          if Configuration.current.requires_pkg_config:
 71              base_flags += """
 72  PKG_CONFIG            = """ + Configuration.current.pkg_config + """
 73  """
 74          if Configuration.current.system_root is not None:
 75              base_flags += """
 76  SYSROOT               = """ + Configuration.current.system_root.absolute() + """
 77  """
 78          base_flags += """
 79  SRCROOT               = """ + Configuration.current.source_root.relative() + """
 80  BINUTILS_VERSION      = 4.8
 81  TARGET_LDSYSROOT      =
 82  """
 83          
 84          if Configuration.current.bootstrap_directory is not None:
 85              base_flags += """
 86  BOOTSTRAP_DIR         = """ + Configuration.current.bootstrap_directory.relative() + """/common
 87  TARGET_BOOTSTRAP_DIR  = """ + Configuration.current.bootstrap_directory.relative() + """/${TARGET}
 88  """
 89  
 90          c_flags = """
 91  TARGET_CFLAGS         = -fcolor-diagnostics -fdollars-in-identifiers -fblocks -fobjc-runtime=macosx-10.11 -fintegrated-as -fPIC --target=${TARGET} """
 92  
 93          if Configuration.current.build_mode == Configuration.Debug:
 94              c_flags += "-g -O0 "
 95          elif Configuration.current.build_mode == Configuration.Release:
 96              c_flags += "-O2 "
 97  
 98          if Configuration.current.system_root is not None:
 99              c_flags += "--sysroot=${SYSROOT}"
100  
101          if Configuration.current.bootstrap_directory is not None:
102              c_flags += """  -I${BOOTSTRAP_DIR}/usr/include -I${BOOTSTRAP_DIR}/usr/local/include """
103              c_flags += """  -I${TARGET_BOOTSTRAP_DIR}/usr/include -I${TARGET_BOOTSTRAP_DIR}/usr/local/include """
104          
105          c_flags += Configuration.current.extra_c_flags
106  
107          swift_flags = "\nTARGET_SWIFTCFLAGS    = -I${SDKROOT}/lib/swift/" + Configuration.current.target.swift_sdk_name + " -Xcc -fblocks -resource-dir ${SDKROOT}/lib/swift "
108          if swift_triple is not None:
109              swift_flags += "-target ${SWIFT_TARGET} "
110          if Configuration.current.system_root is not None:
111              swift_flags += "-sdk ${SYSROOT} "
112  
113          if Configuration.current.bootstrap_directory is not None:
114              swift_flags += """  -I${BOOTSTRAP_DIR}/usr/include -I${BOOTSTRAP_DIR}/usr/local/include """
115              swift_flags += """  -I${TARGET_BOOTSTRAP_DIR}/usr/include -I${TARGET_BOOTSTRAP_DIR}/usr/local/include """
116  
117          if Configuration.current.build_mode == Configuration.Debug:
118              swift_flags += "-g -Onone "
119          elif Configuration.current.build_mode == Configuration.Release:
120              swift_flags += "-O "
121  
122          swift_flags += Configuration.current.extra_swift_flags
123          
124          swift_flags += """
125  TARGET_SWIFTEXE_FLAGS = -I${SDKROOT}/lib/swift/""" + Configuration.current.target.swift_sdk_name + """  -L${SDKROOT}/lib/swift/""" + Configuration.current.target.swift_sdk_name + """ """
126          if Configuration.current.build_mode == Configuration.Debug:
127              swift_flags += "-g -Onone -enable-testing -DNS_FOUNDATION_ALLOWS_TESTABLE_IMPORT "
128          elif Configuration.current.build_mode == Configuration.Release:
129              swift_flags += " "
130          swift_flags += Configuration.current.extra_swift_flags
131  
132  
133  
134          ld_flags = """
135  EXTRA_LD_FLAGS       = """ + Configuration.current.extra_ld_flags
136  
137          ld_flags += """
138  TARGET_LDFLAGS       = --target=${TARGET} ${EXTRA_LD_FLAGS} -L ${SDKROOT}/lib/swift/""" + Configuration.current.target.swift_sdk_name + """/${ARCH} -L${SDKROOT}/lib/swift/""" + Configuration.current.target.swift_sdk_name + """ """
139          if Configuration.current.system_root is not None:
140              ld_flags += "--sysroot=${SYSROOT}"
141  
142          if Configuration.current.bootstrap_directory is not None:
143              ld_flags += """ -L${TARGET_BOOTSTRAP_DIR}/usr/lib"""
144  
145          if Configuration.current.build_mode == Configuration.Debug:
146              ld_flags += """  -rpath ${SDKROOT}/lib/swift/""" + Configuration.current.target.swift_sdk_name + """ """
147  
148          if Configuration.current.linker is not None:
149              ld_flags += " -fuse-ld=" + Configuration.current.linker
150  
151          if Configuration.current.toolchain is not None:
152              bin_dir = Configuration.current.toolchain
153              if not os.path.exists(bin_dir.path_by_appending("ld").relative()):
154                  bin_dir = Configuration.current.toolchain.path_by_appending("bin")
155              c_flags += " -B" + bin_dir.relative()
156              ld_flags += " -B" + bin_dir.relative()
157  
158          c_flags += "\n"
159          swift_flags += "\n"
160          ld_flags += "\n"
161  
162          cxx_flags = """
163  TARGET_CXXFLAGS       = -std=gnu++11 -I${SYSROOT}/usr/include/c++/${BINUTILS_VERSION} -I${SYSROOT}/usr/include/${TARGET}/c++/${BINUTILS_VERSION}
164  """
165  
166          ar_flags = """
167  AR_FLAGS              = rcs
168  """
169  
170          flags = variables + verbose_flags + base_flags + c_flags + swift_flags + cxx_flags + ld_flags + ar_flags
171  
172          cp_command = """
173  rule Cp
174      command = mkdir -p `dirname $out`; /bin/cp -r $in $out
175      description = Cp $in
176  """
177  
178          compilec_command = """
179  rule CompileC
180      command = mkdir -p `dirname $out`; ${CLANG} ${TARGET_CFLAGS} $flags ${VERBOSE_FLAGS} -c $in -o $out 
181      description = CompileC: $in
182  
183  rule CompileCxx
184      command = mkdir -p `dirname $out`; ${CLANGXX} ${TARGET_CFLAGS} ${TARGET_CXXFLAGS} $flags ${VERBOSE_FLAGS} -c $in -o $out 
185      description = CompileCxx: $in
186  """
187  
188          swiftc_command = """
189  rule CompileSwift
190      command = mkdir -p `dirname $out`; mkdir -p ${MODULE_CACHE_PATH}; ${SWIFT} -frontend -c $module_sources ${TARGET_SWIFTCFLAGS} $flags -module-name $module_name -module-link-name $module_name -o $out -emit-module-path $out.~partial.swiftmodule -emit-module-doc-path $out.~partial.swiftdoc -emit-dependencies-path $out.d -emit-reference-dependencies-path $out.swiftdeps -module-cache-path ${MODULE_CACHE_PATH}
191      description = CompileSwift: $in
192      depfile = $out.d
193  
194  rule MergeSwiftModule
195      command = mkdir -p `dirname $out`; ${SWIFT} -frontend -sil-merge-partial-modules -emit-module $partials ${TARGET_SWIFTCFLAGS} $flags -module-cache-path ${MODULE_CACHE_PATH} -module-link-name $module_name -o $out
196      description = Merge $out
197  """
198  
199          assembler_command = """
200  rule Assemble
201      command = mkdir -p `dirname $out`; ${CLANG} -x assembler-with-cpp -c $in -o $out ${TARGET_CFLAGS} $flags ${VERBOSE_FLAGS} 
202      description = Assemble: $in
203  """
204  
205          link_command = """
206  rule Link
207      command = mkdir -p `dirname $out`; ${CLANG} ${TARGET_LDFLAGS} ${VERBOSE_FLAGS} $start $in $end $flags -o $out""" 
208          if Configuration.current.verbose:
209              link_command += "-Xlinker --verbose"
210          link_command += """
211      description = Link: $out
212  
213  rule Archive
214      command = mkdir -p `dirname $out`; ${AR} ${AR_FLAGS} $out $in
215      description = Archive: $out
216  """
217          
218          swift_build_command = """
219  rule SwiftExecutable
220      command = mkdir -p `dirname $out`; ${SWIFTC} ${TARGET_SWIFTEXE_FLAGS} ${EXTRA_LD_FLAGS} $flags $in -o $out
221      description = SwiftExecutable: $out
222  """
223  
224          commands = cp_command + compilec_command + swiftc_command + assembler_command + link_command + swift_build_command
225  
226          script = flags + commands
227  
228          for product in self.products:
229              script += "".join([product_build_command for product_build_command in product.generate() if not isinstance(product_build_command, list)])
230  
231          script += """
232  
233  rule RunReconfigure
234      command = ./configure --reconfigure
235      description = Reconfiguring build script.
236  
237  build ${BUILD_DIR}/.reconfigure: RunReconfigure
238  
239  build reconfigure: phony | ${BUILD_DIR}/.reconfigure
240  
241  """
242          script += self.extra
243          script += "\n\n"
244  
245          return script
246  
247      def generate_workspaces(self):
248  
249          build_project_command = """
250  rule BuildProject
251      command = pushd $project; ninja; popd
252  """
253          script = build_project_command
254  
255          for workspace in self.workspaces:
256              script += workspace.generate()
257  
258          script += "\n\n"
259  
260          return script
261  
262      def generate(self):
263          script = None
264          if self.workspaces is None:
265              script = self.generate_products()
266              script_file = open(Configuration.current.build_script_path.absolute(), 'w')
267              script_file.write(script)
268              script_file.close()
269          else:
270              for workspace in self.workspaces:
271                  workspace.configure()
272              script = self.generate_workspaces()
273              
274