xcodebuild workspace and scheme - ios

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.

Related

Build os x tool as part of iOS project without breaking xcodebuild archive?

Each time I build my iOS project, I'd like to it also build a couple OS X projects. These are command line tools. I don't care if they're included in the Archive, I just want to make sure they compile correctly each and every time.
They're little command line tools for specific tasks which access the same libraries. In the past, I've built these far less frequently and as a result they suffer from code rot. I'd like to build them each time I build the iOS project, even when I just Build in Xcode.
To do this, I tried dragging the projects into my iOS project and set them as dependancies.
This works fine in the IDE, but when I try to build via xcodebuild:
xcrun xcodebuild -sdk iphoneos -workspace AppName.xcworkspace \
-scheme AppName archive
I get an error that looks like this:
=== BUILD TARGET dslfi OF PROJECT dslfi WITH CONFIGURATION Release ===
Check dependencies
target specifies product type 'com.apple.product-type.tool', but there's no such
product type for the 'iphoneos' platform
** ARCHIVE FAILED **
The following build commands failed:
Check dependencies
(1 failure)
Is there any way to continue to build these each time I build while still satisfying xcodebuild?
You can add any number of targets (iOS app, static lib, contole app, etc) into same project.
Then you should create another target -
Then you have options:
3.1 Go to scheme settings for aggregate target and add other targets:
where you can specify actions you want to perform on certain target
3.2 You may pick aggregate target and go to build settings and add other targets as a dependencies for this target.
Option 3.1 seems to be the one you need: you can add as many targets as you wish to be build. And you can specify another target for running.
So you'll have something like:
targets:
target 1 - iOS app
target 2 - other app
target 3 - other app
target 4 - aggregate target
scheme configuration for target 4
build section:
target 1
target 2
target 3
run section:
executable: target 1 (iOS app)
Once this is completed you may use your scheme to do builds
xcodebuild -scheme your_scheme [...other options...] archive
UPDATE
You can skip creation of aggregate target.
You can directly create new scheme and to the configuration you want without involving aggregate target.
UPDATE 2
Make sure to share your scheme to be able to keep it in source control.
UPDATE 3
The option w/o aggregate target is more preferable way to achieve this in case if your targets are not depend on each other directly (as far as I understand you). This is the main purpose for schemes.
A scheme is a collection of settings that specify which targets to
build, what build configuration to use, and the executable environment
to use when the product specified by the target is launched. When you
open an existing project (or create a new one), Xcode automatically
creates a scheme for each target.

How to get the Xcode build directory?

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".

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.

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".

Clean IOS xcode target in command line

I am building/running an IOS app from command line with following commands:
xcodebuild -sdk "${TARGET_SDK}" -xcconfig "${CONFIG_FILE_PATH}" -configuration Release
/usr/bin/xcrun -sdk "${TARGET_SDK}" PackageApplication -v "${PROJECT_BUILD_DIR}/${APPLICATION_NAME}.app" -o "${OUTPUT_DIR}/${APPLICATION_NAME}.ipa"
Is there any command to clean the targets. or these commands take care of cleaning themselves.
From xcodebuild manual page:
xcodebuild [-project projectname] [-target targetname ...] [-configuration configurationname] [-sdk [sdkfullpath | sdkname]] [buildaction ...] [setting=value ...] [-userdefault=value ...]
and build action could take following values (UPD 13.08.2018):
action ...
Specify one or more actions to perform. Available actions are:
build Build the target in the build root (SYMROOT). This is the default action, and
is used if no action is given.
build-for-testing Build the target and associated tests in the build root (SYMROOT). This will
also produce an xctestrun file in the build root. This requires specifying a
scheme.
analyze Build and analyze a target or scheme from the build root (SYMROOT). This
requires specifying a scheme.
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 and optionally a destination.
test-without-building Test compiled bundles. If a scheme is provided with -scheme then the command
finds bundles in the build root (SRCROOT). If an xctestrun file is provided
with -xctestrun then the command finds bundles at paths specified in the
xctestrun file.
install-src 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 distribution root (DSTROOT).
clean Remove build products and intermediate files from the build root (SYMROOT).
In your case
xcodebuild -sdk "${TARGET_SDK}" -xcconfig "${CONFIG_FILE_PATH}" -configuration Release clean build
There are two build actions in this command line: 'clean' and 'build'. The 'clean' action is performed first, then the 'build'. As the documentation states, you can specify multiple build actions in a command, and doing so rather than using separate commands ensures that the other options are the same for all the build actions.
You can just delete build folder:
rm -rf ./build

Resources