xcodebuild - how to use build settings from xcode - ios

I'm trying to build several targets and I already have Build Settings per target in Xcode. I also have a scheme per target. What I'm trying to do is issue one command line instruction to build each target, something like:
xcodebuild -project MyProject.xcodeproj -scheme PRODScheme archive
-archivePath /Users/myUser/Documents/PRODApps/archives/"${PRODUCT_NAME}".xcarchive
-configuration Release
Here, ${PRODUCT_NAME} is the Build Setting variable defined by XCode. I'm thinking on how xcodebuild can make use of the bunch of already defined settings.
Is there a way of reusing those settings in xcodebuild?

Typically you would use the scheme, which would contain the other information you are trying to include:
xcodebuild -scheme PRODScheme build
To use with a configuration file you would use:
xcodebuild -target MyProject.xcodeproj -xcconfig configuration.xcconfig
To build all targets use -alltargets
Command Line tech notes: https://developer.apple.com/library/ios/technotes/tn2339/_index.html
Man xcodebuild: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/xcodebuild.1.html

Related

Build all targets (or schemes) in Xcode project

I have an Xcode project with many targets. Six of them are aggregates which build final release products (static libraries, frameworks) using Run Scripts under Build Phases. I can build them each individually fine, but I can't find any way to hit "one button" to build them all.
Approach #1
First I tried using -alltargets from the command line, like so:
xcodebuild -project MyProject.xcodeproj -alltargets
With that I get errors on my test targets, claiming that they aren't built for testing. I don't know what that means because they normally "test" correctly. Something is different when attempted this way. But technically it's including targets I'm not interested in. I wouldn't mind much if it worked.
Approach #2
Next I tried making an aggregate which had a run script that individually built each aggregate target, like so:
xcodebuild -project MyProject.xcodeproj -target FirstAggregateTarget
xcodebuild -project MyProject.xcodeproj -target SecondAggregateTarget
xcodebuild -project MyProject.xcodeproj -target ThirdAggregateTarget
xcodebuild -project MyProject.xcodeproj -target FourthAggregateTarget
xcodebuild -project MyProject.xcodeproj -target FifthAggregateTarget
xcodebuild -project MyProject.xcodeproj -target SixthAggregateTarget
It doesn't get any errors from Xcode's point of view, but several of the aggregates just don't build properly. Somehow the run scripts in the individual aggregates were influenced by the top-level aggregate, I guess.
Approach #3
Next I then tried making a new "RELEASE_PRODUCTS" scheme that in the build section had the six aggregates listed. With that I got errors like this:
There were also other obscure errors about build products not being found where they were expected to be.
Approach #4
Next I created a script that I run completely outside of Xcode, like so:
#!/bin/bash
# Builds all release products
xcodebuild -project MyProject.xcodeproj -target FirstAggregateTarget
xcodebuild -project MyProject.xcodeproj -target SecondAggregateTarget
xcodebuild -project MyProject.xcodeproj -target ThirdAggregateTarget
xcodebuild -project MyProject.xcodeproj -target FourthAggregateTarget
xcodebuild -project MyProject.xcodeproj -target FifthAggregateTarget
xcodebuild -project MyProject.xcodeproj -target SixthAggregateTarget
That seems to be the only thing that works. But I wish I could get this to work from within Xcode, preferably as something I could hit from the command line if I wanted to, because then I wouldn't have to leave the IDE and it could report to be success or fail.
You could make a dummy target that depends on the other six. Use Target Dependencies in the Build Phases tab
Inspired by sansumbrella's answer in another forum.
Create a new target in your project (I chose to use a CLI tool since my project is CLI based).
According to sansumbrella, you can create an application and delete its plist. My approach does not rely on any special (or non-existent) plists.
Give your target a name, such as ALL, satisfy the remaining fields, and press "Finish".
Click on the new target's Build Phases link and:
Delete the entry in the Compile Sources, which will be main.c if you're doing it how I did.
Open the Target Dependencies and add all the other targets by clicking the + or dragging targets into this space.
You can now build and clean your whole project when you have this target selected as the active schema.

xcodebuild manually building framework in run-script and follow same destination

I have a framework that I need to build manually as a part of my run-script in xcode.
How can I copy the build setting from the current project when building it?
xcodebuild
-project "$PROJECT_DIR/myProject/MyProject.xcodeproj"
-scheme MyProject
-configuration "$MY_PROJECT_CONFIGURATION"
CONFIGURATION_BUILD_DIR="$APP_BUILD_DIR"
build
I'm specifically having problem matching -destination. Is there a way to get the -destination used to build the current project and pass it to xcodebuild
Xcode offers this as a Environmental Variable:
build_dir=${BUILD_DIR}
//use it
... -destination $build_dir ...
This answer shows how to get all Environmental Variables.

How to build a release version of an iOS framework in Xcode?

Let's say I do the following:
Open Xcode 7
File | New | Project | Cocoa Touch Framework
Create "TestFramework" with the Swift language
Create a file Hello.swift with public func hello() { print("Hello") }.
From here, I can build a debug build of the framework (inside the Debug-iphoneos folder), but I cannot figure out how to build the release version of the framework (inside Release-iphoneos). I thought Archive might do it, but it doesn't. Pointers please?
To get a release build, you need to change your scheme settings:
Alternatively, create a new scheme for release builds.
Ensure you have a device selected. Not the simulator.
Build your project and you should see that it gets added to this location:
(Click the arrow to navigate there in finder)
And after drilling down, you should be able to find the release folder with your release framework inside.
This works for me:
Select your framework target then click Product -> Archive. If organizer window does not pop up after successful build of your framework then go to "Build Settings" of your framework target, look for the option "Skip Install" and change it to "No" (and after that Archive again).
An alternative to building a framework via the Xcode IDE is to build it from the command line.
You can produce a release build of your framework for iphoneos devices with the following command:
xcodebuild -workspace TestSDK.xcworkspace -scheme TestSDK -configuration Release -sdk iphoneos
You can change the value of the -configuration argument from Release to Debug in order to produce a debug build, or change the value of the -sdk argument from iphoneos to iphonesimulator in order to produce a build for Simulator devices.
Note that you may need to provide the -project argument instead of -workspace if your target is part of an Xcode project only and not part of an Xcode workspace. Run the xcodebuild -help command for the full list of xcodebuild options.
If you prefer to archive, you can do that from the command line also, as follows:
xcodebuild archive -workspace TestSDK.xcworkspace -scheme TestSDK -configuration Release -sdk iphoneos -archivePath "TestSDK_Release_iphoneos.xcarchive" SKIP_INSTALL=NO
Note that you can specify SKIP_INSTALL=NO as part of your project or target's Build Settings instead if you prefer.
Lastly, if you want to join up your iphoneos and iphonesimulator builds into a single binary, you can do that with the xcodebuild -create-xcframework command as follows:
xcodebuild -create-xcframework \
-framework "TestSDK_Release_iphoneos.xcarchive/Products/Library/Frameworks/TestSDK.framework" \
-framework "TestSDK_Release_iphonesimulator.xcarchive/Products/Library/Frameworks/TestSDK.framework" \
-output "TestSDK.xcframework"
See here for the official guide to creating an XCFramework.
When you add the framework to your other Xcode project then you have to add "$(BUILT_PRODUCTS_DIR)" to Build Settings -> Framework Search Paths.
This will create Debug when you run project (with Debug) and will create Release version when you archive project.
The archive doesn't will create Release version under Products dir but will create Release in "Intermediates.noindex" folder.

Building/running iOS app from command line

I am trying to build/run my iOS app from command line. To build the app, the command which I give in shell script is as follows:
PROJECT_DIR="/Users/ingenyous/Desktop/splistV11_test_sh_build/code/app/ios"
TARGET_NAME="splistapp2"
TARGET_SDK="iphoneos5.1"
PROJECT_BUILD_DIR="${PROJECT_DIR}/build/Release-iphoneos"
OUTPUT_DIR="/Users/ingenyous/Desktop/ipa"
# compile project
echo Building Project
cd "${PROJECT_DIR}"
xcodebuild -target "${TARGET_NAME}" -sdk "${TARGET_SDK}" -configuration Release
Here I specify the target name and other parameters. Is it possible to give the target properties like product name and other options in this script itself, which can overwrite the properties given actually in the editor target. or be able to create the target itself from shell script and not needing to create targets from Xcode editor.
You can certainly set the product name using xcodebuild:
xcodebuild -target "${TARGET_NAME}" -configuration Release build PRODUCT_NAME=MyProduct
There can be issues with multiple targets, see this existing SO question
You can set any build setting in this way. A full list of build settings is available on Apple's developer site, and you can also check out the man for xcodebuild.

xcconfig option in xcodebuild command

I have created an app in IOS and want to build and run it through command line. The xcodebuild command helps in building the app and its basic syntax is as follows:
xcodebuild -target "${TARGET_NAME}" -sdk "${TARGET_SDK}" -configuration Release -xcconfig "${BUILD_SETTINGS_FILE_PATH}"
Each target will contain its product name and other build settings. Now I don't want to take the product name/build settings specified in xcode target, but rather through some external file which can contain build settings. So, i tried using the -xcconfig option but I am not clear with its implementation. What kind of file it should be and how the path to the file be configured?. The official documentation also doesn't seem to be too clear.
xcodebuild PRODUCT_NAME argument affects all targets
.xcconfig file can be created using Xcode and the format of providing value is:
CUSTOM_CFBundleVersion = 3.0.
CUSTOM_CFBundleShortVersionString = 3.0

Resources