Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automake and files with the same name

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!

like image 872
Renato Aquino Avatar asked May 27 '09 20:05

Renato Aquino


People also ask

What is the use of automake?

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.

What is the use of autoconf?

The purpose of autoconf is to collect information from your system to populate the Makefile.in template, which is created using automake .

How do I setup a script autoconf?

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.


2 Answers

You could request for the objects to be built in their respective subdirectories with

AUTOMAKE_OPTIONS = subdir-objects
like image 75
adl Avatar answered Sep 27 '22 23:09

adl


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.

like image 44
Warren Young Avatar answered Sep 27 '22 21:09

Warren Young