4

I am writing a browser plugin for Mac OS that will place a status bar icon in the status bar, which users can use to interface with the browser plugin. I've successfully built a FireBreath 1.6 project in XCode 4.4.1, and can install it in the browser. However, FireBreath uses C++, whereas a large majority of the existing libraries for Mac OS are written in Objective C.

In the /Mac/projectDef.make file, I added the Cocoa Framework and Foundation Framework, as suggested here and in other resources I've found on the Internet:

target_link_libraries(${PROJECT_NAME}
    ${PLUGIN_INTERNAL_DEPS}
    ${Cocoa.framework} # added line
    ${Foundation.framework} # added line
)

I reran prepmac.sh, expecting a new project to be created in XCode with my .mm files, and .m files; however, it seems that they're being ignored. I only see the .cpp and .h files. I added rules for those in the projectDef.make file, but it doesn't seem to make a difference:

file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
    Mac/[^.]*.cpp
    Mac/[^.]*.h
    Mac/[^.]*.m    #added by me
    Mac/[^.]*.mm   #added by me
    Mac/[^.]*.cmake
)

Even if I add the files in manually, I get a series of compilation errors. There are about 20 of them, all related to the file NSObjRuntime.h file:

Parse Issue - Expected unqualified-id
Parse Issue - Unknown type name 'NSString'
Semantic Issue - Use of undeclared identifier 'NSString'
Parse Issue - Unknown type name 'NSString'
...
...
Semantic Issue - Use of undeclared identifier 'aSelectorName'
...
...
Semantic Issue - Use of undeclared identifier 'aClassName'
...

It continues like this for some time with similar errors...

From what I've read, these errors appear because of dependencies on the Foundation Framework, which I believe I've included in the project. I also tried clicking the project in XCode

I'm to the point now where I'm not sure what to try next. People say it's not hard to use Objective C in C/C++ code, but being new to XCode and Objective C might contribute to my confusion. This is only day 4 for me in this new platform.

What do I need to do to get XCode to compile the Objective C code? Please remember that I'm a little new to this, so I'd appreciate it if you leave detailed answers as opposed to the vague one-liners that are common in the tag. I'm just a little in over my head, but if you can get me past this hurdle I'm certain I'll be good to go from there.

UPDATE:

I edited projects/MyPlugin/CMakeLists.txt and added in the .m and .mm rules there too. after running prepmac.sh, the files are included in the project, but I still get the same compile errors.

I moved all the .h files and .mm files from the Obj C code to the MyPlugin root folder and reran the prepmac.sh file. Problem still exists. Same compile errors.

Community
  • 1
  • 1
jamesmortensen
  • 33,636
  • 11
  • 99
  • 120

1 Answers1

2

Your problem is that you have .h files that are being included by C++ files that have objective c type and/or includes in them. In order to do what you want all of your classes that are used by c++ need to either keep all obj c related stuff in an #ifdef or simply not expose anything obj c in the header file.

For example, you can use this ifdef in your header:

#ifdef __OBJC__
     // Objective C / C++ code here
#endif

It's important to remember that .h files are includes as well as header files, so they are actually included. If you include objective c code in a .cpp file the compiler gets confused and cries.


EDIT: The most important thing to remember is that you need to ensure that any objective c header files (or other files with objective c code) are not included from the cpp files. If you can do that you'll be fine.

taxilian
  • 14,229
  • 4
  • 34
  • 73
  • So if I'm including open source Objective C code, I then need to edit each header? I read something about using Prefix.pch files as a way to avoid this and even saw one in an Objective C project example, but I didn't yet figure out how to include that in the FireBreath project. +1, this will definitely get me on the right track! Thanks for taking the time to touch base on this! And you're right! CMake is a pain, but I can see where it's necessary... :) – jamesmortensen Sep 08 '12 at 03:34
  • no no no. If you're including open source objective C code you need to *not* include the headers from it from header files that will also be included by a C++ file. Alternatively wrap the #import in a #ifdef statement to prevent it from being included in the cpp file – taxilian Sep 08 '12 at 03:35
  • Ok, I think that's starting to make sense now. I left the Mac at work, so I'll try this out on Monday. Thanks again! :) – jamesmortensen Sep 08 '12 at 03:36
  • I ended up using the PIMPL method described here: http://stackoverflow.com/a/1061576/552792, which effectively prevents Objective C headers from being included in CPP files by creating a C++ Wrapper header file that acts as a layer between the Objective C++ implementation file (.mm) and the actual (.cpp) files. – jamesmortensen Sep 17 '12 at 21:40
  • that's exactly what I was trying to explain =] – taxilian Sep 17 '12 at 22:26
  • Yes! I see that, and I didn't understand the other post until reading your answer here, so +1 and checkmark! :) I think that the difference is I didn't need to use the ifdef headers using the wrapper. I'm still not entirely sure what I'm doing, and I may jump into the IRC later on this week with some CMake questions. I need to now try and get an icon in the Mac OS status bar, and it sounds like there's some configuration that needs to happen to compile the XIB files. Thanks again for your help! :) – jamesmortensen Sep 18 '12 at 03:04