blob: 3e9e432cf7360c7d9e37ff62b19890b29782a12c [file] [log] [blame]
# 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
#
from .config import Configuration
from .phases import CompileC
from .phases import CompileCxx
from .phases import Assemble
from .phases import BuildAction
from .phases import MergeSwiftModule
from .target import OSType
from .path import Path
import os
class Product(BuildAction):
name = None
product_name = None
phases = []
installed_headers = []
CFLAGS = None
CXXFLAGS = None
LDFLAGS = None
ASFLAGS = None
SWIFTCFLAGS = ""
needs_stdcxx = False
needs_objc = False
GCC_PREFIX_HEADER = None
PUBLIC_HEADERS_FOLDER_PATH = os.path.join("usr", "include")
PUBLIC_MODULE_FOLDER_PATH = os.path.join("usr", "include")
PRIVATE_HEADERS_FOLDER_PATH = os.path.join("usr", "local", "include")
def __init__(self, name):
self.name = name
def generate(self):
generated = "\n\n"
for phase in self.phases:
generated += phase.generate()
return generated
def add_phase(self, phase):
phase.set_product(self)
if len(self.phases) > 0:
phase.previous = self.phases[-1]
self.phases.append(phase)
@property
def product(self):
return Configuration.current.build_directory.path_by_appending(self.name).path_by_appending(self.product_name)
@property
def public_module_path(self):
return Path.path(Configuration.current.build_directory.path_by_appending(self.name).absolute() + "/" + self.PUBLIC_MODULE_FOLDER_PATH)
@property
def public_headers_path(self):
return Path.path(Configuration.current.build_directory.path_by_appending(self.name).absolute() + "/" + self.PUBLIC_HEADERS_FOLDER_PATH)
@property
def private_headers_path(self):
return Path.path(Configuration.current.build_directory.path_by_appending(self.name).absolute() + "/" + self.PRIVATE_HEADERS_FOLDER_PATH)
@property
def project_headers_path(self):
return Path.path(Configuration.current.build_directory.path_by_appending(self.name).absolute() + "/" + self.PROJECT_HEADERS_FOLDER_PATH)
class Library(Product):
conformance_begin = ""
conformance_end = ""
rule = None
def __init__(self, name):
Product.__init__(self, name)
def generate(self, flags, objects = []):
generated = ""
if len(objects) == 0:
generated = Product.generate(self)
for phase in self.phases:
objects += phase.objects
product_flags = " ".join(flags)
if self.LDFLAGS is not None:
product_flags += " " + self.LDFLAGS
if self.needs_stdcxx:
product_flags += " -lstdc++"
generated += """
build """ + self.product.relative() + """: """ + self.rule + """ """ + self.conformance_begin + """ """ + " ".join(objects) + """ """ + self.conformance_end + """ """ + self.generate_dependencies() + """
flags = """ + product_flags
if self.needs_objc:
generated += """
start = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-begin.o
end = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-end.o
"""
generated += """
build """ + self.product_name + """: phony | """ + self.product.relative() + """
default """ + self.product_name + """
"""
return objects, generated
class DynamicLibrary(Library):
def __init__(self, name):
Library.__init__(self, name)
self.name = name
def generate(self, objects = []):
self.rule = "Link"
self.product_name = Configuration.current.target.dynamic_library_prefix + self.name + Configuration.current.target.dynamic_library_suffix
if Configuration.current.target.sdk == OSType.Linux or Configuration.current.target.sdk == OSType.FreeBSD:
self.conformance_begin = '${SDKROOT}/lib/swift/${OS}/${ARCH}/swift_begin.o'
self.conformance_end = '${SDKROOT}/lib/swift/${OS}/${ARCH}/swift_end.o'
return Library.generate(self, ["-shared", "-Wl,-soname," + self.product_name, "-Wl,--no-undefined"], objects)
else:
return Library.generate(self, ["-shared"], objects)
class Framework(Product):
def __init__(self, name):
Product.__init__(self, name)
self.product_name = name + ".framework"
@property
def public_module_path(self):
return Configuration.current.build_directory.path_by_appending(self.name).path_by_appending(self.product_name).path_by_appending("Modules")
@property
def public_headers_path(self):
return Configuration.current.build_directory.path_by_appending(self.name).path_by_appending(self.product_name).path_by_appending("Headers")
@property
def private_headers_path(self):
return Configuration.current.build_directory.path_by_appending(self.name).path_by_appending(self.product_name).path_by_appending("PrivateHeaders")
def generate(self):
generated = Product.generate(self)
objects = []
for phase in self.phases:
objects += phase.objects
product_flags = "-shared -Wl,-soname," + Configuration.current.target.dynamic_library_prefix + self.name + Configuration.current.target.dynamic_library_suffix + " -Wl,--no-undefined"
if self.LDFLAGS is not None:
product_flags += " " + self.LDFLAGS
if self.needs_stdcxx:
product_flags += " -lstdc++"
generated += """
build """ + self.product.path_by_appending(self.name).relative() + """: Link """ + " ".join(objects) + self.generate_dependencies() + """
flags = """ + product_flags
if self.needs_objc:
generated += """
start = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-begin.o
end = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-end.o
"""
generated += """
build """ + self.product_name + """: phony | """ + self.product.relative() + """
default """ + self.product_name + """
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() + """
"""
return generated
class StaticLibrary(Library):
def __init__(self, name):
Library.__init__(self, name)
self.name = name
def generate(self, objects = []):
self.rule = "Archive"
self.product_name = Configuration.current.target.static_library_prefix + self.name + Configuration.current.target.static_library_suffix
self.conformance_begin = ''
self.conformance_end = ''
return Library.generate(self, [], objects)
class StaticAndDynamicLibrary(StaticLibrary, DynamicLibrary):
def __init__(self, name):
StaticLibrary.__init__(self, name)
DynamicLibrary.__init__(self, name)
def generate(self):
objects, generatedForDynamic = DynamicLibrary.generate(self)
_, generatedForStatic = StaticLibrary.generate(self, objects)
return generatedForDynamic + generatedForStatic
class Executable(Product):
def __init__(self, name):
Product.__init__(self, name)
self.product_name = name + Configuration.current.target.executable_suffix
def generate(self):
generated = Product.generate(self)
return generated
class Application(Product):
executable = None
def __init__(self, name):
Product.__init__(self, name)
self.product_name = name + ".app"
def generate(self):
generated = Product.generate(self)
objects = []
for phase in self.phases:
objects += phase.objects
product_flags = ""
if self.LDFLAGS is not None:
product_flags += " " + self.LDFLAGS
if self.needs_stdcxx:
product_flags += " -lstdc++"
generated += """
build """ + self.product.path_by_appending(self.name).relative() + ": Link " + " ".join(objects) + self.generate_dependencies() + """
flags = """ + product_flags
if self.needs_objc:
generated += """
start = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-begin.o
end = ${TARGET_BOOTSTRAP_DIR}/usr/lib/objc-end.o
"""
return generated