Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Carthage Update for iOS 13 Framework without LC_VERSION_MIN_IPHONES gives an error #3289

Open
dogahe opened this issue Jul 1, 2022 · 1 comment

Comments

@dogahe
Copy link

dogahe commented Jul 1, 2022

  • carthage install method: [ ] .pkg, [ *] homebrew, [ ] source
  • which carthage: 0.38
  • carthage version: 0.38.0
  • xcodebuild -version: 13.2.1
  • Are you using --no-build? NO
  • Are you using --no-use-binaries? NO
  • Are you using --use-submodules? NO
  • Are you using --cache-builds? NO
  • Are you using --new-resolver? NO
  • Are you using --use-xcframeworks? NO

Cartfile

One line cartfile:
binary "https://dl.google.com/geosdk/GoogleMaps.json" == 7.0.0

Carthage Output

carthage update

*** Downloading binary-only framework GoogleMaps at
"https://dl.google.com/geosdk/GoogleMaps.json"

*** xcodebuild output can be found in
/var/folders/ry/l6wyzxfj00v2pw4hsglr_4vm00wlqh/T/carthage-xcodebuild.AvWFxD.log

*** Downloading binary-only framework GoogleMaps at
"https://dl.google.com/geosdk/GoogleMaps.json"

*** Downloading GoogleMaps binary at "7.0.0"

Failed to read file or folder at
/private/var/folders/ry/l6wyzxfj00v2pw4hsglr_4vm00wlqh/T/carthage-archive.XCjSfM/Maps/Frameworks/GoogleMapsCore.framework:
Error Domain=com.antitypical.Result Code=0 "could not determine
platform neither from DTSDKName key in plist nor from the framework's
executable" UserInfo={com.antitypical.Result.function=readFailed(_:),
com.antitypical.Result.file=/private/tmp/carthage-20211023-79495-oezjib/Source/CarthageKit/Project.swift,
NSLocalizedDescription=could not determine platform neither from
DTSDKName key in plist nor from the framework's executable,
com.antitypical.Result.line=1424}

Actual outcome
Carthage did not install the framework.

Expected outcome
Carthage should install the framework.

We have noticed that the error is emitted from here:

// Try to read what platfrom this binary is for. Attempt in order:
// 1. Read `DTSDKName` from Info.plist.
// Some users are reporting that static frameworks don't have this key in the .plist,
// so we fall back and check the binary of the executable itself.
// 2. Read the LC_VERSION_<PLATFORM> from the framework's binary executable file
if let sdkNameFromBundle = bundle?.object(forInfoDictionaryKey: "DTSDKName") as? String {
return .success(sdkNameFromBundle)
} else if let sdkNameFromExecutable = sdkNameFromExecutable() {
return .success(sdkNameFromExecutable)
} else {
return .failure(readFailed("could not determine platform neither from DTSDKName key in plist nor from the framework's executable"))
}

Our framework does not have a plist file. Also by trying the otool on our framework, we have noticed that there is no LC_VERSION_MIN_IPHONES in the binary. Instead there is LC_BUILD_VERSION and a platform field.

This could be related to the following:
https://developer.apple.com/forums/thread/673387?answerId=662602022#662602022

@dogahe
Copy link
Author

dogahe commented Jul 5, 2022

The following change in the func sdkNameFromExecutable in file Source/CarthageKit/Project.swift will fix the issue by trying to read the platform name from Load Command "LC_BUILD_VERSION":

func sdkNameFromExecutable() -> String? {
				guard let executableURL = bundle?.executableURL else {
					return nil
				}

				let task = Task("/usr/bin/xcrun", arguments: ["otool", "-lv", executableURL.path])

				let sdkName: String? = task.launch(standardInput: nil)
					.ignoreTaskData()
					.map { String(data: $0, encoding: .utf8) ?? "" }
					.filter { !$0.isEmpty }
					.flatMap(.merge) { (output: String) -> SignalProducer<String, NoError> in
						output.linesProducer
					}
					.filter { $0.contains("LC_VERSION") }
					.take(last: 1)
					.map { lcVersionLine -> String? in
						let sdkString = lcVersionLine.split(separator: "_")
							.last
							.flatMap(String.init)
							.flatMap { $0.lowercased() }

						return sdkString
					}
					.skipNil()
					.single()?
					.value

        // Read platform field under Load Command "LC_BUILD_VERSION"
        var platformFromBuildVersion: String?
        let loadCommands = task.launch(standardInput: nil)
          .ignoreTaskData()
          .map { String(data: $0, encoding: .utf8) ?? "" }
          .filter { !$0.isEmpty }
          .flatMap(.merge) { (output: String) -> SignalProducer<String, NoError> in
            output.linesProducer
          }
          .reduce([String](), { res, item in
            var arr = res
            arr.append(item.trimmingCharacters(in: .whitespacesAndNewlines))
            return arr
          })
          .single()?
          .value
        if let loadCommands = loadCommands {
          if let buildVersionIndex = loadCommands.firstIndex(of: "cmd LC_BUILD_VERSION") {
            let rem = loadCommands.suffix(from: buildVersionIndex)
            if let platformLine = rem.filter { $0.contains("platform") }.first, let platform = platformLine.split(separator: " ").last {
              platformFromBuildVersion = String(platform.lowercased())
            }
          }
        }
        
        return sdkName ?? platformFromBuildVersion
      }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant