Path: utzoo!attcan!uunet!lll-winken!lll-lcc!ames!mailrus!ncar!tank!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.unix.wizards Subject: Re: libraries Message-ID: <15105@mimsy.UUCP> Date: 21 Dec 88 03:54:04 GMT References: <396@aber-cs.UUCP> <43200058@uicsrd.csrd.uiuc.edu> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 98 [subject changed back to follow the other parallel thread] In article <43200058@uicsrd.csrd.uiuc.edu> kai@uicsrd.csrd.uiuc.edu writes: [re replacing archive libraries with directories full of .o files] >Large numbers of object files? You've apparently never worked on a program >so huge that */*.o expands to overflow the shell's command line buffer, so >there is absolutely no way to link without storing them all in a library >first. You are not thinking clearly. Indeed, a large number of .o files is one of the very reasons I was considering giving up or modifying the current library archive scheme. When you have that many .o files, `ar c lib.a *.o' also runs out of argv space, and you must build the library in pieces, because you must name all the .o files for ar. Getting the library sorted becomes a major hassle. But if you were to run `ld -X /lib/crt0.o -o foo foo.o -lc', how is that different from when you now run `ld -X /lib/crt0.o -o foo foo.o -lc'? So *what* if `-lc' tells ld `go look at /lib/libc/*.o' rather than `go look at /lib/libc.a'? Indeed, library directories and library archive-files are not at all incompatible; one could (as I did) imagine ld containing code rather like the following: struct libops { int (*lib_getsyms)(); int (*lib_readobj)(); ... }; int sprintf(); ... if (!arlib_open(&lib, libname) && !dirlib_open(&lib, libname)) stop("cannot find library `%s'", libname); ... int arlib_getsyms(), arlib_readobj(); struct libops arlib_ops = { arlib_getsyms, arlib_readobj, ... }; /* try for an archive .a file */ int arlib_open(lib, libname) struct libdata *lib; char *libname; { struct arlib_data *p; int fd; char fn[MAXPATHLEN]; (void) sprintf(fn, "%s.a", libname); if ((fd = open(fn, O_RDONLY)) < 0) return (0); /* no ar file */ /* got an ar file. set up private data, etc */ p = (struct arlib_data *)xalloc(sizeof(*p)); lib->lib_data = (caddr_t)p; lib->lib_ops = &arlib_ops; p->ar_fd = fd; p->ar_israndom = arlib_hasfile("__.SYMDEF"); ... return (1); } ... int dirlib_getsyms(), dirlib_readobj(); struct libops dirlib_ops = { dirlib_getsyms, dirlib_readobj, ... }; /* try for a directory .a file */ int dirlib_open(lib, libname) struct libdata *lib; char *libname; { struct dirlib_data *p; struct stat st; if (stat(libname, &st) || (st.st_mode & S_IFMT) != S_IFDIR) return (0); /* not a directory library */ /* like, similar, y'know? */ p = (struct dirlib_data *)xalloc(sizeof(*p)); lib->lib_data = (caddr_t)p; lib->lib_ops = &dirlib_ops; p->d_file = p->d_path + sprintf(p->d_path, "%s/", libname); ... return (1); } plus any other arbitrary library scheme one cared to come up with (such as multiple .a files for `sub-groups' of the library, in which loops in the call topology do not cause so much ordering trouble as they do in separate libraries now, because all the sub-groups are treated as a single library by the grouplib() routines). (Some will recognise the above approach as the way one writes `object oriented' code in C.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris