Skip to content
This repository was archived by the owner on Apr 11, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions Sources/CreateXCFramework/Command.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,28 @@ struct Command: ParsableCommand {
let platforms = try package.supportedPlatforms()

// get what we're building
try generator.writeXcconfig()
let project = try generator.generate()

// printing packages?
if self.options.listProducts {
package.printAllProducts(project: project)
Darwin.exit(0)
}


// get valid packages and their SDKs
let productNames = try package.validProductNames(project: project)

let sdks = platforms.flatMap { $0.sdks }

// we've applied the xcconfig to everything, but some dependencies (*cough* swift-nio)
// have build errors, so we remove it from targets we're not building
for target in project.targets where productNames.contains(target.name) == false {
target.buildSettings.xcconfigFileRef = nil
}

// save the project
try project.save(to: generator.projectPath)


// start building
let builder = XcodeBuilder(project: project, projectPath: generator.projectPath, package: package, options: self.options)
Expand Down
6 changes: 6 additions & 0 deletions Sources/CreateXCFramework/PackageInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ struct PackageInfo {
.appendingPathComponent("swift-create-xcframework")
.absoluteURL
}

var distributionBuildXcconfig: Foundation.URL {
return self.projectBuildDirectory
.appendingPathComponent("Distribution.xcconfig")
.absoluteURL
}

// TODO: Map diagnostics to swift-log
let diagnostics = DiagnosticsEngine()
Expand Down
104 changes: 95 additions & 9 deletions Sources/CreateXCFramework/ProjectGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Foundation
import TSCBasic
import TSCUtility
import Xcodeproj

struct ProjectGenerator {
Expand All @@ -31,22 +32,107 @@ struct ProjectGenerator {
}

// MARK: - Generation


/// Writes out the Xcconfig file
func writeXcconfig () throws {
try open(AbsolutePath(self.package.distributionBuildXcconfig.path)) { stream in
stream (
"""
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
"""
)
}
}

/// Generate an Xcode project.
///
/// This is basically a copy of Xcodeproj.generate()
///
func generate () throws -> Xcode.Project {
let path = self.projectPath
try makeDirectories(path)
return try Xcodeproj.generate (
projectName: self.package.package.name,

// Generate the contents of project.xcodeproj (inside the .xcodeproj).
let project = try pbxproj (
xcodeprojPath: path,
graph: self.package.graph,
options: XcodeprojOptions(addExtraFiles: false),
extraDirs: [],
extraFiles: [],
options: XcodeprojOptions(xcconfigOverrides: AbsolutePath(self.package.distributionBuildXcconfig.path)),
diagnostics: self.package.diagnostics
)

return project
}

private func createDirectory (at path: URL) throws {
guard FileManager.default.fileExists(atPath: path.path) == false else { return }
try FileManager.default.createDirectory(at: path, withIntermediateDirectories: true, attributes: nil)
}


// MARK: - Saving Xcode Projects

extension Xcode.Project {

func save (to path: AbsolutePath) throws {
try open(path.appending(component: "project.pbxproj")) { stream in
// Serialize the project model we created to a plist, and return
// its string description.
let str = "// !$*UTF8*$!\n" + self.generatePlist().description
stream(str)
}

for target in self.frameworkTargets {
///// For framework targets, generate target.c99Name_Info.plist files in the
///// directory that Xcode project is generated
let name = "\(target.name.spm_mangledToC99ExtendedIdentifier())_Info.plist"
try open(path.appending(RelativePath(name))) { print in
print("""
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
""")
}
}
}
}

/// Writes the contents to the file specified.
///
/// This method doesn't rewrite the file in case the new and old contents of
/// file are same.
fileprivate func open(_ path: AbsolutePath, body: ((String) -> Void) throws -> Void) throws {
let stream = BufferedOutputByteStream()
try body { line in
stream <<< line
stream <<< "\n"
}
// If the file exists with the identical contents, we don't need to rewrite it.
//
// This avoids unnecessarily triggering Xcode reloads of the project file.
if let contents = try? localFileSystem.readFileContents(path), contents == stream.bytes {
return
}

// Write the real file.
try localFileSystem.writeFileContents(path, bytes: stream.bytes)
}
1 change: 0 additions & 1 deletion Sources/CreateXCFramework/XcodeBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ struct XcodeBuilder {
"-project", self.path.pathString,
"-configuration", self.options.configuration.xcodeConfigurationName,
"-sdk", sdk.sdkName,
"BUILD_LIBRARY_FOR_DISTRIBUTION=YES",
"BUILD_DIR=\(self.buildDirectory.path)"
]

Expand Down