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