Specify precompiled headers directory with xctool - ios

I have an Xcode workspace with CocoaPods that I'm trying to build using xctool on travis. Here's the command that I'm using to do the build:
xctool -workspace MyApp.xcworkspace -scheme MyApp -sdk iphoneos -configuration Release SYMROOT=$PWD/build OBJROOT=$PWD/build ONLY_ACTIVE_ARCH=NO
This successfully builds the static libraries for each CocoaPod and the final app and dSYM into the $PWD/build directory, but the precompiled headers are still placed in DerivedData. I need them to be built into the $PWD/build directory for caching. Is there any way to specify where the precompiled headers are built to?
Thanks.

Figured it out. I needed to add SHARED_PRECOMPS_DIR=$PWD/build onto the xctool command.

Related

Universal Framework Binaries: Why Build Simulator and Archive Device?

I am using a script provided by Greg Brown to successfully build a universal framework binary. Here are the two lines that invoke xcodebuild:
xcodebuild archive -project $FRAMEWORK_DIR/$FRAMEWORK.xcodeproj -scheme $FRAMEWORK -sdk iphoneos SYMROOT=$BUILD
xcodebuild build -project $FRAMEWORK_DIR/$FRAMEWORK.xcodeproj -target $FRAMEWORK -sdk iphonesimulator SYMROOT=$BUILD
Note that the archive action is being used to produce the device (arm64 architecture) whereas the build action is being used to produce the simulator (x86_64 architecture).
In a different article entitled iOS 9 Universal Cocoa Touch Frameworks the author remarks: "Note that you will both have to build with your Simulator and Archive with your device to get a universal."
So, what's up with build vs archive? Why not build both?
So, what's up with build vs archive? Why not build both?
The way it works is that Apple doesn't allow simulator binaries (x86_64 and i386) to be uploaded to the app store. If your frameworks contain those binaries, then you won't be able to upload the containing app to the app store.
You would distribute your framework with all the possible binaries so that it can run on Simulators and devices alike. But would like to strip off those Simulator binaries before uploading to the app store.
P.S. I've explained this in detail in another answer here. The answer also explains as to why the issue doesn't exist when using frameworks via Cocoapods.
Edit:
The difference between build vs archive is that archive accepts a scheme to run.
An Xcode scheme defines a collection of targets to build, a configuration to use when building, and a collection of tests to execute.
Also,
You cannot use archive option for the iOS Simulator platform.
You could essentially use xcodebuild build for both of the platforms. You will essentially get the same result. The commands that I use to build my framework are as follows (both commands use the build action):
xcodebuild -target ${PROJECT_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target ${PROJECT_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

xcodebuild - how to use build settings from xcode

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

Xcodebuild is not creating an app

I'm trying to create a simulator app to submit to Facebook for review. I've followed their instructions to the letter, but keep running into problems. I am using CocoaPods and have a workspace instead of a plain old project. Here's the command I'm running:
xcodebuild -arch i386 -sdk iphonesimulator8.1 -workspace [APP].xcworkspace -scheme [APP]
I get a ** BUILD SUCCEEDED ** message, but either one of two things will happen:
No build folder is created, and I can't find where the .App file is.
A .App is created in a build folder, but is 0 bytes in size and crashes when running with ios-sim.
I read that changing the Run scheme to 'Release' might fix it, but that didn't do anything. Any ideas?
So, I had the same problem and solved it by doing the following:
I made my app as release build instead of debug in xcode: Product->Scheme->Edit Scheme and then Build Configuration set to Release.
After doing this I then went back to the command line and added a destination for the build:
xcodebuild -arch i386 -sdk iphonesimulator8.1 -workspace [APP].xcworkspace -scheme [APP] -derivedDataPath /path/to/build
If you are still having problems make sure you clean and build all of your targets (pods included) and try the above steps again.
Hope this works; it did for me.

Choose or get xcodebuild destination directory for app

Is there a way I can choose the destination folder (directory) for when I build an iOS app via command line using xcodebuild?
Right now I am using a command like
xcodebuild -sdk iphonesimulator -workspace /<path_to_project>/ios-app/CompanyName-iOS.xcworkspace -scheme AppName -configuration Debug RUN_APPLICATION_TESTS_WITH_IOS_SIM=YES ONLY_ACTIVE_ARCH=NO clean build 2>&1
In the output I see something like
GenerateDSYMFile /Users/<username>/Library/Developer/Xcode/DerivedData/CompanyName-iOS-fcvhojqctgtmvgdaavahmjutbfyy/Build/Products/Debug-iphonesimulator/AppNAme.app.dSYM
Is there a way I could get this location where the app is output to or even specify where I would rather have the app be sent to? I need access to the app to run Appium selenium tests and just having a build execute and run tests is not helpful. Also trying to incorporate jenkins into the mix and need to have commands to fully automate the process
Set the CONFIGURATION_BUILD_DIR Build Setting to be the directory you want.
https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW40
So in your example:
xcodebuild ...cut... CONFIGURATION_BUILD_DIR=<desired dir> ...cut...
use -derivedDataPath path to get compiled output onto specific folder.
xcodebuild -scheme xxx -workspace xxx.xcworkspace ONLY_ACTIVE_ARCH=NO -sdk iphonesimulator -configuration Debug -derivedDataPath ./build build
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/xcodebuild.1.html

Why won't my build phase scripts be executed when creating an IPA from command line?

Question - short version:
Why won't my build phase scripts be executed when creating an IPA from the command line?
When I'm running xcodebuild to create an IPA the predefined build phase scripts does not get executed. Why is that?
Question - lengthy version:
I have a workspace with a scheme I want to create an IPA out of from command line.
This works fine except for one thing; I have two scripts in the build phases of the target that is used to put the correct app version (CFBundleShortVersionString) and the correct svn revision number (CFBundleVersion). These to scripts works fine when archiving from xcode but for some reason they do not get run when archiving from command line.
First of all why is that?
Here are the scripts that are working (if archiving form xCode)
When archiving and creating the IPA from the command line I do (the essentials)
# Building
xcodebuild ARCHS="armv7 armv7s" ONLY_ACTIVE_ARCH=NO -workspace MyWorkspace.xcworkspace/ -scheme MyScheme CONFIGURATION_BUILD_DIR=${PROJECT_BUILD_DIR} -configuration Release clean build
# Creating IPA
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "${PROJECT_BUILD_DIR}/${APPLICATION_NAME}.app" -o "${IPA_OUTPUT_PATH}/${APPLICATION_NAME}.ipa"
It works and creates an IPA but none of the build phase scripts gets executed leaving both the revision number and version number untouched.
All suggestions are appreciated!
UPDATE DUE TO BDASH's ANSWER
Instead of making a clean build I make an install as
xcodebuild install ARCHS="armv7 armv7s" ONLY_ACTIVE_ARCH=NO -workspace MyWorkspace.xcworkspace/ -scheme MyScheme CONFIGURATION_BUILD_DIR=${PROJECT_BUILD_DIR} -configuration Release
The predefined script will IN FACT be executed (can be seen in the project version number) with no errors during the install. However the created IPA will have a size of ~300 bytes (instead of ~10MB) and cannot be installed on a device.
Building the app before installing it, i.e.
# Building
xcodebuild clean build ARCHS="armv7 armv7s" ONLY_ACTIVE_ARCH=NO -workspace MyWorkspace.xcworkspace/ -scheme MyScheme CONFIGURATION_BUILD_DIR=${PROJECT_BUILD_DIR} -configuration Release
# Installing
xcodebuild install ARCHS="armv7 armv7s" ONLY_ACTIVE_ARCH=NO -workspace MyWorkspace.xcworkspace/ -scheme MyScheme CONFIGURATION_BUILD_DIR=${PROJECT_BUILD_DIR} -configuration Release
and then creating the IPA will result in an IPA with executed version script and of correct size BUT it is not possible installing it on a device. Trying to put it on a device will give an error message saying
"The program "MyApp" was not installed on you iPhone device "My Device" because an unknown error has occurred."
You have "Run script only when installing" checked for at least one of the script phases. That phase won't be run when using the build action to xcodebuild, only if using the install action.

Resources