Built-in preprocessor token to detect iPhone app target - objective-c

I need to set up correctly the FIRM ID for my app(according to target).For example I wrote in my Distribution.h the following lines:
#define X_FIRM_ID #"X"
#define XX_FIRM_ID #"XX"
#define FIRM_ID XX_FIRM_ID
For each build that I made I must manually change the FIRM_ID.I want to this automatically, just like I do for Default.png and other images used in my apps.
I have 2 targets: one for X and another one for XX.In each target I filled the Preprocessor macros with X and XX accordingly.
Now I want to define in Distribution.h the FIRM_ID accordingly with the preprocessor macro and I don't know how to do this.
#define FIRM_ID if defined(XX) XX
The above one do not work.
Please help me with this, if it can be done.

There are several ways to do this, here are two:
In your target info, under build, set Preprocessor macros
Import different Prefix headers for the two targets

Related

What is the need for __NSX_PASTE__ to define a macro?

Let's review Clang's MIN macro through this article: Deep learning IOS development of macro. The final result is what you can also find here:
#define __NSX_PASTE__(A,B) A##B
#define __NSMIN_IMPL__(A,B,L) ({\
__typeof__(A) __NSX_PASTE__(__a,L) = (A);\
__typeof__(B) __NSX_PASTE__(__b,L) = (B);\
(__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__a,L) : __NSX_PASTE__(__b,L);\
})
But I don't understand the need of defining __NSX_PASTE__. Wouldn't it be the same and more readable to use directly:
#define __NSMIN_IMPL__(A,B,L) ({\
__typeof__(A) __a##L = (A);\
__typeof__(B) __b##L = (B);\
(__a##L < __b##L) ? __a##L : __b##L;\
})
The simple answer is the __NSX_PASTE__ is required as without it the __COUNTER__ macro (not shown in the question but see the full source in the linked article, or look at the definition in Apple's NSObjCRuntime.h) will not be expanded. This is due to the weird and wonderful way the C Preprocessor works and how it handles stringification and concatenation, a good place to read how all this works is the GCC documentation on macros.
To see the results with and without the __NSX_PASTE__ put your above macros in a test file, say test.m, in Xcode renaming __NSMIN_IMPL__ to MY__NSMIN_IMPL__ (or you'll get a duplicate macro warning), add the macro you omitted - again renamed to avoid clashes:
#define MY_MIN(A,B) MY__NSMIN_IMPL__(A,B,__COUNTER__)
and add some code which uses MY_MIN. Now in Xcode select the menu item Product > Perform Action -> Preprocess "test.m" - this will show you the result after the preprocessor has run. If you try it with your version of __NSMIN_IMPL__ which does not use __NSX_PASTE__ you will see __COUNTER__ is not expanded.
HTH

How to deal with arguments in macro names in Objective-C?

The idea is to setup several fixed CGPoint values with macros, and read them in code flexibly (randomly or with provided integer value)
I have a header file defining several CGPoints value like this:
#define kSpawnPoint1 {550,20}
#define kSpawnPoint2 {550,80}
#define kSpawnPoint3 {200,175}
I'm generating a random integer in my code between 1 to 3, and plan to read the CGPoint value in the macro according to the integer value. But don't know how to do it. After learning other tutorials about preprocessors, I write my code like following.
#define kSpawnPoint1 {550,20}
#define kSpawnPoint2 {550,80}
#define kSpawnPoint3 {200,175}
#define kSpawnPoint(x) kSpawnPoint##x
in the m file:
int tempInt = 1;
CGPoint tempSpawnPoint = kSpawnPoint(temInt);
However it doesn't work.(with warning: undeclared identifier 'kSpawnPointspawnPoint') How can I make this right? And is it the right way to pre-define several CGPoint? I think I must use the preprocessor to achieve this considering future multi-screen resolution support would be easier to implement in macro too, and my kSpawnPoints would not be the same with different screen resolution.
Macros only operate on text, not the values of variables. When you write kSpawnPoint(an_int), the preprocessor takes the literal string "an_int" and then pastes it, so you end up with kSpawnPointan_int. Thus, you would have to put a literal number as the argument in order to end up with one of your points: kSpawnPoint(1) -> kSpawnPoint1 -> {550, 20}
To choose randomly among your macros, you will have to put them into a structure that will exist at runtime, like an array or a switch statement.

How do I limit the scope of the preprocessing definitions used?

How do I preprocess a code base using the clang (or gcc) preprocessor while limiting its text processing to use only #define entries from a single header file?
This is useful generally: imagine you want to preview the immediate result of some macros that you are currently working on… without having all the clutter that results from the mountain of includes inherent to C.
Imagine a case, where there are macros that yield a backward compatible call or an up-to-date one based on feature availability.
#if __has_feature(XYZ)
# define JX_FOO(_o) new_foo(_o)
# define JX_BAR(_o) // nop
...
#else
# define JX_FOO(_o) old_foo(_o)
# define JX_BAR(_o) old_bar(_o)
...
#endif
A concrete example is a collection of Objective-C code that was ported to be ARC-compatible (Automatic Reference Counting) from manual memory management (non-ARC) using a collection of macros (https://github.com/JanX2/google-diff-match-patch-Objective-C/blob/master/JXArcCompatibilityMacros.h) so that it compiles both ways afterwards.
At some point, you want to drop non-ARC support to improve readability and maintainability.
Edit: The basis for getting the preprocessor output is described here: C, Objective-C preprocessor output
Edit 2: If someone has details of how the source-to-source transformation options in Xcode are implemented (Edit > Refactor > Convert To…), that might help.
If you are writing the file from scratch or all the includes are in one place, why not wrap them inside of:
#ifndef MACRO_DEBUG
#include "someLib.h"
/* ... */
#endif
But as I mentioned, this only works when the includes are in consecutive lines and in the best case, you are starting to write the file yourself from scratch so you don't have to go and look for the includes.
This is a perfect case for sed/awk. However there exists an even better tool available for the exact use-case that you mention. Checkout coan.
To pre-process a source file as if the symbol <SYMBOL>is defined,
$ coan source -D<SYMBOL> sourcefile.c
Similarly to pre-process a source file as if the symbol <SYMBOL>is NOT defined,
$ coan source -U<SYMBOL> source.c
This is a bit of a stupid solution, but it works: apparently you can use AppCode’s refactoring to delete uses of a macro.
This limits the solution to OS X, though. It also is slightly tedious, because you have to do this manually for every JX_FOO() and JX_BAR().

Setting up user specific preprocessor macros for Xcode

I'd like to be able to have specific code blocks such as #ifdef SOME_VARIABLE and the value of variable would be filled at project's build time if the project is being built on a specific user's machine.
Is that possible?
You set the value in the "Preprocessor Macros" Build Settings. Setting "SOME_VARIABLE=${USER}" in the build settings is equivalent to #define SOME_VARIABLE "jappleseed" in your code.
Then in your code you can do this:
#define jappleseed 1
#define sjobs 2
#if DEV_USER == jappleseed
NSLog(#"Hi Jhonny");
#elif DEV_USER == sjobs
NSLog(#"Hi Steve");
#endif
Note: This is a contrived example if you really want the string "jappleseed" for use in your code you should be using an Info.plist and not #define
In Xcode 6 (at least) you can include your username as part of the name of the macro in the preprocessor macros section of the Build Settings:
ENV_USER_$(USER)=1 (this will define the macro ENV_USER_myusername)
Then, in your code, you can use
#if ENV_USER_myusername
...
#endif
The =1in the definition may be redundant, since Xcode seems to define the variable as true by default. We put it there just to be on the safe side and be able to use either #if or #ifdef. This way there is no concern that it might be defined, but evaluating to false, in which case #ifdef would still work but #ifwouldn't. Of course, you might define it to be any value you wish, depending on what you want.
in swift: add DEBUG_$(USER) to "Active Compilation Conditions"
there is no way to assign a value

How do I create an #ifdef command to differentiate between my two targets in XCode?

Hopefully this is a simple question to answer - I think I'm being a n00b here.
I have, for the first time, created an XCode project with two targets. But I now want to add some code to differentiate between my two targets.
#ifdef MyTargetOne
x = 1;
#ifdef MyTargetTwo
x = 2;
I have two targets, but where do I declare "MyTarget1" and "MyTarget2"??
THANKS GUYS!
For each target you need a target-specific define - you can use the Preprocessor Macros setting for this ([GCC_PREPROCESSOR_DEFINITIONS, -D]) - add MyTargetOne=1 in the first target and MyTargetTwo=1 in the second.