Carthage: --cache-builds sometimes fails to recognize a cached dependency

Created on 18 Oct 2018  路  6Comments  路  Source: Carthage/Carthage

  • carthage install method: [ ] .pkg, [x] homebrew, [ ] source
  • which carthage: /usr/local/bin/carthage
  • carthage version: 0.31.1
  • xcodebuild -version: Xcode 9.2 - 9C40b
  • Are you using --no-build? no
  • Are you using --no-use-binaries? no
  • Are you using --use-submodules? no
  • Are you using --cache-builds? yes
  • Are you using --new-resolver? no

Cartfile

github "typelift/Swiftz" ~> 0.6.3
github "OpenShelter/Tyro" ~> 0.2.0
github "Alamofire/Alamofire" ~> 4.4.0

Cartfile.resolved

github "Alamofire/Alamofire" "4.7.3"
github "OpenShelter/Tyro" "v0.2.0"
github "swisspol/GCDWebServer" "3.4.2"
github "typelift/Swiftz" "0.6.3"

Carthage Output

20:03:48 Tommaso@mars ~/Code/<redacted>
$ carthage update --platform iOS --cache-builds
*** Fetching Tyro
*** Fetching Swiftz
*** Fetching GCDWebServer
*** Fetching Alamofire
*** Checking out Alamofire at "4.7.3"
*** Checking out GCDWebServer at "3.4.2"
*** Checking out Swiftz at "0.6.3"
*** Checking out Tyro at "v0.2.0"
*** No cache found for Alamofire, building with all downstream dependencies
*** No cache found for GCDWebServer, building with all downstream dependencies

*** No cache found for Swiftz, building with all downstream dependencies  # <- ok

*** xcodebuild output can be found in /var/folders/b4/qz7m1r9x3mj1bm3nfsjjf64m0000gp/T/carthage-xcodebuild.TRCyO8.log
*** Building scheme "Alamofire iOS" in Alamofire.xcworkspace
*** Building scheme "GCDWebServers (iOS)" in GCDWebServer.xcodeproj
*** Building scheme "Swiftz-iOS" in Swiftz.xcodeproj
*** Building scheme "Tyro-iOS" in Tyro.xcodeproj
20:06:46 Tommaso@mars ~/Code/<redacted>
$ carthage update --platform iOS --cache-builds
*** Fetching Tyro
*** Fetching Swiftz
*** Fetching GCDWebServer
*** Fetching Alamofire
*** Checking out feingoldtech-ios-core at "2de13363960863adfda16c51657c511d0c17b913"
*** Checking out Alamofire at "4.7.3"
*** Checking out GCDWebServer at "3.4.2"
*** Checking out Swiftz at "0.6.3"
*** Checking out Tyro at "v0.2.0"
*** xcodebuild output can be found in /var/folders/b4/qz7m1r9x3mj1bm3nfsjjf64m0000gp/T/carthage-xcodebuild.bHTkpU.log
*** Valid cache found for Alamofire, skipping build
*** Valid cache found for GCDWebServer, skipping build

*** Invalid cache found for Swiftz, rebuilding with all downstream dependencies  # <- wat?

*** Building scheme "Swiftz-iOS" in Swiftz.xcodeproj
^C

Actual outcome
After a fresh build of dependencies with --cache-builds, a second __consecutive__ rebuild considers one of the cached binaries invalid.

Expected outcome
A second __consecutive__ rebuild considers all already built binaries valid. Note: there is no update to the version of the dependency between the two runs.

bug

Most helpful comment

That fallbacks makes sense to me. 馃憤

All 6 comments

Turns out https://github.com/Carthage/Carthage/blob/master/Source/CarthageKit/FrameworkExtensions.swift#L300 not all frameworks have a -Swift.h header. If they have a .h file at all, it may not contain the swift+clang version

It's debatable whether this is a carthage bug or an oddity of some libraries.

It's possible to get the swift compiler version by:

  • looking at the __current version__ of libswiftCore.dylib
$ otool -L Carthage/Build/iOS/Swiftz.framework/Swiftz
Carthage/Build/iOS/Swiftz.framework/Swiftz:
    @rpath/Swiftz.framework/Swiftz (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1452.23.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /usr/lib/libSystem.dylib (compatibility version 1.0.0, current version 1252.50.4)
    /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1452.23.0)
    @rpath/libswiftCore.dylib (compatibility version 1.0.0, current version 902.0.54) 
    @rpath/libswiftDarwin.dylib (compatibility version 1.0.0, current version 902.0.54)
  • digging in the debug_info (or debug_str) section of the dSYM
$ dwarfdump --debug-info Carthage/Build/iOS/Swiftz.framework.dSYM
----------------------------------------------------------------------
 File: Carthage/Build/iOS/Swiftz.framework.dSYM/Contents/Resources/DWARF/Swiftz (i386)
----------------------------------------------------------------------
.debug_info contents:

0x00000000: Compile Unit: length = 0x000000ac  version = 0x0004  abbr_offset = 0x00000000  addr_size = 0x04  (next CU at 0x000000b0)

0x0000000b: TAG_compile_unit [1] *
             AT_producer( "Apple Swift version 4.1.2 effective-3.3.2 (swiftlang-902.0.54 clang-902.0.39.2) -emit-object /Users/Tommaso/<redacted>

The __clang version__ is only available in the dSYM.

I supposed that the clang version is not essential but I would like to leave things are they are as much as possible. So then, I would propose the following:

  1. Keep looking for the -Swift.h header
  2. If that fails, take a look at the dSYM if available
  3. if that fails, add a "greedy" mode to --cache-builds and just look at the swiftlang version from libswiftCore.dylib

Would be great if someone else could express an opinion on this. @ikesyo @jdhealy @mdiep @scottrhoyt

That fallbacks makes sense to me. 馃憤

alright then, off I go.

Addressed by #2622.

Was this page helpful?
0 / 5 - 0 ratings