Cannot include Bullet headers in Objective-C headers: iOS

thepog
Posts: 5
Joined: Thu Apr 21, 2011 3:37 pm

Cannot include Bullet headers in Objective-C headers: iOS

Post by thepog »

Hello,

I am getting > 2000 compile errors, all which point to Bullet source files, if I try compiling with an #import statement to anything Bullet inside an Objective-C header. I am not having trouble including C++ headers from within my own project, i.e. any C++ source I wrote myself. Also, I am not having any trouble getting a good Bullet example to work properly as long as I use Bullet imports in my interface implementations (.m). Another thing is, if I try creating a project for Mac (rather than iOS), I do not run into this problem. I know it's possible to do this. I have searched all over for a solution and found plenty of examples of people doing exactly this without error. I suspect it must be related to the way I included Bullet into my project, but I really don't know. :?

The way I included Bullet into the project was by creating a new target, calling it "bullet," adding "bullet" as a "Direct Dependency" to my main target and including the library "libbullet.a" into this target. I then right click on my "bullet" target and add existing files. I select three folders inside the bullet-2.78 src folder: BulletDynamics, BulletCollision, and LinearMath. I set my header search paths to the src directory and change the source type of any .m file that imports Bullet to sourcecode.cpp.objcpp. This all works just fine. I can compile the project and get zero errors and zero warnings. However, doing something like this (below) will make XCode asplode:

Code: Select all

// Ship.h

#import "Vec3.h"
#import "Vec4.h"
#import "btBulletDynamicsCommon.h" // this line, XCode no likey

@interface Ship : NSObject
{
	Vec3 *position, *velocity, *acceleration;
	Vec3 *localX, *localY, *localZ;
	float thrustForce, damping, matrix[16];
	BOOL useThruster;
}
I'll include an example compile error just for good measure, but they don't seem to be very descriptive of the problem.

Code: Select all

[in file btCollisionWorld.h]

#ifndef BT_COLLISION_WORLD_H
#define BT_COLLISION_WORLD_H

class btStackAlloc;   // this line here is what it's complaining about
...

/Users/pogalog/Documents/GLEssentials 2/bullet-2.78/src/BulletCollision/CollisionDispatch/btCollisionWorld.h:68:0 /Users/pogalog/Documents/GLEssentials 2/bullet-2.78/src/BulletCollision/CollisionDispatch/btCollisionWorld.h:68: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'btStackAlloc'
I realize that I could just pitch Obj-C out the window and go completely with C++ and be done with this issue. But I really do prefer using Obj-C for this project and I'm not willing to throw it out. Any insights provided will be most appreciated.

Thanks for looking,
Nathan
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Cannot include Bullet headers in Objective-C headers: iO

Post by dphil »

I'm not positive, but to me the error seems to be saying that it doesn't know what the "class" keyword is. Perhaps it has something to do with what is described here:
"You similarly cannot use C++’s class keyword, because the “plain” Objective-C compiler doesn’t recognize it."
Mind you, that's for using c++ in an obj-c file, so I'm not sure how relevant it is. Still, maybe you need to make sure that the bullet code is being compiled as c++ and not "plain obj-c". In my project we are working on Mac OS, not iOS, and we use pre-built frameworks from the bullet source, so we don't actually compile the source in our own project.
Nickeeh
Posts: 14
Joined: Wed Feb 09, 2011 8:35 pm

Re: Cannot include Bullet headers in Objective-C headers: iO

Post by Nickeeh »

Headers get their "code-type" from the file they are included from within Xcode. You must include the Bullet headers from a (Obj-)C++ context. Yes, Obj-C++ exists, and while it comes with a few quirks, I like it. Best of both on iOS.
thepog
Posts: 5
Joined: Thu Apr 21, 2011 3:37 pm

Re: Cannot include Bullet headers in Objective-C headers: iO

Post by thepog »

You must include the Bullet headers from a (Obj-)C++ context.
This is what I have been doing, if I understand what you mean by this. If I am using an Obj-C++ class implementation and include the header for that class, you are saying that this is enough to tell XCode that this header file is also Obj-C++, right? I have always changed the .m files to sourcecode.cpp.objcpp. This doesn't seem to be enough for some reason. For example, you mean

Code: Select all

// .h file
@interface Fraction: NSObject {
    int numerator;
    int denominator;
}

// .m file
#import "Fraction.h"
@implementation Fraction
...
What you're saying is that if Fraction.m is marked as Obj-C++, then so is Fraction.h?

@dphil - your link doesn't seem to be working. :(
I understand that I wouldn't be able to include a C++ class using the obj-c keyword "class." I was just trying to use #import "header.h".
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Cannot include Bullet headers in Objective-C headers: iO

Post by dphil »

Odd...I can click the link and it works fine.

I didn't mean that you are trying to use the "class" keyword, I just meant that the fact that it seems to have problems with the class keyword in a bullet c++ file (not your own) might indicate that the compiler is treating it as objective-c, not c++, though I'm not entirely sure why. I suppose it's possible you inadvertently set their file types to objective c?

When you say "I have always changed the .m files to sourcecode.cpp.objcpp", do you mean you have set the file types to sourcecode.cpp.objcpp in the "get info" menu for the files? In my project we just rename objective-c++ files with the *.mm extension, which has the same effect and makes it a bit more explicit, but I think either way should be fine. One other thing; you could go to the build settings for your "bullet" target and for the "Compile Source As" setting, specify c++ instead of "According to file type" (which I think is the default), which should just force it to treat it as c++. If none of that works, I'm not sure what the problem could be.
thepog
Posts: 5
Joined: Thu Apr 21, 2011 3:37 pm

Re: Cannot include Bullet headers in Objective-C headers: iO

Post by thepog »

When you say "I have always changed the .m files to sourcecode.cpp.objcpp", do you mean you have set the file types to sourcecode.cpp.objcpp in the "get info" menu for the files?
Yes, this is what I do to set the source type.
I didn't mean that you are trying to use the "class" keyword [...]
Ok, I understand now. I'm not sure if that would be the problem. I mean, I guess if it is trying to compile Bullet as Obj-C for some odd reason, then it would have a problem with the C++ "class" keyword. But I expect that it would have problems with just about everything else too since the syntax is radically different. Honestly, it kind of sounds like this is what might be happening based on the number of compile errors and the kinds of things the errors complain about.

I tried changing the "Compile As" option to be C++. As expected, it didn't like that at all. It tried compiling all the Obj-C in the project as C++ so I ended up with 52000 errors. I'm still a little curious to know if there is something strange about the way that I imported Bullet into the project. Based on the description in my first post, does it sound strange or is this how you do it too?

Edit: I have just noticed something potentially a little strange about the Obj-C headers in the project. For some reason, none of them have target memberships selected. The corresponding .m files have the main target selected, but I cannot select a target affiliation for the headers. I'm not even sure this would make a difference...
Also, I was dumb earlier with the 52000 compile errors. I had my main target compile as C++ instead of the Bullet target. Now I have switched the Bullet target to C++ compiling just to be sure, but it didn't make any difference. :(
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Cannot include Bullet headers in Objective-C headers: iO

Post by dphil »

How you included the bullet code shouldn't really matter, at least not for the "class" error you are getting. This is just a simple compilation error. I can reproduce the "class" error by creating a brand new Xcode cocoa project, adding a header file with nothing more than "class Blah;" in it, and then importing this header in the MyDocument.h file. Changing MyDocument.m (which imports MyDocument.h) to MyDocument.mm fixes the problem. This is basically what Nikeesh was getting at, in that my c++ header is treated as obj-c if used in a plain obj-c .m file, whereas it allows for c++ if included by a c++ or obj-c++ file (.mm, in this case).

In the example in your first post that was giving an error, you are including the bullet c++ header in your Ship.h file. So, for every source file you have that imports/includes (either directly or indirectly) Ship.h, change the extension from .m to .mm, and see what happens. You would need to change the extension of every source file that imports/includes, directly or indirectly, bullet headers.

You did already say that you set your files to be treated as obj-c++, but maybe you missed something. Try the above and see.
thepog
Posts: 5
Joined: Thu Apr 21, 2011 3:37 pm

Re: Cannot include Bullet headers in Objective-C headers: iO

Post by thepog »

That was it. There were source files using Ship.h that needed to also be converted. I simply changed the types to sourcecode.cpp.objcpp. Compiles without problems now.

Thank you so much for the effort you put into helping me.
Nathan