I've a C++ autoconf managed project that I'm adapting to compile on FreeBSD hosts. The original system was Linux so I made one AM_CONDITIONAL to distinguish the host I'm building and separate the code into system specific files.
configure.ac
AC_CANONICAL_HOST AM_CONDITIONAL([IS_FREEBSD],false) case $host in *free*) AC_DEFINE([IS_FREEBSD],[1],[FreeBSD Host]) AM_CONDITIONAL([IS_FREEBSD],true) BP_ADD_LDFLAG([-L/usr/local/lib]) ;; esac
Makefile.am
lib_LTLIBRARIES=mylib.la mylib_la_SOURCES=a.cpp \ b.cpp if IS_FREEBSD mylib_la_SOURCES+=freebsd/c.cpp else mylib_la_SOURCES+=linux/c.cpp endif
When I run automake it fails with this kind of message:
Makefile.am: object `c.lo' created by `linux/c.cpp' and `freebsd/c.cpp'
Any ideas on how to configure automake to respect this conditional even in the Makefile.in build proccess?
I this works if the files have diferent names, but it's c++ code and I'm trying to keep the filenames the same as the class name.
Thanks in advance!
automake is a tool used for automatically generating Makefile.in files compliant with the set GNU Coding Standards. autoconf is required for the use of automake. automake manual can either be read on-line or downloaded in the PDF format. More formats are also offered for download or on-line reading.
The purpose of autoconf is to collect information from your system to populate the Makefile.in template, which is created using automake .
To create a configure script with Autoconf, you need to write an Autoconf input file configure.ac (or configure.in ) and run autoconf on it. If you write your own feature tests to supplement those that come with Autoconf, you might also write files called aclocal. m4 and acsite.
You could request for the objects to be built in their respective subdirectories with
AUTOMAKE_OPTIONS = subdir-objects
Another option, besides subdir-objects, is to give each sub-project some custom per-project build flags. When you do this, automake changes its *.o naming rules to prepend the target name onto the module name. For example, this:
mylib_la_CXXFLAGS=$(AM_CXXFLAGS)
mylib_la_SOURCES=a.cpp b.cpp
will result in the output files mylib_la-a.o and mylib_la-b.o, rather than a.o and b.o. Thus you can have two different projects with the same output directory that each have, say, a b.cpp file, and not have their outputs conflict.
Notice that I did this by setting the project-specific CXXFLAGS to the values automake was already going to use, AM_CXXFLAGS. Automake isn't smart enough to detect this trick and use the shorter *.o names. If it happens that you do need per-project build options, you can of course do that instead of this hack.
There's a whole list of automake variables that, when set on a per-executable basis, give this same effect. So for instance, maybe one sub-project needs special link flags already, so you give it something like:
mylib_la_LDFLAGS=-lfoo
This will give you the prefixed *.o files just as the AM_CXXFLAGS trick did, only now you are "legitimately" using this feature, instead of tricking automake into doing it.
By the way, it's bad autoconf style to change how your program builds based solely on the OS it's being built for. Good autoconf style is to check only for specific platform features, not whole platforms, because platforms change. FreeBSD might be a certain way today, but maybe in the next release it will copy a feature from Linux that would erase the need for you to build your program two different ways. Or, maybe the feature you're using today is deprecated, and will be dropped in the next version.
There's forty years of portable Unix programming wisdom in the autotools, grasshopper. The "maybes" I've given above have happened in the past, and will certainly do so again. Testing individual features is the nimblest way to cope with constantly changing platforms.
You can get unexpected bonuses from this approach, too. For instance, maybe your program needs two nonportable features to do its work. Say that on FreeBSD, these are the A and B features, and on Linux, they're the X and Y features; A and X are similar mechanisms but with different interfaces, and the same for B and Y. It could be that feature A comes from the original BSDs, and is in Solaris because it has BSD roots from SunOS in the 80's, and Solaris also has feature Y from it's System V based redesign in the early 90's. By testing for these features, your program could run on Solaris, too, because it has the features your program needs, just not in the same combination as on FreeBSD and Linux.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With