Nat! bio photo

Nat!

Senior Mull

Twitter Github Twitch

xcodebuild driving me nuts again with a zombie OBJROOT

I used to have /Library/Developer/BuildArea as my OBJROOT. But not so anymore. To make really sure that it’s not used anymore, I did a chmod 000 on it.

Now Xcode.app builds fine, but xcodebuild doesn’t. Since it still tries to access /Library/Developer/BuildArea! This is already majorly weird.

But it gets even weirder…

xcodebuild lies

xcodebuild -showBuildSettings | grep OBJROOT gives

    OBJROOT = /Volumes/Source/srcM/MulleScion/build/Intermediates

My “Location” Preferences in Xcode itself are

"Derived Data" : Default
"Snapshots" : Default
"Archives" : Default


Advanced Settings:

Custom: "Relative to Workspace"
	build/Products
	build/Intermediates

The OBJROOT returned from -showBuildSettings says its NOT /Library/Developer/BuildArea, the view inside Xcode preferences says it’s NOT /Library/Developer/BuildArea. But when I build it, xcodebuild clearly uses it.

So how do I go about a scenario like this ? I search for a possible offender setting OBJROOT behind my back.

Poking around …

Is it in the xcodeproj file ?

In the project directory

find . -type f -exec grep -l -s BuildArea {} \;

yields nothing.

Opensnoop to the rescue ?

Modified opensnoop so it gives me only the filename of all files opened by xcodebuild and nothing else.

Then I used the resulting list of files to grep for “BuildArea” in the contents of each file. To put some emphasis on it: this checked, if any file that xcodebuild had opened contained the string “BuildArea”.

Nothing. Now that’s magical!

Lets go paranoid

nvram -p | grep BuildArea

nothing.

Back to more sanity

env | grep BuildArea

nothing.

OK, it’s more like Windows nowadays anyway

reboot

nothing.

Exhaustive search through ~/Library

find ~/Library -type f -exec grep -l -s BuildArea {} \;

yields

/Volumes/Users/nat/Library/Preferences/xcodebuild.plist
/Volumes/Users/nat/Library/Preferences/com.apple.Xcode.plist
/Volumes/Users/nat/Library/Preferences/com.apple.dt.Xcode.plist

All these files define OBJROOT in some manner as /Library/Developer/BuildArea. Finally there is a lead.

defaults delete xcodebuild does nothing. defaults delete com.apple.Xcode PBXApplicationwideBuildSettings does nothing.

Found it

defaults delete com.apple.dt.Xcode IDEApplicationwideBuildSettings finally does it. xcodebuild does not use /Library/Developer/BuildArea anymore.

WTF ?

When I grep through the opensnoop files, I see no open of ~/Library/Preferences/com.apple.dt.Xcode.plist. I do see an open of /Library/Preferences/com.apple.dt.Xcode.plist though, which also exists.

I run xcodebuild with opensnoop a couple of times and nothing differs. Only the /Library/Preferences/com.apple.dt.Xcode.plist is opened.

If I had not found the string in ~/Library/Preferences/com.apple.dt.Xcode.plist and removing it had not worked, I would have assumed, that the string is somewhere in a compressed or encrypted file. But now it only makes me come to the conclusion, that xcodebuild communicates with some other process, that gives it this preference information.

I am pretty sure that this daemon is cfprefsd. Whenever I make a change in ~/Library/Preferences/com.apple.dt.Xcode.plist it seems to get picked up immediately by that process.

Summary: xcodebuild, do not want

The amount of time I have wasted because of Xcode and it’s opaque build system is crazy. Because there is no indication what’s going on, I had to waste half a day on this closed source build system, to figure out an obscure bug or behavior. Not for the first time.

Want to reproduce the problem ? Do this in some place, where you have an Xcode project lying around:

defaults write com.apple.dt.Xcode IDEApplicationwideBuildSettings \
     '{ OBJROOT=/tmp/BuildArea; }'
mkdir -p /tmp/BuildArea
chmod 000 /tmp/BuildArea
xcodebuild # this will not work
xcodebuild -showBuildSettings | grep OBJROOT

Postscriptum

Something I learned from @joar_at_work:

Whenever you initiate xcodebuild without specifying a scheme, xcodebuild chooses a “legacy behavior” path, which I assume corresponds to Xcode 3. This uses a different preferences scheme than the modern behavior.

I would hazard a guess, that -showBuildSettings without a scheme goes wrongly through the “modern behavior”, giving wrong values.

The main problem again and again is, that everything is opaque and magic. Would it hurt to output “using legacy behavior” when going down that code path ? Why, yes! It could confuse some noobs.


Post a comment

All comments are held for moderation; basic HTML formatting accepted.

Name:
E-mail: (not published)
Website: