XCode project for app, moved app project to folder

This commit is contained in:
Joe Mattiello
2023-03-01 22:07:19 -05:00
parent 365cadbb31
commit 4c9c5b1a56
371 changed files with 625 additions and 39 deletions

View File

@@ -0,0 +1,59 @@
//
// BuildSettings.swift
// Cargo
//
// Created by Joseph Mattiello on 02/28/23.
// Copyright © 2023 Joseph Mattiello. All rights reserved.
//
//set -eu;
//
//BUILT_SRC="./em_proxy/$LIB_FILE_NAME.a"
//ln -f -- "$BUILT_SRC" "$TARGET_BUILD_DIR/$EXECUTABLE_PATH" || cp "$BUILT_SRC" "$TARGET_BUILD_DIR/$EXECUTABLE_PATH"
//echo "$BUILT_SRC -> $TARGET_BUILD_DIR/$EXECUTABLE_PATH"
//# generated with cargo-xcode 1.5.0
//# modified to use prebuilt binaries
//
//set -eu;
//
//BUILT_SRC="./minimuxer/$LIB_FILE_NAME.a"
//ln -f -- "$BUILT_SRC" "$TARGET_BUILD_DIR/$EXECUTABLE_PATH" || cp "$BUILT_SRC" "$TARGET_BUILD_DIR/$EXECUTABLE_PATH"
//echo "$BUILT_SRC -> $TARGET_BUILD_DIR/$EXECUTABLE_PATH"
//
//# xcode generates dep file, but for its own path, so append our rename to it
// #DEP_FILE_SRC="minimuxer/target/${CARGO_XCODE_TARGET_TRIPLE}/release/${CARGO_XCODE_CARGO_DEP_FILE_NAME}"
// #if [ -f "$DEP_FILE_SRC" ]; then
//# DEP_FILE_DST="${DERIVED_FILE_DIR}/${CARGO_XCODE_TARGET_ARCH}-${EXECUTABLE_NAME}.d"
//# cp -f "$DEP_FILE_SRC" "$DEP_FILE_DST"
//# echo >> "$DEP_FILE_DST" "$SCRIPT_OUTPUT_FILE_0: $BUILT_SRC"
//#fi
//
//# lipo script needs to know all the platform-specific files that have been built
//# archs is in the file name, so that paths don't stay around after archs change
//# must match input for LipoScript
// #FILE_LIST="${DERIVED_FILE_DIR}/${ARCHS}-${EXECUTABLE_NAME}.xcfilelist"
// #touch "$FILE_LIST"
// #if ! egrep -q "$SCRIPT_OUTPUT_FILE_0" "$FILE_LIST" ; then
//# echo >> "$FILE_LIST" "$SCRIPT_OUTPUT_FILE_0"
//#fi
import ArgumentParser
/// A representation of a build setting in an Xcode project, e.g.
/// `IPHONEOS_DEPLOYMENT_TARGET=13.0`
struct BuildSetting: ExpressibleByArgument {
/// The name of the build setting, e.g. `IPHONEOS_DEPLOYMENT_TARGET`
let name: String
/// The value of the build setting
let value: String
init?(argument: String) {
let components = argument.components(separatedBy: "=")
guard components.count == 2 else { return nil }
name = components[0].trimmingCharacters(in: .whitespacesAndNewlines)
value = components[1].trimmingCharacters(in: .whitespacesAndNewlines)
}
}

View File

@@ -0,0 +1,71 @@
//
// Command+Options.swift
// Cargo
//
// Created by Joseph Mattiello on 02/28/23.
// Copyright © 2023 Joseph Mattiello. All rights reserved.
//
import ArgumentParser
import PackageModel
extension Command {
struct Options: ParsableArguments {
// MARK: - Package Loading
@Option(help: ArgumentHelp("The location of the Package", valueName: "directory"))
var packagePath = "."
// MARK: - Building
@Option(help: ArgumentHelp("The location of the build/cache directory to use", valueName: "directory"))
var buildPath = ".build"
@Option(help: ArgumentHelp("Build with a specific configuration", valueName: "debug|release"))
var configuration = PackageModel.BuildConfiguration.release
@Flag(inversion: .prefixedNo, help: "Whether to clean before we build")
var clean = true
@Flag(inversion: .prefixedNo, help: "Whether to include debug symbols in the built XCFramework")
var debugSymbols = true
@Flag(help: "Prints the available products and targets")
var listProducts = false
@Option(help: "The path to a .xcconfig file that can be used to override Xcode build settings. Relative to the package path.")
var xcconfig: String?
@Flag(help: "Enables Library Evolution for the whole build stack. Normally we apply it only to the targets listed to be built to work around issues with projects that don't support it.")
var stackEvolution: Bool = false
@Option(help: ArgumentHelp("Arbitrary Xcode build settings that are passed directly to the `xcodebuild` invocation. Can be specified multiple times.", valueName: "NAME=VALUE"))
var xcSetting: [BuildSetting] = []
// MARK: - Output Options
@Option(
help: ArgumentHelp(
"A list of platforms you want to build for. Can be specified multiple times."
+ " Default is to build for all platforms supported in your Package.swift, or all Apple platforms (except for maccatalyst platform) if omitted",
valueName: TargetPlatform.allCases.map { $0.rawValue }.joined(separator: "|")
)
)
var platform: [TargetPlatform] = []
@Option(help: ArgumentHelp("Where to place the compiled library", valueName: "directory"))
var output = "."
@Flag(help: .hidden)
var githubAction: Bool = false
// MARK: - Targets
@Argument(help: "An optional list of products (or targets) to build. Defaults to building all `.library` products")
var products: [String] = []
}
}
// MARK: - ParsableArguments Extensions
extension PackageModel.BuildConfiguration: ExpressibleByArgument {}

View File

@@ -0,0 +1,142 @@
//
// Command.swift
// Cargo
//
// Created by Joseph Mattiello on 02/28/23.
// Copyright © 2023 Joseph Mattiello. All rights reserved.
//
import ArgumentParser
import Foundation
import PackageLoading
import PackageModel
import TSCBasic
import Workspace
import Xcodeproj
struct Command: ParsableCommand {
// MARK: - Configuration
static var configuration = CommandConfiguration(
abstract: "Builds a `rust` package using `cargo`.",
discussion:
"""
""",
version: "1.1.0"
)
// MARK: - Arguments
@OptionGroup()
var options: Options
// MARK: - Execution
// swiftlint:disable:next function_body_length
func run() throws {
// load all/validate of the package info
let package = try PackageInfo(options: options)
// validate that package to make sure we can generate it
let validation = package.validationErrors()
if validation.isEmpty == false {
for error in validation {
print(error.isFatal ? "Error:" : "Warning:", error.errorDescription!)
}
if validation.contains(where: { $0.isFatal }) {
Darwin.exit(1)
}
}
// generate the Xcode project file
let generator = ProjectGenerator(package: package)
let platforms = try package.supportedPlatforms()
// get what we're building
try generator.writeDistributionXcconfig()
let project = try generator.generate()
// printing packages?
if 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
if options.stackEvolution == false {
try project.enableDistribution(targets: productNames, xcconfig: AbsolutePath(package.distributionBuildXcconfig.path).relative(to: AbsolutePath(package.rootDirectory.path)))
}
// save the project
try project.save(to: generator.projectPath)
// start building
let builder = XcodeBuilder(project: project, projectPath: generator.projectPath, package: package, options: options)
// clean first
if options.clean {
try builder.clean()
}
// all of our targets for each platform, then group the resulting .frameworks by target
var frameworkFiles: [String: [XcodeBuilder.BuildResult]] = [:]
for sdk in sdks {
try builder.build(targets: productNames, sdk: sdk)
.forEach { pair in
if frameworkFiles[pair.key] == nil {
frameworkFiles[pair.key] = []
}
frameworkFiles[pair.key]?.append(pair.value)
}
}
var xcframeworkFiles: [(String, Foundation.URL)] = []
// then we merge the resulting frameworks
try frameworkFiles
.forEach { pair in
xcframeworkFiles.append((pair.key, try builder.merge(target: pair.key, buildResults: pair.value)))
}
// zip it up if thats what they want
if options.zip {
let zipper = Zipper(package: package)
let zipped = try xcframeworkFiles
.flatMap { pair -> [Foundation.URL] in
let zip = try zipper.zip(target: pair.0, version: self.options.zipVersion, file: pair.1)
let checksum = try zipper.checksum(file: zip)
try zipper.clean(file: pair.1)
return [zip, checksum]
}
// notify the action if we have one
if options.githubAction {
let zips = zipped.map { $0.path }.joined(separator: "\n")
let data = Data(zips.utf8)
let url = Foundation.URL(fileURLWithPath: options.buildPath).appendingPathComponent("xcframework-zipfile.url")
try data.write(to: url)
}
}
}
}
// MARK: - Errors
private enum Error: Swift.Error, LocalizedError {
case noProducts
var errorDescription: String? {
switch self {
case .noProducts: return ""
}
}
}

View File

@@ -0,0 +1,12 @@
//
// Collection-Extensions.swift
// swift-create-xcframework
//
// Created by Rob Amos on 9/5/20.
//
extension Collection {
var nonEmpty: Self? {
isEmpty ? nil : self
}
}

View File

@@ -0,0 +1,27 @@
//
// PackageDescription+Extensions.swift
// swift-create-xcframework
//
// Created by Rob Amos on 7/5/20.
//
import PackageModel
extension ProductType {
var isLibrary: Bool {
if case .library = self {
return true
}
return false
}
}
extension Manifest {
var libraryProductNames: [String] {
products
.compactMap { product in
guard product.type.isLibrary else { return nil }
return product.name
}
}
}

View File

@@ -0,0 +1,113 @@
//
// Platforms.swift
// Cargo
//
// Created by Joseph Mattiello on 02/28/23.
// Copyright © 2023 Joseph Mattiello. All rights reserved.
//
import ArgumentParser
import PackageModel
enum TargetPlatform: String, ExpressibleByArgument, CaseIterable {
case ios
case macos
case maccatalyst
case tvos
case watchos
init?(argument: String) {
self.init(rawValue: argument.lowercased())
}
var platformName: String {
switch self {
case .ios: "ios"
case .macos: "macos"
case .maccatalyst: "macos"
case .tvos: "tvos"
case .watchos: "watchos"
}
}
// MARK: - Target SDKs
struct SDK {
let destination: String
let archiveName: String
let releaseFolder: String
let buildSettings: [String: String]?
}
var sdks: [SDK] {
switch self {
case .ios:
return [
SDK(
destination: "generic/platform=iOS",
archiveName: "iphoneos.xcarchive",
releaseFolder: "Release-iphoneos",
buildSettings: nil
),
SDK(
destination: "generic/platform=iOS Simulator",
archiveName: "iphonesimulator.xcarchive",
releaseFolder: "Release-iphonesimulator",
buildSettings: nil
)
]
case .macos:
return [
SDK(
destination: "generic/platform=macOS,name=Any Mac",
archiveName: "macos.xcarchive",
releaseFolder: "Release",
buildSettings: nil
)
]
case .maccatalyst:
return [
SDK(
destination: "generic/platform=macOS,variant=Mac Catalyst",
archiveName: "maccatalyst.xcarchive",
releaseFolder: "Release-maccatalyst",
buildSettings: ["SUPPORTS_MACCATALYST": "YES"]
)
]
case .tvos:
return [
SDK(
destination: "generic/platform=tvOS",
archiveName: "appletvos.xcarchive",
releaseFolder: "Release-appletvos",
buildSettings: nil
),
SDK(
destination: "generic/platform=tvOS Simulator",
archiveName: "appletvsimulator.xcarchive",
releaseFolder: "Release-appletvsimulator",
buildSettings: nil
)
]
case .watchos:
return [
SDK(
destination: "generic/platform=watchOS",
archiveName: "watchos.xcarchive",
releaseFolder: "Release-watchos",
buildSettings: nil
),
SDK(
destination: "generic/platform=watchOS Simulator",
archiveName: "watchsimulator.xcarchive",
releaseFolder: "Release-watchsimulator",
buildSettings: nil
)
]
}
}
}

View File

@@ -0,0 +1,9 @@
//
// main.swift
// Cargo
//
// Created by Joseph Mattiello on 02/28/23.
// Copyright © 2023 Joseph Mattiello. All rights reserved.
//
Command.main()