xcodecontinuous-integrationparallel-buildsderiveddata

xcode build error when building in parallel


in a CI/CD system, when multiple concurrent xcode processes run in parallel on the same mac-agent, errors occur with the processing of the shared cache.

Error example: ❌ fatal error: malformed or corrupted AST file: 'could not find file '.../Pods/Firebase/CoreOnly/Sources/module.modulemap' referenced by AST file '~Library/Developer/Xcode/DerivedData/ModuleCache.noindex/2FKA2K2BK8GI0/ObjectiveC-1KD62J152BYGO.pcm''

in the build on another agent the following error:

❌ fatal error: module file '~/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/2FKA2K2BK8GI0/Foundation-A3SOD99KJ0S9.pcm' is out of date and needs to be rebuilt: signature mismatch

add a trigger on the xcode process to read-write data movement in DerivedData

if the process somehow goes on, then wait and start the process in a minute

also think about isolating build threads to xcode xcode 13.4.1


Solution

  • I took advantage of ruby and sketched out such a script that simply suspends other parallel xcode build processes if the xcodebuild process is already running on the agent.

    sleep_time = ((Time.now.to_f - Time.now.strftime("%s").to_f) * 1000000).to_i # 988589 or 153779 or 39680
      case
      when sleep_time > 300000
        sleep_time /= 10000
      when sleep_time > 100000 && sleep_time < 300000
        sleep_time /= 1000
      when sleep_time > 10000 && sleep_time < 100000
        sleep_time /= 1000
      when sleep_time > 1000 && sleep_time < 10000
        sleep_time /= 100
      when sleep_time > 300 && sleep_time < 1000
        sleep_time /= 10
      end
      puts("maximal sleep time = #{sleep_time}")
    
      # sleep(Random.rand(sleep_time))
      sleep(sleep_time)
      loop do
        xcodebuildProcess = `ps -A | grep xcodebuild | awk '{print $4}'`
        xcodebuildProcesschecker = false
        if xcodebuildProcess.match("Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild")
          xcodebuildProcesschecker = true
          puts 'find Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild'
          sleep(30)
        else
          xcodebuildProcesschecker = false
          puts("xcodebuild process is not running")
          break
        end
        break if xcodebuildProcesschecker == false
      end
    
      sh("ls -la ~/Library/Developer/Xcode/")
      sh("ls -la ~/Library/Developer/Xcode/DerivedData/") if Dir.exists?("~/Library/Developer/Xcode/DerivedData/")
      sh("rm -rf ~/Library/Developer/Xcode/DerivedData/")
      sh("ls -la ~/Library/Developer/Xcode/")