views:

74

answers:

2

I have a problem trying to use autotools for a simple contrived project, the task is simple, use Objective-C on Mac OSX, and C++ on Windows (mingw) - with some C glue in the middle.

The project is structured like so (minus all the automatically generated files):

    ./aclocal.m4
    ./configure
    ./configure.ac
    ./Makefile.am
    ./src/darwin/greet.m
    ./src/greet.h
    ./src/main.cpp
    ./src/Makefile.am
    ./src/mingw32/greet.cpp    

The contents of the key files are here on github in a gist. (didn't want to spam here)

I'm using the following command between changes:

$ autoreconf -vis && ./configure && make

The error I receive is full output (here in another gist):

....
Making all in src
g++  -g -O2   -o greetings main.o  
Undefined symbols:
  "greet()", referenced from:
      _main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make[1]: *** [greetings] Error 1
make: *** [all-recursive] Error 1

I'm very new to autotools, and have come a long way with the help of a couple of good people on IRC, but I think I'm making a conceptual mistake here, really hope there's a simple mistake I am making.

It was my understanding from the docs that EXTRA_progname_SOURCES should contain all possible files, and that the conditionals which are setup should work to select the correct ones.

Alarmingly, I don't think my makefiles are being remade, because even when I change the line in src/Makefile.am to include the sources explicitly for my platform (which is Max OS X Darwin, most of the time) -- the output remains completely the same.

A: 

g++ -g -O2 -o greetings main.o

This line tries to build greetings executable from main.o. If greet() function is defined in some other file, for example, greet.cpp, it should be:

++ -g -O2 -o greetings main.o greet.o

Possibly, this line from Makefile.am

greetings_SOURCES = main.cpp greet.h

should be something like this:

greetings_SOURCES = main.cpp greet.cpp

In Makefile.am you have:

if OS_DARWIN  
greetings_SOURCES += darwin/greet.mm
endif
if OS_MINGW32  
greetings_SOURCES += mingw32/greet.cpp
endif

This is the place which is not executed properly. You need to check it.

Alex Farber
Acknowledged, but I don't know enough about autotools to debug this, what can you suggest?
Beaks
Try to change greetings_SOURCES unconditionally, adding required .cpp file to it. It it solves the problem, this means, that "if" or += is not executed as expected. If you are working with autotools, read this book: http://www.freesoftwaremagazine.com/books/autotools_a_guide_to_autoconf_automake_libtool
Alex Farber
I just did a small test using only `.c` files: it seems to be safe to += a `foo_SOURCES` variable if everything is listed in `EXTRA_foo_SOURCES`.
Jack Kelly
A: 

I see that you're referring to greet.mm in the gist, but greet.m in the question. Automake does not appear to natively support Objective-C++ code. For Objective-C code, you need to have AC_PROG_OBJC in your configure.ac. If you really meant Objective-C++ code, you'll need to do this via a suffix rule.

Jack Kelly
Jack, thanks for the tip, I'll take a look into that today, if I find some time.
Beaks
You were right, as soon as I fixed the `Makefile.am` to look for `.m` files, `autoreconf` warned me that I should add `AC_PROG_OBJC` to `configure.ac` - at which time the list of files passed to the compiler was complete, but left me still with linker problems which I'm working through.
Beaks
@Beaks: What is your automake version (`automake --version`)?
Jack Kelly
@Jack, this is resolved (partly) now - but here's the info you asked for: `automake (GNU automake) 1.11.1` and `autoconf (GNU Autoconf) 2.67`
Beaks
@Beaks: With an automake version that recent I can't see you having problems with `+=`. Can you open another question and provide pastebins of a full `configure;make` run?
Jack Kelly
Jack, I gave you the vote as the correct answer, because the file naming was wrong - the trouble I have now is that the linker doesn't find the symbols from the .m file (probably because they're `C++` code in a `.m` file. I'll open another question (and ping you early, if you like) with my follow-up.
Beaks
@Beaks: If you do, I'll give helping out a shot. If automake is adding the file but it's not linking (as in, you see two `.o` files on the link line), you probably want to declare the functions that cross the boundary `extern "C"`. (Alternative: Use objective-C++ here?) If you're not compiling the second file _at all_, then it's some weirdness in the build tool.
Jack Kelly