product.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 from .phases import CompileC 12 from .phases import CompileCxx 13 from .phases import Assemble 14 from .phases import BuildAction 15 from .phases import MergeSwiftModule 16 from .target import OSType 17 from .path import Path 18 19 import os 20 21 class Product(BuildAction): 22 name = None 23 product_name = None 24 phases = [] 25 installed_headers = [] 26 CFLAGS = None 27 CXXFLAGS = None 28 LDFLAGS = None 29 ASFLAGS = None 30 SWIFTCFLAGS = "" 31 needs_stdcxx = False 32 needs_objc = False 33 GCC_PREFIX_HEADER = None 34 PUBLIC_HEADERS_FOLDER_PATH = os.path.join("usr", "include") 35 PUBLIC_MODULE_FOLDER_PATH = os.path.join("usr", "include") 36 PRIVATE_HEADERS_FOLDER_PATH = os.path.join("usr", "local", "include") 37 38 def __init__(self, name): 39 self.name = name 40 41 def generate(self): 42 generated = "\n\n" 43 for phase in self.phases: 44 generated += phase.generate() 45 return generated 46 47 def add_phase(self, phase): 48 phase.set_product(self) 49 if len(self.phases) > 0: 50 phase.previous = self.phases[-1] 51 self.phases.append(phase) 52 53 @property 54 def product(self): 55 return Configuration.current.build_directory.path_by_appending(self.name).path_by_appending(self.product_name) 56 57 @property 58 def public_module_path(self): 59 return Path.path(Configuration.current.build_directory.path_by_appending(self.name).absolute() + "/" + self.PUBLIC_MODULE_FOLDER_PATH) 60 61 @property 62 def public_headers_path(self): 63 return Path.path(Configuration.current.build_directory.path_by_appending(self.name).absolute() + "/" + self.PUBLIC_HEADERS_FOLDER_PATH) 64 65 @property 66 def private_headers_path(self): 67 return Path.path(Configuration.current.build_directory.path_by_appending(self.name).absolute() + "/" + self.PRIVATE_HEADERS_FOLDER_PATH) 68 69 @property 70 def project_headers_path(self): 71 return Path.path(Configuration.current.build_directory.path_by_appending(self.name).absolute() + "/" + self.PROJECT_HEADERS_FOLDER_PATH) 72 73 class Library(Product): 74 runtime_object = '' 75 rule = None 76 def __init__(self, name): 77 Product.__init__(self, name) 78 79 def generate(self, flags, objects = []): 80 generated = "" 81 if len(objects) == 0: 82 generated = Product.generate(self) 83 for phase in self.phases: 84 objects += phase.objects 85 86 product_flags = " ".join(flags) 87 if self.LDFLAGS is not None: 88 product_flags += " " + self.LDFLAGS 89 if self.needs_stdcxx: 90 product_flags += " -lstdc++" 91 92 generated += """ 93 build """ + self.product.relative() + """: """ + self.rule + """ """ + self.runtime_object + """ """ + " ".join(objects) + """ """ + self.generate_dependencies() + """ 94 flags = """ + product_flags 95 if self.needs_objc: 96 generated += """ 97 start = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-begin.o 98 end = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-end.o 99 """ 100 101 generated += """ 102 103 build """ + self.product_name + """: phony | """ + self.product.relative() + """ 104 105 default """ + self.product_name + """ 106 107 """ 108 109 return objects, generated 110 111 112 class DynamicLibrary(Library): 113 def __init__(self, name, uses_swift_runtime_object = True): 114 Library.__init__(self, name) 115 self.name = name 116 self.uses_swift_runtime_object = uses_swift_runtime_object 117 118 def generate(self, objects = []): 119 self.rule = "Link" 120 self.product_name = Configuration.current.target.dynamic_library_prefix + self.name + Configuration.current.target.dynamic_library_suffix 121 if (Configuration.current.target.sdk == OSType.Linux or Configuration.current.target.sdk == OSType.FreeBSD) and self.uses_swift_runtime_object: 122 self.runtime_object = '${SDKROOT}/lib/swift/${OS}/${ARCH}/swiftrt.o' 123 return Library.generate(self, ["-shared", "-Wl,-soname," + self.product_name, "-Wl,--no-undefined"], objects) 124 else: 125 return Library.generate(self, ["-shared"], objects) 126 127 128 class Framework(Product): 129 def __init__(self, name): 130 Product.__init__(self, name) 131 self.product_name = name + ".framework" 132 133 @property 134 def public_module_path(self): 135 return Configuration.current.build_directory.path_by_appending(self.name).path_by_appending(self.product_name).path_by_appending("Modules") 136 137 @property 138 def public_headers_path(self): 139 return Configuration.current.build_directory.path_by_appending(self.name).path_by_appending(self.product_name).path_by_appending("Headers") 140 141 @property 142 def private_headers_path(self): 143 return Configuration.current.build_directory.path_by_appending(self.name).path_by_appending(self.product_name).path_by_appending("PrivateHeaders") 144 145 def generate(self): 146 generated = Product.generate(self) 147 objects = [] 148 for phase in self.phases: 149 objects += phase.objects 150 product_flags = "-shared -Wl,-soname," + Configuration.current.target.dynamic_library_prefix + self.name + Configuration.current.target.dynamic_library_suffix + " -Wl,--no-undefined" 151 if self.LDFLAGS is not None: 152 product_flags += " " + self.LDFLAGS 153 if self.needs_stdcxx: 154 product_flags += " -lstdc++" 155 156 generated += """ 157 158 build """ + self.product.path_by_appending(self.name).relative() + """: Link """ + " ".join(objects) + self.generate_dependencies() + """ 159 flags = """ + product_flags 160 if self.needs_objc: 161 generated += """ 162 start = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-begin.o 163 end = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-end.o 164 """ 165 166 generated += """ 167 build """ + self.product_name + """: phony | """ + self.product.relative() + """ 168 169 default """ + self.product_name + """ 170 171 build ${TARGET_BOOTSTRAP_DIR}/usr/lib/""" + Configuration.current.target.dynamic_library_prefix + self.name + Configuration.current.target.dynamic_library_suffix + """: Cp """ + self.product.path_by_appending(self.name).relative() + """ 172 """ 173 174 return generated 175 176 class StaticLibrary(Library): 177 def __init__(self, name): 178 Library.__init__(self, name) 179 self.name = name 180 181 def generate(self, objects = []): 182 self.rule = "Archive" 183 self.product_name = Configuration.current.target.static_library_prefix + self.name + Configuration.current.target.static_library_suffix 184 self.runtime_object = '' 185 return Library.generate(self, [], objects) 186 187 class StaticAndDynamicLibrary(StaticLibrary, DynamicLibrary): 188 def __init__(self, name): 189 StaticLibrary.__init__(self, name) 190 DynamicLibrary.__init__(self, name) 191 192 def generate(self): 193 objects, generatedForDynamic = DynamicLibrary.generate(self) 194 _, generatedForStatic = StaticLibrary.generate(self, objects) 195 return generatedForDynamic + generatedForStatic 196 197 class Executable(Product): 198 def __init__(self, name): 199 Product.__init__(self, name) 200 self.product_name = name + Configuration.current.target.executable_suffix 201 202 def generate(self): 203 generated = Product.generate(self) 204 205 return generated 206 207 class Application(Product): 208 executable = None 209 def __init__(self, name): 210 Product.__init__(self, name) 211 self.product_name = name + ".app" 212 213 def generate(self): 214 generated = Product.generate(self) 215 objects = [] 216 for phase in self.phases: 217 objects += phase.objects 218 product_flags = "" 219 220 if self.LDFLAGS is not None: 221 product_flags += " " + self.LDFLAGS 222 if self.needs_stdcxx: 223 product_flags += " -lstdc++" 224 225 226 generated += """ 227 build """ + self.product.path_by_appending(self.name).relative() + ": Link " + " ".join(objects) + self.generate_dependencies() + """ 228 flags = """ + product_flags 229 if self.needs_objc: 230 generated += """ 231 start = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-begin.o 232 end = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-end.o 233 """ 234 235 return generated 236