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.