From: gordon@sneaky.lonestar.org (Gordon Burditt)
Subject: Re: Libraries specified in source?
Organization: Gordon Burditt
Date: Wed, 27 Jan 1993 09:28:07 GMT

>>Surely the standard can't
>>specify how to use extensions.
>
>Surely the standard can evolve to include a few good ideas, like Ray's
>#library directive.

Is it a good idea?  I have my doubts.  However, I think it will need
a lot of polishing before it is implemented.

Problem 1:  What's a legal file name?  I don't think there is any
absolute path name that is legal under MS-DOS, VMS, and UNIX.  The
least common denominator is a file name relative to some directory.

Include files solved this problem by (1) building in certain names
that HAD to work right, and (2) using file names relative to one
of several system-specific directories.  So let's use relative
file names for the library.

Problem #2:  Where are the commonly-used libraries?  386BSD doesn't
HAVE a /lib directory.  On XENIX and V7 UNIX and a lot of other UNIX
systems, libc is in /lib.  Further, XENIX/*86 has various libraries
like /lib/Slibc.a, /lib/Mlibc.a, etc.  Ok, let's use the include
file solution:  you specify part of the library name, and the
compiler searches for it in one of several places.  Ok, instead
of -lm, we now have:

# library <m>

Maybe we could make that name a bit more descriptive.
In the case of 286 model-ridden implementations, the currently
in use model can select the appropriate library from the available
/lib/[SMCLHGEU]libc.a depending on whether small, medium, compact,
large, huge, gigantic, enormous, or universal model is in use.
(Did I miss any?)  I believe mixed-model constructions may become
a nightmare, although they probably were already.

Problem #3:  It invalidates all the code that doesn't specify libraries.
Easy fix:  all the libraries containing the ANSI C functions have to
be included anyway, without asking for them.  That gets rid of the
need for:
# library <m>
# library <c>
in most every source file, because they're implied.

Problem #4:  What are the appropriate statements to call on a
particular library?  Well, we can standardize on the names, following
existing conventions.  Now we've got something like:

# ifdef BSD
# library <curses>
# library <termcap>
# endif
# ifdef SYSV
# library <curses>
# endif
# ifdef XENIX_SYSV
# library <curses>
# library <termlib>
# endif
# ifdef XENIX_SYSIII
oh, heck, what goes here?
# endif

A few appropriate names to standardize might be <curses>, <ndbm>,
<X11>, <yacc>, <lex>, <rpc>, etc.  Note that I'm not ruling out
local libraries invoked with something like:

# library "isam"

Ok, now some problems I don't have good answers for:

Problem #5:  Do I really want to have to edit the source code to
use a different version of a library?  Some systems have different
variants of libraries, such as profiled and non-profiled libraries.
You don't necessarily want all the libraries profiled or all non-profiled.
I really don't want to have to edit the source to use or not use
shared libraries.  

This gets particularly frustrating if someone has taken it on
themselves to put # library directives in the system include files
to be helpful.  It could be very helpful, until you want to use
an experimental version of something.

Note that it's not unusual to have a library version conflict with
a user supplied version of the same routine, and that warnings for
such a situation are annoying.  The yacc library, for example, contains 
a default main() routine if the user doesn't supply one, but it's
not used if one is supplied.

It's also not uncommon to have conflicts between one library and another,
also not deserving of a warning.  System V systems often have two
versions of malloc, one in libc and another in a separate library.

Problem #6:  Does library order matter?  With many existing linkers, it
does, especially if libraries call routines in other libraries.
I know, "fix all the linkers".  Sometimes it's not that easy.
And sometimes tricks are used with library order intentionally
to do system-dependent things, like assuring order in the
final executable, or using external references to select one 
of two identically-named routines, often printf() (integer-only
and integer+floating versions).  Maybe these tricks deserve
to die.


Problem #7:  Does # library select which routine you get when
there are two routines named the same in different libraries?
Example:  a.c and b.c are linked to make a complete program.

File a.c:

# library <GNUmalloc>
... uses malloc() ...

File b.c:

# library <SYSVmalloc>
... uses malloc()

Ok, what happens?  (a) routines in both a.c and b.c use GNUmalloc's
version of malloc(), (b) routines in both a.c and b.c use SYSVmalloc's
version of malloc(), (c) routines in a.c use GNUmalloc's version of malloc(),
and routines in b.c use SYSVmalloc's version of malloc(), (d) you get
a duplicate symbol error, or (e) you get (a) or (b) but can't predict
in advance which.  

Suppose you get choice (c), and have two malloc()s in use, and both
malloc()s call __free(), which are defined in their respective libraries.
Neither __free() is declared static.  Which malloc() calls which free()?

Problem #8: What happens when linking together many source files, several
of which specify libraries?  Do you use all specified libraries, after
weeding out the duplicates?  What order is used, if it matters?
Given a System V with two versions of malloc() in two different
libraries, both specified, which one gets used?  (This situation
is common practice, I believe).

					Gordon L. Burditt
					sneaky.lonestar.org!gordon