Specify individual target build settings with xcodebuild - ios

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.

Related

Xcode: Custom build configurations in Swift Package Manager

I'm trying to get SPM to work with different build configurations other than Debug and Release. Our iOS project has different schemes (e.g. Debug-Staging, Debug-Production, Alpha-Staging, Alpha-Production, etc.) where I set the bundle identifier, some flags, etc.
Is there a way to achieve that diversification even if SPM only "understands" Debug and Release?
Specify path to your custom config file when invoking generate-xcodeproj command.
Sample
swift-package generate-xcodeproj --xcconfig-overrides Config.xcconfig

Created new XCode Configuration and Scheme - linker is suddenly failing

A new XCode project has Debug and Release Configurations. I've added a new one under "ProjectName > Info" called "development", which is for now a duplicate of "debug".
I wanted to create a new scheme for building the app in development mode, so I duplicated the "Projectname" scheme and named it "DevelopmentScheme".
I set the build configuration for "run" and "archive" to the new "development" configuration that I created.
I'm still able to build the original Scheme.
I'm also able to build all of the required libraries when the project is configured with the development scheme, but when I get to the linking phase, I get the error:
ld: library not found for -lRNCookieManagerIOS
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Being relatively new to iOS development, I'm not really sure what the issue could be. Since I duplicated everything, shouldn't that mean they behave in the same way? Thoughts on what might be different between the original and new schemes?
The problem is that Xcode will expect to find the libraries inside a folder named after your custom configuration. You can add the custom configuration to each library you use, or better follow the steps below to make it use the libraries built via the Release configuration.
Steps:
Select your target
Open Build Settings tab
Search for 'Library Search Paths'
You'll see your new configuration name alongside Debug and Release
Double-click the space next to your new configuration name
Enter "$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)"
Set recursive to true.
Exit the dialog and you should see:
(inspired by this post)
Xcode 8.3.2 needs a bit different changes.
To make it work, you need to change the Per-configuration Build Products Path for your custom build config. For example, I have an Internal build config. In that field, instead of $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME), I put $(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME), and now it works :).

Xcode: How to remove a target dependency from the build phase for a specific configuration

I have an app that includes a Watch Extension and App target. I would to be able to have one of my configurations (for a beta) exclude these targets from the target dependencies so that I can distribute the build without the Watch Extension/App. However I still want my debug configuration to include them. Is this possible? Perhaps there is some run script that could add Target Dependencies manually? Thanks.
Duplicate your "Release" Configuration, that will include your Watch Extension. Here the official resource: https://developer.apple.com/library/ios/recipes/xcode_help-project_editor/Articles/BasingBuildConfigurationsonConfigurationFiles.html
In this configuration.
Remove the WatchKit extension from Target Dependencies
Remove WatchKit extension from Embed App Extensions
Duplicate your main target and remove the dependencies from the copy. Then duplicate your scheme and set its target to your new target.
Another solution would be to wrap the build and embedding into a separate script and run it manually, you can see how cocoapods are doing that.

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.

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

Resources