How to get the Xcode build directory? - ios

How do I get the URL or url string to the build directory of a workspace or a project? I don't want to set it myself to know what it is instead I want to know the default set by Xcode.
How to get the directory programmatically?

If you need the build directory path for use within an Xcode build script (Build Phases > Run Script), then use the following variable:
$TARGET_BUILD_DIR
For an exhaustive list of all variables exposed by Xcode in build scripts, follow this answer:
$ xcodebuild -project myProject.xcodeproj -target "myTarget" -showBuildSettings

Building up on Daniel Jones answer above, to get the BUILD_DIR of a workspace, you should run:
xcodebuild -workspace ios/myApp.xcworkspace -scheme myApp
-showBuildSettings | grep BUILD_DIR
example of response:
BUILD_DIR = /Users/Olivier/Library/Developer/Xcode/DerivedData/myApp-ceetrcnutlegngflgvvfjaaaycrc/Build/Products

Select you project in the Xcode. On the right side select "Build Settings". Select desired target and under "Build Locations" you will find paths for debug, release and distribution configurations. These paths are relative to your "Deriver Data" directory. To open that directory in Finder, do the following.
Xcode menu: Window->Organizer. When you get "Organizer" window, on the left side select you project and on the right side you will get "Derive Data" path. Clicking on the arrow at the end of the "Derived Data" path you will open that directory in the Finder.
If you want a build directory path to use in some Pre-actions or Post-actions scripts, then variable name for it can be found in Quick Help Inspector, once you clicked on desired build directory in "Build Locations".

Related

xcodebuild archives all targets instead of one

I need to archive a specific scheme from my xcodeproj. To do this I run
xcodebuild archive \
-scheme $SCHEME \
-target $TARGET \
-archivePath $ARCHIVE_PATH
Although I explicitly define a scheme and target, the resulting xcarchive contains both targets and the follow-up IPA export call complains with
error: the archive at path '<path>.xcarchive' is not a single-bundle archive
** EXPORT FAILED **
Why does xcodebuild produce an archive with multiple bundles?
It was a problem with the project's schemes. I created new Schemes by duplicating the original one instead of adding a new one. The resulting scheme then listed 2 targets in the build section instead of one (only god knows why) and Xcode would not let me remove the other target.
Once I removed all schemes and created them from scratch everything worked just fine.
One more scenario when this happens is when your sub-project(Target dependency) has Skip Install set to No in build settings.
To find which sub-project, check the content inside the archive. Products folder should have only one product.
In my case a sub-project was a dynamic library and was added in the archive under /<path to archive>/Products/usr/lib/<library> path.

Why when generating .app file, xcode needs to be open?

I'm writing a script to build and generate an .app file from an specific target and scheme (to work with simulator). I was using something like:
DEVELOPER_DIR=$xcode_app_path/Contents/Developer xcodebuild -sdk iphonesimulator -scheme "${SCHEME}" -target "${TARGET}" ONLY_ACTIVE_ARCH=NO CONFIGURATION_BUILD_DIR="${build_folder}" clean build
The problem is, that I need to open XCode for the code above to work, otherwise will show me a message telling me that:
xcodebuild: error: The project 'Project-name' does not contain a scheme named "${SCHEME}"
I still yet, don't understand what is XCode doing in background. But if I open the IDE and run the script, works. If I open and later close it, and run the script works. It's not working if the project hasn't been opened first with XCode ¬¬
Any suggestion would be appreaciated
If someone is facing the same experience, this is what I found out. And works.
Well, apparently when you create a new scheme through command line, by default is not "shared". So when you start to link to the folder
xcshareddata --> xcschemes
(trying to build with command line, for example) there's nothing to link with. Xcode do this automaticaly under the hood when you open your project...
The guys from CocoaPods were facing the same issue, so they created a Ruby gem that shares the scheme and place the file in his xcscheme folder:
This is the repo: https://github.com/CocoaPods/Xcodeproj
Also, thanks to this post and this post I found out how to use xcodeproj gem, and change the shared option with a script that I put downhere:
require 'xcodeproj'
xcproj = Xcodeproj::Project.open("MyProject.xcodeproj")
xcproj.recreate_user_schemes
xcproj.save

Xcode workspace schemes definition

There is a nice command that lists all schemes in a Xcode workspace:
xcodebuild -workspace PATH -list
How to extract this list programmatically without xcodebuild? It should be stored somewhere in Xcode project files. But I can't find it inside xcworkspace. For example, in this project.
the schemes are in the xcuserdata -- lone file per scheme
they are build on the fly if they don't exist. (e.g. if that folder wasn't checked in like in that repo)
To build them just enum all targets
the exception being shared schemes: they also come as 1 file per scheme but are in xcshareddata directory.
enum those files to get the schemes. if they don't exist, the user never ran Xcode

Target Properties changes by xcodebuild command

How can i manipulate my iOS Target Properties by xcodebuild command tool ?
In example, i have one project with one target and with Facebook SDK Key in Target Properties in Info tab
FacebookAppID: 01234567891234
And with console command xcodebuild i'm compiling two Apps with Developer and Production provisions with two console commands:
For Developer:
xcodebuild -project Projectname.xcodeproj clean install OBJROOT=ObjRoot ... CODE_SIGN_IDENTITY={iPhoneDeveloper} PROVISIONING_PROFILE="Dev.mobileprovision"
For Distribution:
xcodebuild -project Projectname.xcodeproj clean install OBJROOT=ObjRoot ... CODE_SIGN_IDENTITY={iPhoneProduction} PROVISIONING_PROFILE="Prod.mobileprovision"
And i need use in Developer one FacebookAppID, and in Production a other FacebookAppID, and how i can change my command lines for realize this?
Thanks
Arguments to xcodebuild are best used for values that change every time they're invoked, like a destination directory that includes a build number.
For data as foundational as a Facebook app ID, I'd recommend using your build configurations, e.g. "Debug" and "Release". Create a user-defined build setting (in Xcode 5.0.2, Editor -> Add Build Setting -> Add User-Defined Setting) named something like "FACEBOOK_ID", and in your Info.plist, set your desired key's value to ${FACEBOOK_ID}. In your target's build settings, define FACEBOOK_ID differently for your Debug and Release configurations. Your code then now has to pull the current value out of Info.plist at runtime.
If you really want to override build settings as arguments to xcodebuild, you can do so, just by adding "FACEBOOK_ID=12341234" to the end of the command, but this only works if you've done the work I just described to make FACEBOOK_ID into a configuration-specific build setting. I can't think of any sound reasons to keep this kind of app data outside of a build configuration.
If build configurations are new to you, I'd suggest starting with WWDC 2012 session 408, "Working with Schemes and Projects in Xcode".

xcodebuild workspace and scheme

I am a little confused as to what happens with the xcodebuild command line tool when you specify a workspace and scheme.
I understand how a configured scheme works in the XCode IDE GUI. The build action lists the targets to build and for each action (Analyze, Test, Run, Profile, Archive), you select which one you want the build action to execute for.
So if I have each action (Analyze, Test, Run, Profile, Archive) selected in the build action for building, what happens when I execute the below command.
xcodebuild clean install -workspace MyWorkspace.xcworkspace -scheme MyScheme
-configuration AdHoc SYMROOT=PATH DSTROOT=PATH...
It searches for MyScheme.xcscheme in the main xcodeproj which has all this configuration specified when editing the scheme in XCode.
What does xcodebuild read in from this file? Does it just build the configured target with the AdHoc configuration and disregard everything else?
You're almost there, but your syntax is a bit off.
According to the man page:
xcodebuild -workspace workspacename -scheme schemename [-configuration configurationname]
[-sdk [sdkfullpath | sdkname]] [buildaction ...] [setting=value ...]
[-userdefault=value ...]
Where buildaction is one of the following:
buildaction ...
Specify a build action (or actions) to perform on the target. Available build actions are:
build Build the target in the build root (SYMROOT). This is the default build action.
archive Archive a scheme from the build root (SYMROOT). This requires specifying a scheme.
test Test a scheme from the build root (SYMROOT). This requires specifying a scheme.
installsrc Copy the source of the project to the source root (SRCROOT).
install Build the target and install it into the target's installation directory in the dis-
tribution root (DSTROOT).
clean Remove build products and intermediate files from the build root (SYMROOT).
In the Xcode IDE, you choose the buildaction to run through the Product menu, or by clicking and holding the round button on the top left of the IDE (Run = Play triangle, Test = wrench icon, etc).
Also, be careful to note where xcodebuild is looking for your build scheme - it can either be in your .xcproj OR your .xcworkspace file, depending on which one you created.
(If you didn't manually create a workspace, you will have a .xcproj file).
You can also ascertain which schemes you have via your 'Manage Schemes' setting in Xcode.

Resources