Skip to content
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
90 changes: 41 additions & 49 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ func envEnable(_ key: String, default defaultValue: Bool = false) -> Bool {
}
}

// MARK: - Env and Config

let isXcodeEnv = Context.environment["__CFBundleIdentifier"] == "com.apple.dt.Xcode"

// Xcode use clang as linker which supports "-iframework" while SwiftPM use swiftc as linker which supports "-Fsystem"
let systemFrameworkSearchFlag = isXcodeEnv ? "-iframework" : "-Fsystem"

let swiftBinPath = Context.environment["_"] ?? "/usr/bin/swift"
let swiftBinURL = URL(fileURLWithPath: swiftBinPath)
let SDKPath = swiftBinURL.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent().path
let includePath = SDKPath.appending("/usr/lib/swift")

var sharedCSettings: [CSetting] = [
.unsafeFlags(["-I", includePath], .when(platforms: .nonDarwinPlatforms)),
.define("__COREFOUNDATION_FORSWIFTFOUNDATIONONLY__", to: "1", .when(platforms: .nonDarwinPlatforms)),
.define("_WASI_EMULATED_SIGNAL", .when(platforms: [.wasi])),
]

var sharedSwiftSettings: [SwiftSetting] = [
.enableUpcomingFeature("BareSlashRegexLiterals"),
.enableUpcomingFeature("InternalImportsByDefault"),
Expand All @@ -25,54 +43,27 @@ var sharedSwiftSettings: [SwiftSetting] = [
.swiftLanguageMode(.v5),
]

// MARK: - [env] OPENGRAPH_TARGET_RELEASE

let releaseVersion = Context.environment["OPENSWIFTUI_TARGET_RELEASE"].flatMap { Int($0) } ?? 2024
sharedCSettings.append(.define("OPENSWIFTUI_RELEASE", to: "\(releaseVersion)"))
sharedSwiftSettings.append(.define("OPENSWIFTUI_RELEASE_\(releaseVersion)"))
if releaseVersion >= 2021 {
for year in 2021 ... releaseVersion {
sharedSwiftSettings.append(.define("OPENSWIFTUI_SUPPORT_\(year)_API"))
}
}

let platforms: [SupportedPlatform] = switch releaseVersion {
case 2024: // iOS 18.0
[
.iOS(.v18),
.macOS(.v15),
.macCatalyst(.v18),
.tvOS(.v18),
.watchOS(.v10),
.visionOS(.v2),
]
case 2021: // iOS 15.5
[
.iOS(.v15),
.macOS(.v12),
.macCatalyst(.v15),
.tvOS(.v15),
.watchOS(.v7),
]
default:
[
.iOS(.v13),
.macOS(.v10_15),
.macCatalyst(.v13),
.tvOS(.v13),
.watchOS(.v7), // WKApplicationMain is available for watchOS 7.0+
.visionOS(.v1),
]
}

let isXcodeEnv = Context.environment["__CFBundleIdentifier"] == "com.apple.dt.Xcode"

// Xcode use clang as linker which supports "-iframework" while SwiftPM use swiftc as linker which supports "-Fsystem"
let systemFrameworkSearchFlag = isXcodeEnv ? "-iframework" : "-Fsystem"
// MARK: - [env] OPENSWIFTUI_DEVELOPMENT

let development = envEnable("OPENSWIFTUI_DEVELOPMENT")

if development {
sharedSwiftSettings.append(.define("OPENSWIFTUI_DEVELOPMENT"))
}

// MARK: - [env] OPENSWIFTUI_WERROR

let warningsAsErrorsCondition = envEnable("OPENSWIFTUI_WERROR", default: isXcodeEnv && development)
if warningsAsErrorsCondition {
// Hold off the werror feature as we can't avoid the concurrency warning.
Expand All @@ -82,6 +73,12 @@ if warningsAsErrorsCondition {
// sharedSwiftSettings.append(.unsafeFlags(["-Wwarning", "concurrency"]))
}

// MARK: - [env] OPENSWIFTUI_BRIDGE_FRAMEWORK

let bridgeFramework = Context.environment["OPENSWIFTUI_BRIDGE_FRAMEWORK"] ?? "SwiftUI"

// MARK: - Targets

// NOTE:
// In macOS: Mac Catalyst App will use macOS-varient build of SwiftUI.framework in /System/Library/Framework and iOS varient of SwiftUI.framework in /System/iOSSupport/System/Library/Framework
// Add `|| Mac Catalyst` check everywhere in `OpenSwiftUICore` and `OpenSwiftUI_SPI`.
Expand Down Expand Up @@ -113,7 +110,6 @@ let openSwiftUIExtensionTarget = Target.target(
swiftSettings: sharedSwiftSettings
)

let bridgeFramework = Context.environment["OPENSWIFTUI_BRIDGE_FRAMEWORK"] ?? "SwiftUI"
let openSwiftUIBridgeTarget = Target.target(
name: "OpenSwiftUIBridge",
dependencies: [
Expand Down Expand Up @@ -168,11 +164,6 @@ let openSwiftUIBridgeTestTarget = Target.testTarget(
swiftSettings: sharedSwiftSettings
)

let swiftBinPath = Context.environment["_"] ?? "/usr/bin/swift"
let swiftBinURL = URL(fileURLWithPath: swiftBinPath)
let SDKPath = swiftBinURL.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent().path
let includePath = SDKPath.appending("/usr/lib/swift")

// Workaround iOS CI build issue (We need to disable this on iOS CI)
let supportMultiProducts: Bool = envEnable("OPENSWIFTUI_SUPPORT_MULTI_PRODUCTS", default: true)

Expand All @@ -189,7 +180,6 @@ if supportMultiProducts {

let package = Package(
name: "OpenSwiftUI",
platforms: platforms,
products: products,
dependencies: [
.package(url: "https://github.com/apple/swift-numerics.git", from: "1.0.2"),
Expand All @@ -207,19 +197,12 @@ let package = Package(
.target(
name: "OpenSwiftUI_SPI",
publicHeadersPath: ".",
cSettings: [
.unsafeFlags(["-I", includePath], .when(platforms: .nonDarwinPlatforms)),
.define("__COREFOUNDATION_FORSWIFTFOUNDATIONONLY__", to: "1", .when(platforms: .nonDarwinPlatforms)),
.define("_WASI_EMULATED_SIGNAL", .when(platforms: [.wasi])),
]
cSettings: sharedCSettings
),
.target(
name: "COpenSwiftUI",
publicHeadersPath: ".",
cSettings: [
.unsafeFlags(["-I", includePath], .when(platforms: .nonDarwinPlatforms)),
.define("__COREFOUNDATION_FORSWIFTFOUNDATIONONLY__", to: "1", .when(platforms: .nonDarwinPlatforms)),
.define("_WASI_EMULATED_SIGNAL", .when(platforms: [.wasi])),
cSettings: sharedCSettings + [
.headerSearchPath("../OpenSwiftUI_SPI"),
]
),
Expand Down Expand Up @@ -315,6 +298,15 @@ if renderBoxCondition {
openSwiftUIBridgeTestTarget.addRBSettings()
}

if attributeGraphCondition || renderBoxCondition {
let release = Context.environment["DARWIN_PRIVATE_FRAMEWORKS_TARGET_RELEASE"].flatMap { Int($0) } ?? 2024
package.platforms = switch release {
case 2024: [.iOS(.v18), .macOS(.v15), .macCatalyst(.v18), .tvOS(.v18), .watchOS(.v10), .visionOS(.v2)]
case 2021: [.iOS(.v15), .macOS(.v12), .macCatalyst(.v15), .tvOS(.v15), .watchOS(.v7)]
default: nil
}
}

if useLocalDeps {
package.dependencies += [
.package(path: "../OpenGraph"),
Expand Down
25 changes: 16 additions & 9 deletions Sources/OpenSwiftUICore/Util/Tracing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,26 @@ package struct Tracing {
if let cachedName = moduleLookupCache.value[nominalDescriptor] {
return cachedName
} else {
#if canImport(Darwin)
var info = Dl_info()
guard dladdr(nominalDescriptor, &info) != 0 else {
// Use C Shims layer to import dladdr since we can't call it on non-Darwin Swift platform
// See https://forums.swift.org/t/dladdr-and-the-clang-importer/26379/11
//
// var info = Dl_info()
// guard dladdr(nominalDescriptor, &info) != 0 else {
// return unknown
// }
// let pathName = info.dli_fname

guard let pathName = getSymbolPathName(nominalDescriptor) else {
return unknown
}
let name = (String(cString: info.dli_fname) as NSString).lastPathComponent
moduleLookupCache.value[nominalDescriptor] = name
return name
let path = String(cString: pathName)
#if canImport(Darwin)
let libraryName = (path as NSString).lastPathComponent
#else
// TODO: [Easy] Add a C layer to import dladdr on non-Darwin Swift platform
// See https://forums.swift.org/t/dladdr-and-the-clang-importer/26379/11
return unknown
let libraryName = URL(filePath: path).lastPathComponent
#endif
moduleLookupCache.value[nominalDescriptor] = libraryName
return libraryName
}
}

Expand Down
19 changes: 19 additions & 0 deletions Sources/OpenSwiftUI_SPI/Shims/CSymbols/OpenSwiftUI_CSymbols.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// OpenSwiftUI_CSymbols.c
// OpenSwiftUI_SPI

#ifdef __linux__
#define _GNU_SOURCE
#endif

#include "OpenSwiftUI_CSymbols.h"
#include <dlfcn.h>

const char * getSymbolPathName(const void *address) {
Dl_info info;
int result = dladdr(address, &info);
if (result == 0) {
return NULL;
}
return info.dli_fname;
}
16 changes: 16 additions & 0 deletions Sources/OpenSwiftUI_SPI/Shims/CSymbols/OpenSwiftUI_CSymbols.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// OpenSwiftUI_CSymbols.h
// OpenSwiftUI_SPI

#ifndef OpenSwiftUI_CSymbols_h
#define OpenSwiftUI_CSymbols_h

#include "OpenSwiftUIBase.h"

OPENSWIFTUI_ASSUME_NONNULL_BEGIN

const char * _Nullable getSymbolPathName(const void *address);

OPENSWIFTUI_ASSUME_NONNULL_END

#endif /* OpenSwiftUI_CSymbols_h */
2 changes: 1 addition & 1 deletion Tests/OpenSwiftUICoreTests/Util/TracingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct TracingTests {
}

@Test(
.disabled(if: !attributeGraphEnabled, "OGTypeNominalDescriptor is not implemented yet"),
.enabled(if: swiftToolchainSupported),
arguments: [
(type: Int.self as Any.Type, libraryNames: ["libswiftCore.dylib"]),
(type: String.self as Any.Type, libraryNames: ["libswiftCore.dylib"]),
Expand Down
Loading