Xcode 12 "Build input file cannot be found" $DERIVED_FILES_DIR

I've got several Xcode projects that build command line tools, that have a "Run Script" build phase which generates a modified Info.plist file into the $DERIVEDFILESDIR based on the build target's assigned Info.plist. This derived Info.plist file is then referenced in the build target's "Other linker flags" as an input to "-sectcreate TEXT info_plist".

With Xcode 12, if I do a "Clean" then "Build" the build will fail the first time every time with a Link error

Code Block
error: Build input file cannot be found: '[snip]-apyyjhtaurzdhaaqytutfobpvoth/Build/Intermediates.noindex/ProductName.build/Debug/ProductName.build/DerivedSources/Info.plist'


Building a second time (without cleaning) seems to work fine, because a version of the "DerivedSources/Info.plist" file already exists. But Cleaning again and then building results in the same error again.

The "Run Script" phase that generates the file is before "Compile Sources" and "Link Binary with Libraries". I have tried unchecking the new "Based on dependency analysis" checkbox in the Run Script phase, but the problem still happens.

This is annoying for me as a developer, but livable for the short term. However, it's almost impossible for my automated build system to deal with.

Is there another way I should be generating the Info.plist file prior to linking?

Thanks,
John

Replies

Ah finally seeing a similar issue. My case is very alike - I try to add template files to the project if they don't exist, then take them in during the building process. However, it seems Xcode cached all the content whenever a build starts, and doesn't detect file changes afterwards.

It would be great if there is an option to run script prior to the build process.
After some digging up, one can actually add a pre-action to the building scheme under "Build" tab (by clicking the bullet icon). It solved my problem.
  • Could you please let me know, in this case in pre-action what needs to be added here to fix the above issue. I am facing an error as below. Are you mention the /bin/sh/ executables needs to be here in this case?

    Build input file cannot be found: '/Users/name/Library/Developer/Xcode/DerivedData/Application-dhdivlzaazbnhlgnkkglsibo/Build/Products/Debug-iphonesimulator/Application.app/Application'

Add a Comment
It appears that the build system under Xcode 12 and higher is now validating that any files referenced in the "Other Linker Flags" (probably other build settings as well before actually building the target. The workaround to the problem is to force the file into existence before the target itself starts to build by "touch"-ing it prior to the build. The the existing project build phase script can still be used to populate the file before the build gets to the linking stage, the file just has to exist on disk.

The "Pre-action" scripts in build schemes don't really work well for our situation, as we have several schemes that include the build targets.

The best solution I've found is to move the generated plist file to a project relative location (instead of in $DERIVEDFILESDIR  which is target specific). I then added an Aggregate build target to the actual target's project and made it a dependency of the original build target. This dependency gets built BEFORE Xcode validates the file existence. In the aggregate target, there is a build phase scipt that executes a "touch" on the necessary file, creating it if it's missing.

The generated file is added to .gitignore so that it does not get committed since it's constantly changing. Otherwise it shows up as a modified file with every new build.

Hope this helps anybody who runs across this problem.