I have a project I am splitting into two targets. The original single-target project uses a number of define commands, however I need these values to now be different depending on which target I am building.
What's the correct way to do that? Should I be using NStrings declared on the AppDelegate? Or can I use a #if statement when settings the #defines?
Any help, much appreciated.
One approach would be like this:
#if defined(MON_TARGET_A)
#define MON_TARGET_NAME "App A"
#elif defined(MON_TARGET_B)
#define MON_TARGET_NAME "App B"
#else
#error "which target are you building?"
#endif
Then add MON_TARGET_A or MON_TARGET_B to your target's preprocessor settings.
Usually, you'll use GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS and not GCC_PREPROCESSOR_DEFINITIONS because the latter can prevent sharing of PCH headers.
To add this, go to:
Project Navigator -> Project -> Target -> Build Settings
then drop GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS into the search field and set its value to something like: MON_TARGET_A $(inherited)
You can add additional preprocessor macros in your target settings (Preprocessing->Preprocessor Macros) and use #ifdef.
This is the most flexible approach.
Related
I have a preprocessor macro in my XCODE project called LINPHONE_DEBUG. In my build settings, I have set the macro to 0 exactly like this: LINPHONE_DEBUG=0.
But somehow when I use this code:
#if LINPHONE_DEBUG
foo()
#endif
The foo() is still called see the screenshot below.
You can see that I printed po LINPHONE_DEBUG and it is 0, but it still reached the code.
I am running XCODE 6.4 (6E35b).
From the Swift iBook: Using Swift with Cocoa and Objective-C (Swift 2 Prerease)
“The Swift compiler does not include a preprocessor. Instead, it takes advantage of compile-time attributes, build configurations, and language features to accomplish the same functionality. For this reason, preprocessor directives are not imported in Swift.”
“Build Configurations
Swift code and Objective-C code are conditionally compiled in different ways. Swift code can be conditionally compiled based on the evaluation of build configurations. Build configurations include the literal true and false values, command line flags, and the platform-testing functions listed in the table below. You can specify command line flags using -D <#flag#>.”
See the documentation for more information on Build Configurations.
Update: This solution working in objective c.
You should try like this:
#if LINPHONE_DEBUG > 0
foo()
#endif
You can avoid the preprocessor directives by putting your environment configurations into structs.
In my app there are five targets. Every target has its own plist.
I want to get 2 urls in AppDelegate when I build a target. Those 2 urls are different for each target. There are 5 plists (MyApp1-Info.plist, MyApp2-Info.plist, MyApp3-Info.plist, MyApp4-Info.plist, MyApp5-Info.plist). Each attached with only 1 target.
I have put those urls in plists. If I build MyApp2 then I should get urls from MyApp2-Info.plist. How can I do that? Or is there any better way to do that?
Thanks in advance.
The better method of using a common source file within multiple targets is to use preprocessor macro that is different for each target. This directs the source file to perform different actions, or use different values, depending on which target is being compiled.
For example assume you set the prepropressor macro TARGET to 1, 2, etc. (or something more meaningful to your project), by setting the flag -DTARGET=1, -DTARGET=2, etc in the Xcode build settings, then the source file can use different URLs as simply as:
#if TARGET == 1
#define URL "http://one.com"
#elif TARGET == 2
#define URL "http://two.com"
#else
#error Invalid TARGET value
#endif
and away you go.
You can obviously also provide any amount of conditional-compilation using this method, for example:
#if TARGET == 1
doSomethingDrastic();
#endif
This is a much simpler, and a much more traditional, approach to defining per-target behaviour than embedding stuff within a .plist file.
Can I import a file with a pre-defined prefix.
e.g. something like this (pseudo code)
#import PRODUCT_NAME+"-Config.h"
I want to have different targets in Xcode for my application. Each target can have its own configuration file(s). I want this to be automatic however, so if the PRODUCT_NAME bit can be the actual target product name that would be the best way.
Thanks for any help you can give me.
Many thanks.
Setup each target with a unique flag under the Other C Flags build setting. Then you can do something like:
#if defined(TARGET1)
#import "Target1Config.h"
#elif defined(TARGET2)
#import "Target2Config.h"
#endif
where TARGET1 and TARGET2 are each defined only for the corresponding target's build settings.
Just give the config files the exact same name, but locate them in different folders. Make sure that each config file only has the appropriate target ticked. Then you can just do #import "Config.h", and the relevant Config.h will be used each time.
I have an application with several different Targets defined. I know that I can use preprocessor directives to have different sections of code for different targets, but how do the naming conventions work? For instance, if I have two Targets called "Smith" and "Smith Plus" how do these translate?
#if (Smith)
#elif (Smith Plus)
#endif
You basically have it right.
In your project settings, when you click on a target you will see a tab for 'build settings'. Under there search for preprocessor macros. For your smith target, add a the preprocessor macro "SMITH=1". Do the same for your smith plus target (SMITH_PLUS=1).
Then, in your code, you just use the like you illustrated yourself:
#if SMITH
// do something
#elif SMITH_PLUS
// do something else
#endif
I have a project I am splitting into two targets. The original single-target project uses a number of define commands, however I need these values to now be different depending on which target I am building.
What's the correct way to do that? Should I be using NStrings declared on the AppDelegate? Or can I use a #if statement when settings the #defines?
Any help, much appreciated.
One approach would be like this:
#if defined(MON_TARGET_A)
#define MON_TARGET_NAME "App A"
#elif defined(MON_TARGET_B)
#define MON_TARGET_NAME "App B"
#else
#error "which target are you building?"
#endif
Then add MON_TARGET_A or MON_TARGET_B to your target's preprocessor settings.
Usually, you'll use GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS and not GCC_PREPROCESSOR_DEFINITIONS because the latter can prevent sharing of PCH headers.
To add this, go to:
Project Navigator -> Project -> Target -> Build Settings
then drop GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS into the search field and set its value to something like: MON_TARGET_A $(inherited)
You can add additional preprocessor macros in your target settings (Preprocessing->Preprocessor Macros) and use #ifdef.
This is the most flexible approach.