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

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.

Related

Specify individual target build settings with xcodebuild

I have an iOS app that uses Cocoapods, and has a local cocoa touch framework target, and I'm running into an issue with specifying build settings in the command line using xcodebuild.
I understand that you can specify build settings like PROVISIONING_PROFILE, CODE_SIGN_IDENTITY, and DEVELOPMENT_TEAM by appending their key=value pair to the end of the command.
However those setting appear to be applied to the entire project, but I only need them to apply to the app target since touch frameworks cannot be signed.
How do I specify build settings for an individual target using xcodebuild? If it cannot be done using xcodebuild, could this be accomplished using fastlane?
Use schemes. You can set the scheme to build/archive with a particular build configuration and executable.

Embedded framework build directory not matching scheme

I have several frameworks embedded in my Xcode workspace. In my scheme list, I have four schemes - 2 products: 1 release, 1 beta version of each. Each scheme has its own info.plist, product name, build settings, build path. In my main scheme, my app will build and archive correctly.
When I change to the alternate scheme (release or beta) I get a build error because my embedded frameworks are building in the original build/Release-iphoneos directory and not the build/Release AlternateName-iphoneos. I have tried everything I can think of to get my Framework SearchPaths and Library SearchPaths to point to the embedded framework build directory but I'm having no luck.
Has anyone run into this problem before or have any suggestions? Would the best solution be to have a run script phase that copies the embedded builds into the target directory?

Lipo error with additional schemes in XCode

I want to create additional build configurations and schemes in my XCode project in order to build sepcific archives for TestFlight. One connected to our DEV environment for internal testers, and one connected to our PROD environment for external beta testers.
So I was following this excellent blog post and I created 2 additional build configurations by duplicating the Release one. Then I created 2 additional schemes based on the default one, by changing the build configuration of the Archive build operation to the proper build configuration. Finally I set some user-defined settings in each build configuration to point to the right server URL depending on whether we are in a DEV build or a PROD build.
But now when I archive my project using one of these two additional schemes, I get the following Lipo error:
/fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can’t open input file: /Users/sarbogast/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/MyAppTestFlightPROD/IntermediateBuildFilesPath/MyApp.build/TestFlight PROD-iphoneos/MyApp.build/Objects-normal/armv7/MyApp (No such file or directory)
And indeed when I go to /Users/sarbogast/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/MyAppTestFlightPROD/IntermediateBuildFilesPath/MyApp.build/TestFlight PROD-iphoneos/MyApp.build/Objects-normal/armv7 directory, there is no MyApp file or directory in there.
I read here and there that setting 'Build Active Architecture only' to YES might solve the problem, but I don't want to do that as these are release builds for TestFlight and I want them to work on all architectures.
Any idea what might be wrong in my set up?
I am using CocoaPods and I had log messages saying that the linker could not find Pods for my new scheme. So I added my new scheme to link_with in my podfile and now it works perfectly.
I still don't understand why, because I thought link_with was only to list targets and this is not a target, this is a scheme. But it works.

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