📄 autobook_62.html
字号:
allow the rest of the project to be written in the knowledge that anyfunctions required by the project but missing from the installers systemlibraries will be available nonetheless. GNU <TT>`libiberty'</TT>comes to the rescue again -- it already has an implementation of<TT>`strerror.c'</TT> that I was able to use with a little modification.</P><P>Being able to supply a simple implementation of <CODE>strerror</CODE>, as the<TT>`strerror.c'</TT> file from <TT>`libiberty'</TT> does, relies on there beinga well defined <CODE>sys_errlist</CODE> variable. It is a fair bet that ifthe target host has no <CODE>strerror</CODE> implementation, however, that thesystem <CODE>sys_errlist</CODE> will be broken or missing. I need to write aconfigure macro to check whether the system defines <CODE>sys_errlist</CODE>,and tailor the code in <TT>`strerror.c'</TT> to use this knowledge.</P><P>To avoid clutter in the top-level directory, I am a great believer inkeeping as many of the configuration files as possible in their ownsub-directory. First of all, I will create a new directory called<SAMP>`config'</SAMP> inside the top-level directory, and put<TT>`sys_errlist.m4'</TT> inside it:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre></pre></td></tr></table></P><P>I must then add a call to this new macro in the <TT>`configure.in'</TT> file being careful to put it in the right place --somewhere between <EM>typedefs and structures</EM> and <EM>libraryfunctions</EM> according to the comments in <TT>`configure.scan'</TT>:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>SIC_VAR_SYS_ERRLIST</pre></td></tr></table></P><P>GNU Autotools can also be set to store most of their files in asubdirectory, by calling the <CODE>AC_CONFIG_AUX_DIR</CODE> macro near the topof <TT>`configure.in'</TT>, preferably right after <CODE>AC_INIT</CODE>:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>AC_INIT(sic/eval.c)AC_CONFIG_AUX_DIR(config)AM_CONFIG_HEADER(config.h)...</pre></td></tr></table></P><P>Having made this change, many of the files added by running<CODE>autoconf</CODE> and <CODE>automake --add-missing</CODE> will be put inthe <EM>aux_dir</EM>.</P><P>The source tree now looks like this:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>sic/ +-- configure.scan +-- config/ | +-- sys_errlist.m4 +-- replace/ | +-- strerror.c +-- sic/ +-- builtin.c +-- builtin.h +-- common.h +-- error.c +-- error.h +-- eval.c +-- eval.h +-- list.c +-- list.h +-- sic.c +-- sic.h +-- syntax.c +-- syntax.h +-- xmalloc.c +-- xstrdup.c +-- xstrerror.c</pre></td></tr></table></P><P>In order to correctly utilise the fallback implementation,<CODE>AC_CHECK_FUNCS(strerror)</CODE> needs to be removed and <CODE>strerror</CODE>added to <CODE>AC_REPLACE_FUNCS</CODE>:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre># Checks for library functions.AC_REPLACE_FUNCS(strerror)</pre></td></tr></table></P><P>This will be clearer if you look at the <TT>`Makefile.am'</TT> for the<TT>`replace'</TT> subdirectory:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre></pre></td></tr></table></P><P>The code tells <CODE>automake</CODE> that I want to build a library for usewithin the build tree (i.e. not installed -- <SAMP>`noinst'</SAMP>), and thathas no source files by default. The clever part here is that whensomeone comes to install Sic, they will run <CODE>configure</CODE> whichwill test for <CODE>strerror</CODE>, and add <TT>`strerror.o'</TT> to<CODE>LIBOBJS</CODE> if the target host environment is missing its ownimplementation. Now, when <TT>`configure'</TT> creates<TT>`replace/Makefile'</TT> (as I asked it to with <CODE>AC_OUTPUT</CODE>),<SAMP>`@LIBOBJS@'</SAMP> is replaced by the list of objects required on theinstaller's machine.</P><P>Having done all this at configure time, when my user runs<CODE>make</CODE>, the files required to replace functions missingfrom their target machine will be added to <TT>`libreplace.a'</TT>.</P><P>Unfortunately this is not quite enough to start building the project.First I need to add a top-level <TT>`Makefile.am'</TT> from which toultimately create a top-level <TT>`Makefile'</TT> that will descend intothe various subdirectories of the project:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>## Makefile.am -- Process this file with automake to produce Makefile.inSUBDIRS = replace sic</pre></td></tr></table></P><P>And <TT>`configure.in'</TT> must be told where it can find instances of<CODE>Makefile.in</CODE>:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>AC_OUTPUT(Makefile replace/Makefile sic/Makefile)</pre></td></tr></table></P><P>I have written a <CODE>bootstrap</CODE> script for Sic, for details see<A HREF="autobook_43.html#SEC43">8. Bootstrapping</A>:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre></pre></td></tr></table></P><P>The <SAMP>`--foreign'</SAMP> option to <CODE>automake</CODE> tells it to relaxthe GNU standards for various files that should be present in aGNU distribution. Using this option saves me from having to createempty files as we did in <A HREF="autobook_23.html#SEC23">5. A Minimal GNU Autotools Project</A>.</P><P>Right. Let's build the library! First, I'll run <CODE>bootstrap</CODE>:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>$ ./bootstrap+ aclocal -I config+ autoheader+ automake --foreign --add-missing --copyautomake: configure.in: installing config/install-shautomake: configure.in: installing config/mkinstalldirsautomake: configure.in: installing config/missing+ autoconf</pre></td></tr></table></P><P>The project is now in the same state that an end-user would see, havingunpacked a distribution tarball. What follows is what an end user mightexpect to see when building from that tarball:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>$ ./configurecreating cache ./config.cachechecking for a BSD compatible install... /usr/bin/install -cchecking whether build environment is sane... yeschecking whether make sets ${MAKE}... yeschecking for working aclocal... foundchecking for working autoconf... foundchecking for working automake... foundchecking for working autoheader... foundchecking for working makeinfo... foundchecking for gcc... gccchecking whether the C compiler (gcc ) works... yeschecking whether the C compiler (gcc ) is a cross-compiler... nochecking whether we are using GNU C... yeschecking whether gcc accepts -g... yeschecking for ranlib... ranlibchecking how to run the C preprocessor... gcc -Echecking for ANSI C header files... yeschecking for unistd.h... yeschecking for errno.h... yeschecking for string.h... yeschecking for working const... yeschecking for size_t... yeschecking for strerror... yesupdating cache ./config.cachecreating ./config.statuscreating Makefilecreating replace/Makefilecreating sic/Makefilecreating config.h</pre></td></tr></table></P><P>Compare this output with the contents of <TT>`configure.in'</TT>, and noticehow each macro is ultimately responsible for one or more consecutivetests (via the Bourne shell code generated in <TT>`configure'</TT>). Nowthat the <TT>`Makefile'</TT>s have been successfully created, it is safe tocall <CODE>make</CODE> to perform the actual compilation:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>$ makemake all-recursivemake[1]: Entering directory `/tmp/sic'Making all in replacemake[2]: Entering directory `/tmp/sic/replace'rm -f libreplace.aar cru libreplace.aranlib libreplace.amake[2]: Leaving directory `/tmp/sic/replace'Making all in sicmake[2]: Entering directory `/tmp/sic/sic'gcc -DHAVE_CONFIG_H -I. -I. -I.. -I.. -g -O2 -c builtin.cgcc -DHAVE_CONFIG_H -I. -I. -I.. -I.. -g -O2 -c error.cgcc -DHAVE_CONFIG_H -I. -I. -I.. -I.. -g -O2 -c eval.cgcc -DHAVE_CONFIG_H -I. -I. -I.. -I.. -g -O2 -c list.cgcc -DHAVE_CONFIG_H -I. -I. -I.. -I.. -g -O2 -c sic.cgcc -DHAVE_CONFIG_H -I. -I. -I.. -I.. -g -O2 -c syntax.cgcc -DHAVE_CONFIG_H -I. -I. -I.. -I.. -g -O2 -c xmalloc.cgcc -DHAVE_CONFIG_H -I. -I. -I.. -I.. -g -O2 -c xstrdup.cgcc -DHAVE_CONFIG_H -I. -I. -I.. -I.. -g -O2 -c xstrerror.crm -f libsic.aar cru libsic.a builtin.o error.o eval.o list.o sic.o syntax.o xmalloc.oxstrdup.o xstrerror.oranlib libsic.amake[2]: Leaving directory `/tmp/sic/sic'make[1]: Leaving directory `/tmp/sic'</pre></td></tr></table></P><P>On this machine, as you can see from the output of <CODE>configure</CODE>above, I have no need of the fallback implementation of <CODE>strerror</CODE>,so <TT>`libreplace.a'</TT> is empty. On another machine this might not bethe case. In any event, I now have a compiled <TT>`libsic.a'</TT> -- sofar, so good.</P><P><A NAME="A Sample Shell Application"></A></TR></TABLE><BR> <FONT SIZE="-1">This document was generatedby <I>Gary V. Vaughan</I> on <I>September, 12 2004</I>using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html"><I>texi2html</I></A></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -