So, I’ve been working for some time on connecting hashing out a trivial application, comprising C++ and Objective-C, to prove some concepts and try and learn something.
Here’s where I’m at now, my command (being run, and re-run on changes) is
$ autoreconf -vis && make clean && ./configure && make && ./src/greetings
Note, that I’m hoping that it’ll run when I’m done, here’s a brief file list:
$ find . | ack '\.(?:cpp|mm|h)$' ./src/darwin/greet.cpp ./src/darwin/greeting.h ./src/darwin/greeting.mm ./src/greet.h ./src/main.cpp ./src/mingw32/greet.cpp ./src/mingw32/greet.h
The files in full, can all be found in this Gist at Github.
Rather than being a problem specifically with mixing the languages ( I don’t even make it that far) – I appear to stumble at the compiler not recognising that this is Objective-C (or ObjecC++) – for that reason, my autoconf files are in this gist.
With the complete error output here, also in a Gist.
Here’s a sample:
In file included from /usr/include/c++/4.2.1/iosfwd:48,
from /usr/include/c++/4.2.1/ios:43,
from /usr/include/c++/4.2.1/ostream:45,
from /usr/include/c++/4.2.1/iostream:45,
from darwin/greet.cpp:10:
/usr/include/c++/4.2.1/bits/stringfwd.h:48: error: template with C linkage
/usr/include/c++/4.2.1/bits/stringfwd.h:51: error: template with C linkage
/usr/include/c++/4.2.1/bits/stringfwd.h:54: error: template with C linkage
/usr/include/c++/4.2.1/bits/stringfwd.h:58: error: template specialization with C linkage
/usr/include/c++/4.2.1/bits/stringfwd.h:63: error: template specialization with C linkage
In file included from /usr/include/c++/4.2.1/iosfwd:49,
from /usr/include/c++/4.2.1/ios:43,
from /usr/include/c++/4.2.1/ostream:45,
from /usr/include/c++/4.2.1/iostream:45,
from darwin/greet.cpp:10:
From playing around with the zip file, here is what I recommend:
Use a C-only interface on the language boundary. This will avoid automake’s non-existent Objective-C++ support. Use the
trick on your headers to ensure that the C++ compiler is going to generate C functions and the Objective-C compiler can handle the headers. This will make it possible for the Objective-C code to call your interface.
Set up your source tree as you have before: common code in
src/, OS-specific code insrc/darwin,src/msdos(:P),src/win32and so on. List all sources inEXTRA_foo_SOURCESinMakefile.am.In
configure.ac, test which platform you are compiling for and useAM_CONDITIONALto set flags thatMakefile.amcan read (you’ve done this correctly already).In
Makefile.am, use the conditionals to include the correct additional sources:Note that because of how the linker is chosen, a C++ link will be attempted. Additional linker flags to make the Objective-C code link will need to be in
foo_LDFLAGS.What had happened in your case was the following: In
greet.h, you did not declarevoid greet();asextern "C". This meant that whenmain.cppwas compiled, it expected avoid greet()that had C++ linkage (in my case, the symbol wasgreet).darwin/greet.cppwas compiled and hadvoid greet()declared asextern "C", so it produced a C version (with the symbol_greet). Linking then failed because the linker expected agreetsymbol but nothing provided that.