[CMake] XCODE_DEPEND_HELPER.make Deletes Targets Before (and While) They're Built

Jim Wong jim at airtime.com
Mon Sep 17 20:32:54 EDT 2018


Folks,

I’m working with a very large CMakeLists.txt, and I’m having trouble generating a working
Xcode project from it (the Ninja and Make generators seem to work fine).

What’s happening is that the post-build step associated with each of the targets in
XCODE_DEPEND_HELPER.make is aggressively deleting a bunch of other targets, including
some that either a) haven’t been built yet; or b) are in the process of being built.
The former isn’t an issue, but the latter is: I get a build error when this happens.

Here’s a *very* cut-down look at what’s happening:

Showing All Messages, Filtering for "libpacing.a".
PhaseScriptExecution CMake\ PostBuild\ Rules build/xcode-osx/cmake/osx/Release/project.build/Debug/ApiVideo_CodecsVideo_Codecs_Api.build/Script-62A3C733E930414E85209FFB.sh
    cd /Users/jim/Workspace/myproject
    /bin/sh -c /Users/jim/Workspace/myproject/build/xcode-osx/cmake/osx/Release/project.build/Debug/ApiVideo_CodecsVideo_Codecs_Api.build/Script-62A3C733E930414E85209FFB.sh
/bin/rm -f /Users/jim/Workspace/myproject/build/xcode-osx/obj/modules/pacing/Debug/libpacing.a

PhaseScriptExecution CMake\ PostBuild\ Rules build/xcode-osx/cmake/osx/Release/project.build/Debug/Rtc_BaseAudio_Format_To_String.build/Script-61E5555E2FB7443C905B7CC4.sh
    cd /Users/jim/Workspace/myproject
    /bin/sh -c /Users/jim/Workspace/myproject/build/xcode-osx/cmake/osx/Release/project.build/Debug/Rtc_BaseAudio_Format_To_String.build/Script-61E5555E2FB7443C905B7CC4.sh
/bin/rm -f /Users/jim/Workspace/myproject/build/xcode-osx/obj/modules/pacing/Debug/libpacing.a
    
*** there are a lot more instances of this pattern ***

Libtool build/xcode-osx/obj/modules/pacing/Debug/libpacing.a normal x86_64
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static -arch_only x86_64 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -L/Users/jim/Workspace/myproject/build/xcode-osx/obj/modules/pacing/Debug -filelist /Users/jim/Workspace/myproject/build/xcode-osx/cmake/osx/Release/project.build/Debug/ModulesPacingPacing.build/Objects-normal/x86_64/pacing.LinkFileList /Users/jim/Workspace/myproject/build/xcode-osx/cmake/osx/Release/project.build/Debug/Rtc_BaseRtc_Event.build/Objects-normal/x86_64/event.o -o /Users/jim/Workspace/myproject/build/xcode-osx/obj/modules/pacing/Debug/libpacing.a
fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't stat file output file: /Users/jim/Workspace/myproject/build/xcode-osx/obj/modules/pacing/Debug/libpacing.a (No such file or directory)

*** here we’re dead ***

*** deleting libpacing.a one more time for good measure ***

PhaseScriptExecution CMake\ PostBuild\ Rules build/xcode-osx/cmake/osx/Release/project.build/Debug/ModulesAudio_ProcessingAgc2Fixed_Digital.build/Script-A48E7039684F4F828D6DC3DE.sh
    cd /Users/jim/Workspace/myproject
    /bin/sh -c /Users/jim/Workspace/myproject/build/xcode-osx/cmake/osx/Release/project.build/Debug/ModulesAudio_ProcessingAgc2Fixed_Digital.build/Script-A48E7039684F4F828D6DC3DE.sh
/bin/rm -f /Users/jim/Workspace/myproject/build/xcode-osx/obj/modules/pacing/Debug/libpacing.a

As you can see, Xcode is complaining about the file libpacing.a not existing at the same time
it’s trying to link that very file.  My guess has been that the file is getting deleted out
from under the linker.  I’m not sure how to resolve that issue, however.

Part of the issue here is that we’re working with a very large CMake file that was generated
from the output of another build system (don’t ask), so narrowing this down to an easily
replicable scenario has been challenging.  As far as I can tell, the problem is as follows:

1. Target A is an object library that is used by several targets.
2. Target A* is the post-build target for A.
3. Target B is an executable that depends on A.
4. Target C is different library that B depends on.

Notably, C does not depend on A; nor does A depend on C.

After A is built by Xcode, it builds A* in XCODE_DEPEND_HELPER.make.  Because B depends on A,
A* depends on B in this Makefile.  As a result, B’s dependencies are checked to make sure it’s
up to date.

B depends on C (both in reality and in XCODE_DEPEND_HELPER.make), so C’s dependencies are
checked.  And if C’s dependencies aren’t up to date, or if C doesn’t exist at all, C is
“built”, which in the context of XCODE_DEPEND_HELPER.make means that it’s deleted, since
the action for C is “rm -f C”.

As a consequence, building A seems to result in the deletion of C; and if there are many
targets like A (targets that are depended on by things that also depend on C), C can
be deleted many times.

And, since there’s no dependency relationship between A and C, there’s nothing preventing
A’s post-build step from running at the same time C is being built, which produces (I think)
the errors we’re seeing.

Does this analysis seem correct, or am I missing something about how XCODE_DEPEND_HELPER.make
is supposed to work?

Assuming I’m on the right track, what’s the right path to resolve the issue?  The dependency
structure referenced above seems to be valid, at least superficially, but it’s giving Xcode fits.
We’re in the process of massaging the generated CMake into shape manually, but I want to
make sure we’re headed in the right direction.

Thanks in advance for any hints or guidance you can provide.



More information about the CMake mailing list