which carthage: /usr/local/bin/cartagecarthage version: current master (https://github.com/Carthage/Carthage/commit/c31b3f5261d9ac1927ad26cb0543f9202bec1a39)xcodebuild -version: Xcode 10.1--no-build? n--no-use-binaries? y--use-submodules? y--cache-builds? y--new-resolver? nCartfile
github "Openium/SwiftiumKit" ~> 1.3
github "github/Archimedes" ~> 1.0
Carthage Output
carthage update --platform iOS --no-use-binaries --use-submodules
*** Fetching Archimedes
*** Fetching SwiftiumKit
*** Checking out SwiftiumKit at "v1.4.0"
*** Checking out Archimedes at "1.1.5"
*** xcodebuild output can be found in /var/folders/7v/dfg0p2vj1z58n65d99l2n1lh0000gp/T/carthage-xcodebuild.vPJM7m.log
*** Building scheme "Archimedes iOS" in Archimedes.xcworkspace
*** Building scheme "SwiftiumKit" in SwiftiumKit.xcodeproj
Actual outcome
Carthage did not produce the .Archimedes.version file in Carthage/Build:
$ ls -a Carthage/Build/
. .. .SwiftiumKit.version iOS
I think it is related to https://github.com/Carthage/Carthage/pull/2585, which adds swiftToolchainVersion to the version file, by looking for swift version in Dep.framework/Headers/Dep-Swift.h
And thus, make CI job (https://travis-ci.org/Carthage/Carthage/jobs/477319552) of the https://github.com/Carthage/Carthage/issues/2400 PR I made on "shared cache" fail after last update to current master
The origin is there is no Dep-Swift.h header generated for "ObjC only" frameworks (as github/Archimedes is)
Expected outcome
Carthage should generate the .Archimedes.version file
Carthage also looks at dSYMs to generate the version file.
You're right:
https://github.com/Carthage/Carthage/blob/master/Source/CarthageKit/VersionFile.swift#L151-L152
But frameworkSwiftVersion() is also called here without the check in dSYM https://github.com/Carthage/Carthage/blob/master/Source/CarthageKit/VersionFile.swift#L414-L415, which is executed after Archimedes.framework build
@kenji21 Do you want to take a shot at improving this?
This is a bit curious though as for example I'm sure the version file is generated for https://github.com/swisspol/GCDWebServer
It is also the case for GCDWebServer, got it printed:
*** Building scheme "Archimedes iOS" in Archimedes.xcworkspace
error Unable to determine framework Swift version: Could not derive version from header file. for dep : (dependency: github "github/Archimedes", version: "1.1.5")
*** Building scheme "GCDWebServers (iOS)" in GCDWebServer.xcodeproj
error Unable to determine framework Swift version: Could not derive version from header file. for dep : (dependency: github "swisspol/GCDWebServer", version: "3.5.2")
with these changes:
diff --git a/Source/CarthageKit/Xcode.swift b/Source/CarthageKit/Xcode.swift
index cf3cca07..5536ec90 100644
--- a/Source/CarthageKit/Xcode.swift
+++ b/Source/CarthageKit/Xcode.swift
@@ -893,7 +893,10 @@ public func buildInDirectory( // swiftlint:disable:this function_body_length
buildProducts: urls,
rootDirectoryURL: rootDirectoryURL
)
- .flatMapError { _ in .empty }
+ .flatMapError { e in
+ print("error \(e) for dep : \(dependency)")
+ return .empty
+ }
}
The error is "caught" with the flatMapError at https://github.com/Carthage/Carthage/blob/master/Source/CarthageKit/Xcode.swift#L896
I replaced the error of my previous comment to look for version in dSYM:
diff --git a/Source/CarthageKit/Xcode.swift b/Source/CarthageKit/Xcode.swift
index cf3cca07..9af0fde3 100644
--- a/Source/CarthageKit/Xcode.swift
+++ b/Source/CarthageKit/Xcode.swift
@@ -59,7 +59,8 @@ internal func frameworkSwiftVersion(_ frameworkURL: URL) -> SignalProducer<Strin
let contents = String(data: data, encoding: .utf8),
let swiftVersion = parseSwiftVersionCommand(output: contents)
else {
- return SignalProducer(error: .unknownFrameworkSwiftVersion(message: "Could not derive version from header file."))
+ return dSYMSwiftVersion(frameworkURL.appendingPathExtension("dSYM"))
+ //return SignalProducer(error: .unknownFrameworkSwiftVersion(message: "Could not derive version from header file."))
}
And it still fails (as expected because these frameworks can't have a swiftVersion):
*** Building scheme "Archimedes iOS" in Archimedes.xcworkspace
error Unable to determine framework Swift version: No version found in dSYM. for dep : (dependency: github "github/Archimedes", version: "1.1.5")
*** Building scheme "GCDWebServers (iOS)" in GCDWebServer.xcodeproj
error Unable to determine framework Swift version: No version found in dSYM. for dep : (dependency: github "swisspol/GCDWebServer", version: "3.5.2")
The compiler for objc is clang:
/usr/bin/xcrun dwarfdump --arch=armv7 --debug-info Carthage/Build/iOS/Archimedes.framework.dSYM/ |grep AT_producer
AT_producer( "Apple LLVM version 10.0.0 (clang-1000.11.45.5)" )
I think this is a bug that should be fixed.
And for Objective-C-only frameworks, we don't need to validate the compiler version becase ObjC has binary compatibility.
So the frameworkSwiftVersion()function can return ~an empty string~ a constant indicating "NotASwiftFramework"
with this simple code:
diff --git a/Source/CarthageKit/Xcode.swift b/Source/CarthageKit/Xcode.swift
index cf3cca07..27fba7b0 100644
--- a/Source/CarthageKit/Xcode.swift
+++ b/Source/CarthageKit/Xcode.swift
@@ -53,6 +53,10 @@ private func parseSwiftVersionCommand(output: String?) -> String? {
/// Determines the Swift version of a framework at a given `URL`.
internal func frameworkSwiftVersion(_ frameworkURL: URL) -> SignalProducer<String, SwiftVersionError> {
+ guard frameworkURL.swiftmoduleURL() != nil else {
+ return SignalProducer(value: "NotASwiftFramework")
+ }
+
guard
let swiftHeaderURL = frameworkURL.swiftHeaderURL(),
let data = try? Data(contentsOf: swiftHeaderURL),
or "PureObjectiveCFramework" for the constant which will be stored in the version file
I agree this is a bug.
If I understand correctly you are suggesting to replace the swift version with a known value?
I think it would be better not to abuse the property and simply create a new one for objc. @ikesyo ?
I'm for creating a new (maybe boolean?) field to determine that a framework is including Swift or not.
Or maybe a property indicating what language the binary was produced from so that in the unlikely event of a third language we don't have to introduce another flag?
On a second thought @ikesyo is right and we don't need to know the language but just if it contains swift or not.
This bug seems to be causing bootstrap to fail when referencing a binary objc framework in Cartfile. Is a fix already in progress I should wait for?
I'm having the same error trying to build my project using Swift 5.0 compiler and Carthage master built locally. (803941b8)
Apple Swift version 5.0 (swiftlang-1001.0.45.7 clang-1001.0.37.7)
Target: x86_64-apple-darwin18.2.0
ABI version: 0.6
carthage build
*** Downloading binary-only framework Crashlytics at "https://building42.github.io/Specs/Carthage/iOS/Crashlytics.json"
*** xcodebuild output can be found in /var/folders/w4/qv7tltnn5bn0jw2r2grrkk3r0000gn/T/carthage-xcodebuild.m7Gmcs.log
Unable to determine framework Swift version: Could not derive version from header file.
The log file is empty.
Is there a workaround for this ?
Carthage derives the version looking at聽-Swift.h header or via the dSYM.
I just tried to implement the fix by adding a "isSwiftFramework" boolean to the CachedFramework structure, but Codable don't allow to specify a default value for this boolean when Decoding json, so its initialiser returns nil and make some tests failing
First, I added a check for version file presence of test "should build for one platform" which build Archimedes framework: https://github.com/Carthage/Carthage/compare/master...openium:fix-2677-no-version-objc-frameworks#diff-21b1859b20014a70776faa1516cd5064R347
And then added the frameworkSwiftVersionIfIsSwiftFramework function return an Optional
https://github.com/openium/Carthage/tree/fix-2677-no-version-objc-frameworks
Do you think it's ready to merge like this ?
@kenji21 鈥撀燱ould this work for any Objective-C projects that I've checked out and run carthage build --no-skip-current and carthage archive on, then released a tag with the newly created binary framework?
Currently encountering the following when doing the above, given that third-party-vendor.xcodeproj is entirely Objective-C and therefore has no identified SWIFT_VERSION:
*** Downloading third-party-vendor.framework binary at "2.0.0"
*** Skipped installing third-party-vendor.framework binary due to the error:
"Unable to determine framework Swift version: Could not derive version from header file."
Falling back to building from the source
Trying to avoid building every time for a framework that rarely changes (or that we rarely take updates from).
I just tried with SimulatorStatusMagic:
git clone https://github.com/shinydevelopment/SimulatorStatusMagic
~/github/Carthage/.build/debug/carthage build --no-skip-current
*** xcodebuild output can be found in /var/folders/7v/dfg0p2vj1z58n65d99l2n1lh0000gp/T/carthage-xcodebuild.IB5Cy9.log
*** Building scheme "SimulatorStatusMagiciOS" in SimulatorStatusMagic.xcodeproj
ls Carthage/Build/
.SimulatorStatusMagic.version iOS/
cat Carthage/Build/.SimulatorStatusMagic.version
{
"Mac" : [
],
"watchOS" : [
],
"tvOS" : [
],
"commitish" : "2.4.1",
"iOS" : [
{
"name" : "SimulatorStatusMagiciOS",
"hash" : "d0256cbe7099312e2603049e4ec453df899daab9c21e02ab44773382837f96b2"
}
]
}
~/github/Carthage/.build/debug/carthage archive
*** Found Carthage/Build/iOS/SimulatorStatusMagiciOS.framework
*** Found Carthage/Build/iOS/SimulatorStatusMagiciOS.framework.dSYM
*** Found Carthage/Build/iOS/E31C631B-7A08-3228-B279-5AEE5D379A23.bcsymbolmap
*** Found Carthage/Build/iOS/3419D63A-0D5C-30CD-9B79-B78B3F45852B.bcsymbolmap
*** Found Carthage/Build/iOS/FFC52F13-D9DE-3497-B90A-1E214A0CF77B.bcsymbolmap
*** Found Carthage/Build/iOS/F14B1F88-403F-30A3-B9A6-BB81876ED115.bcsymbolmap
*** Created SimulatorStatusMagiciOS.framework.zip
The zip doesn't contains the .SimulatorStatusMagic.version file, and I don't know if it is expected or not
@gdoublev do you know an objc only framework with zip uploaded on GitHub release (just to add it to a sample Cartfile and check) ?
@kenji21 鈥撀爊o, but I forked the SimulatorStatusMagiciOS repository that you mentioned and archived a binary using the version of Carthage from your fix branch (https://github.com/openium/Carthage/tree/fix-2677-no-version-objc-frameworks) and was able to download that Objective-C framework binary without rebuilding the project, so that's awesome!
$ carthage update --platform iOS
Please update to the latest Carthage version: 0.32.0. You currently are on 0.31.2
*** Cloning SimulatorStatusMagic
*** Checking out SimulatorStatusMagic at "2.4.2"
*** xcodebuild output can be found in /var/folders/zw/kcs4m2kd7j386jn0rdq_7sdc0000gn/T/carthage-xcodebuild.xBH6fr.log
*** Downloading SimulatorStatusMagic.framework binary at "2.4.2"
$
Nice work! 馃憤
@kenji21 鈥撀燼ny plans to PR your fix?
As is it merged in 0.33, maybe this issue can be closed