Xcode 4 build succeeds, command line build fails?

46,411

Solution 1

Ok, so nearly 6 (billable) hours later, I've gotten the build to work correctly in Xcode and on the command line (and on the build server, the whole point of this exercise).

Along the way I would fix one problem just to cause another - I would apparently fix the linker/Ld problem, only to cause problems in compilation ("SomeClass undeclared (first use in this function)" or "SomeHeader.h: No such file or directory" errors were common).

It was one of those times that I adjusted nearly every setting I could find, so it's hard to say what exactly what wrong and what exactly fixed it.

Things I think might have helped are are as follows:

  • Converted build to use an Xcode workspace & scheme (instead of project & target)
  • Rearranged workspace to have the App project and static library as siblings (not as parent/child)
  • Changed Xcode and workspace settings to use build locations specified in targets
  • Change Build Products Path for App and Library to use ../build (both project files are contained in sibling subfolders of a master directory, so having them build into the same folder solved the original linker/Ld command problem, I think)
  • Edited the App scheme to explicitly build the Library target, and build it before the App target
  • In the Build Phases for the App target, explicitly add the Library under "Link Binary With Libraries"
  • Change the location type of the Library's .a file reference to "Relative to Build Products"
  • Added a "Copy Headers" build phase to the Library project, added the appropriate headers to the Public section
  • Changed the Public Headers Folder Path of the Library project to "/include"
  • Changed the Installation Directory of the Library to $(BUILT_PRODUCTS_DIR)
  • Changed the Library Search Paths and the User Header Search Paths of the App target to $(BUILT_PRODUCTS_DIR) (recursive)
  • Added a Clean command before the build on my Jenkins build server
  • Added explicit SDK and Arch arguments to the build command
  • Removed spaces from build configuration name

Final build command looks like this:

xcodebuild -workspace ClientName.xcworkspace -scheme AppName -configuration "ProdAdHoc" -sdk iphoneos -arch "armv6 armv7"

Some useful resources I used while debugging this issue:

Anyway, I hope I've peppered enough keywords above that anybody who has any similar build issues in the future stumbles upon this and finds it useful. I have no clue how a workflow I did many times in Xcode 3.x got so messed up when I moved to Xcode 4, here's hoping Apple is able to clean this up in future releases.

This was a heck of a learning experience for me, and going through all of this did seem to clear up issues with autocomplete I was having beforehand. I will say things could have been much worse; I could still be developing for SharePoint.

Solution 2

I ran in to the same issue yesterday and was able to work it out. In an effort to narrow down what worked for James, I'll point to what I had to do. I had to add a workspace and switch to running xcodebuild with workspace/scheme instead of project/target.

Using workspace/scheme forced xcodebuild to use the DerivedData folder instead of the build output folder under the main project. This allowed the linker to find the associated static library.

This blog post was hugely helpful:

http://blog.carbonfive.com/2011/05/04/automated-ad-hoc-builds-using-xcode-4/

Solution 3

I got this error when I was experimenting with my files I add the @implementation to the .h file and left the .m file empty. I don't believe this is your error but if anyone else gets it maybe check that you haven't done this.

Solution 4

I don't know if this will work for you but in my case, I had more than one main.m file. All I had to do was detach one of the main.m from the target and it worked. Make sure you don't have more than one main.m in your project.

Solution 5

Check if you didn't import the .m files in your header files! Changing .m to .h fixed this for me!

Share:
46,411
James J
Author by

James J

iPhone Developer. In another life, I was a .NET junkie, with a bad SharePoint habit.

Updated on November 08, 2020

Comments

  • James J
    James J over 3 years

    I have a project in Xcode 4 (the latest non-beta version) that builds fine when built in Xcode itself. Specifically, the Ld command correctly uses the derived data directory (where build products, including a dependent static library, are placed).

    However, when I build the same project from the command line, the Ld command fails, as it is trying to use the /build folder within the project, which is not being populated.

    I've tried adjusting every build setting I know about, both in the parent and the dependent project.

    Any ideas on where to start debugging this? I can provide more info as needed.

    Edit 1: Full Xcode build command:

    xcodebuild -project AppName.xcodeproj -target AppName -configuration "Config Name"
    

    Where AppName and Config Name are both the correct values for the build.

    Edit 2: Link (Ld) commands.

    When built in Xcode (this works):

    Ld /Users/james/Library/Developer/Xcode/DerivedData/AppName-apkmkuhwuccsbpblulxcsafyxkwa/Build/Products/Debug-iphonesimulator/AppName.app/AppName normal i386
    cd /Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName
    setenv MACOSX_DEPLOYMENT_TARGET 10.6
    setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/opt/local/bin:/usr/local/git/bin"
    /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2 -arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk -L/Users/james/Library/Developer/Xcode/DerivedData/AppName-apkmkuhwuccsbpblulxcsafyxkwa/Build/Products/Debug-iphonesimulator -L/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName -F/Users/james/Library/Developer/Xcode/DerivedData/AppName-apkmkuhwuccsbpblulxcsafyxkwa/Build/Products/Debug-iphonesimulator -filelist /Users/james/Library/Developer/Xcode/DerivedData/AppName-apkmkuhwuccsbpblulxcsafyxkwa/Build/Intermediates/AppName.build/Debug-iphonesimulator/AppName.build/Objects-normal/i386/AppName.LinkFileList -mmacosx-version-min=10.6 -lxml2 -all_load -ObjC -licucore -Xlinker -objc_abi_version -Xlinker 2 -lMyClientLibrary -lxml2 -lsqlite3.0 -framework Security -framework MessageUI -framework QuartzCore -framework MediaPlayer -framework MapKit -framework CoreLocation -framework AudioToolbox -lz.1.2.3 -framework MobileCoreServices -framework SystemConfiguration -framework CFNetwork -framework UIKit -framework Foundation -framework CoreGraphics -o /Users/james/Library/Developer/Xcode/DerivedData/AppName-apkmkuhwuccsbpblulxcsafyxkwa/Build/Products/Debug-iphonesimulator/AppName.app/AppName
    

    When built from command line using build command above (this fails):

    Ld "build/AppName.build/Prod Ad Hoc-iphoneos/AppName.build/Objects-normal/armv6/AppName" normal armv6
    cd /Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName
    setenv IPHONEOS_DEPLOYMENT_TARGET 4.0
    setenv PATH "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Developer/usr/bin:/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/usr/X11/bin:/opt/local/bin"
    /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk "-L/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName/build/Prod Ad Hoc-iphoneos" -L/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName "-F/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName/build/Prod Ad Hoc-iphoneos" -filelist "/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName/build/AppName.build/Prod Ad Hoc-iphoneos/AppName.build/Objects-normal/armv6/AppName.LinkFileList" -dead_strip -lxml2 -all_load -ObjC -licucore -miphoneos-version-min=4.0 -lMyClientLibrary -lxml2 -lsqlite3.0 -framework Security -framework MessageUI -framework QuartzCore -framework MediaPlayer -framework MapKit -framework CoreLocation -framework AudioToolbox -lz.1.2.3 -framework MobileCoreServices -framework SystemConfiguration -framework CFNetwork -framework UIKit -framework Foundation -framework CoreGraphics -o "/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName/build/AppName.build/Prod Ad Hoc-iphoneos/AppName.build/Objects-normal/armv6/AppName"
    

    Which returns:

    ld: library not found for -lMyClientLibrary
    collect2: ld returned 1 exit status
    Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 failed with exit code 1
    
  • James J
    James J almost 13 years
    Took a look at that, edited my original post with the Ld command from both Xcode and command line builds. Command line still fails to link though.
  • Shawn Craver
    Shawn Craver over 12 years
    For future reference, making sure the right schemes were shared, and switching the xcodebuild command line tool to use to use workspaces and schemes worked for me.
  • phatmann
    phatmann about 11 years
    This post pointed me in the right direction. You need at least one scheme and you must specify it on the command line.
  • abbood
    abbood about 9 years
    you know @RacZo answers like these can really use a screenshot
  • Genki
    Genki about 9 years
    Thanks to the billable client as well.
  • a paid nerd
    a paid nerd about 9 years
    Confirmed. Using -scheme X instead of -project Y -target Z worked for me. (I didn't have to create any new schemes.)
  • Hayi Nukman
    Hayi Nukman about 8 years
    I think, the question is 'the build is failed when building the apps from command line' not from the XCode GUI app...
  • aqsa arshad
    aqsa arshad over 7 years
    I'm using -scheme but i'm getting this error "Ld /Users/confiz/Library/Developer/Xcode/DerivedData/CloudMessa‌​ge-afevkkqtjcnmoddyc‌​vosdhbgoraa/Build/In‌​termediates/ArchiveI‌​ntermediates/LTDMess‌​aging/IntermediateBu‌​ildFilesPath/CloudMe‌​ssage.build/Release-‌​iphoneos/LTDMessagin‌​g.build/Objects-norm‌​al/arm64/LTD\ Messaging normal arm64" I've cleared drived data and have done everything you asked above but it didn't work.