views:

1402

answers:

3

We're adding CoreData support to our iPhone app. It's a far reaching change (moving from SQLitePersistentObject). To avoid branching, we are running a single codeline with the new code within #ifdef blocks.

When I enable this code from one of my headers (#define CORE_DATA_BUILD) everything works fine. When I create a new target and define my preprocessor macro there, I get errors in the system headers. Specifically; CFBag.h, CFArray.h, CFBinaryHeap.h, CFDictionary.h and CFSet.h all fail to compile.

The error is expected ';', ',' or ')' before '>' token

I created my new target by copying my existing app target and then adding CORE_DATA_BUILD to the C Pre processor definitions section of GCC-4.2 - Preprocessing.

I'm pretty sure the pre-processor definition is set up and my macro name doesn't clash with any Apple symbols. The error also manifests when I add my define to "Preprocessor Macros Not Used In Precompiled Headers". I have cleaned the build and removed the precompiled headers but I still get the error.

Invocation and error output from Xcode is:

ProcessPCH /var/folders/Ay/AyBvIizJERGjIMkWxjcIfU+++TI/-Caches-/com.apple.Xcode.501/SharedPrecompiledHeaders/UIKit-fzghyhumbyslqcedmtegbkgafwpy/UIKit.h.gch /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h normal i386 objective-c com.apple.compilers.gcc.4_2
    cd /Users/rog/Development/Groove
    setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 -x objective-c-header -arch i386 -fmessage-length=0 -pipe -std=c99 -Wno-trigraphs -fpascal-strings -fasm-blocks -O0 -Werror -Wreturn-type -Wunused-variable -DCOREDATA -D<Multiple -Dvalues> -D__IPHONE_OS_VERSION_MIN_REQUIRED=30000 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk -fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -iquote /Users/rog/Development/Groove/build/Groove.build/Debug-iphonesimulator/Tests.build/Tests-generated-files.hmap -I/Users/rog/Development/Groove/build/Groove.build/Debug-iphonesimulator/Tests.build/Tests-own-target-headers.hmap -I/Users/rog/Development/Groove/build/Groove.build/Debug-iphonesimulator/Tests.build/Tests-all-target-headers.hmap -iquote /Users/rog/Development/Groove/build/Groove.build/Debug-iphonesimulator/Tests.build/Tests-project-headers.hmap -F/Users/rog/Development/Groove/build/Debug-iphonesimulator -F/Users/rog/Development/Groove -I/Users/rog/Development/Groove/build/Debug-iphonesimulator/include -I/Users/rog/Development/Groove/build/Groove.build/Debug-iphonesimulator/Tests.build/DerivedSources/i386 -I/Users/rog/Development/Groove/build/Groove.build/Debug-iphonesimulator/Tests.build/DerivedSources -c /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h -o /var/folders/Ay/AyBvIizJERGjIMkWxjcIfU+++TI/-Caches-/com.apple.Xcode.501/SharedPrecompiledHeaders/UIKit-fzghyhumbyslqcedmtegbkgafwpy/UIKit.h.gch
<command-line>: error: macro names must be identifiers
<command-line>: error: ISO C99 requires whitespace after the macro name
In file included from /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:39,
                 from /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:6,
                 from /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:8,
                 from /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:9:
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CFArray.h:173: error: expected ';', ',' or ')' before '>' token
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CFArray.h:359: error: expected ';', ',' or ')' before '>' token
In file included from /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:40,
etc...

My Prefix.pch file is standard:

//
// Prefix header for all source files of the 'Groove' target in the 'Groove' project
//

#ifdef __OBJC__
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
#endif

Any idea what's going wrong?

+1  A: 

Bit of a stab in the dark here - are you generating a precompiled header file? Have you rebuilt the precompiled header file since you changed the preprocessor symbol? You may be seeing a difference in the symbol as built into the precompiled header, and the symbol as seen in the other compilation units.

1800 INFORMATION
Upvote because it's a good suggestion but I am cleaning the build and removing the pre-compiled headers.
Roger Nolan
+1  A: 

Please post the invocation line of the compiler, not just the error; it tells us infinitely more. The error you cited is typical when an upstream error confuses the compiler when it's #importing downstream header files; it obviously doesn't mean there are errors in CFBag.h et al.

My suspicion is that when you created a different target, you got a different Prefix Header File for that target, and it's not set up correctly; compare the Prefix Header File build settings for the old and new targets, and compare the files themselves.

One common error is to include Objective-C header files from a C++ project. That doesn't work; you need to turn your .cpp files into .mm files if you want to intermix Objective-C and C++. But C++ should be able to #include CoreFoundation header files.

cdespinosa
Thanks. I've tried making the new varient by copying the existing build target and setting up a new one from scratch. I've also added the build directive to my original build and I still get the errors.
Roger Nolan
+2  A: 
    -D<Multiple -Dvalues> 
<command-line>: error: macro names must be identifiers
<command-line>: error: ISO C99 requires whitespace after the macro name

It looks like at some point you edited All Configurations of the Preprocessor Macros build setting of your project or target. Different configurations had different values. Rather than pressing Cancel or replacing them uniformly, you somehow confirmed the placeholder text .

Xcode is dutifully passing "<Multiple" and "Values>" as preprocessor definitions, instead of the preprocessor definitions you want.

Go to the target inspector Build tab, find Preprocessor Macros, delete its current value, and replace it with the value you really want.

cdespinosa
Doh, I completely didn't regiter that :-( Thanks very much. I have no idea how I did that but investigating quickly today, I did notice that when I was trying to delete my COREDATA macro Xcode wasn't overwriting the settings correctly.
Roger Nolan
Thanks this is the problem. The root cause seems to be adding a compiler flag to Xcode for all configurations when you have different values for other configurations. For example, I define DEBUG for only my debug builds. When I then add COREDATA for all configurations, Xcode converts its <multiple Values> display string into a real value used in the compiler invocation and generates the defect you pointed out.
Roger Nolan