I'd like to be able to make changes to an Xcode project (change source code, move files around on the file system, add dependencies or libraries, etc.) and then build it and compare the build product to the one before making the changes to confirm that they're identical. How do I do this?
Diffing the Build Products Doesn't Work; They're Different Every Time
I tried diffed two different products built the same way at different times, and they differ. Huh? Hmm.. the build time must affect the build product. Here's what I did:
In Xcode, after building the product (Command + B
), press Command + 7
to show the Log navigator. Then, click "Build ${PRODUCT_NAME}" in the Navigator. Then, at the bottom of the Editor, expand the "Touch ..." transcript by clicking on the bubble at the right. Copy the last directory path in the transcript. It should look something like: /Users/${USER}/Library/Developer/Xcode/DerivedData/${PRODUCT_NAME}-abomilaxrsffqkeasoiwbfisjghq/Build/Products/Debug-iphonesimulator/${PRODUCT_NAME}.app
This is the path to your build product. Then, open Terminal, and do something like:
# Change to the build product's directory.
cd /开发者_StackOverflow中文版Users/${USER}/Library/Developer/Xcode/DerivedData/${PRODUCT_NAME}-abomilaxrsffqkeasoiwbfisjghq/Build/Products/Debug-iphonesimulator/
# Copy the build product to another directory, like your Desktop.
open . # if you prefer Finder
cp -R ${PRODUCT_NAME}.app ~/Desktop/ # or use Terminal
# Confirm the bundles are identical.
diff -r ${PRODUCT_NAME}.app ~/Desktop/${PRODUCT_NAME}.app
Now, do Command + Shift + K
in Xcode to Clean. Then, build again and run the same diff above. They're different!
How do I get the assembly generated by Xcode?
So, is there a way to diff the assembly to see if they're different? I saw a way to do this in an answer on a question here, but I forgot where it is, and I couldn't find it.
If the assembly is the same, does that mean the build products will be the same too? I don't think so because I think certain build settings affect how the assembly is compiled into machine code. If so, which build settings do affect how the assembly is compiled into machine code. That way, I can just confirm that those are identical before & after and be confident that the products are identical (besides their build timestamps).
Using diff is not a good tool to compare binaries directly.
Assembly for the Whole Binary
Inside your Product.app should be a file probably just named "Product." That's the real executable. You can find it by right-clicking on the Product.app
file in the Products
group and selecting "Show in Finder." An example location is: ~/Library/Developer/Xcode/DerivedData/Product-dqcwcdqvrxhcfzdkoovramlggzzg/Build/Products/Debug-iphoneos/Product.app/Product
.
$ file Product.app/Product
Mach-O executable arm
Now you want to disassemble it. You can do this with the Mach-O object tool, otool
$ xcrun -sdk iphoneos otool -tv Product.app/Product
This should dump out a disassembly of your whole binary. Save that to a file and you can diff it against your other recompilation. That's for the whole binary.
Assembly for a Single File
If you only care about a few files, they should exist in a location like ~/Library/Developer/Xcode/DerivedData/Product-hdomilaxrhfpqkeanoiwbrirngqq/Build/Intermediates/Product.build/Debug-iphoneos/Product.build/Objects-normal/
in armv6
or armv7
. There should be a .o
file version of your C and Obj-C files, and you can disassemble those individually with the same command as above. E.g.:
$ xcrun -sdk iphoneos otool -tv AppDelegate.o
As far as I know, Xcode doesn't leave intermediate assembly files around, though there might be a flag somewhere to force it to generate them.
精彩评论