autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Solving the config.h nightmare ?


From: Daniel Reed
Subject: Re: Solving the config.h nightmare ?
Date: Sat, 22 Apr 2006 18:35:17 -0400 (EDT)

On Sat, 22 Apr 2006, Olivier Boudeville wrote:
Daniel Reed a écrit :
If mode_t is always in <unistd.h>, why do you need to check for it at
all? If it's not always in <unistd.h>, is it possible it might move at
some point in the future, say if the system operator upgrades his
libc? Why would you test for something that is always true, and why
would you hardcode something in *your* header that doesn't depend on
*your* software (and hence should be constantly retested by all
software to be built in the future)?
As I understood, depending on the platform not all 'standard' symbols
are always in headers whose filenames are the same. But, in a given
platform, I hope there is little chance of symbol migration, hence the
test might be regarded as useless indeed. Would not be autoconf's task

Perhaps there is some type or definition that the installer's libc's headers define in a historical but deprecated location. If and when the system operator upgrades to a libc that moves the definition to a "more correct" location, the results of the check that was performed at the install time of your software become invalid. Someone trying to build software based on yours might be confounded by the sudden breakage of your header files without any apparent change to their installation of your software. Something your software computed at install time simply became invalid. Better to have dependent software reperform the check at each build time.

And this is probably more of an issue for dependency types from non-system software, where there may be less concern for -devel-file stability.


It's almost always a mistake to install generated headers. Distribute
an .m4 with your software that [re]performs all of the checks that
dependent software will need to make. Install that instead of what is
essentially just the cached output of its run (which is what your
config.h is, whatever you prefer to call it) so dependent software
devlopers can just call OB_PROG_CEYLON in their configure.ac and get
their own config.h files (or CPPFLAGS or whatever mechanism they
prefer) sanitized.
Well, yes, the relevant tests might be factored out in an independant m4
file. But I suppose the user program can as well, if no name collision
can occur, just include here the main Ceylan header, which itself
includes its corresponding "config.h" which contains the result of these
tests instead.

The issue is when these tests are performed. You perform them when Ceylon is installed, then you want to save the results of those tests in an installed header file for other software to use. I want you to perform the tests when Ceylon is installed and then forget their results, forcing dependent software to perform the same tests again when it (the dependent software) is built.

What you are doing is essentially treating all dependent software as a part of your own software. You aren't a provider of an API, you are a code base that other people's software is integrating into rather than using as a consumer. The difference being that I should be able to compile (if not link) software to be used with your software with nothing more than your header files, your APIs. I may, for example, choose to distribute your header files with my own program, and instead of linking against your software at build time, perform a dlopen() of your library at run time to see if I can use your library's functionality or not. How your library was (or will be) built should not affect me as a consumer of your API at all. (And if eventual implementation details can not be isolated, then your API should be versioned or otherwise staticly marked so I could, for example, include code for all permutations of your API and still be able to dlopen at run time, choosing my own internal code path for the API version of the library that dlopen finds.)

Doing so requires you to choose to use external data types, and/or create abstraction types around external data types, so your API does not change based on what other software is installed. For example, use a forward-declared but undefined struct pointer as a handle in .h files, only defining it internally (to contain whatever mode_t or png_header or whatever you need), then only deal with the opaque handle in your API.


pthread_mutex_t *ceylon_create_mutex(void);

becomes

struct ceylon_thread_mutex_t;
struct ceylon_thread_mutex_t *ceylon_create_mutex(void);

You can typedef pthread_mutex_t ceylon_thread_mutex_t; in your actual implementation, or create it as a struct with a pthread_mutex_t element, or whatever, but, so long as you always refer only to pointers of ceylon_thread_mutex_t, and never an instance of the [fake] type itself, you never need to define what is in it in installable headers.

--
Daniel Reed <address@hidden>      http://shell.n.ml.org/n/        
http://naim.n.ml.org/
There are people who do things and people who take the credit, and the
trick is to be in the first group; there is a lot less competition. --
Dwight Morrow, American Diplomat

reply via email to

[Prev in Thread] Current Thread [Next in Thread]