Skip to content
Open
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
56 changes: 13 additions & 43 deletions BuildSupport/SwiftSyntax/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,46 +1,16 @@
include(FetchContent)

# Ensure that the SwiftSyntax symbols we use are disjoint from elsewhere in
# the compiler toolchain.
set(SWIFT_MODULE_ABI_NAME_PREFIX "_PM")

# Use separate target names so the underlying libraries have a prefix separate
# from the rest of the toolchain.
set(SWIFTSYNTAX_TARGET_NAMESPACE "_PM")

# Handle installation on our own.
set(SWIFT_SYNTAX_INSTALL_TARGETS NO)
if(DEFINED SWIFTPM_PATH_TO_SWIFT_SYNTAX_SOURCE)
file(TO_CMAKE_PATH "${SWIFTPM_PATH_TO_SWIFT_SYNTAX_SOURCE}" swift_syntax_path)
FetchContent_Declare(SwiftSyntax
SOURCE_DIR "${swift_syntax_path}")
else()
FetchContent_Declare(SwiftSyntax
GIT_REPOSITORY https://github.com/swiftlang/swift-syntax
GIT_TAG main)
find_package(SwiftSyntax CONFIG GLOBAL)
if(NOT SwiftSyntax_FOUND)
set(SWIFT_SYNTAX_INSTALL_TARGETS YES)
if(DEFINED SWIFTPM_PATH_TO_SWIFT_SYNTAX_SOURCE)
file(TO_CMAKE_PATH "${SWIFTPM_PATH_TO_SWIFT_SYNTAX_SOURCE}" swift_syntax_path)
FetchContent_Declare(SwiftSyntax
SOURCE_DIR "${swift_syntax_path}")
else()
FetchContent_Declare(SwiftSyntax
GIT_REPOSITORY https://github.com/swiftlang/swift-syntax
GIT_TAG main)
endif()
FetchContent_MakeAvailable(SwiftSyntax)
endif()
FetchContent_MakeAvailable(SwiftSyntax)

# FIXME: Use FetchContent_Declare's EXCLUDE_FROM_ALL after CMake 3.28
FetchContent_GetProperties(SwiftSyntax BINARY_DIR binary_dir)
set_property(DIRECTORY "${binary_dir}" PROPERTY EXCLUDE_FROM_ALL TRUE)

# Install SwiftPM versions of the swift-syntax libraries we use.
set(SWIFTPM_SWIFT_SYNTAX_MODULES
_PMSwiftBasicFormat
_PMSwiftDiagnostics
_PMSwiftIDEUtils
_PMSwiftParser
_PMSwiftParserDiagnostics
_PMSwiftRefactor
_PMSwiftSyntax
_PMSwiftSyntaxBuilder
)

set(SWIFT_HOST_LIBRARIES_SUBDIRECTORY "swift/host")
foreach(target ${SWIFTPM_SWIFT_SYNTAX_MODULES})
install(TARGETS ${target}
LIBRARY DESTINATION lib/${SWIFT_HOST_LIBRARIES_SUBDIRECTORY}
RUNTIME DESTINATION bin
)
endforeach()
11 changes: 10 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,16 @@ let package = Package(
"Basics",
"PackageModel",
"SourceControl",
],
] + swiftSyntaxDependencies(
[
"SwiftDiagnostics",
"SwiftIfConfig",
"SwiftOperators",
"SwiftParser",
"SwiftParserDiagnostics",
"SwiftSyntax",
]
),
exclude: ["CMakeLists.txt", "README.md"],
swiftSettings: commonExperimentalFeatures
),
Expand Down
2 changes: 1 addition & 1 deletion Sources/Commands/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ add_library(Commands
Utilities/XCTEvents.swift)
target_link_libraries(Commands PUBLIC
SwiftCollections::OrderedCollections
SwiftSyntax::_PMSwiftRefactor
SwiftSyntax::SwiftRefactor
SwiftSystem::SystemPackage
ArgumentParser
Basics
Expand Down
33 changes: 33 additions & 0 deletions Sources/CoreCommands/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ public struct GlobalOptions: ParsableArguments {

@OptionGroup(title: "Trait Options")
public var traits: TraitOptions

@OptionGroup(title: "Manifest Options")
public var manifest: ManifestOptions
}

public struct LocationOptions: ParsableArguments {
Expand Down Expand Up @@ -877,6 +880,36 @@ public struct SBOMOptions: ParsableArguments {
}
}

public struct ManifestOptions: ParsableArguments {
public init() {}

@Option(
name: .customLong("experimental-manifest-processing-mode"),
help: "Specifies how manifest files are processed"
)
public var manifestProcessingMode: ManifestProcessingMode = .onlyExecuted

@Flag(
name: .customLong("experimental-show-manifest-parser-limitations"),
help: "Show any manifest parser limitations uncovered in the manifest file"
)
public var showManifestParserLimitations: Bool = false

public enum ManifestProcessingMode: String, ExpressibleByArgument {
case onlyParsed = "only-parsed"
case onlyExecuted = "only-executed"
case crosscheck = "crosscheck"
case parsedWithFallback = "parsed-with-fallback"

public static var allValueDescriptions: [String: String] {
["only-parsed" : "Use the built-in manifest parser",
"only-executed" : "Build and execute the manifest",
"parsed-with-fallback": "Use the built-in manifest parser. If it encounters limitations, fall back to building and executing the manifest.",
"crosscheck" : "Use both the built-in manifest parser and also execute the manifest, cross-checking the results"]
}
}
}

// MARK: - Extensions

extension BuildConfiguration {
Expand Down
28 changes: 26 additions & 2 deletions Sources/CoreCommands/SwiftCommandState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ public final class SwiftCommandState {
return rootManifests.values.map { $0.toolsVersion }.min()
}

func getManifestLoader() throws -> ManifestLoader {
func getManifestLoader() throws -> any ManifestLoaderProtocol {
try self._manifestLoader.get()
}

Expand Down Expand Up @@ -1113,7 +1113,16 @@ public final class SwiftCommandState {
)
})

private lazy var _manifestLoader: Result<ManifestLoader, Swift.Error> = Result(catching: {
private func createParsingManifestLoader() throws -> ParsingManifestLoader {
return try ParsingManifestLoader(
toolchain: self.getHostToolchain(),
pruneDependencies: self.options.resolver.pruneDependencies,
extraManifestFlags: self.options.build.manifestFlags,
environment: nil
)
}

private func createExecutingManifestLoader() throws -> ManifestLoader {
let cachePath: AbsolutePath? = switch (
self.options.caching.shouldDisableManifestCaching,
self.options.caching.manifestCachingMode
Expand Down Expand Up @@ -1143,6 +1152,21 @@ public final class SwiftCommandState {
importRestrictions: .none,
pruneDependencies: self.options.resolver.pruneDependencies
)
}

private lazy var _manifestLoader: Result<any ManifestLoaderProtocol, Swift.Error> = Result(
catching: {
switch self.options.manifest.manifestProcessingMode {
case .onlyParsed: try createParsingManifestLoader()
case .onlyExecuted: try createExecutingManifestLoader()
case .crosscheck, .parsedWithFallback:
ChainedParsingManifestLoader(
parsingLoader: try createParsingManifestLoader(),
executingLoader: try createExecutingManifestLoader(),
showLimitations: self.options.manifest.showManifestParserLimitations,
crosscheck: self.options.manifest.manifestProcessingMode == .crosscheck
)
}
})

/// An enum indicating the execution status of run commands.
Expand Down
20 changes: 18 additions & 2 deletions Sources/PackageLoading/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,28 @@ add_library(PackageLoading
RegistryReleaseMetadataSerialization.swift
Target+PkgConfig.swift
TargetSourcesBuilder.swift
ToolsVersionParser.swift)
ToolsVersionParser.swift

ManifestParsing/BuildConfiguration+HostToolchain.swift
ManifestParsing/ChainedParsingManifestLoader.swift
ManifestParsing/ManifestParseLimitation.swift
ManifestParsing/ManifestParserError.swift
ManifestParsing/ParsingManifestLoader.swift
)

target_link_libraries(PackageLoading PUBLIC
TSCBasic
Basics
PackageModel
TSCUtility)
TSCUtility

SwiftSyntax::SwiftDiagnostics
SwiftSyntax::SwiftIfConfig
SwiftSyntax::SwiftOperators
SwiftSyntax::SwiftParser
SwiftSyntax::SwiftParserDiagnostics
SwiftSyntax::SwiftSyntax
)
target_link_libraries(PackageLoading PUBLIC
$<$<NOT:$<PLATFORM_ID:Darwin>>:Foundation>)
target_link_libraries(PackageLoading PRIVATE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2014-2026 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
//
//===----------------------------------------------------------------------===//

import Basics
import SwiftIfConfig
import TSCUtility
import Foundation

extension StaticBuildConfiguration {
public static func getHostConfiguration(
usingSwiftCompiler swiftCompiler: AbsolutePath,
extraManifestFlags: [String],
) throws -> StaticBuildConfiguration {
// Call the compiler to get the static build configuration JSON.
let compilerOutput: String
do {
let args = [swiftCompiler.pathString, "-frontend", "-print-static-build-config"] + extraManifestFlags
let result = try AsyncProcess.popen(arguments: args)
compilerOutput = try result.utf8Output()
} catch {
throw InternalError("Failed to get target info (\(error.interpolationDescription))")
}

// Parse the compiler's JSON output.
guard let outputData = compilerOutput.data(using: .utf8) else {
throw InternalError("Failed to get data from compiler output for static build configuration: \(compilerOutput)")
}

let decoder = JSONDecoder()
return try decoder.decode(StaticBuildConfiguration.self, from: outputData)
}
}
Loading
Loading