guile-devel
[Top][All Lists]
Advanced

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

What to do about config.h, etc...


From: Rob Browning
Subject: What to do about config.h, etc...
Date: Tue, 04 Mar 2003 13:04:18 -0600
User-agent: Gnus/5.090008 (Oort Gnus v0.08) Emacs/21.2 (i386-pc-linux-gnu)

In 1.6 and 1.7, configure has been changed to generate config.h rather
than libguile/scmconfig.h, and now libguile/scmconfig.h is generated
from ../config.h using sed.  During this process sed removes
autoheader's global PACKAGE #define, so that it won't conflict with
any other package's public headers.

This was a quick and ugly hack for the release, and it's only a
stopgap.  We probably need to do something else so that we're not
defining hundreds of fairly generic configure symbols in the global
namespace whenever anyone #includes one of our public headers.
i.e. C_ALLOCA, DEBUG_EXTENSIONS, HAVE_*, SIZEOF_*, etc.

Ideally, the symbols that really need to remain public should probably
be renamed with the SCM_ prefix, and the rest of the symbols should be
moved off to a private header that's only #included by non-public
files.  Of course if anyone has been using any of the symbols we
rename or make private, we may break backward compatibility, so we
need to decide which evil we prefer: namespace pollution, or API
change.

To make things more difficult, AFAICT the auto* tools don't really
provide us with any easy mechanism to fix this problem.  Off the top
of my head I can see three choices:

  - Edit configure.in to change all symbols produced by configure to
    have SCM_ prefixes and just keep #including a copy of the
    automatically generated header (i.e. no private symbols) as we do
    now.  The main disadvantages to this approach are that we have to
    do a lot of editing of configure.in to override default behaviors,
    (i.e. we can't use AC_CHECK_FUNCS with multiple arguments as we do
    now), we'll always have to keep an eye on things to make sure
    autoheader doesn't add any new symbols that we have to "fix" in
    configure.in, and we may end up with a lot of global symbols that
    don't need to be global (i.e. are only used in .c files).

  - Use sed or similar to mangle config.h into a public and private
    header (or perhaps to just rename FOO -> SCM_FOO globally).  I'm
    concerned that this approach may be brittle -- trying to sed C
    syntax and not make mistakes seems a little fragile to me, and
    mistakes here may be hard to track down, i.e. symbols that just
    get missed or misdefined may still allow the compiles to proceed
    without incident, even though the code being generated is
    potentially incorrect.  If we did try this approach, we would need
    to make sure that symbols only made it into either the public
    header or the private header so that we don't have conflicts in .c
    files that directly or indirectly include both.

  - Use a C program to translate from config.h to the public and
    private headers, i.e. write a trivial C program that is built at
    compile time, that #includes config.h, and that when run, spits
    out our public and/or private headers.  The advantages here are
    that we're sure that we're parsing config.h properly (unlike with
    the sed approach), and that we have careful control over what
    makes it into the headers, along with the ability to rename
    symbols, etc.  The disadvantage is that it adds some complexity,
    and doesn't allow us to easily copy the documenting comments from
    config.h to our public/private headers.

    As a toy example of this approach.  The C program to generate the
    private header (say scmconfig-private.h) might look like this:

      #include <config.h>

      #ifndef CRAY_STACKSEG_END
      #define CRAY_STACKSEG_END 0
      #endif

      #ifndef SOMETHING_ELSE_ONLY_USED_IN_C_FILES
      #define SOMETHING_ELSE_ONLY_USED_IN_C_FILES 0
      #endif
      ...

      #define PRINT_DEF(SYM) print_if_defined(#SYM, SYM)

      static void
      print_if_defined (const char name[], int defined_p)
      {
        if (defined_p)
          printf ("#define %s\n", name);
        else
          printf ("/* #undef %s */\n", name);
      }

      int
      main (int argc, char *argv[])
      {
        print_preamble (); /* contains copyright header, etc. */
        printf ("\n");
        printf ("/* See config.h for symbol documentation. */\n");
        printf ("\n");
        PRINT_DEF(CRAY_STACKSEG_END);
        PRINT_DEF(SOMETHING_ELSE_ONLY_USED_IN_C_FILES);
        PRINT_DEF(YET_ANOTHER_THING_THATS_ONLY_PRIVATE);
        return 0;
      }

    The code to generate the public header might be similar, but would
    probably be a little more complex since we might also want to
    output some documenting comments for the symbols (as config.h does
    now).  Also, for the public header, we would likely need to rename
    things as well:

      printf ("#define SCM_SIZEOF_INT %d\n", SIZEOF_INT);

Thoughts?  Better alternatives?

-- 
Rob Browning
rlb @defaultvalue.org, @linuxdevel.com, and @debian.org
Previously @cs.utexas.edu
GPG starting 2002-11-03 = 14DD 432F AE39 534D B592  F9A0 25C8 D377 8C7E 73A4




reply via email to

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