Xcode 5.0 XCTest: ambiguous expansion of macro 'NULL' - objective-c

I'm using Xcode 5. I have a OS X Framework / iOS static library project with mixed ObjC/C++ code and language dialects set to C11/C++11.
I added a Cocoa Unit Testing Bundle target which uses XCTest, I created one for both the iOS static library and the OS X framework.
This is the code I have and the error I get in both:
-(void) testExample
{
NSObject* world = [NSObject new];
world = nil; <--- Ambiguous expansion of macro 'NULL'
}
Running the iOS test the compiler tells me it is using the definition of NULL from stddef.h (line 74, ((void*)0)) and the other definition being in usr/include/stdlib.h (line 115, __DARWIN_NULL).
The OS X test fails points to usr/include/MacTypes.h (line 90, __DARWIN_NULL) with this time the alternative being in stddef.h (line 74, ((void*)0)).
Google has nothing on this issue. I'm just like "Well, I guess it's just one of these days...".
Any clues as to what may be going on here, and how to fix it?
UPDATE:
The iOS tests not running were due to creating the iOS unit test bundle with the OS X "Cocoa Unit Testing Bundle". /me slap
The OS X testing issue persists though. But I have a hunch that being on OS X 10.9 (Mavericks) this may be related to a missing 10.9 SDK (Base SDK is set to 10.8).

In your Build Settings for your test target, try setting "Enable Modules" to NO.
I've been having various kinds of trouble with test targets, all around preprocessor expansion. Doing this fixed things for me.

Try this: Add -Wno-ambiguous-macro to Xcode -> Build Settings -> Other C Flags

Related

How to include WebView in Objective C without crashing

When I include a WebView component on a form in my Objective C project in XCode7 for a Cocoa application on OSX and try to compile, it compiles and then has a runtime error of:
NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (WebView) for key (NS.objects); the class may be defined in source code or a library that is not linked
What's the fix?
In XCode7, if you use a WebView widget, you have to add the framework. Go to the Project Navigator and click the first icon, which is your project icon. In the middle of your screen on that IDE then, you'll see General > Linked Frameworks and Libraries. Click the + and add WebKit.framework. Now when you compile, the linkage will be there and it will work.
The drawback I think is that it says it's a 10.11 component, and so if I want to deploy my app to a 10.9 system or 10.10 system, it won't work. I'm not 100% certain of this without testing, however, but do have this hunch.
ADDENDUM:
I set my project to be 10.8 compliant and then found I can run just fine on 10.8 all the way to the latest OSX.

When to use "#if __IPHONE_OS_VERSION_MIN_REQUIRED > x"?

This question addresses how to conditionally include code based on iOS version. But how does it work?
Suppose I set iOS Deployment Target to 3.2 in Xcode 4.5.2. In my code I put in some #ifdef statements:
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0
// Some iOS 4+ code
#endif
If I run the code on a 3.2 device, this code won't be there, but if I run it on a 4.3 device, it will, right? How does that happen? Or am I misunderstanding what's going on here?
That is a compile time check so it will create the same behavior on any iOS version. Since the Deployment Target is less than 4.0 the code inside the if statement will not run on any device.
If you want the behavior you described you need to do a runtime check. You can see an example of how to do this in the thread that you linked.

Separate code between different versions of Mac OS X?

I want some code tobe compiled under 10.6 and below but not 10.7 and above.
For example:
#ifdef current version is MAC_OS_X_VERSION_10_6 or below
// do this
elif current version is MAC_OS_X_VERSION_10_7 or above
//do that
#endif
Can someone help me ge proper macros for it? I looked into AvailabilityMacros.h but was not able to figure out proper ifdef.
I have a dynamic library, and it cannot be loaded under 10.7 and above but loads properly under 10.6. This is due to private symbol _CGContextAppendPath. I want to keep it using under 10.6 and below but avoid its use in 10.7 and below. This is because _CGContextAppendPath symbol is not present on 10.7 and above.
I used,
SInt32 version = 0;
Gestalt( gestaltSystemVersion, &version );
bool lionabove = ( version >= 0x1070 );
did not work.
For Objective C, the go-to route would be to check the availability of specific APIs via e.g. [object respondsToSelector:].
For the C library you are using, weak-link to CoreGraphics.framework (so the loading doesn't fail when some functions aren't present) and check for availability of the function in question via &_CGContextAppendPath != NULL.
Details in http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/cross_development/Configuring/configuring.html#//apple_ref/doc/uid/10000163i-CH1-107837 and http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/cross_development/Using/using.html#//apple_ref/doc/uid/20002000-1114537-BABHHJBC.
Apple introduced a new Availability.h macro file for iOS and Mac OS 10.6 and above (located in <SDK>/usr/include/Availability.h). You can do what you are asking like this:
#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1070
// code to run up through 10.6
#else
// code to run on 10.7 or higher
#endif
Note that this macro is also available (which might be preferable depending on your logic):
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
// code to run on 10.7 or above
#else
// code to run below 10.7
#endif
The documentation for this is here: Conditionally Compiling for Different SDKs, particularly worth looking at if you are mixing iOS and Mac OS X code. I also highly recommend reading the header file mentioned above.

How to check if my IOS App support IOS 3+? And something about anonymous function

I'm new to IOS development, sometimes I use a function but ignore its Doc.
So, I may use some functions are only supported on IOS 4 or even IOS 5, but I want to support IOS 3+.
Does it has any way to check if my app support IOS 3+?
I don't want to check line by line, thx.
And BTW, anonymous function like void (^ funcName)(NSString *) is objective-c feature, right? So it is supported on all IOS version, right?
Change your 'Deployment Target' to 3.x to see if any methods you're using aren't supported on that version.
That however is not a substitute for testing on 3.x; so either find a 3.x device or drop support for that version. Also, blocks (the 'anonymous function' you describe) are only available on iOS 4 and above.
If you want to write different sets of code for different version targets, you can use preprocessor directives:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 50000
... 5.x code here ...
#elif __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
... 4.x code here ...
#else
... 3.x code here ...
#endif
Try running your app on a device running 3.x
by anonymous functions do you mean blocks like:
[self performSomeBlock:^(NSString *smth) {
NSLog(#"%#", smth);
}];
or do you mean just c like definitions (its late so i forgot the legit name)
void doSomething(void *(*func)(NSString *)) {
...
}

How can I get XCode / GDB to break in a Safari 5.1 NPAPI plugin?

I have an NPAPI plug in running on OS X 10.6.8 that I'd like to debug. When I load it using FireFox 3.6.19, I can set the active executable to FF, start FF, attach using XCode, and the breakpoint will fire at the expected time.
When using Safari 5.1, I see that the plug in runs out of process, so I created and activated a customer executable for /System/Library/PrivateFrameworks/WebKit2.framework/PluginProcess.app. I then start Safari, navigate to the page hosting the plug in, attach to the plug in process, and then use the UI such the breakpoint should fire, but it doesn't. I can tell by the UI that the plug in definately loaded. If the pause the process, I see:
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep y <PENDING> "ADP_NPAPI_Interface.m":34
2 breakpoint keep y <PENDING> "ADP_NPAPI_Interface.m":34
3 breakpoint keep y <PENDING> "ADP_NPAPI_Interface.m":34
4 breakpoint keep y <PENDING> "plugin.cpp":244
5 breakpoint keep y <PENDING> "plugin.cpp":358
6 breakpoint keep y <PENDING> objc_exception_throw
(gdb) show directories
Source directories searched: $cdir:$cwd
(gdb) info sources
No symbol table is loaded. Use the "file" command.
(gdb) file sources
sources: No such file or directory
(gdb) info file
No registers.
No registers.
(gdb) show paths
Executable and object file path: /Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym. My understanding is that the symbols will be in the plug in, so, I believe that gdb can't find my source files.
Thanks in advance for your help,
Dave
One method that I have used occasionally with FireBreath plugins is this:
#if WAIT_FOR_DEBUGGER
static bool beingDebugged() {
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; size_t mib_size = 4;
struct kinfo_proc kp; size_t kp_size = sizeof(kp);
int result = sysctl(mib, mib_size, &kp, &kp_size, NULL, 0);
return (0 == result) ? (P_TRACED & kp.kp_proc.p_flag) : false;
}
#endif
Then in one of the entrypoints (such as NP_Initialize) you do:
#if WAIT_FOR_DEBUGGER
#warning "WILL BLOCK ON P_TRACED"
while (!beingDebugged())
sleep(1);
#endif
A friend of mine came up with this, and it seems to work pretty well. However, you should know that in Safari 5.1 the browser will kill the plugin (send a SIG_KILL) after a (fairly brief) time of not getting a response from it. Because of this, it's nearly impossible to debug with Safari 5.1; I highly recommend you debug in either Firefox or Chrome because of this.
This will cause the plugin to wait for your debugger to attach. Note that in Safari 5.1 the name of the plugin process has changed; I forget what it is now exactly, but it's definitely out of process and it's not Safari =]
One of these days I'll get around to adding this to the default FireBreath np_mainmain.cpp file....
Xcode has an option to Run ->Attach to process. Use this to attach to plugin process and not the browser. From here you can start debugging plugin running in 64 bit browser
The "with-dsym" part of dwarf-with-dsym means that the symbols are in a separate symbol file, not in the binary.
Your options are:
- sWitch to plain dwarf
- copy the .dsym bundle from your build directory to next to the installed plugin
- manually load the dsym in gdb (at least, I believe this is possible; I haven't actually done it though)