xcodebuild arguments ignored when using archive - continuous-integration

My name is Luca and I am currently working on iOS continuous integration to build apps in xcode for distribution (Ad Hoc and App Store) using shell-scripting.
So far I achieved good results with IPA files. My problem comes for distribution in App Store. To build a .app from script (passing some arguments) I do:
xcodebuild -scheme myScheme -configuration myConfiguration PRODUCT_NAME=myProductName TARGETED_DEVICE_FAMILY=myTargetedDeviceFamily .... etc
Since with XCode 4.2, apps submission is done using the XCode Organizer Window I must be able also to archive my executable.
Therefore I modify the previous command line as follow:
xcodebuild -scheme myScheme -configuration myConfiguration PRODUCT_NAME=myProductName TARGETED_DEVICE_FAMILY=myTargetedDeviceFamily .... etc **archive**
Unfortunately after I do so, it seems that the 'archive' argument force xcodebuild to ignore the other ones (PRODUCT_NAME, TARGETED_DEVICE_FAMILY, ....) and my output is built using the XCode predefined build settings.
I want to be able to pass the arguments with xcodebuild and be effective, but the 'archive' action seems to prevent this.
I am going nuts, please help :)
Thanks

The archive action for xcodebuild seems to have a bug in Xcode 4.2. Normally overrides for the project configuration can be specified as either command-line parameters or via the -xcconfig parameter.
Although the build action honors them, archive does not. (Presumably this is because archive is a meta-action that invokes build internally, but doesn't pass-through the options to the internal invocation.) There is an OpenRadar bug that describes this issue, so presumably it's been reported to Apple.
Finally, note that if you're going to use the archive action from a script then you can't rely on the exit code from xcodebuild. The archive action always yields an exit code of 0 (success, by convention). To detect build failure you need to scrape the output.

I've ran into this same issue. My current work-around is basically to delete the other configurations so archive is forced to use the one you want. Not really a solution that can be done via command-line, hopefully Apple will fix this glaring issue.

this may be too late for the original poster, but may help others. for my build process, i use xcodebuild to with first clean and then build, then i use xcrun to create the archive:
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "build/<Path_to_build_dir>/<App_Name>.app" -o "<Path_to_archive_output>.ipa" --sign "<signing identity>" --embed "<path to provision profile>.mobileprovision"
with this command, i can create an archive for the app store, or even upload an ad-hoc build to TestFlight like this:
curl http://testflightapp.com/api/builds.json \
-F file="<path to archive>" \
-F api_token='<api token>' \
-F team_token='<team token>' \
-F notes='Automated build' \
-F notify=True \
-F distribution_lists='me'
this works as of xcode 6.1

Related

Does xcode use "xcodebuild" under the hood?

Does xcode use of the xcodebuild command behind the scenes to build?
If so, how can I find the exact xcodebuild command that is run?
I checked the report navigator but couldn't find it in there.
I would have thought that running xcodebuild -sdk iphonesimulator -configuration Debug -project <myproject>.xcodeproj -scheme <myscheme> would be identical to selecting product -> build in xcode (with a scheme/destination matching the command line), but they seem to have slightly different behavior.
For example, when running the command line above with the -showBuildSettings option, I noticed that BUILD_ACTIVE_RESOURCES_ONLY=NO even though it should be set to YES according to the target's build settings. When running product -> build from xcode, the build settings logs (generated by following #Slipp D. Thompson's answer here) show BUILD_ACTIVE_RESOURCES_ONLY=YES.
There are few other strange differences I noticed as well.
No. One could do an experiment: move all xcodebuild binaries in some local folder and check that Xcode still able to build some application.
Since Apple presents xcodebuild as a self contained command line tool for building Xcode projects, it is reasonable to suspect that use code sharing between both tools.

the ipa created by command-line is smaller than create by xcode6,why?

The command-line script:
xcodebuild
xcodebuild -verbose ARCHS="armv7 arm64" VALID_ARCHS="armv7 armv7s arm64" ONLY_ACTIVE_ARCH=NO DEPLOYMENT_POSTPROCESSING=YES \
-configuration Release PROVISIONING_PROFILE="${profilename}" CODE_SIGN_IDENTITY="${codesign}" \
clean build OBJROOT=${distDir}/Obj.root SYMROOT=${distDir}/Sym.root
# ipa
appname=$(basename ${distDir}/Sym.root/Release-iphoneos/*.app*)
target_name=$(echo $appname | awk -F. '{print $1}')
mkdir -p $project_path/package/Products
xcrun -sdk iphoneos PackageApplication -v "${distDir}/Sym.root/Release-iphoneos/${target_name}.app" -o "$project_path/package/Products/${ipaName}" --embed "${profile}"
And the result is: command-line's ipa is 8M smaller than xcode one, Why?
Sadly, ipa files generated from the command line are not identical to those from the Xcode app.
As you already noted, the command line one has a few missing items.
In addition to Symbols, if your app is written in Swift, there will be a SwiftSupport folder with a few libraries in the ipa generated by the Xcode app but not the command line one. Similarly, if your app includes a Watch App, there will be a missing WatchKitSupport folder.
Some of these missing items will be problematic when it comes to uploading an ipa to iTunes Connect. You will find numerous posts about these issues and the workarounds being adopted - but it all boils down to this issue of command line builds lacking all the required content for app distribution.
Luckily, the new version of xcodebuild within Xcode 7 has a solution to most of these issues but is not yet documented. Here's some details on it if you are interested.

Jenkins xcode plugin - how to resolve library search path issues?

I am running into this error in my jenkins xcode build which I'm attempting to setup:
clang: error: no such file or directory: '/Users/boo/.jenkins/jobs/myProject/workspace/DerivedData/Release-iphoneos/libIBAForms.a'
clang: error: no such file or directory: '/Users/boo/.jenkins/jobs/myProject/workspace/DerivedData/Release-iphoneos/libLambdaAlert.a'
clang: error: no such file or directory: '/Users/boo/.jenkins/jobs/myProject/workspace/DerivedData/Release-iphoneos/libRestKit.a'
I cannot figure out a few things regarding the configuration:
what prompted the jenkins-xcode-plugin ( https://wiki.jenkins-ci.org/display/JENKINS/Xcode+Plugin ) to use /DerivedData/Release-iphoneos/ in the path for the lookup of the .a files
instead why didn't it select /DerivedData/Debug-iphoneos/ as the fragment in the path for the lookup to the .a files
finally the submodules that produce - libIBAForms, libLambdaAlert, libRestKit - are all projects that have a release and a debug profile ... so why the files are actually missing from the /DerivedData/Release-iphoneos/ path where they are supposed to be ... is beyond me.
Regarding points #1 and #2, this is configured based on the Configuration parameter for XCode plugin (and Xcode itself). By default, the plugin uses "Release" value for the parameter. If you want to use "Debug", you should set it as such.
Don't know what to say regarding #3
Personally, i found the Xcode plugin to be restrictive and not providing me with options that i needed. I am using the command line tools that came with xcode (through regular Execute Shell build step)
// Below are my build parameters for the job through regular means
CONFIGURATION=Debug
CODE_SIGN_IDENTITY=iPhone Developer: <DeveloperNameHere>
PROVISIONING_PROFILE=3000000B-7000-4000-9CD5-D0000B0F0000
//
// Code for Execute Shell
xcodebuild -verbose -alltargets -configuration ${CONFIGURATION} clean build CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" PROVISIONING_PROFILE=${PROVISIONING_PROFILE}
&&
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "${WORKSPACE}/path_here/${CONFIGURATION}-iphoneos/application.app" -o "${WORKSPACE}/path_here/${CONFIGURATION}-iphoneos/application.ipa" --sign "${CODE_SIGN_IDENTITY}" --embed "/Users/<youruser>/Library/MobileDevice/Provisioning Profiles/${PROVISIONING_PROFILE}.mobileprovision"
Setup parameters as usual for the job
The xcodebuild command does the actual build
The xcrun command packages the app into an IPA (the Archive step in Xcode), signs it, and embeds a provisioning profile directly into the IPA.
Note that some of these switches are options and may not be required for you. But that's the benefit of doing through the command line: you have full control of what you want to do
Small note: make sure you provide full paths to -v and -o switches on the second command
I was able to get past all this when I adeed the submodules which generate libIBAForms and libLambdaAlert as the main project's "Target Dependencies"

Xcode / Build automation - How do I pass the Code Signing Identity as an argument to xcodebuild?

I'm trying to automate our entire build process using hudson and a mashup of ruby scripts. Is it possible to pass the values for Versioning System, Bundle Version, Code Signing Identity and Entitlements as arguments to xcodebuild?
+1 for using hudson to automate your build process, it makes for a great development environment.
xcodebuild -help
You can specify all sorts of things that should help you. You will possibly have to configure some schemes or configurations to get exactly what you need, but it should all be do-able.
In Xcode 5 we are using CODE_SIGN_IDENTITY
xcodebuild -workspace MyProject.xcodeproj/project.xcworkspace \
-scheme "$(SCHEME)" -derivedDataPath ./ \
-configuration $(XCODE_BUILD_CONFIGURATION) \
PROFILE_NAME="$(PROFILE_NAME)" \
ARCHS="armv7" \
CODE_SIGN_IDENTITY="$(CODE_SIGN_IDENTITY)" \
CODE_SIGN_ENTITLEMENTS="$(CODE_SIGN_ENTITLEMENTS)" \
build

Can anyone give an example of how to configure Bamboo to build an Xcode project?

I've been searching for how to configure Bamboo (a continuous integration system) to build an Xcode project. This should be pretty simple, as it is just getting it to run a shell command such as:
xcodebuild -project ProjectName -target TargetName -configuration ConfigType
However this is proving more difficult than expected. I've investigated creating a "custom builder" for the xcodbuild command (tells Bamboo about the command) but then it only seems to let you pass ONE argument to the command not the multiple that the xcodebuild command requires. Any help or pointers would be much appreciated, including links to any appropriate examples (I couldn't find any.) Thanks.
OK, I got a "HelloWorld" example working by choosing the "script" option with a shell script rather than a "custom builder" and trying to tell Bamboo how to use xcodebuild command directly. Just specified a script like below.
#!/bin/bash
/usr/bin/xcodebuild -project TestProject/TestProject.xcodeproj -target TestProject -configuration Release build
That might have done the trick but there is a more generic way to do it.
You can define in your agent capabilities as a Command to execute /usr/bin/xcodebuild. Then in your tasks after you checkout your code, you can define a task Command, and you can select Xcode from the drop down list and provide the arguments needed for the project in the relevant input -workspace YourProject.xcworkspace -scheme YourProject. This approach provides more flexibility since Xcode installation can differ from agent to agent but bamboo will still be able to forward your builds properly where they can be build.

Resources