Question

For my project (library), I use configure with libtool and automake to build under linux hosts. The library consists of a C API, as well as an optional C++ extension. So, since AC_PROG_CXX must be called globally, I use automake conditionals:

*configure.ac*:

AC_PROG_CC
AC_PROG_CXX
AM_PROG_AR

LT_INIT

... some tests to figure out 'build_cxx' ...

AC_CONDITIONAL([CXX], [ test x$build_cxx = xyes ])

And inside Makefile.am

sources = files.c
if CXX then
   cxx_sources = files.cpp
else
   cxx_sources =
endif

sources = $sources $cxx_sources

The whole thing, however, does not work when configure is not able to locate g++ (which practically kills the extra logic for the c++ extension). After some research, I've come down to the conclusion that AC_PROG_CXX somehow tells libtool to assume that c++ support. I was also surprised to realise that if AC_PROG_CXX fails, it sets CXX to 'g++'!!!

Anyway, calling AC_PROG_CXX conditionally produces errors like 'am_fastdepCXX is never defined', which seems logical to me. The worst thing is that the error is not shown while configure is running, but it appears later in the linking phase, in to form of 'unknown libtool option -o' (ouch).

The full source code can be found here -> http://bitbucket.org/sdlu/sdlu/src

Can somebody help me?

Thanks in advance...

Was it helpful?

Solution

It's an Automake limitation, it doesn't care about the condition when choosing the linker.

One work-around is to conditionally rewrite the _LINK command, as suggested in this mailing list post:

if USE_CXX
    cxx_sources = ...
else
    cxx_sources =
    libSDLU_la_LINK = $(LINK) $(libSDLU_la_CFLAGS) $(libSDLU_la_LDFLAGS)
endif

Another way (suggested in the same discussion) is to put the C++ sources in a utility library that is built and added conditionally, then added to the main library:

if CXX
    noinst_LTLIBRARIES = libSDLUxx.la
    libSDLUxx_la_SOURCES =  src/cxx/SDLU_CButton.cxx \
                            src/cxx/SDLU_CIniHandler.cxx \
                            src/cxx/SDLU_CRenderer.cxx \
                            src/cxx/SDLU_CSprite.cxx \
                            src/cxx/SDLU_CTexture.cxx \
                            src/cxx/SDLU_CWindow.cxx
    libSDLU_la_LIBADD = libSDLUxx.la
endif

Some unrelated notes

  1. Do not put generated files (Makefile.in, configure, etc) into source control.

  2. Add a bootstrap script that invokes the autotools to generate things.

  3. Prefer pkg-config (i.e. PKG_CHECK_MODULES(SDL2, sdl2)) over hand-crafted autoconf macros (i.e. AM_PATH_SDL2);

  4. Do not install autoheaders (i.e. SDLU_config.h.in). It makes your library incompatible with every autoconf-based software, as you are re-defining PACKAGE, VERSION, and all library-detection macros. See my answer in this question for examples on how to do it.

  5. I would have the C++ API built and installed as an independent, optional library; drop the sdlu-config script altogether, then write sdluxx.pc that requires sdlu. Do not bother checking if the C++ compiler works, if the user passed --enable-cxx he knows what he's doing; I prefer to have the build fail than silently have an incomplete library.

OTHER TIPS

I don't think it is a good idea to interfere in the handling of the CXX variable.

Use your own variable BUILD_CXX

AC_CONDITIONAL([BUILD_CXX], [ test x$build_cxx = xyes ])here

and

if BUILD_CXX
  # ....
endif
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top