PackageFramework.swift 4.34 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright (c) 2016 Anarchy Tools Contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

15 16 17 18 19 20 21
#if os(Linux)
import Glibc
#else
import Darwin
#endif

import atfoundation
22
import atpkg
23

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
private enum ModuleMapType: String {
    case Synthesized = "synthesized"
}

private enum Options: String {
    case Resources = "resources"
    case Headers = "headers"
    case ModuleMapType = "module-map-type"
    case Name = "name"
}

class PackageFramework: Tool {
    func compiler_crash() {
        #if !os(OSX)
        fatalError("packageframework is unsupported on this platform")
        #endif
    }
Drew's avatar
Drew committed
41
    func run(task: Task) {
Drew's avatar
Drew committed
42 43
        print("Warning: package-framework is deprecated and will be removed.  Use the plugin instead.")
        sleep(5)
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
        compiler_crash() //work around a compiler crash

        guard let moduleMapType = task[Options.ModuleMapType.rawValue]?.string else {
            fatalError("Specify a \(Options.ModuleMapType.rawValue)")
        }
        guard let name = task[Options.Name.rawValue]?.string else {
            fatalError("Specify a \(Options.Name.rawValue)")
        }
        precondition(moduleMapType == ModuleMapType.Synthesized.rawValue, "Unknown \(Options.ModuleMapType.rawValue) \(moduleMapType)")

        guard let resourcesV = task[Options.Resources.rawValue]?.vector else {
            fatalError("Specify \(Options.Resources.rawValue).  This should contain at least an info plist.")
        }
        if resourcesV.count < 0 {
            fatalError("\(Options.Resources.rawValue) should contain an info plist.")
        }
        var resources: [String] = []
        for resource in resourcesV {
            guard let s = resource.string else { fatalError("Non-string resource \(resource)")}
            resources.append(s)
        }

        //rm framework if it exists
67
        let frameworkPath = Path("bin/\(name).framework")
68 69
        let _ = try? FS.removeItem(path: frameworkPath, recursive: true)
        let _ = try? FS.createDirectory(path: frameworkPath)
70 71

        //'a' version
72 73
        let relativeAVersionPath = Path("Versions/A")
        let AVersionPath = frameworkPath + relativeAVersionPath
74
        try! FS.createDirectory(path: AVersionPath, intermediate: true)
75
        //'current' (produces code signing failures if absent)
76
        try! FS.symlinkItem(from: Path("A"), to: frameworkPath + "Versions/Current")
77
        //copy payload
78
        let payloadPath = task.importedPath.appending("bin").appending(name + Platform.targetPlatform.dynamicLibraryExtension)
79
        print(payloadPath)
80
        try! FS.copyItem(from: payloadPath, to: AVersionPath.appending(name))
81 82
        try! FS.symlinkItem(from: relativeAVersionPath.appending(name), to: frameworkPath.appending(name))

83 84

        //copy modules
85 86
        let modulePath = AVersionPath.appending("Modules").appending(name + ".swiftmodule")
        try! FS.createDirectory(path: modulePath, intermediate: true)
Drew's avatar
Drew committed
87 88
        try! FS.copyItem(from: Path("bin/\(name).swiftmodule"), to: modulePath.appending(Platform.targetPlatform.architecture.description + ".swiftmodule"))
        try! FS.copyItem(from: Path("bin/\(name).swiftdoc"), to: modulePath.appending(Platform.targetPlatform.architecture.description + ".swiftdoc"))
89
        try! FS.symlinkItem(from: relativeAVersionPath.appending("Modules"), to: frameworkPath.appending("Modules"))
90 91

        //copy resources
92 93
        let resourcesPath = AVersionPath.appending("Resources")
        try! FS.createDirectory(path: resourcesPath, intermediate: true)
94
        for resource in resources {
95
            try! FS.copyItem(from: task.importedPath + resource, to: resourcesPath + resource)
96
        }
97
        try! FS.symlinkItem(from: relativeAVersionPath + "Resources", to: frameworkPath + "Resources")
98 99

        //codesign
100
        let cmd = "codesign --force --deep --sign - --timestamp=none '\(AVersionPath)'"
101
        print(cmd)
Drew's avatar
Drew committed
102
        anarchySystem(cmd, environment: [:])
103 104
    }
}