Skip to content
Draft
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
11 changes: 10 additions & 1 deletion Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ let package = Package(
name: "xtool",
platforms: [
.iOS(.v16),
.macOS(.v13),
.macOS(.v14),
],
products: [
.library(
Expand Down Expand Up @@ -56,6 +56,7 @@ let package = Package(

.package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.0.0"),
.package(url: "https://github.com/swiftlang/swift-subprocess", .upToNextMinor(from: "0.4.0")),
.package(url: "https://github.com/swiftlang/swift-tools-protocols", exact: "0.0.10"),

.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.23.0"),
.package(url: "https://github.com/swift-server/swift-openapi-async-http-client", from: "1.0.0"),
Expand Down Expand Up @@ -159,6 +160,7 @@ let package = Package(
.product(name: "NIOPosix", package: "swift-nio"),
.product(name: "Version", package: "Version"),
.product(name: "libunxip", package: "unxip"),
.product(name: "LanguageServerProtocolTransport", package: "swift-tools-protocols"),
],
cSettings: cSettings
),
Expand Down
4 changes: 4 additions & 0 deletions Sources/CXKit/include/CXKit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "inotify_shim.h"
#include "stdout_shim.h"
#include "version.h"
#include "mobileprovision.h"
21 changes: 21 additions & 0 deletions Sources/CXKit/include/inotify_shim.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef CINOTIFY_SHIMS_H
#define CINOTIFY_SHIMS_H

#ifdef __linux__

#include <stdio.h>
#include <stdint.h>
#include <sys/inotify.h>

static inline const char *cin_event_name(const struct inotify_event *event) {
if (event->len)
return event->name;
else
return NULL;
}

static const uint32_t cin_all_events = IN_ALL_EVENTS;

#endif

#endif /* CINOTIFY_SHIMS_H */
51 changes: 42 additions & 9 deletions Sources/PackLib/BuildSettings.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Foundation
import Subprocess
import XUtils
import Superutils

public struct BuildSettings: Sendable {
private static let customBinDir =
Expand Down Expand Up @@ -44,9 +45,29 @@ public struct BuildSettings: Sendable {
return result.standardOutput?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
}

private static let swiftURL = Task {
private static let _swiftURL = Task {
try await FilePath(xcrun(["-f", "swift"]))
}

public static func swiftURL() async throws -> FilePath {
try await _swiftURL.value
}

private static let _swiftcURL = Task {
try await FilePath(xcrun(["-f", "swiftc"]))
}

public static func swiftcURL() async throws -> FilePath {
try await _swiftcURL.value
}
#else
public static func swiftURL() async throws -> FilePath {
try await FilePath(ToolRegistry.locate("swift")).orThrow(StringError("Got bad path for swift executable"))
}

public static func swiftcURL() async throws -> FilePath {
try await FilePath(ToolRegistry.locate("swiftc")).orThrow(StringError("Got bad path for swiftc executable"))
}
#endif

public func swiftPMInvocation(
Expand All @@ -66,7 +87,7 @@ public struct BuildSettings: Sendable {
// 1) invoking the real swift executable (located with `xcrun -f`) and
// 2) explicitly removing SDKROOT from the env, as it may be inherited
// through the `swift run pack` invocation.
executable = .path(try await Self.swiftURL.value)
executable = .path(try await Self.swiftURL())
#else
executable = .name("swift")
#endif
Expand All @@ -78,22 +99,34 @@ public struct BuildSettings: Sendable {
"--configuration", configuration.rawValue,
]

var rawEnv = ProcessInfo.processInfo.environment
rawEnv.removeValue(forKey: "SDKROOT")
let env = Dictionary(uniqueKeysWithValues: rawEnv.map {
(Environment.Key(rawValue: $0)!, $1)
})

return Configuration(
executable,
arguments: .init(baseArguments + extraArguments + sdkOptions + options + arguments),
environment: .custom(env),
environment: .inherit.updating(["SDKROOT": nil]),
platformOptions: .withGracefulShutDown,
)
}

public var buildServerArguments: [String] {
return [
"package", "experimental-build-server",
"--package-path", "\(FileManager.default.currentDirectoryPath)/xtool/.xtool-tmp",
"--build-system", "swiftbuild",
"--disable-automatic-resolution",
// TODO: once https://github.com/swiftlang/swift-package-manager/pull/9819 makes it into a release
// (Swift 6.4), pass --experimental-skip-acquiring-lock
] + sdkOptions + options
}
}

public enum BuildConfiguration: String, CaseIterable, Sendable {
case debug
case release

var swiftBuildValue: String {
switch self {
case .debug: "Debug"
case .release: "Release"
}
}
}
39 changes: 37 additions & 2 deletions Sources/PackLib/Packer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,38 @@ import XUtils
import Subprocess

public struct Packer: Sendable {
public enum BuildSystem: Sendable {
case swiftPM
case swiftBuild

public static var `default`: Self {
#if os(macOS)
return .swiftBuild
#else
return .swiftPM
#endif
}

fileprivate var pmName: String {
switch self {
case .swiftPM: "native"
case .swiftBuild: "swiftbuild"
}
}
}

public let buildSettings: BuildSettings
public let plan: Plan
public let buildSystem: BuildSystem

public init(buildSettings: BuildSettings, plan: Plan) {
public init(
buildSettings: BuildSettings,
plan: Plan,
buildSystem: BuildSystem = .default,
) {
self.plan = plan
self.buildSettings = buildSettings
self.buildSystem = buildSystem
}

private func build() async throws {
Expand Down Expand Up @@ -67,6 +93,7 @@ public struct Packer: Sendable {
// in order to dump the plan, so we can skip resolution here to skirt
// the issue.
"--disable-automatic-resolution",
"--build-system", buildSystem.pmName,
]
)
try await Subprocess.run(
Expand All @@ -83,8 +110,16 @@ public struct Packer: Sendable {

let outputURL = output.url

let binPath: String
switch buildSystem {
case .swiftPM:
binPath = "\(buildSettings.triple)/\(buildSettings.configuration.rawValue)"
case .swiftBuild:
let platformName = buildSettings.triple.contains("simulator") ? "iphonesimulator" : "iphoneos"
binPath = "out/Products/\(buildSettings.configuration.swiftBuildValue)-\(platformName)"
}
let binDir = URL(
fileURLWithPath: ".build/\(buildSettings.triple)/\(buildSettings.configuration.rawValue)",
fileURLWithPath: ".build/\(binPath)",
isDirectory: true
)

Expand Down
30 changes: 30 additions & 0 deletions Sources/XToolSupport/DevBSPCommand.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import ArgumentParser
import Foundation
import XKit
import PackLib
import Subprocess

struct DevBSPCommand: AsyncParsableCommand {
static let configuration = CommandConfiguration(
commandName: "build-server",
abstract: "Run build server",
)

@Option
var triple: String?

func run() async throws {
let settings = try await BuildSettings(
configuration: .debug,
triple: triple ?? PackOperation.defaultTriple
)
try await Subprocess.run(
.path(BuildSettings.swiftURL()),
arguments: .init(settings.buildServerArguments),
input: .standardInput,
output: .standardOutput,
error: .standardError,
)
.checkSuccess()
}
}
Loading
Loading