| Autoconf, Automake, and Libtool | ||
|---|---|---|
| <<< Previous | Writing Portable C++ with GNU Autotools | Next >>> |
Each of the GNU Autotools contribute to C++ portability. Now that you are familiar with the issues, the following subsections will outline precisely how each tool contributes to achieving C++ portability.
Of the GNU Autotools, perhaps the most valuable contribution to the portability of your C++ programs will come from Autoconf. All of the portability issues raised in the section called Changeable C++ can be detected using Autoconf macros.
Luc Maisonobe has written a large suite of macros for this purpose and they can be found in the Autoconf macro archive (see the section called Autoconf macro archive in the chapter called Writing New Macros for Autoconf). If any of these macros become important enough, they may become incorporated into the core Autoconf release. These macros perform their tests by compiling small fragments of C++ code to ensure that the compiler accepts them. As a side effect, these macros typically use AC_DEFINE to define preprocessor macros of the form HAVE_feature, which may then be exploited through conditional compilation.
Automake provides support for compiling C++ programs. In fact, it makes it practically trivial: files listed in a SOURCES primary may include .c++, .cc, .cpp, .cxx or .C extensions and Automake will know to use the C++ compiler to build them.
For a project containing C++ source code, it is necessary to invoke the AC_PROG_CXX macro in configure.in so that Automake knows how to run the most suitable compiler. Fortunately, when little details like this happen to escape you, automake will produce a warning:
$ automake
automake: Makefile.am: C++ source seen but CXX not defined in
automake: Makefile.am: `configure.in'
|
At the moment, Libtool is the weak link in the chain when it comes to working with C++. It is very easy to naively build a shared library from C++ source using libtool:
$ libtool -mode=link g++ -o libfoo.la -rpath /usr/local/lib foo.c++
|
This works admirably for trivial examples, but with real code, there are several things that can go wrong:
On many architectures, for a variety of reasons, libtool needs to perform object linking using ld. Unfortunately, the C++ compiler often links in standard libraries at this stage, and using ld causes them to be dropped. This can be worked around (at the expense of portability) by explicity adding these missing libraries to the link line in your Makefile. You could even write an Autoconf macro to probe the host machine to discover likely candidates.
The C++ compiler likes to instantiate static constructors in the library objects, which C++ programmers often rely on. Linking with ld will cause this to fail. The only reliable way to work around this currently is to not write C++ that relies on static constructors in libraries. You might be lucky enough to be able to link with LD=$CXX in your environment with some projects, but it would be prone to stop working as your project develops.
Libtool's inter-library dependency analysis can fail when it can't find the special runtime library dependencies added to a shared library by the C++ compiler at link time. The best way around this problem is to explicity add these dependencies to libtool's link line:
$ libtool -mode=link g++ -o libfoo.la -rpath /usr/local/lib foo.cxx \
-lstdc++ -lg++
|
Now that C++ compilers on Unix are beginning to see widespread acceptance and are converging on the ISO standard, it is becoming unacceptable for Libtool to impose such limits. There is work afoot to provide generalized multi-language and multi-compiler support into Libtool---currently slated to arrive in Libtool 1.5. Much of the work for supporting C++ is already finished at the time of writing, pending beta testing and packaging [1] .
| [1] | Visit the Libtool home page at @uref{http://www.gnu.org/software/libtool} for breaking news. |
| <<< Previous | Home | Next >>> |
| Compiler Quirks | Up | Further Reading |