This commit was manufactured by cvs2svn to create tag
'NSPRPUB_19980421_BASE'. git-svn-id: svn://10.0.0.236/tags/NSPRPUB_19980421_BASE@459 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
8c58ba330b
commit
c3c48dfb7d
293
CVSROOT/modules
293
CVSROOT/modules
@ -1,293 +0,0 @@
|
||||
# Three different line formats are valid:
|
||||
# key -a aliases...
|
||||
# key [options] directory
|
||||
# key [options] directory files...
|
||||
#
|
||||
# Where "options" are composed of:
|
||||
# -i prog Run "prog" on "cvs commit" from top-level of module.
|
||||
# -o prog Run "prog" on "cvs checkout" of module.
|
||||
# -e prog Run "prog" on "cvs export" of module.
|
||||
# -t prog Run "prog" on "cvs rtag" of module.
|
||||
# -u prog Run "prog" on "cvs update" of module.
|
||||
# -d dir Place module in directory "dir" instead of module name.
|
||||
# -l Top-level directory only -- do not recurse.
|
||||
#
|
||||
# NOTE: If you change any of the "Run" options above, you'll have to
|
||||
# release and re-checkout any working directories of these modules.
|
||||
#
|
||||
# And "directory" is a path to a directory relative to $CVSROOT.
|
||||
#
|
||||
# The "-a" option specifies an alias. An alias is interpreted as if
|
||||
# everything on the right of the "-a" had been typed on the command line.
|
||||
#
|
||||
# You can encode a module within a module by using the special '&'
|
||||
# character to interpose another module into the current module. This
|
||||
# can be useful for creating a module that consists of many directories
|
||||
# spread out over the entire source repository.
|
||||
|
||||
ClientSourceProduct -a \
|
||||
ClientSourceProductWin \
|
||||
ClientSourceProductMac \
|
||||
ClientSourceProductUnix \
|
||||
|
||||
ClientSourceProductWin -a MozillaCommon MozillaWinOnly
|
||||
|
||||
ClientSourceProductMac -a MozillaCommon MozillaMacOnly
|
||||
|
||||
ClientSourceProductUnix -a MozillaCommon MozillaUnixOnly
|
||||
|
||||
MozillaCommon -a \
|
||||
ns/LEGAL \
|
||||
ns/LICENSE \
|
||||
ns/CHANGES.html \
|
||||
ns/build \
|
||||
ns/include \
|
||||
ns/jpeg \
|
||||
ns/js \
|
||||
ns/lib/htmldlgs \
|
||||
ns/lib/layout \
|
||||
ns/lib/libcnv \
|
||||
ns/lib/libi18n \
|
||||
ns/lib/liblayer \
|
||||
ns/lib/libmisc \
|
||||
ns/lib/libmime \
|
||||
ns/lib/libmocha \
|
||||
ns/lib/libnet \
|
||||
ns/lib/libparse \
|
||||
ns/lib/libpics \
|
||||
ns/lib/libpwcac \
|
||||
ns/lib/libstyle \
|
||||
ns/lib/plugin \
|
||||
ns/lib/xlate \
|
||||
ns/lib/xp \
|
||||
ns/modules/edtplug/classes \
|
||||
ns/modules/edtplug/src \
|
||||
ns/modules/edtplug/include \
|
||||
ns/modules/libfont/classes \
|
||||
ns/modules/libfont/public \
|
||||
ns/modules/libfont/src \
|
||||
ns/modules/libhook \
|
||||
ns/modules/libimg \
|
||||
ns/modules/libpref \
|
||||
ns/modules/libreg \
|
||||
ns/modules/libutil \
|
||||
ns/modules/progress/src \
|
||||
ns/modules/rdf \
|
||||
ns/modules/schedulr \
|
||||
ns/modules/security/freenav \
|
||||
ns/modules/softupdt/classes \
|
||||
ns/modules/softupdt/include \
|
||||
ns/modules/softupdt/src \
|
||||
ns/modules/xml \
|
||||
ns/modules/zlib/src \
|
||||
ns/nav-java/stubs \
|
||||
ns/nsprpub \
|
||||
ns/xpcom \
|
||||
ns/l10n \
|
||||
ns/nsprpub \
|
||||
ns/dbm \
|
||||
ns/modules/schedulr \
|
||||
README
|
||||
|
||||
MozillaWinOnly -a \
|
||||
ns/client.mak \
|
||||
ns/cmd/makefile.win \
|
||||
ns/cmd/dialup \
|
||||
ns/cmd/wincom \
|
||||
ns/cmd/winfe \
|
||||
ns/config \
|
||||
ns/lib/makefile.win \
|
||||
ns/modules/coreincl \
|
||||
ns/modules/edtplug/makefile.win \
|
||||
ns/makefile.win \
|
||||
ns/modules/libfont/jmcgen \
|
||||
ns/modules/libfont/makefile.win \
|
||||
ns/modules/libfont/producers/makefile.win \
|
||||
ns/modules/libfont/producers/win \
|
||||
ns/modules/libfont/producers/win/classes \
|
||||
ns/modules/libfont/producers/win/classes/netscape \
|
||||
ns/modules/libfont/producers/win/classes/netscape/fonts \
|
||||
ns/modules/libfont/producers/win/src \
|
||||
ns/modules/makefile.win \
|
||||
ns/modules/progress/makefile.win \
|
||||
ns/modules/progress/public \
|
||||
ns/modules/security/makefile.win \
|
||||
ns/modules/softupdt/makefile.win \
|
||||
ns/modules/zlib/makefile.win \
|
||||
ns/nav-java/makefile.win \
|
||||
JavaStubWin
|
||||
|
||||
|
||||
MozillaUnixOnly -a \
|
||||
ns/cmd/Makefile \
|
||||
ns/cmd/stubfe \
|
||||
ns/cmd/xfe \
|
||||
ns/config/.cvsignore \
|
||||
ns/config/AIX.mk \
|
||||
ns/config/BSD_OS.mk \
|
||||
ns/config/bsdecho.c \
|
||||
ns/config/bsdecho.c \
|
||||
ns/config/clobber_miss.pl \
|
||||
ns/config/clobber_miss.pl \
|
||||
ns/config/common.mk \
|
||||
ns/config/common.mk \
|
||||
ns/config/config.guess \
|
||||
ns/config/config.mk \
|
||||
ns/config/coreconf.mk \
|
||||
ns/config/coreconf.mk \
|
||||
ns/config/cvsco.pl \
|
||||
ns/config/cvsco.pl \
|
||||
ns/config/fastcwd.pl \
|
||||
ns/config/fastcwd.pl \
|
||||
ns/config/FreeBSD.mk \
|
||||
ns/config/gtscc.c \
|
||||
ns/config/HP-UX.mk \
|
||||
ns/config/IRIX.mk \
|
||||
ns/config/Linux.mk \
|
||||
ns/config/makecopy.c \
|
||||
ns/config/makecopy.c \
|
||||
ns/config/Makefile \
|
||||
ns/config/Makefile \
|
||||
ns/config/mangle.c \
|
||||
ns/config/mangle.c \
|
||||
ns/config/mantomak.c \
|
||||
ns/config/mantomak.c \
|
||||
ns/config/mkdepend \
|
||||
ns/config/NCR.mk \
|
||||
ns/config/NEC.mk \
|
||||
ns/config/NEWS-OS.mk \
|
||||
ns/config/NEXTSTEP.mk \
|
||||
ns/config/nfspwd.pl \
|
||||
ns/config/nfspwd.pl \
|
||||
ns/config/nodl.pl \
|
||||
ns/config/nodl.pl \
|
||||
ns/config/nsinstall.c \
|
||||
ns/config/nsinstall.c \
|
||||
ns/config/OSF1.mk \
|
||||
ns/config/outofdate.pl \
|
||||
ns/config/outofdate.pl \
|
||||
ns/config/pathsub.c \
|
||||
ns/config/pathsub.c \
|
||||
ns/config/pathsub.h \
|
||||
ns/config/pathsub.h \
|
||||
ns/config/pkg2dpth.pl \
|
||||
ns/config/pkg2dpth.pl \
|
||||
ns/config/ports \
|
||||
ns/config/revdepth.pl \
|
||||
ns/config/revdepth.pl \
|
||||
ns/config/Rhapsody.mk \
|
||||
ns/config/rules.mk \
|
||||
ns/config/SCOOS.mk \
|
||||
ns/config/SINIX.mk \
|
||||
ns/config/sj.pl \
|
||||
ns/config/sj.pl \
|
||||
ns/config/SunOS.mk \
|
||||
ns/config/SunOS4.mk \
|
||||
ns/config/SunOS5.mk \
|
||||
ns/config/UNIXWARE.mk \
|
||||
ns/config/xmversion.sh \
|
||||
ns/lib/Makefile \
|
||||
ns/Makefile \
|
||||
ns/modules/edtplug/Makefile \
|
||||
ns/modules/libfont/jmcgen \
|
||||
ns/modules/libfont/Makefile \
|
||||
ns/modules/libfont/producers/Makefile \
|
||||
ns/modules/Makefile \
|
||||
ns/modules/progress/Makefile \
|
||||
ns/modules/progress/public \
|
||||
ns/modules/security/Makefile \
|
||||
ns/modules/softupdt/Makefile \
|
||||
ns/modules/zlib/Makefile \
|
||||
ns/nav-java/Makefile \
|
||||
ns/lib/mariner \
|
||||
JavaStubUnix
|
||||
|
||||
|
||||
MozillaMacOnly -a \
|
||||
ns/cmd/dialup \
|
||||
ns/cmd/macfe \
|
||||
ns/lib/mac/AutoAdmin \
|
||||
ns/lib/mac/Includes \
|
||||
ns/lib/mac/MacMemoryAllocator \
|
||||
ns/lib/mac/Misc \
|
||||
ns/lib/mac/MoreFiles \
|
||||
ns/lib/mac/NSRuntime \
|
||||
ns/lib/mac/NSStdLib \
|
||||
ns/lib/mac/patches \
|
||||
ns/lib/mac/PowerPlant \
|
||||
ns/lib/mac/UserInterface \
|
||||
ns/modules/coreincl \
|
||||
ns/modules/edtplug/macbuild \
|
||||
ns/modules/libfont/jmcgen/include \
|
||||
ns/modules/libfont/jmcgen/src \
|
||||
ns/modules/libfont/macbuild \
|
||||
ns/modules/progress/macbuild \
|
||||
ns/modules/progress/public \
|
||||
ns/modules/softupdt/macbuild \
|
||||
ns/modules/zlib/macbuild \
|
||||
ns/lib/mariner \
|
||||
JavaStubMac
|
||||
|
||||
JavaStubAll -a \
|
||||
JavaStubWin \
|
||||
JavaStubMac \
|
||||
JavaStubUnix
|
||||
|
||||
JavaStubCore -a \
|
||||
ns/sun-java/stubs/include \
|
||||
ns/sun-java/stubs/src
|
||||
|
||||
JavaStubMac -a \
|
||||
JavaStubCore \
|
||||
ns/sun-java/stubs/macbuild \
|
||||
ns/sun-java/stubs/macjri
|
||||
|
||||
JavaStubUnix -a \
|
||||
JavaStubCore \
|
||||
ns/sun-java/Makefile \
|
||||
ns/sun-java/stubs/jri \
|
||||
ns/sun-java/stubs/Makefile
|
||||
|
||||
JavaStubWin -a \
|
||||
JavaStubCore \
|
||||
ns/sun-java/makefile.win \
|
||||
ns/sun-java/stubs/jri \
|
||||
ns/sun-java/stubs/makefile.win
|
||||
|
||||
######################################################################
|
||||
|
||||
#
|
||||
# Modules for the raptor layout effort. Note that raptor dist is temporary
|
||||
# until raptor is integrated into the mainline build.
|
||||
#
|
||||
|
||||
RaptorDist -a \
|
||||
ns/nsprpub \
|
||||
ns/include \
|
||||
ns/jpeg \
|
||||
ns/modules/libreg \
|
||||
ns/xpcom \
|
||||
ns/modules/zlib \
|
||||
ns/modules/libutil \
|
||||
ns/sun-java \
|
||||
ns/nav-java \
|
||||
ns/js \
|
||||
ns/modules/security/freenav \
|
||||
ns/modules/libpref \
|
||||
ns/modules/libimg \
|
||||
ns/lib/xp \
|
||||
ns/lib/libnet \
|
||||
ns/base
|
||||
|
||||
Raptor -a \
|
||||
ns/htmlparser \
|
||||
ns/dom \
|
||||
ns/gfx \
|
||||
ns/view \
|
||||
ns/widget \
|
||||
ns/layout \
|
||||
ns/webshell
|
||||
|
||||
RaptorAll -a \
|
||||
RaptorDist \
|
||||
Raptor
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
@ -1,875 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=x-mac-roman">
|
||||
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 (Macintosh; I; PPC) [Netscape]">
|
||||
<TITLE>MacFE Build Instructions</TITLE>
|
||||
<!--This file created 3/17/98 9:38 PM by Claris Home Page version 3.0 30 Day Trial-->
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF">
|
||||
|
||||
<H1>
|
||||
MacFE Build Instructions</H1>
|
||||
This is a general document on how to build, what works, what doesn't, and
|
||||
things to watch out for when working on the Mac client. <B>Please read
|
||||
the entire document before you start tinkering</B>...heck, you may just
|
||||
learn something!
|
||||
|
||||
<P>Abbreviations you will probably see in this document:
|
||||
<UL>
|
||||
<LI>
|
||||
<B>MacFE</B> - the Macintosh front end, including all the things you see
|
||||
and some you don't.</LI>
|
||||
|
||||
<LI>
|
||||
<B>XP</B> - cross platform back end code, mostly written in C. You will
|
||||
see this used like, "This is an XP problem" which means it's broken everywhere.</LI>
|
||||
|
||||
<LI>
|
||||
<B>MW</B> - Metrowerks Corporation. They make our build tools (CodeWarrior)
|
||||
and PowerPlant</LI>
|
||||
|
||||
<LI>
|
||||
<B>PP</B> - PowerPlant, the GUI framework on which our app is built</LI>
|
||||
|
||||
<LI>
|
||||
<B>CWProX</B> - CodeWarrior Pro version X. You'll probably see CWPro1,
|
||||
CWPro2, and CWPro3. We may also just refer to this as <B>CW</B>.</LI>
|
||||
|
||||
<LI>
|
||||
<B>IDE</B> - Integrated Development Environment. CodeWarrior is an IDE.</LI>
|
||||
|
||||
<BR><!--<LI>
|
||||
<B>NC</B> - the working name for our Aurora technology, the Navigation
|
||||
Center.</LI>
|
||||
|
||||
<LI>
|
||||
<B>HT</B> - HyperTree, a layer of XP APIs over RDF on which the NavCenter
|
||||
is built.</LI>--></UL>
|
||||
|
||||
<H3>
|
||||
<A HREF="#Building">Building</A></H3>
|
||||
<!--<H3>
|
||||
<A HREF="#NewFeatures">New 5.0 Features</A></H3>
|
||||
|
||||
<H3>
|
||||
<A HREF="#Unfinished">Unfinished Features</A></H3>-->
|
||||
<H3>
|
||||
<A HREF="#Pitfalls">Pitfalls</A></H3>
|
||||
|
||||
<H3>
|
||||
<A HREF="#HistFuture">History and Future</A></H3>
|
||||
|
||||
<H2>
|
||||
|
||||
<HR><A NAME="Building"></A>Building</H2>
|
||||
|
||||
<H4>
|
||||
What are the minimum machine requirements?</H4>
|
||||
To build Navigator, you need a fast PPC Mac. The faster the better. You
|
||||
can't build with a 68K machine because we have too many resources, and
|
||||
the build process will crash when trying to generate resources out of our
|
||||
cross-platform strings. See the discussion below for a way around this.
|
||||
|
||||
<P>You will need about 96 MB of physical RAM to "fast link" the app. You
|
||||
can still fast link if you give your machine 96 MB of virtual memory, but
|
||||
then the VM hit is large enough to counteract any improvement. One of our
|
||||
beta testers had a machine with only 64MB of physical RAM (VM was off)
|
||||
and it ran out of memory trying to link. Turning VM on got it to link,
|
||||
but build time increased greatly.
|
||||
|
||||
<P>The moral of the story: get lots of physical RAM and don't use VM.
|
||||
<H4>
|
||||
How big of a partition do I need for the source?</H4>
|
||||
You should be ok with a 400MB disk partition, even when fully built. This
|
||||
does not include tools like the IDE, just source.
|
||||
<H4>
|
||||
Why do I need CWPro2 or better?</H4>
|
||||
We use CodeWarrior as our development environment at Netscape for the MacFE.
|
||||
All of the projects and tools are geared towards the CodeWarrior IDE. In
|
||||
addition, we make heavy use of PowerPlant and MSL which you can only get
|
||||
from Metrowerks.
|
||||
|
||||
<P>While we say you need at least CWPro2, you may be able to get by with
|
||||
Pro1, but probably not for very long. We haven't tested it, so we don't
|
||||
recommend it. Get the upgrade. CodeWarrior kicks serious butt!
|
||||
<H4>
|
||||
How do I setup my development environment?</H4>
|
||||
Here's a list of 3rd party <B>software</B> that we compile into the application
|
||||
and where to get it:
|
||||
<UL>
|
||||
<LI>
|
||||
PowerPlant 1.8 - obtainable from the CodeWarrior CD.</LI>
|
||||
|
||||
<LI>
|
||||
MSL - the Metrowerks Standard Library, obtainable from the CodeWarrior
|
||||
CD</LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="ftp://ftp.boingo.com//dan/WASTE/waste-13.hqx">WASTE 1.3</A></LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="http://www.bact.wisc.edu/CWASTEEdit/CWASTEEdit.sit.hqx">CWASTE
|
||||
1.6.2</A></LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="ftp://ftp.scripting.com/userland/menuSharingToolkit4.1.sit.hqx">Menu
|
||||
Sharing Toolkit</A> (from UserLand)</LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="ftp://ftp.digitalalchemy.com/pub/digitalalchemy/mercutio-SDK.sit.bin">Mercutio
|
||||
1.5 SDK</A> (only download the SDK, not the entire package, else the access
|
||||
paths will be wrong)</LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="ftp://ftp.share.com/pub/internet-configuration/ICProgKit1.4.sit">Internet
|
||||
Config 1.4 SDK</A></LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="http://www.mooseyard.com/Jens/Software/">AEGizmos 1.4.2</A></LI>
|
||||
</UL>
|
||||
Here's a list of other build <B>tools</B> that you need to install in order
|
||||
to build and where to get them:
|
||||
<UL>
|
||||
<LI>
|
||||
<A HREF="ftp://sunsite.cnlab-switch.ch/software/platform/macos/perl/Mac_Perl_519r4_tool.bin">MacPerl
|
||||
5 MPW Tool</A></LI>
|
||||
|
||||
<LI>
|
||||
MakeStub - MPW (installed with CodeWarrior Heaven option). If you choose
|
||||
not to install MPW, it is located on the MacOS Tools CD in "CW Pro 2 Tools:CodeWarrior
|
||||
MPW:MPW:Tools"</LI>
|
||||
|
||||
<LI>
|
||||
RunTSScript - in Mozilla source distribution (ns:build:mac:RunTSScript),
|
||||
needs to be installed by hand</LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="ftp://dev.apple.com/devworld/Tool_Chest/Core_Mac_OS_Tools/MPW_etc./MPW-GM/MPW/ToolServer.sit.hqx">ToolServer</A>
|
||||
- or in the CW distribution (CW Pro 2 Tools:Apple Development Tools:ToolServer
|
||||
3.4.1.sit). <B>We recommend pulling it off the CD</B> because it comes
|
||||
with configuration files for CodeWarrior which you would have to create
|
||||
manually were you to pull it off the net.</LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="ftp://dev.apple.com/devworld/Periodicals/develop/develop25/develop_Issue_25_code/ToolFrontEnd.sit.hqx">ToolFrontEnd</A></LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="http://sunsite.cnlab-switch.ch/ftp/software/platform/macos/src/HTML/MPW_C.html">patch
|
||||
2.1</A></LI>
|
||||
</UL>
|
||||
Once you have all the pieces, here are the steps required to put everything
|
||||
together:
|
||||
<OL>
|
||||
<LI>
|
||||
Install CodeWarrior from the CD. While it is large, installing the "CodeWarrior
|
||||
Heaven" option will guarantee that you have everything you need. This will
|
||||
give you PowerPlant, MSL, and MPW. If you choose to install less, proceed
|
||||
at your own risk.</LI>
|
||||
|
||||
<LI>
|
||||
In the Finder, increase the memory partition of the IDE to 15MB (you can
|
||||
get by with 12, if need be).</LI>
|
||||
|
||||
<LI>
|
||||
Download ToolFrontEnd. After expanding it, in "ToolFrontEnd Folder:Drop-Ins"
|
||||
there are three items:</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
<I>#include</I></LI>
|
||||
|
||||
<LI>
|
||||
<I>ToolFrontEnd</I></LI>
|
||||
|
||||
<LI>
|
||||
<I>ToolFrontEnd Panel</I></LI>
|
||||
</UL>
|
||||
Create a folder named "Include Scanners". Place the file "#include" into
|
||||
the Include Scanners folder. Move the Include Scanners folder to the CodeWarrior
|
||||
Plugins folder. Create a folder named "ToolFrontEnd". Place the files "ToolFrontEnd"
|
||||
and "ToolFrontEnd Panel" into the ToolFrontEnd folder. Place this folder
|
||||
in the CodeWarrior Plugins folder.
|
||||
|
||||
<P>Open "ToolFrontEnd Panel" with ResEdit. Change the file type from 'Panl'
|
||||
to 'PanL'. Save.
|
||||
<LI>
|
||||
Uncompress the StuffIt Archive for ToolServer. Place the ToolServer folder
|
||||
in the same folder as your CodeWarrior environment (its actual placement
|
||||
is not important). Create an alias from the Tools folder that lives in
|
||||
the CodeWarrior MPW distribution and place it in the ToolServer folder.
|
||||
Now ToolServer and MPW will share the same tool set and you only have to
|
||||
maintain one tool repository.</LI>
|
||||
|
||||
<LI>
|
||||
After installing the MacPerl distribution (run the InstallerVISE application),
|
||||
in the "MacPerl €" folder, there will be an MPW tool named "perl". Install
|
||||
this in the same location as the rest of the MPW tools for ToolServer.</LI>
|
||||
|
||||
<LI>
|
||||
Install the "patch" and "MakeStub" MPW Tools in the same location. Note
|
||||
that "MakeStub" is automatically installed by the "CodeWarrior Heaven"
|
||||
install option.</LI>
|
||||
|
||||
<LI>
|
||||
Install RunTSScript (found in the Mozilla source distribution) in the compilers
|
||||
folder in your build environment</LI>
|
||||
|
||||
<LI>
|
||||
Next, after downloading all the 3rd party software components, drag WASTE,
|
||||
CWASTE, Menu Sharing, Mercutio, Internet Config, and the AEGizmo folders
|
||||
(just as they are) into the "MacOS Support" folder in your build environment.</LI>
|
||||
|
||||
<LI>
|
||||
Start ToolServer from within CodeWarrior (or use MPW if you are brave enough).
|
||||
We're about to patch some files. Make sure the ToolServer menu is in the
|
||||
CodeWarrior menu bar by turning on the <A HREF="../../../IDEPrefs.gif">preference</A>
|
||||
under the "Extras" panel in the IDE Preferences (not the project preferences!).
|
||||
The menu bar should look like this:</LI>
|
||||
|
||||
|
||||
<P><IMG SRC="IDEMenuBar.gif" X-CLARIS-USEIMAGEWIDTH X-CLARIS-USEIMAGEHEIGHT HEIGHT=20 WIDTH=359 ALIGN=BOTTOM>
|
||||
|
||||
<P>Choose "Start ToolServer" from the ToolServer menu (this is the icon
|
||||
menu between "Window" and "Help" in the menubar above). You will now see
|
||||
a window with no close box. This is your ToolServer Worksheet where you
|
||||
will type (or cut & paste) the commands for the following steps.
|
||||
|
||||
<P>In case you have never used MPW/ToolServer before, the following is
|
||||
<B>very important</B>. Pressing "return" does not execute commands like
|
||||
you might think. It just inserts a newline into the worksheet like a normal
|
||||
text editor. <B>To actually get ToolServer to execute the command, you
|
||||
must press "Enter" (lower right of numeric keypad).</B> This executes the
|
||||
line that the cursor is on, and only that line. If you want to execute
|
||||
multiple lines at once, select them all and hit Enter.
|
||||
<LI>
|
||||
Set the shell variables {IDE} and {Source} to the correct paths for your
|
||||
build environment. {IDE} is where your CodeWarrior IDE is located. {Source}
|
||||
is the folder containing the toplevel "ns" folder of the Mozilla source.
|
||||
Mine look like this (don't forget to keep the quotes if your path includes
|
||||
spaces), yours will almost certainly be different:</LI>
|
||||
|
||||
<PRE>Set IDE "Develop:Source331 Build Environment:CW Pro 2:Metrowerks CodeWarrior:"
|
||||
Set Source "Source:FreeSource:"</PRE>
|
||||
|
||||
<LI>
|
||||
If you are using CWPro2, execute the following lines to patch LDropFlag
|
||||
to draw correcly over non-white backgrounds. <B>You do not have to do this
|
||||
if you are using Pro3</B> because it has been fixed.</LI>
|
||||
|
||||
<PRE>directory "{IDE}MacOS Support:PowerPlant:_In Progress:_Table Classes:"
|
||||
patch LDropFlag.cp "{Source}ns:lib:mac:patches:LDropFlag.patch"
|
||||
duplicate -y "{Source}ns:lib:mac:patches:DropFlag Icons.rsrc" "{IDE}MacOS Support:PowerPlant:PowerPlant Resources:"</PRE>
|
||||
|
||||
<LI>
|
||||
Execute the following lines to patch menusharing.c to allow it to compile
|
||||
with the new Universal Headers. It references an obsolete header file (GestaltEqu.h).</LI>
|
||||
|
||||
<PRE>directory "{IDE}MacOS Support:Menu Sharing Toolkit 4.1:"
|
||||
patch menusharing.c "{Source}ns:lib:mac:patches:menusharing.patch"</PRE>
|
||||
|
||||
<LI>
|
||||
If you are using CWPro2 straight off the CD, you need to patch AppleEvents.r
|
||||
to fix a problem with the Universal Headers (the definition of the 'aedt'
|
||||
resource was omitted). <B>You do not have to do this if you have applied
|
||||
the netborne patch to Pro2 or are using Pro3</B> because it has been fixed.</LI>
|
||||
|
||||
<PRE>directory "{IDE}MacOS Support:Headers:Rez Headers:"
|
||||
patch AppleEvents.r "{Source}ns:lib:mac:patches:AppleEvents.r.patch"</PRE>
|
||||
|
||||
<LI>
|
||||
You need to patch stat.mac.h to fix a problem in MSL where lines were omitted
|
||||
(both CWPro2 and Pro3 share this problem)</LI>
|
||||
|
||||
<PRE>directory "{IDE}Metrowerks Standard Library:MSL C:MSL Mac:Public Includes"
|
||||
patch stat.mac.h "{Source}ns:lib:mac:patches:stat.mac.h.patch"</PRE>
|
||||
|
||||
<LI>
|
||||
If you are using CWPro3, you have to unstuff and copy the old Grayscale
|
||||
Appearance classes into the PowerPlant hierarchy. As of Pro3, they are
|
||||
now obsolete and are located with the rest of the obsolete PowerPlant files.
|
||||
We'll fix this shortly.</LI>
|
||||
</OL>
|
||||
|
||||
<H4>
|
||||
Ok, so how do I build?</H4>
|
||||
There is an AppleScript called <B>BuildList</B> located in ns:cmd:macfe:projects.
|
||||
This droplet takes, as input, a text file which lists the projects in the
|
||||
order which they are to be built. This allows us to build different versions
|
||||
of the product just by dropping a different "script" on BuildList (such
|
||||
as Debug, Optimized, Navigator stand-alone, or navigator + composer).
|
||||
|
||||
<P>These scripts are located in ns:cmd:macfe:projects:client and have names
|
||||
like <B>BuildMozPPCDebugList.txt</B>. This script will build a debug version
|
||||
of Mozilla (navigator + composer) for PPC. Get it? Good. All you have to
|
||||
do is drag this script to the BuildList droplet and watch it crunch away.
|
||||
Now go out to dinner. By the time you get back, you should have an executable
|
||||
in ns:cmd:macfe:projects:client called, for this particular script, <B>MozillaPPCDebug</B>.
|
||||
You will see the following build lists in the client folder, but as of
|
||||
3/31, only BuildMozPPCList.txt and BuildMozPPCDebugList.txt are guaranteed
|
||||
to work:
|
||||
<UL>
|
||||
<LI>
|
||||
BuildMozPPCList.txt</LI>
|
||||
|
||||
<LI>
|
||||
BuildMozPPCDebugList.txt</LI>
|
||||
|
||||
<LI>
|
||||
BuildNavPPCDebugList.txt [ might work ]</LI>
|
||||
|
||||
<LI>
|
||||
BuildNavPPCList.txt [ might work ]</LI>
|
||||
</UL>
|
||||
If there were any errors in any of the projects along the way, the script
|
||||
will stop at that point and the IDE will tell you the errors. You can fix
|
||||
them and make sure they current project builds, but to continue the automation,
|
||||
you have to start from the beginning by dropping the script onto BuildList.
|
||||
This isn't quite as bad as it sounds because the previous projects are
|
||||
already built (unless you changed some major header file).
|
||||
|
||||
<P>Don't worry too much about the numerous warnings generated during the
|
||||
build. We try our best to get the XP teams to use real compilers, but alas,
|
||||
they continue to write warning-laden code. There is also some generated
|
||||
code (Java is one example) that has a lot of warnings that we can't help
|
||||
either. If you write any new code, please help us in our quest to get zero
|
||||
warnings.
|
||||
<H4>
|
||||
How long does it take to build?</H4>
|
||||
On a G3 with the source and IDE on a RAM disk, it takes about 25 minutes.
|
||||
On a PowerTowerPro 225 and everything on the hard drive, it takes about
|
||||
45mins to an hour. On a 9500/132 it takes over 2 1/2 hours.
|
||||
|
||||
<P>The moral of the story: Don't try this on your 6100/66.
|
||||
<H4>
|
||||
What's special about running the debug build?</H4>
|
||||
Running the optimized (non-debug) version is easy, just double-click it
|
||||
and it will work. This is because all the shared libraries are compiled
|
||||
directly into the application. We don't do this with the debug version
|
||||
to facilitate changing bits in projects other than the main one. This way,
|
||||
you don't have to relink the entire app (which can take a while) to see
|
||||
the changes, just the project that was modified.
|
||||
|
||||
<P>As a result, you have to find a way to get all the shared libraries
|
||||
from where they are built (scattered throughout the tree) into the same
|
||||
folder as the app so CFM can find them. Luckily, the BuildList script will
|
||||
create all these aliases for you and put them in the right places!
|
||||
|
||||
<P>Another nicety about the debug build is that there is a special "trace"
|
||||
function which can be used to display messages about the state of the application
|
||||
as it runs through certain blocks of code. To see these messages (since
|
||||
the Mac doesn't have stdout or stderr) you need to run an application called
|
||||
TraceMonitor. << where do we distribute this???!?>>
|
||||
<H4>
|
||||
How do I build a 68K version?</H4>
|
||||
For now, you can't. The projects have not been kept up to date and aren't
|
||||
even in the tree anymore. If you would like to create them and get all
|
||||
the exports right with CFM-68K, go right ahead. We will be so happy!
|
||||
<H4>
|
||||
Why use IDE_Options.h when all that is in the project file?</H4>
|
||||
It was originally intended to make sure that all 300 of us at Netscape
|
||||
are using the same environment and compilation flags. If something gets
|
||||
turned on/off by accident in the project prefs, it can introduce a subtle
|
||||
bug that can take days to track down for naught. Having a file that specifies
|
||||
exactly what flags should be used guarantees that this can't happen.
|
||||
|
||||
<P>Now that we move to net development, I'm sure you will agree that this
|
||||
is even more important.
|
||||
<H2>
|
||||
|
||||
<HR><A NAME="NewFeatures"></A>New 5.0 Features</H2>
|
||||
We can't present this section until after 3/31/98. Please check back here
|
||||
after that. <!--
|
||||
<H3>
|
||||
Navigator Center (Aurora)</H3>
|
||||
The Navigation Center (referred to as "Aurora" in press releases) is an
|
||||
attempt to make it easier to access and organize information on the web.
|
||||
The NC unifies Bookmarks, History, Search, and local files into a sequence
|
||||
of workspaces which are accessible from a single location in the browser
|
||||
window. One of the ways the NavCenter diverges from a similar concept seen
|
||||
from our competition is the ability for users to create their own workspaces
|
||||
to organize and store information from both the web and their desktop.
|
||||
<UL>
|
||||
<LI>
|
||||
Main access point is a bar along the left side of the browser.</LI>
|
||||
|
||||
<LI>
|
||||
Each icon represents a workspace. <B>Click any workspace icon once to slide
|
||||
out a hierarchical tree</B> (like the list view in the Finder) that displays
|
||||
the information appropriate to that workspace. You can manipulate the URLs
|
||||
and folders in the tree while you are surfing the web in the adjacent pane.</LI>
|
||||
|
||||
<LI>
|
||||
Clicking on another workspace while the shelf is open switches to showing
|
||||
the contents of that workspace.</LI>
|
||||
|
||||
<LI>
|
||||
<B>To hide the shelf, click the close box above the column headers</B></LI>
|
||||
|
||||
<LI>
|
||||
To create new bookmarks, <B>drag bookmarks from the location bar of the
|
||||
browser into the NC</B> and file them where you want. Of course, the old
|
||||
methods still work.</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
If the NC shelf is not open, drag to the workspace where you want to file
|
||||
the bookmark and after a small delay, the <B>shelf will spring open</B>.
|
||||
You can now drop your new bookmark exactly where you want.</LI>
|
||||
|
||||
<LI>
|
||||
If the workspace you want is not displayed, drag over that workspace and
|
||||
after a small delay, the contents of that workspace will become visible.</LI>
|
||||
</UL>
|
||||
|
||||
<LI>
|
||||
You can also <B>open a stand-alone NC window</B> from the Communicator
|
||||
menu. The standard "cmd-b" and "cmd-h" for bookmarks and history are wired
|
||||
to open a new NC window with the appropriate workspace visible.</LI>
|
||||
|
||||
<LI>
|
||||
You can <B>hide the list of workspaces</B> at the left of the browser window
|
||||
by choosing "View:Hide NavCenter Selector". You can show it again by doing
|
||||
the same thing. Even when hidden in the browser, the stand-alone versions
|
||||
are always available.</LI>
|
||||
|
||||
<LI>
|
||||
Drag bookmarks to the trash to delete them. You can also hit the "delete"
|
||||
key (backspace) to remove bookmarks.</LI>
|
||||
|
||||
<LI>
|
||||
The NavCenter is fully <B>context-menu savvy</B>. There are many commands
|
||||
that are in context menus that are not in the main menubar (right now).</LI>
|
||||
|
||||
<LI>
|
||||
<B>ToolTip savvy</B>. Both the title and URL can be seen in their entirety
|
||||
by hovering over the appropriate column.</LI>
|
||||
|
||||
<LI>
|
||||
3-state <B>sorting: alphabetical, reverse-alphabetical, none</B>. Like
|
||||
in the Finder, setting a sort does not change the hierarchy or make any
|
||||
permanent modifications to your organizational structure.</LI>
|
||||
</UL>
|
||||
|
||||
<H3>
|
||||
Personal Toolbar</H3>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
A toolbar to store bookmarks, first seen on Win/UNIX in 4.0. Single click
|
||||
to load URL in current browser window</LI>
|
||||
|
||||
<LI>
|
||||
<B>Drag and drop bookmarks to the toolbar to add them.</B> Drag existing
|
||||
bookmarks on the toolbar to rearrange the order. Drag bookmarks to the
|
||||
trash can to remove them from the toolbar.</LI>
|
||||
|
||||
<LI>
|
||||
<B>Dynamically allocates horizontal space</B> to buttons on toolbar. Adding
|
||||
new buttons shrinks existing ones, removing buttons distributes the vacated
|
||||
space to existing buttons. Changing the window width reallocates space
|
||||
accordingly.</LI>
|
||||
|
||||
<LI>
|
||||
You can further manipulate, rename, rearrange, add to and remove the URLs
|
||||
in the folder that represents the personal toolbar in the Navigation Center.</LI>
|
||||
|
||||
<LI>
|
||||
ToolTips show the full title.</LI>
|
||||
</UL>
|
||||
|
||||
<H3>
|
||||
Navigator</H3>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
new "Mariner" technology makes table layout much faster and does not reload
|
||||
the page when the window is resized.</LI>
|
||||
|
||||
<LI>
|
||||
buttons/popup menus in the chrome now look more like MacOS controls.</LI>
|
||||
</UL>
|
||||
|
||||
<H3>
|
||||
Composer Features</H3>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
Drag and Drop</LI>
|
||||
|
||||
<LI>
|
||||
Direct manipulation editing of tables</LI>
|
||||
</UL>
|
||||
-->
|
||||
<H2>
|
||||
|
||||
<HR><A NAME="Unfinished"></A>Unfinished "Features"</H2>
|
||||
We can't present this section until after 3/31/98. Please check back here
|
||||
after that. <!--
|
||||
This source release is not of beta quality, hence it will have lots of
|
||||
bugs that a normal beta (or even an alpha) would not have. There are many
|
||||
features which we are not even close to being finished with, let alone
|
||||
knowing what the final UI will be. Here are some things that we know about
|
||||
but didn't have time to get to before the code left the building. Feel
|
||||
inclined to help us out? Grrrrrrreat!
|
||||
<H3>
|
||||
Aurora</H3>
|
||||
Aurora is definitely a work in progress. Here are the bugs that we just
|
||||
don't have time to fix
|
||||
<UL>
|
||||
<LI>
|
||||
Real icons for files on disk</LI>
|
||||
|
||||
<LI>
|
||||
changing view from XP code (e.g., JavaScript) has not been tested, but
|
||||
should work</LI>
|
||||
|
||||
<LI>
|
||||
move vs. copy notification (cursor doesn't change, etc. No XP support for
|
||||
this yet)</LI>
|
||||
|
||||
<LI>
|
||||
double-click on the text of an item should launch the url, not trigger
|
||||
an in-place edit</LI>
|
||||
|
||||
<LI>
|
||||
separator needs UI consensus and its own icon</LI>
|
||||
|
||||
<LI>
|
||||
drag & drop</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
can't disallow drags to trash when pane is read only. Trash will still
|
||||
highlight even though nothing will happen.</LI>
|
||||
|
||||
<LI>
|
||||
occasional -49 error when dragging repeatedly to browser window. I think
|
||||
the DragManager is corrupt because -49 is not a drag manager error and
|
||||
d&d doesn't work anywhere else after that.</LI>
|
||||
|
||||
<LI>
|
||||
drag feedback doesn't work correctly when view is sorted or when some items
|
||||
are local vs. remote.</LI>
|
||||
|
||||
<LI>
|
||||
Composer needs to correctly handle HT_Node flavor</LI>
|
||||
|
||||
<LI>
|
||||
Sometimes things will move, other times they will copy. Its an XP thing.</LI>
|
||||
</UL>
|
||||
|
||||
<LI>
|
||||
Chrome properties not correctly respected (relies on personal toolbar being
|
||||
hidden to hide NavCenter)</LI>
|
||||
|
||||
<LI>
|
||||
sort state of columns not saved (nor is anything else with columns)</LI>
|
||||
|
||||
<LI>
|
||||
we shouldn't be using HT_SetNodeName(). Use HT_SetNodeData() instead</LI>
|
||||
|
||||
<LI>
|
||||
Open/Close context menu does not redraw disclosure triangle after executing</LI>
|
||||
|
||||
<LI>
|
||||
There are currently no user configurable prefs for Aurora. This will change.</LI>
|
||||
|
||||
<LI>
|
||||
You can't edit the URL field because RDF uses this as the key in its database.
|
||||
As a result, having two bookmarks in the same workspace can lead to odd
|
||||
behavior</LI>
|
||||
|
||||
<LI>
|
||||
Undo/redo does not work yet (XP problem)</LI>
|
||||
|
||||
<LI>
|
||||
Cut deletes nodes, it does not put them on a clipboard. Copy/paste do nothing.
|
||||
This is an XP problem.</LI>
|
||||
</UL>
|
||||
Still major work to do:
|
||||
<UL>
|
||||
<LI>
|
||||
create new workspaces with d&d</LI>
|
||||
|
||||
<LI>
|
||||
rollover feedback on selector</LI>
|
||||
|
||||
<LI>
|
||||
sitemap notification</LI>
|
||||
|
||||
<LI>
|
||||
scroll selector bar</LI>
|
||||
|
||||
<LI>
|
||||
HTML pane/search pane</LI>
|
||||
|
||||
<LI>
|
||||
spring-loaded folders on d&d</LI>
|
||||
</UL>
|
||||
|
||||
<H3>
|
||||
General FE Problems</H3>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
<B>DNS lookups may hang up the machine for up to a minute. Don't worry,
|
||||
your mac did not freeze!</B></LI>
|
||||
|
||||
<LI>
|
||||
FTP doesn't work quite right. URLs typed into the location bar will not
|
||||
load and the MIME mappings (save to disk, etc) are broken so everything
|
||||
is loaded into the browser window instead of saving to disk.</LI>
|
||||
|
||||
<LI>
|
||||
frame around current tab group broken</LI>
|
||||
|
||||
<LI>
|
||||
tabbing around to text entry areas and back to the Location field is broken</LI>
|
||||
|
||||
<LI>
|
||||
can't drag from Navigator when app is in background</LI>
|
||||
|
||||
<LI>
|
||||
Folders on personal toolbar. Sigh, unless we can rewrite the bookmarks
|
||||
menu code, we just don't have enough hierarchical menu id's to put menus
|
||||
on personal toolbar folders. They still act as drop sites, so you can drop
|
||||
urls into them but clicking on them will just beep.</LI>
|
||||
|
||||
<LI>
|
||||
Printing is....sub-optimal.</LI>
|
||||
|
||||
<LI>
|
||||
"Mariner" layout improvements are nice, but on very complicated pages the
|
||||
machine will hang for a few seconds while it is relaying out the page.
|
||||
This can last 4-6 seconds sometimes. This really looks bad when the NavCenter
|
||||
shelf is sliding out during a drag and drop. If you are patient enough,
|
||||
you will be rewarded, but it is slow.</LI>
|
||||
</UL>
|
||||
-->
|
||||
<H2>
|
||||
|
||||
<HR><A NAME="Pitfalls"></A>Pitfalls</H2>
|
||||
There are a couple of pitfalls that we have to keep straight when it comes
|
||||
to editing resources.
|
||||
<H4>
|
||||
Why do I keep getting messages about unknown custom types in Constructor?</H4>
|
||||
For starters, make sure you have an alias to the following two files in
|
||||
your Constructor folder:
|
||||
<UL>
|
||||
<LI>
|
||||
ns:cmd:macfe:rsrc:CrossProduct:Mozilla_Custom_CPPbs</LI>
|
||||
|
||||
<LI>
|
||||
ns:cmd:macfe:rsrc:Communicator:MailNewsCppbs.cnst</LI>
|
||||
</UL>
|
||||
You may have to explicitly open these files up while running Constructor
|
||||
to be able to see the new types, especially for the ones in MailNewsCppbs.cnst.
|
||||
Not sure why yet.
|
||||
|
||||
<P>For editing other kinds of resources, we have a TMPL file for ResEdit/Resourcerer.
|
||||
Place these in the appropriate location for your resource editor
|
||||
<UL>
|
||||
<LI>
|
||||
ns:cmd:macfe:rsrc:CrossProduct:Mozilla_Custom_TMPLs</LI>
|
||||
|
||||
<LI>
|
||||
ns:cmd:macfe:rsrc:CrossProduct:Other_Comm_TMPLS.rsrc</LI>
|
||||
</UL>
|
||||
|
||||
<H4>
|
||||
Why don't my toolbar buttons work anymore in the browser window?</H4>
|
||||
Because of the way we have the toolbars as CIncludeViews (which work in
|
||||
a similar way to #include in C/C++), the RidL will be messed up if you
|
||||
edit the main browser window PPob. Constructor regenerates this list based
|
||||
on all the controls that are in the view when you save, but because we
|
||||
use CIncludeView, the toolbar buttons aren't actually in the view so the
|
||||
RidL is empty. They will still show up when you build, but they won't do
|
||||
anything because they are not registered with the browser window. Until
|
||||
we fix this, just use Resourcer to replace the incorrectly generated one
|
||||
with an old version. The old version is about 58 bytes long and the new
|
||||
one is about 10 so you should be able to easily tell which is which.
|
||||
<H4>
|
||||
Why are there so many damn resources?</H4>
|
||||
As you may have noticed, we've got too many damn resources. Most of them
|
||||
are 'STR ' resources which are generated at build time and contain all
|
||||
of our cross-platfrom strings. We would like to generate these resources
|
||||
more intelligently (into 1/10 the number of 'STR#' resources maybe) but
|
||||
ran out of time before the source had to go out. Before you rush out and
|
||||
change it for us, <B>stop</B>! There are some constraints on the final
|
||||
solution, mostly to do with i18n and l10n being able to leverage existing
|
||||
work on older product to do new products. If you want to help us out with
|
||||
this, please send us some email and we can have out i18n team talk with
|
||||
you to make sure it gets done correctly!
|
||||
<H4>
|
||||
Why doesn't it work better with Internet Config?</H4>
|
||||
For starters, the main reason why we never drank the IC kool-aid was that
|
||||
there was no support for multiple profiles. Being one of the main features
|
||||
which our competition did not have, we thought this was pretty important.
|
||||
There are rumblings in the IC world that IC 2.0 will support multiple profiles.
|
||||
Great! That still leaves us with the second reason: there are many, many,
|
||||
many preferences that we use that are not reflected in IC. As a result,
|
||||
we already have to maintain prefs for those that are not covered by IC
|
||||
so we can't be totally IC dependent.
|
||||
|
||||
<P>Of course, now that the source is free, maybe we can drive the direction
|
||||
of IC to include all of our wacky networking prefs.
|
||||
<H4>
|
||||
Where are all my old 4.0X bookmarks and prefs?</H4>
|
||||
In the process of getting the source ready for distribution, we removed
|
||||
all mentions of "Netscape" from the product. As you may know, the 4.0X
|
||||
preferences are stored in a folder called "Netscape Users." Well, that
|
||||
folder is now called "Navigator Users" and the preference file is now called
|
||||
"Navigator Preferences" instead of "Netscape Preferences."
|
||||
|
||||
<P>It's probably best not to use any of your old prefs at this point since
|
||||
some of them rely on security calls that are no longer in the free source
|
||||
product. After you create a new profile (and you will have to when you
|
||||
start the free source), copy your bookmarks.html file from your old profile
|
||||
into the new user profile folder and replace the empty one that's already
|
||||
there (if there is one).
|
||||
|
||||
<P><B>For your old bookmarks to be seen, you must throw away the "NavCntr"
|
||||
folder</B> created in your new profile folder. After you do that bookmarks
|
||||
will be imported into Aurora automagically. Note that changes that you
|
||||
make to your bookmarks in 5.0 will not (as of today) be written back to
|
||||
the Bookmarks.html file, but instead are stored in a database within the
|
||||
"NavCntr" folder. If anything gets corrupted in the NavCenter, you can
|
||||
always throw this folder into the trash and your original bookmarks will
|
||||
be reimported.
|
||||
|
||||
<P>Also note that these new bookmarks and preferences are totally separate
|
||||
from your 4.0X prefs.
|
||||
<H2>
|
||||
|
||||
<HR><A NAME="HistFuture"></A>History and Future</H2>
|
||||
|
||||
<H3>
|
||||
History</H3>
|
||||
Excuse me while I ramble...
|
||||
<UL>
|
||||
<LI>
|
||||
Built using Metrowerks PowerPlant, the client has been PPC native from
|
||||
day one. 68K support was dropped in 5.0 due to the high cost of maintenance.
|
||||
Any takers?</LI>
|
||||
|
||||
<LI>
|
||||
Mail/News was added in 2.0 and Composer was added in 3.0 (called Navigator
|
||||
Gold). Both were dramatically improved with 4.0.</LI>
|
||||
|
||||
<LI>
|
||||
Java came to the Mac in 3.0, even though Windoze and unix had it in 2.0.</LI>
|
||||
|
||||
<LI>
|
||||
Multi-byte language support for inline edit fields added in 4.0</LI>
|
||||
|
||||
<LI>
|
||||
The preferences used to be STR# resources. Now they are done in javascript.</LI>
|
||||
|
||||
<LI>
|
||||
Because of the sheer number of resources (and the "theoretical limit" on
|
||||
the number of resources in a file imposed by the Resource manager -- which
|
||||
we still exceed on a daily basis), a number of strings and icons were moved
|
||||
out of the main application and into a file called "Netscape Resources"
|
||||
in 4.0</LI>
|
||||
|
||||
<LI>
|
||||
For plain-text email/form composition, we used VText up through 4.0. For
|
||||
5.0, we switched to WASTE because of its minimal impact on the PowerPlant
|
||||
hierarchy. VText caused us fits every time we wanted to upgrade to a newer
|
||||
version of PowerPlant because it wrapped its tentacles around every limb
|
||||
of PowerPlant.</LI>
|
||||
|
||||
<LI>
|
||||
4.0 included a new memory management scheme which drastically reduced the
|
||||
amount of memory used by the client. This is why the memory partition of
|
||||
4.0 is about half of 3.0.</LI>
|
||||
|
||||
<LI>
|
||||
A version of Navigator sans Mail/News/Composer debuted with 4.03, and again
|
||||
two days later with 4.03.1.</LI>
|
||||
</UL>
|
||||
|
||||
<H3>
|
||||
Future</H3>
|
||||
There is certainly a lot to do. In order to not duplicate too much work
|
||||
(since we are still working on this full time here at Netscape), I've put
|
||||
together a list of what we plan on doing and what we want to do but probably
|
||||
won't get around to because of time constraints.
|
||||
|
||||
<P>Things that we are going to focus on:
|
||||
<UL>
|
||||
<LI>
|
||||
More NavCenter work</LI>
|
||||
|
||||
<LI>
|
||||
Solve the issues with too many 'STR ' resources (see note on <A HREF="#Pitfalls">issues
|
||||
page</A>)</LI>
|
||||
|
||||
<LI>
|
||||
Modularization (HTML display isolated from networking, etc)</LI>
|
||||
|
||||
<LI>
|
||||
use new Appearance Manager classes in PowerPlant</LI>
|
||||
|
||||
<LI>
|
||||
Navigation Services (new open/save dialogs in Allegro) support. We have
|
||||
an ancient SDK and have integrated it in a few places, but the current
|
||||
implemenation that we have doesn't work very well. It's cool, though.</LI>
|
||||
|
||||
<LI>
|
||||
More drag and drop in composer.</LI>
|
||||
|
||||
<LI>
|
||||
More support for Internet Config (see note on <A HREF="#Pitfalls">issues
|
||||
page</A>).</LI>
|
||||
|
||||
<LI>
|
||||
external Java VM support (MRJ, etc)</LI>
|
||||
</UL>
|
||||
Things we would like some help on:
|
||||
<UL>
|
||||
<LI>
|
||||
printing support</LI>
|
||||
|
||||
<LI>
|
||||
68K version</LI>
|
||||
|
||||
<LI>
|
||||
Context Menu Manager support</LI>
|
||||
|
||||
<LI>
|
||||
bug fixes of any kind</LI>
|
||||
|
||||
<LI>
|
||||
performance tuning of any kind</LI>
|
||||
|
||||
<LI>
|
||||
getting around the limitation of 255 hierarchical menus imposed by the
|
||||
OS. This would let us do a "real" personal toolbar with folders that have
|
||||
popup menus.</LI>
|
||||
|
||||
<LI>
|
||||
Fixing the build system so it uses makefiles without having to give up
|
||||
the CW IDE for source browsing/editing.</LI>
|
||||
|
||||
<LI>
|
||||
better publishing in Composer</LI>
|
||||
|
||||
<LI>
|
||||
add NavCenter to Composer window</LI>
|
||||
|
||||
<LI>
|
||||
better table editing in Composer</LI>
|
||||
</UL>
|
||||
|
||||
<ADDRESS>
|
||||
|
||||
<HR>Mike Pinkerton (<A HREF="mailto:pinkerton@netscape.com">pinkerton@netscape.com</A>)</ADDRESS>
|
||||
|
||||
<BR>
|
||||
<HR WIDTH="100%">
|
||||
<CENTER><FONT SIZE=-1>Copyright © 1998 <A HREF="http://home.netscape.com/misc/contact_info.html">Netscape
|
||||
Communications Corporation</A></FONT></CENTER>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@ -1,82 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Unix Build Instructions</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF">
|
||||
|
||||
<H2>
|
||||
<FONT FACE="Arial,Helvetica">Unix Build Instructions</FONT></H2>
|
||||
This document explains how to build Mozilla for Unix.
|
||||
<BR>
|
||||
<HR WIDTH="100%">
|
||||
<PRE>Requirements:
|
||||
|
||||
Memory:
|
||||
32MB of RAM, 128MB of swap, recommended 64MB of RAM.
|
||||
|
||||
Tools:
|
||||
GNU C/C++ compiler 2.7.2 or better
|
||||
GNU make 3.74 or better
|
||||
Motif 1.2 (Lesstif has been used with limited success)
|
||||
|
||||
Tools that will be helpful later:
|
||||
Perl 5.0
|
||||
CVS 1.8.1
|
||||
RCS
|
||||
gdb 4.16
|
||||
|
||||
NOTE:
|
||||
* gcc version 2.8 has been used successfully.
|
||||
Your mileage may vary.
|
||||
|
||||
Build:
|
||||
|
||||
Untar the tar.gz file with the following (or your favorite variant thereof):
|
||||
|
||||
gzip -dc tarball.tar.gz | tar -xvf -
|
||||
|
||||
Set the following environment variables:
|
||||
csh/tcsh:
|
||||
setenv NO_SECURITY 1
|
||||
setenv MOZ_MEDIUM 1
|
||||
setenv MOZILLA_CLIENT 1
|
||||
setenv NO_MDUPDATE 1
|
||||
|
||||
sh/bash/ksh:
|
||||
NO_SECURITY=1
|
||||
MOZ_MEDIUM=1
|
||||
MOZILLA_CLIENT=1
|
||||
NO_MDUPDATE=1
|
||||
export NO_SECURITY MOZ_MEDIUM MOZILLA_CLIENT NO_MDUPDATE
|
||||
|
||||
Debug build is default; optimized build:
|
||||
setenv BUILD_OPT 1
|
||||
(BUILD_OPT=1; export BUILD_OPT)
|
||||
|
||||
On AIX, <B>ap</B>pend /usr/lpp/xlC/bin to your PATH.
|
||||
On Solaris, SINIX, and UnixWare, <B>pre</B>pend /usr/ccs/bin to your PATH.
|
||||
|
||||
Build it. Default target is "export libs install":
|
||||
cd ns
|
||||
gmake -k
|
||||
|
||||
NOTE:
|
||||
|
||||
If you haven't got perl:
|
||||
|
||||
setenv PERL /bin/echo
|
||||
|
||||
gmake -ek
|
||||
|
||||
Run the app:
|
||||
Executable lives in ns/cmd/xfe/{ARCHITECTURE}.{DBG|OPT}.OBJ
|
||||
(e.g. ns/cmd/xfe/Linux2.0.31_x86_DBG.OBJ/mozilla-export)
|
||||
Statically-linked app is "mozilla-export"
|
||||
dynamically-linked app is "moz-export"</PRE>
|
||||
|
||||
<HR WIDTH="100%">
|
||||
<CENTER><FONT SIZE=-1>Copyright © 1998 <A HREF="http://home.netscape.com/misc/contact_info.html">Netscape
|
||||
Communications Corporation</A></FONT></CENTER>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@ -1,220 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=x-mac-roman">
|
||||
<META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en]C-NSCP (WinNT; U) [Netscape]">
|
||||
<META NAME="KeyWords" CONTENT="client, source, documentation">
|
||||
<META NAME="Author" CONTENT="Chris Yeh">
|
||||
<TITLE>WinFE Build Instructions</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF">
|
||||
|
||||
<H2>
|
||||
<FONT FACE="Arial,Helvetica">WinFE Build Instructions</FONT></H2>
|
||||
This document explains how to build Mozilla for the Windows platform. WinFE
|
||||
is the Windows front end module.
|
||||
<HR><B><FONT SIZE=+1>Required Tools:</FONT></B>
|
||||
<UL>
|
||||
<LI>
|
||||
<B>Microsoft Visual C++ version 4.2 or later</B></LI>
|
||||
|
||||
<LI>
|
||||
<B>GNU Tools for Windows:</B>You can find these all over the web. Specifically,
|
||||
you'll need:</LI>
|
||||
|
||||
<PRE> cp.exe
|
||||
|
||||
rm.exe</PRE>
|
||||
|
||||
<UL>Here are some sample download sites to find these:
|
||||
<LI>
|
||||
<A HREF="http://www.cygnus.com/misc/gnu-win32">Cygnus</A></LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="http://www.gnu.org/order/ftp.html">GNU home page</A></LI>
|
||||
|
||||
<LI>
|
||||
<A HREF="ftp://prep.ai.mit.edu/pub/gnu">MIT</A></LI>
|
||||
</UL>
|
||||
Netscape has internally modified version of gmake, shmsdos and win32gnu
|
||||
that we use to get around some problems we were having keeping in sync
|
||||
with the Unix version of gmake. This version of gmake and it's source is
|
||||
included in the Mozilla source distribution. The specific files pertaining
|
||||
to this are:
|
||||
<PRE> gmake.exe
|
||||
|
||||
shmsdos.exe
|
||||
|
||||
uname.exe</PRE>
|
||||
These are located in the \tools\bin directory of the source package. All
|
||||
of these tools need to be put in your path.
|
||||
<LI>
|
||||
Additionally, there are Netscape-developed tools that need to be built
|
||||
prior to your first compile. These are covered in the build section.</LI>
|
||||
</UL>
|
||||
<B><FONT SIZE=+1>Setting up:</FONT></B>
|
||||
<UL>
|
||||
<LI>
|
||||
You need a Pentium with at least a 133 MHz processor and at least 250 megs
|
||||
(NTFS partition) or 500 megs (FAT partition) of hard drive space. You need
|
||||
to have a minimum of 64 megs of memory in order to build this tree. Having
|
||||
at least 128 megs of memory will make your debugging experience noticeably
|
||||
less agonizing</LI>
|
||||
|
||||
<LI>
|
||||
The preferred platform is NT 4.0. NT 3.51 will also work, and Win95 might
|
||||
work if you're lucky. Maybe.</LI>
|
||||
|
||||
<LI>
|
||||
Install MSVC. If you don't choose to have the MSVC install modify your
|
||||
environment variables for PATH, INCLUDE, and LIB information, be sure to
|
||||
run VCVARS32.BAT out of the MSVC bin directory prior to attempting to build.</LI>
|
||||
|
||||
<LI>
|
||||
Download and install GNU tools. Put them in your path.</LI>
|
||||
|
||||
<LI>
|
||||
Install Mozilla source.</LI>
|
||||
|
||||
<LI>
|
||||
There are several environment variables you will need to set, either manually
|
||||
or via a script within a command session, or by setting them in your system
|
||||
environment located through the Control Panel | System icon. Those variables
|
||||
are:</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
set MOZ_BITS=32</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_DEBUG=1 (don't set this if you want to build an optimized release
|
||||
build)</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_GOLD=1</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_MEDIUM=1</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_NT=351 (if running NT 3.51, don't set otherwise)</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_OUT=(location of resulting executable and totally optional, see
|
||||
Notes for more details)</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_SRC=(top of your tree, drive letter and path, i.e. set MOZ_SRC=d:\mozilla_src.
|
||||
The topmost directory under this should be ns)</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_TOOLS=(location of the bin directory containing your GNU tools.
|
||||
The build looks for MOZ_TOOLS\bin\gmake.exe, so make sure your MOZ_TOOLS
|
||||
is figured appropriately)</LI>
|
||||
|
||||
<LI>
|
||||
set NO_SECURITY=1</LI>
|
||||
|
||||
<LI>
|
||||
set NSPR20=1</LI>
|
||||
|
||||
<LI>
|
||||
if you are running VC++ 5.0 or higher: set _MSC_VER=1100</LI>
|
||||
</UL>
|
||||
</UL>
|
||||
<B><FONT SIZE=+1>Building:</FONT></B>
|
||||
<UL>
|
||||
<LI>
|
||||
You need to be running a vanilla command prompt. Other shells may work,
|
||||
but you might have to tweak makefiles.</LI>
|
||||
|
||||
<LI>
|
||||
<B>Build the tools:</B> This generates several tools that handle things
|
||||
like dependency generation</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
cd ns\config</LI>
|
||||
|
||||
<LI>
|
||||
nmake /f makefile.win</LI>
|
||||
</UL>
|
||||
|
||||
<LI>
|
||||
<B>Build the whole lizard:</B> This will do a complete build of the source
|
||||
tree. You will end up with a mozilla.exe at the end.</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
cd ns</LI>
|
||||
|
||||
<LI>
|
||||
nmake /f client.mak</LI>
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
If you want to build communicator a piece at a time, these are the steps
|
||||
that client.mak steps through. If you successfully ran the client.mak step
|
||||
above, you don't need to do this.</LI>
|
||||
|
||||
<LI>
|
||||
<B>Build the back end:</B> This builds cross platform components like NSPR
|
||||
and the shared library modules. All of the interesting output from this
|
||||
part of the build will end up in ns\dist, under public\ if it's a library
|
||||
header, and under WIN32_D.OBJ\ (or WIN32_O.OBJ\ for an optimized build)
|
||||
if it's a dynamic or static library. The exception is the NSPR public headers,
|
||||
which live in WIN32_D.OBJ\include.</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
cd ns</LI>
|
||||
|
||||
<LI>
|
||||
nmake /f makefile.win</LI>
|
||||
</UL>
|
||||
|
||||
<LI>
|
||||
<B>Build the front end:</B> This builds and links into the final executable,
|
||||
mozilla.exe.</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
cd ns\cmd\winfe\mkfiles32</LI>
|
||||
|
||||
<LI>
|
||||
nmake /f mozilla.mak DEPEND=1</LI>
|
||||
|
||||
<LI>
|
||||
nmake /f mozilla.mak</LI>
|
||||
</UL>
|
||||
</UL>
|
||||
<B><FONT SIZE=+1>Notes:</FONT></B>
|
||||
<UL>
|
||||
<LI>
|
||||
MOZ_OUT: If you don't set this, mozilla.exe will be generated into ns\cmd\winfe\mkfiles32\x86dbg
|
||||
(or x86rel for optimized builds)</LI>
|
||||
|
||||
<LI>
|
||||
This build process does not use Visual C++ generated project files for
|
||||
several reasons having to do with (among other things) size, maintainability,
|
||||
and the long term desire to start using more of tools like gmake, or plug
|
||||
and play developer tools. This does not preclude you from using the Visual
|
||||
C++ IDE, or it's debugger (somebody fill this out with more detail).</LI>
|
||||
|
||||
<LI>
|
||||
All of the DLLs that you need to run mozilla.exe get copied automagically
|
||||
into your output directory as the last part of build, so all you need to
|
||||
do is cd into x86dbg and run mozilla.exe to get a runnable browser.</LI>
|
||||
|
||||
<LI>
|
||||
On a Pentium II 266 MHz machine with 128 megs of memory, it takes approximately
|
||||
30 minutes to build. Your mileage may vary.</LI>
|
||||
</UL>
|
||||
|
||||
<HR WIDTH="100%">
|
||||
<CENTER><FONT SIZE=-1>Copyright © 1998 <A HREF="http://home.netscape.com/misc/contact_info.html">Netscape
|
||||
Communications Corporation</A></FONT></CENTER>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@ -1,53 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<META NAME="Author" CONTENT="Chris Yeh">
|
||||
<META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en]C-NSCP (WinNT; U) [Netscape]">
|
||||
<TITLE>Running Mozilla...</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<H2>
|
||||
<FONT FACE="Arial,Helvetica">Running Mozilla Without Trashing Netscape
|
||||
Installation</FONT></H2>
|
||||
This document explains how to run <TT>mozilla.exe</TT> separately from
|
||||
<TT>netscape.exe</TT> without trashing your regular installation of Netscape
|
||||
Communicator. This is necessary if, for example, you want to use Communicator's
|
||||
mail client while you work on Mozilla development.
|
||||
<BR>
|
||||
<HR WIDTH="100%">
|
||||
<OL>
|
||||
<LI>
|
||||
Before running <TT>mozilla.exe</TT>, create a new user profile either from
|
||||
a Netscape 4.0x installation using the "User Profile Manager" shortcut
|
||||
in the Utilities folder (on Windows) or by using the <TT>-new_account</TT>
|
||||
option on the command line of either <TT>netscape.exe</TT> or <TT>mozilla.exe</TT>.
|
||||
We suggest calling the profile "<TT>mozilla</TT>."</LI>
|
||||
|
||||
<LI>
|
||||
Always use that new account when running <TT>mozilla.exe</TT>, and never
|
||||
run <TT>netscape.exe</TT> using that same account profile.</LI>
|
||||
</OL>
|
||||
To make things easier, you can start the application with the user account
|
||||
on the command line, for example:
|
||||
<UL><TT>mozilla.exe -P"mozilla"</TT></UL>
|
||||
This assures that prefs and the cache will not interfere between the two
|
||||
versions. This will be especially
|
||||
<BR>important as new prefs are added to the Mozilla product. Note that
|
||||
you must use quotes around the name and there can be no space between the
|
||||
"P" and the profile name. Otherwise, the application won't catch the profile
|
||||
switch, and it will try to load the profile name as the initial URL.
|
||||
|
||||
<P>
|
||||
<HR WIDTH="100%">
|
||||
<BR>You can copy your <TT>bookmark.htm</TT> file from an existing profile
|
||||
to your new profile directory if you want to share bookmarks.
|
||||
|
||||
<P>After the initial 3/31 release, we will add some code to Mozilla to
|
||||
prevent running with a profile that is already being used by <TT>netscape.exe</TT>.
|
||||
<BR>
|
||||
<HR WIDTH="100%">
|
||||
<BR><FONT SIZE=-1>Copyright © 1998 <A HREF="http://home.netscape.com/misc/contact_info.html">Netscape
|
||||
Communications Corporation</A></FONT>
|
||||
</BODY>
|
||||
</HTML>
|
||||
@ -1,180 +0,0 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=x-mac-roman">
|
||||
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; U) [Netscape]">
|
||||
<META NAME="KeyWords" CONTENT="client, source, documentation">
|
||||
<META NAME="Author" CONTENT="Kipp E.B. Hickman">
|
||||
<TITLE>Raptor Windows Build Instructions</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF">
|
||||
|
||||
<H2>
|
||||
<FONT FACE="Arial,Helvetica">Raptor Windows Build Instructions</FONT></H2>
|
||||
This document explains how to build Raptor for the Windows platform.
|
||||
<HR><B><FONT SIZE=+1>Required Tools:</FONT></B>
|
||||
<UL>
|
||||
<LI>
|
||||
<B>Microsoft Visual C++ version 4.2 or later</B></LI>
|
||||
|
||||
<LI>
|
||||
<B>The same set of tools for building <A HREF="http://www.mozilla.org/docs/tplist/catBuild/winbuild.htm">Mozilla</A></B></LI>
|
||||
</UL>
|
||||
<B><FONT SIZE=+1>Setting up:</FONT></B>
|
||||
<UL>
|
||||
<LI>
|
||||
You need a Pentium with at least a 133 MHz processor and at least 250 megs
|
||||
(NTFS partition) or 500 megs (FAT partition) of hard drive space. You need
|
||||
to have a minimum of 64 megs of memory in order to build this tree. These
|
||||
numbers are approximations.</LI>
|
||||
|
||||
<LI>
|
||||
The preferred platform is NT 4.0. NT 3.51 will also work, and Win95 might
|
||||
work if you're lucky. Maybe.</LI>
|
||||
|
||||
<LI>
|
||||
Install MSVC. If you don't choose to have the MSVC install modify your
|
||||
environment variables for PATH, INCLUDE, and LIB information, be sure to
|
||||
run VCVARS32.BAT out of the MSVC bin directory prior to attempting to build.</LI>
|
||||
|
||||
<LI>
|
||||
Download and install GNU tools. Put them in your path.</LI>
|
||||
|
||||
<LI>
|
||||
Install Raptor source.</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
cd <your-source-area></LI>
|
||||
|
||||
<LI>
|
||||
unzip -o -q win-19980415.zip</LI>
|
||||
</UL>
|
||||
|
||||
<LI>
|
||||
There are several environment variables you will need to set, either manually
|
||||
or via a script within a command session, or by setting them in your system
|
||||
environment located through the Control Panel | System icon.<P>
|
||||
<B>Note: There is an additional variable for building Raptor!
|
||||
Use this list carefully!</B><P>
|
||||
The variables are:</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
set MOZ_BITS=32</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_DEBUG=1 (don't set this if you want to build an optimized release
|
||||
build)</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_GOLD=1</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_MEDIUM=1</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_NT=351 (if running NT 3.51, don't set otherwise)</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_OUT=(location of resulting executable and totally optional, see
|
||||
Notes for more details)</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_SRC=(top of your tree, drive letter and path, i.e. set MOZ_SRC=d:\mozilla_src.
|
||||
The topmost directory under this should be ns)</LI>
|
||||
|
||||
<LI>
|
||||
set MOZ_TOOLS=(location of the bin directory containing your GNU tools.
|
||||
The build looks for MOZ_TOOLS\bin\gmake.exe, so make sure your MOZ_TOOLS
|
||||
is figured appropriately)</LI>
|
||||
|
||||
<LI>
|
||||
set NO_SECURITY=1</LI>
|
||||
|
||||
<LI>
|
||||
set NSPR20=1</LI>
|
||||
|
||||
<LI>
|
||||
if you are running VC++ 5.0 or higher: set _MSC_VER=1100; if you are running
|
||||
VC++ 4.2 then set MOZ_VCVER=42</LI>
|
||||
|
||||
<LI>
|
||||
<B>set STANDALONE_IMAGE_LIB=1</B></LI>
|
||||
|
||||
</UL>
|
||||
</UL>
|
||||
<B><FONT SIZE=+1>Building:</FONT></B>
|
||||
<UL>
|
||||
<LI>
|
||||
You need to be running a vanilla command prompt. Other shells may work,
|
||||
but you might have to tweak makefiles.</LI>
|
||||
|
||||
<LI>
|
||||
<B>Build the tools:</B> This generates several tools that handle things
|
||||
like dependency generation</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
cd ns\config</LI>
|
||||
|
||||
<LI>
|
||||
nmake /f makefile.win</LI>
|
||||
</UL>
|
||||
|
||||
<LI>
|
||||
<B>Build the Raptor:</B> This will do a complete build of the source tree.
|
||||
You will end up with a viewer.exe at the end. The viewer.exe will be in
|
||||
your dist\win32_[OD].obj\bin directory (O will be used when you don't set
|
||||
MOZ_DEBUG; D will be used when you set MOZ_DEBUG).</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
cd ns</LI>
|
||||
|
||||
<LI>
|
||||
nmake /f raptor.mak</LI>
|
||||
</UL>
|
||||
</UL>
|
||||
<B><FONT SIZE=+1>Running:</FONT></B>
|
||||
<UL>
|
||||
<LI>
|
||||
Once you have built the system, do this to run the viewer program (the
|
||||
viewer program is a simple test program that uses the nsIWebWidget API
|
||||
to embed a web widget object). The viewer program has a few basic menu
|
||||
items, include "Samples" which load sample tests.</LI>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
cd ns\dist\win32_[OD].obj\bin</LI>
|
||||
|
||||
<LI>
|
||||
.\viewer.exe</LI>
|
||||
</UL>
|
||||
</UL>
|
||||
<B><FONT SIZE=+1>Notes:</FONT></B>
|
||||
<UL>
|
||||
<LI>
|
||||
This build process does not use Visual C++ generated project files for
|
||||
several reasons having to do with (among other things) size, maintainability,
|
||||
and the long term desire to start using more of tools like gmake, or plug
|
||||
and play developer tools. This does not preclude you from using the Visual
|
||||
C++ IDE, or it's debugger. Once you have built a viewer.exe do this to
|
||||
run it under the debugger:</LI>
|
||||
</UL>
|
||||
|
||||
<UL>
|
||||
<UL>
|
||||
<LI>
|
||||
cd ns\dist\win32_[OD].obj\bin</LI>
|
||||
|
||||
<LI>
|
||||
msdev viewer.exe</LI>
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
<HR WIDTH="100%">
|
||||
<CENTER><FONT SIZE=-1>Copyright © 1998 <A HREF="http://home.netscape.com/misc/contact_info.html">Netscape
|
||||
Communications Corporation</A></FONT></CENTER>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@ -1,339 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,176 +0,0 @@
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
in the source code directory. After you have installed the package for
|
||||
one architecture, use `make distclean' before reconfiguring for another
|
||||
architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made.
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
#
|
||||
# GNU Makefile for building gmake.exe on WIN32
|
||||
# This is the top-level makefile. It only does the optimized build.
|
||||
#
|
||||
|
||||
CSRCS = ar.c \
|
||||
arscan.c \
|
||||
commands.c \
|
||||
default.c \
|
||||
dir.c \
|
||||
expand.c \
|
||||
file.c \
|
||||
function.c \
|
||||
getloadavg.c \
|
||||
getopt.c \
|
||||
getopt1.c \
|
||||
implicit.c \
|
||||
job.c \
|
||||
main.c \
|
||||
misc.c \
|
||||
read.c \
|
||||
remake.c \
|
||||
remote-stub.c \
|
||||
rule.c \
|
||||
signame.c \
|
||||
variable.c \
|
||||
version.c \
|
||||
vpath.c
|
||||
|
||||
OBJS = $(CSRCS:.c=.obj) glob/fnmatch.obj glob/glob.obj
|
||||
|
||||
CC = cl
|
||||
|
||||
CFLAGS = $(CC_SWITCHES) $(INCLUDES) $(DEFINES) $(CC_OUTPUTS)
|
||||
|
||||
CC_SWITCHES = -nologo -ML -W3 -O2
|
||||
|
||||
INCLUDES = -I. -Iglob
|
||||
|
||||
DEFINES = -DWIN32 -DNDEBUG -D_CONSOLE -DNETSCAPE -DHAVE_CONFIG_H
|
||||
|
||||
CC_OUTPUTS = -Fpgmake.pch -YX -c
|
||||
|
||||
LINK = link
|
||||
|
||||
LINK_FLAGS = -nologo -subsystem:console \
|
||||
-incremental:no -machine:I386 -out:$@
|
||||
|
||||
all: gmake.exe
|
||||
|
||||
build_glob:
|
||||
cd glob; $(MAKE)
|
||||
|
||||
gmake.exe: build_glob $(OBJS)
|
||||
$(LINK) $(LINK_FLAGS) $(OBJS)
|
||||
|
||||
%.obj: %.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
|
||||
clean:
|
||||
cd glob; $(MAKE) $@
|
||||
rm -rf $(OBJS) gmake.pch gmake.exe
|
||||
@ -1,307 +0,0 @@
|
||||
# NOTE: If you have no `make' program at all to process this makefile, run
|
||||
# `build.sh' instead.
|
||||
#
|
||||
# Copyright (C) 1988, 89, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Make is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU Make; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
#
|
||||
# Makefile for GNU Make
|
||||
#
|
||||
|
||||
# Ultrix 2.2 make doesn't expand the value of VPATH.
|
||||
VPATH = @srcdir@
|
||||
# This must repeat the value, because configure will remove `VPATH = .'.
|
||||
srcdir = @srcdir@
|
||||
|
||||
CC = @CC@
|
||||
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
# Define these for your system as follows:
|
||||
# -DNO_ARCHIVES To disable `ar' archive support.
|
||||
# -DNO_FLOAT To avoid using floating-point numbers.
|
||||
# -DENUM_BITFIELDS If the compiler isn't GCC but groks enum foo:2.
|
||||
# Some compilers apparently accept this
|
||||
# without complaint but produce losing code,
|
||||
# so beware.
|
||||
# NeXT 1.0a uses an old version of GCC, which required -D__inline=inline.
|
||||
# See also `config.h'.
|
||||
defines = @DEFS@ -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\"
|
||||
|
||||
# Which flavor of remote job execution support to use.
|
||||
# The code is found in `remote-$(REMOTE).c'.
|
||||
REMOTE = @REMOTE@
|
||||
|
||||
# If you are using the GNU C library, or have the GNU getopt functions in
|
||||
# your C library, you can comment these out.
|
||||
GETOPT = getopt.o getopt1.o
|
||||
GETOPT_SRC = $(srcdir)/getopt.c $(srcdir)/getopt1.c $(srcdir)/getopt.h
|
||||
|
||||
# If you are using the GNU C library, or have the GNU glob functions in
|
||||
# your C library, you can comment this out. GNU make uses special hooks
|
||||
# into the glob functions to be more efficient (by using make's directory
|
||||
# cache for globbing), so you must use the GNU functions even if your
|
||||
# system's C library has the 1003.2 glob functions already. Also, the glob
|
||||
# functions in the AIX and HPUX C libraries are said to be buggy.
|
||||
GLOB = glob/libglob.a
|
||||
|
||||
# If your system doesn't have alloca, or the one provided is bad, define this.
|
||||
ALLOCA = @ALLOCA@
|
||||
ALLOCA_SRC = $(srcdir)/alloca.c
|
||||
|
||||
# If your system needs extra libraries loaded in, define them here.
|
||||
# System V probably need -lPW for alloca. HP-UX 7.0's alloca in
|
||||
# libPW.a is broken on HP9000s300 and HP9000s400 machines. Use
|
||||
# alloca.c instead on those machines.
|
||||
LOADLIBES = @LIBS@
|
||||
|
||||
# Any extra object files your system needs.
|
||||
extras = @LIBOBJS@
|
||||
|
||||
# Common prefix for machine-independent installed files.
|
||||
prefix = @prefix@
|
||||
# Common prefix for machine-dependent installed files.
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
# Directory to install `make' in.
|
||||
bindir = $(exec_prefix)/bin
|
||||
# Directory to find libraries in for `-lXXX'.
|
||||
libdir = $(exec_prefix)/lib
|
||||
# Directory to search by default for included makefiles.
|
||||
includedir = $(prefix)/include
|
||||
# Directory to install the Info files in.
|
||||
infodir = $(prefix)/info
|
||||
# Directory to install the man page in.
|
||||
mandir = $(prefix)/man/man$(manext)
|
||||
# Number to put on the man page filename.
|
||||
manext = 1
|
||||
# Prefix to put on installed `make' binary file name.
|
||||
binprefix =
|
||||
# Prefix to put on installed `make' man page file name.
|
||||
manprefix = $(binprefix)
|
||||
|
||||
# Whether or not make needs to be installed setgid.
|
||||
# The value should be either `true' or `false'.
|
||||
# On many systems, the getloadavg function (used to implement the `-l'
|
||||
# switch) will not work unless make is installed setgid kmem.
|
||||
install_setgid = @NEED_SETGID@
|
||||
# Install make setgid to this group so it can read /dev/kmem.
|
||||
group = @KMEM_GROUP@
|
||||
|
||||
# Program to install `make'.
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
# Program to install the man page.
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
# Generic install program.
|
||||
INSTALL = @INSTALL@
|
||||
|
||||
# Program to format Texinfo source into Info files.
|
||||
MAKEINFO = makeinfo
|
||||
# Program to format Texinfo source into DVI files.
|
||||
TEXI2DVI = texi2dvi
|
||||
|
||||
# Programs to make tags files.
|
||||
ETAGS = etags -w
|
||||
CTAGS = ctags -w
|
||||
|
||||
objs = commands.o job.o dir.o file.o misc.o main.o read.o remake.o \
|
||||
rule.o implicit.o default.o variable.o expand.o function.o \
|
||||
vpath.o version.o ar.o arscan.o signame.o remote-$(REMOTE).o \
|
||||
$(GLOB) $(GETOPT) $(ALLOCA) $(extras)
|
||||
srcs = $(srcdir)/commands.c $(srcdir)/job.c $(srcdir)/dir.c \
|
||||
$(srcdir)/file.c $(srcdir)/getloadavg.c $(srcdir)/misc.c \
|
||||
$(srcdir)/main.c $(srcdir)/read.c $(srcdir)/remake.c \
|
||||
$(srcdir)/rule.c $(srcdir)/implicit.c $(srcdir)/default.c \
|
||||
$(srcdir)/variable.c $(srcdir)/expand.c $(srcdir)/function.c \
|
||||
$(srcdir)/vpath.c $(srcdir)/version.c \
|
||||
$(srcdir)/remote-$(REMOTE).c \
|
||||
$(srcdir)/ar.c $(srcdir)/arscan.c \
|
||||
$(srcdir)/signame.c $(srcdir)/signame.h $(GETOPT_SRC) \
|
||||
$(srcdir)/commands.h $(srcdir)/dep.h $(srcdir)/file.h \
|
||||
$(srcdir)/job.h $(srcdir)/make.h $(srcdir)/rule.h \
|
||||
$(srcdir)/variable.h $(ALLOCA_SRC) $(srcdir)/config.h.in
|
||||
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .o .c .h .ps .dvi .info .texinfo
|
||||
|
||||
all: make
|
||||
info: make.info
|
||||
dvi: make.dvi
|
||||
# Some makes apparently use .PHONY as the default goal if it is before `all'.
|
||||
.PHONY: all check info dvi
|
||||
|
||||
make.info: make.texinfo
|
||||
$(MAKEINFO) -I$(srcdir) $(srcdir)/make.texinfo -o make.info
|
||||
|
||||
make.dvi: make.texinfo
|
||||
$(TEXI2DVI) $(srcdir)/make.texinfo
|
||||
|
||||
make.ps: make.dvi
|
||||
dvi2ps make.dvi > make.ps
|
||||
|
||||
make: $(objs)
|
||||
$(CC) $(LDFLAGS) $(objs) $(LOADLIBES) -o make.new
|
||||
mv -f make.new make
|
||||
|
||||
# -I. is needed to find config.h in the build directory.
|
||||
.c.o:
|
||||
$(CC) $(defines) -c -I. -I$(srcdir) -I$(srcdir)/glob \
|
||||
$(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION)
|
||||
|
||||
# For some losing Unix makes.
|
||||
SHELL = /bin/sh
|
||||
@SET_MAKE@
|
||||
|
||||
glob/libglob.a: FORCE config.h
|
||||
cd glob; $(MAKE) libglob.a
|
||||
FORCE:
|
||||
|
||||
tagsrcs = $(srcs) $(srcdir)/remote-*.c
|
||||
TAGS: $(tagsrcs)
|
||||
$(ETAGS) $(tagsrcs)
|
||||
tags: $(tagsrcs)
|
||||
$(CTAGS) $(tagsrcs)
|
||||
|
||||
.PHONY: install installdirs
|
||||
install: installdirs \
|
||||
$(bindir)/$(binprefix)make $(infodir)/make.info \
|
||||
$(mandir)/$(manprefix)make.$(manext)
|
||||
|
||||
installdirs:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(infodir) $(mandir)
|
||||
|
||||
$(bindir)/$(binprefix)make: make
|
||||
$(INSTALL_PROGRAM) make $@.new
|
||||
@if $(install_setgid); then \
|
||||
if chgrp $(group) $@.new && chmod g+s $@.new; then \
|
||||
echo "chgrp $(group) $@.new && chmod g+s $@.new"; \
|
||||
else \
|
||||
echo "$@ needs to be owned by group $(group) and setgid;"; \
|
||||
echo "otherwise the \`-l' option will probably not work."; \
|
||||
echo "You may need special privileges to install $@."; \
|
||||
fi; \
|
||||
else true; fi
|
||||
# Some systems can't deal with renaming onto a running binary.
|
||||
-rm -f $@.old
|
||||
-mv $@ $@.old
|
||||
mv $@.new $@
|
||||
|
||||
$(infodir)/make.info: make.info
|
||||
if [ -r ./make.info ]; then dir=.; else dir=$(srcdir); fi; \
|
||||
for file in $${dir}/make.info*; do \
|
||||
name="`basename $$file`"; \
|
||||
$(INSTALL_DATA) $$file \
|
||||
`echo $@ | sed "s,make.info\$$,$$name,"`; \
|
||||
done
|
||||
# Run install-info only if it exists.
|
||||
# Use `if' instead of just prepending `-' to the
|
||||
# line so we notice real errors from install-info.
|
||||
# We use `$(SHELL) -c' because some shells do not
|
||||
# fail gracefully when there is an unknown command.
|
||||
if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
|
||||
if [ -r ./make.info ]; then dir=.; else dir=$(srcdir); fi; \
|
||||
install-info --infodir=$(infodir) $$dir/make.info; \
|
||||
else true; fi
|
||||
|
||||
$(mandir)/$(manprefix)make.$(manext): make.man
|
||||
$(INSTALL_DATA) $(srcdir)/make.man $@
|
||||
|
||||
|
||||
loadavg: loadavg.c config.h
|
||||
$(CC) $(defines) -DTEST -I. -I$(srcdir) $(CFLAGS) $(LDFLAGS) \
|
||||
loadavg.c $(LOADLIBES) -o $@
|
||||
# We copy getloadavg.c into a different file rather than compiling it
|
||||
# directly because some compilers clobber getloadavg.o in the process.
|
||||
loadavg.c: getloadavg.c
|
||||
ln $(srcdir)/getloadavg.c loadavg.c || \
|
||||
cp $(srcdir)/getloadavg.c loadavg.c
|
||||
check-loadavg: loadavg
|
||||
@echo The system uptime program believes the load average to be:
|
||||
-uptime
|
||||
@echo The GNU load average checking code believes:
|
||||
./loadavg
|
||||
check: check-loadavg
|
||||
|
||||
|
||||
.PHONY: clean realclean distclean mostlyclean
|
||||
clean: glob-clean
|
||||
-rm -f make loadavg *.o core make.dvi
|
||||
distclean: clean glob-realclean
|
||||
-rm -f Makefile config.h config.status build.sh stamp-config
|
||||
-rm -f config.log config.cache
|
||||
-rm -f TAGS tags
|
||||
-rm -f make.?? make.??s make.log make.toc make.*aux
|
||||
-rm -f loadavg.c
|
||||
realclean: distclean
|
||||
-rm -f make.info*
|
||||
mostlyclean: clean
|
||||
|
||||
.PHONY: glob-clean glob-realclean
|
||||
glob-clean glob-realclean:
|
||||
cd glob; $(MAKE) $@
|
||||
|
||||
Makefile: config.status $(srcdir)/Makefile.in
|
||||
$(SHELL) config.status
|
||||
glob/Makefile: config.status $(srcdir)/glob/Makefile.in
|
||||
$(SHELL) config.status
|
||||
config.h: stamp-config ;
|
||||
stamp-config: config.status $(srcdir)/config.h.in
|
||||
$(SHELL) config.status
|
||||
touch stamp-config
|
||||
|
||||
#configure: configure.in aclocal.m4
|
||||
# cd $(srcdir) && autoconf $(ACFLAGS)
|
||||
#config.h.in: configure.in aclocal.m4
|
||||
# cd $(srcdir) && autoheader $(ACFLAGS)
|
||||
|
||||
# This tells versions [3.59,3.63) of GNU make not to export all variables.
|
||||
.NOEXPORT:
|
||||
|
||||
# The automatically generated dependencies below may omit config.h
|
||||
# because it is included with ``#include <config.h>'' rather than
|
||||
# ``#include "config.h"''. So we add the explicit dependency to make sure.
|
||||
$(objs): config.h
|
||||
|
||||
# Automatically generated dependencies will be put at the end of the file.
|
||||
|
||||
# Automatically generated dependencies.
|
||||
commands.o : commands.c make.h dep.h commands.h file.h variable.h job.h
|
||||
job.o: job.c make.h commands.h job.h file.h variable.h
|
||||
dir.o: dir.c make.h
|
||||
file.o: file.c make.h commands.h dep.h file.h variable.h
|
||||
misc.o: misc.c make.h dep.h
|
||||
main.o: main.c make.h commands.h dep.h file.h variable.h job.h getopt.h
|
||||
read.o: read.c make.h commands.h dep.h file.h variable.h glob/glob.h
|
||||
remake.o: remake.c make.h commands.h job.h dep.h file.h
|
||||
rule.o : rule.c make.h config.h commands.h dep.h file.h variable.h rule.h
|
||||
implicit.o : implicit.c make.h rule.h dep.h file.h
|
||||
default.o: default.c make.h rule.h dep.h file.h commands.h variable.h
|
||||
variable.o : variable.c make.h commands.h variable.h dep.h file.h
|
||||
expand.o: expand.c make.h commands.h file.h variable.h
|
||||
function.o: function.c make.h variable.h dep.h commands.h job.h
|
||||
vpath.o : vpath.c make.h file.h variable.h
|
||||
version.o: version.c
|
||||
ar.o : ar.c make.h file.h dep.h
|
||||
arscan.o: arscan.c make.h
|
||||
signame.o: signame.c signame.h
|
||||
remote-stub.o : remote-stub.c make.h commands.h
|
||||
getopt.o: getopt.c getopt.h
|
||||
getopt1.o : getopt1.c getopt.h
|
||||
getloadavg.o: getloadavg.c
|
||||
@ -1,557 +0,0 @@
|
||||
GNU make NEWS -- history of user-visible changes. 26 January 1995
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
|
||||
Please send GNU make bug reports to bug-gnu-utils@prep.ai.mit.edu.
|
||||
|
||||
Version 3.73
|
||||
|
||||
* Converted to use Autoconf version 2, so `configure' has some new options.
|
||||
See INSTALL for details.
|
||||
|
||||
* You can now send a SIGUSR1 signal to Make to toggle printing of debugging
|
||||
output enable by -d, at any time during the run.
|
||||
|
||||
Version 3.72
|
||||
|
||||
* DJ Delorie has ported Make to MS-DOS using the GO32 extender.
|
||||
He is maintaining the DOS port, not the GNU Make maintainer;
|
||||
please direct bugs and questions for DOS to <djgpp@sun.soe.clarkson.edu>.
|
||||
MS-DOS binaries are available for FTP from oak.oakland.edu:pub/msdos/djgpp.
|
||||
|
||||
* The `MAKEFLAGS' variable (in the environment or in a makefile) can now
|
||||
contain variable definitions itself; these are treated just like
|
||||
command-line variable definitions. Make will automatically insert any
|
||||
variable definitions from the environment value of `MAKEFLAGS' or from
|
||||
the command line, into the `MAKEFLAGS' value exported to children. The
|
||||
`MAKEOVERRIDES' variable previously included in the value of `$(MAKE)'
|
||||
for sub-makes is now included in `MAKEFLAGS' instead. As before, you can
|
||||
reset `MAKEOVERRIDES' in your makefile to avoid putting all the variables
|
||||
in the environment when its size is limited.
|
||||
|
||||
* If `.DELETE_ON_ERROR' appears as a target, Make will delete the target of
|
||||
a rule if it has changed when its commands exit with a nonzero status,
|
||||
just as when the commands get a signal.
|
||||
|
||||
* The automatic variable `$+' is new. It lists all the dependencies like
|
||||
`$^', but preserves duplicates listed in the makefile. This is useful
|
||||
for linking rules, where library files sometimes need to be listed twice
|
||||
in the link order.
|
||||
|
||||
* You can now specify the `.IGNORE' and `.SILENT' special targets with
|
||||
dependencies to limit their effects to those files. If a file appears as
|
||||
a dependency of `.IGNORE', then errors will be ignored while running the
|
||||
commands to update that file. Likewise if a file appears as a dependency
|
||||
of `.SILENT', then the commands to update that file will not be printed
|
||||
before they are run. (This change was made to conform to POSIX.2.)
|
||||
|
||||
Version 3.71
|
||||
|
||||
* The automatic variables `$(@D)', `$(%D)', `$(*D)', `$(<D)', `$(?D)', and
|
||||
`$(^D)' now omit the trailing slash from the directory name. (This change
|
||||
was made to comply with POSIX.2.)
|
||||
|
||||
* The source distribution now includes the Info files for the Make manual.
|
||||
There is no longer a separate distribution containing Info and DVI files.
|
||||
|
||||
* You can now set the variables `binprefix' and/or `manprefix' in
|
||||
Makefile.in (or on the command line when installing) to install GNU make
|
||||
under a name other than `make' (i.e., ``make binprefix=g install''
|
||||
installs GNU make as `gmake').
|
||||
|
||||
* The built-in Texinfo rules use the new variables `TEXI2DVI_FLAGS' for
|
||||
flags to the `texi2dvi' script, and `MAKEINFO_FLAGS' for flags to the
|
||||
Makeinfo program.
|
||||
|
||||
* The exit status of Make when it runs into errors is now 2 instead of 1.
|
||||
The exit status is 1 only when using -q and some target is not up to date.
|
||||
(This change was made to comply with POSIX.2.)
|
||||
|
||||
Version 3.70
|
||||
|
||||
* It is no longer a fatal error to have a NUL character in a makefile.
|
||||
You should never put a NUL in a makefile because it can have strange
|
||||
results, but otherwise empty lines full of NULs (such as produced by
|
||||
the `xmkmf' program) will always work fine.
|
||||
|
||||
* The error messages for nonexistent included makefiles now refer to the
|
||||
makefile name and line number where the `include' appeared, so Emacs's
|
||||
C-x ` command takes you there (in case it's a typo you need to fix).
|
||||
|
||||
Version 3.69
|
||||
|
||||
* Implicit rule search for archive member references is now done in the
|
||||
opposite order from previous versions: the whole target name `LIB(MEM)'
|
||||
first, and just the member name and parentheses `(MEM)' second.
|
||||
|
||||
* Make now gives an error for an unterminated variable or function reference.
|
||||
For example, `$(foo' with no matching `)' or `${bar' with no matching `}'.
|
||||
|
||||
* The new default variable `MAKE_VERSION' gives the version number of
|
||||
Make, and a string describing the remote job support compiled in (if any).
|
||||
Thus the value (in this release) is something like `3.69' or `3.69-Customs'.
|
||||
|
||||
* Commands in an invocation of the `shell' function are no longer run with
|
||||
a modified environment like target commands are. As in versions before
|
||||
3.68, they now run with the environment that `make' started with. We
|
||||
have reversed the change made in version 3.68 because it turned out to
|
||||
cause a paradoxical situation in cases like:
|
||||
|
||||
export variable = $(shell echo value)
|
||||
|
||||
When Make attempted to put this variable in the environment for a target
|
||||
command, it would try expand the value by running the shell command
|
||||
`echo value'. In version 3.68, because it constructed an environment
|
||||
for that shell command in the same way, Make would begin to go into an
|
||||
infinite loop and then get a fatal error when it detected the loop.
|
||||
|
||||
* The commands given for `.DEFAULT' are now used for phony targets with no
|
||||
commands.
|
||||
|
||||
Version 3.68
|
||||
|
||||
* You can list several archive member names inside parenthesis:
|
||||
`lib(mem1 mem2 mem3)' is equivalent to `lib(mem1) lib(mem2) lib(mem3)'.
|
||||
|
||||
* You can use wildcards inside archive member references. For example,
|
||||
`lib(*.o)' expands to all existing members of `lib' whose names end in
|
||||
`.o' (e.g. `lib(a.o) lib(b.o)'); `*.a(*.o)' expands to all such members
|
||||
of all existing files whose names end in `.a' (e.g. `foo.a(a.o)
|
||||
foo.a(b.o) bar.a(c.o) bar.a(d.o)'.
|
||||
|
||||
* A suffix rule `.X.a' now produces two pattern rules:
|
||||
(%.o): %.X # Previous versions produced only this.
|
||||
%.a: %.X # Now produces this as well, just like other suffixes.
|
||||
|
||||
* The new flag `--warn-undefined-variables' says to issue a warning message
|
||||
whenever Make expands a reference to an undefined variable.
|
||||
|
||||
* The new `-include' directive is just like `include' except that there is
|
||||
no error (not even a warning) for a nonexistent makefile.
|
||||
|
||||
* Commands in an invocation of the `shell' function are now run with a
|
||||
modified environment like target commands are, so you can use `export' et
|
||||
al to set up variables for them. They used to run with the environment
|
||||
that `make' started with.
|
||||
|
||||
Version 3.66
|
||||
|
||||
* `make --version' (or `make -v') now exits immediately after printing
|
||||
the version number.
|
||||
|
||||
Version 3.65
|
||||
|
||||
* Make now supports long-named members in `ar' archive files.
|
||||
|
||||
Version 3.64
|
||||
|
||||
* Make now supports the `+=' syntax for a variable definition which appends
|
||||
to the variable's previous value. See the section `Appending More Text
|
||||
to Variables' in the manual for full details.
|
||||
|
||||
* The new option `--no-print-directory' inhibits the `-w' or
|
||||
`--print-directory' feature. Make turns on `--print-directory'
|
||||
automatically if you use `-C' or `--directory', and in sub-makes; some
|
||||
users have found this behavior undesirable.
|
||||
|
||||
* The built-in implicit rules now support the alternative extension
|
||||
`.txinfo' for Texinfo files, just like `.texinfo' and `.texi'.
|
||||
|
||||
Version 3.63
|
||||
|
||||
* Make now uses a standard GNU `configure' script. See the new file
|
||||
INSTALL for the new (and much simpler) installation procedure.
|
||||
|
||||
* There is now a shell script to build Make the first time, if you have no
|
||||
other `make' program. `build.sh' is created by `configure'; see README.
|
||||
|
||||
* GNU Make now completely conforms to the POSIX.2 specification for `make'.
|
||||
|
||||
* Elements of the `$^' and `$?' automatic variables that are archive
|
||||
member references now list only the member name, as in Unix and POSIX.2.
|
||||
|
||||
* You should no longer ever need to specify the `-w' switch, which prints
|
||||
the current directory before and after Make runs. The `-C' switch to
|
||||
change directory, and recursive use of Make, now set `-w' automatically.
|
||||
|
||||
* Multiple double-colon rules for the same target will no longer have their
|
||||
commands run simultaneously under -j, as this could result in the two
|
||||
commands trying to change the file at the same time and interfering with
|
||||
one another.
|
||||
|
||||
* The `SHELL' variable is now never taken from the environment.
|
||||
Each makefile that wants a shell other than the default (/bin/sh) must
|
||||
set SHELL itself. SHELL is always exported to child processes.
|
||||
This change was made for compatibility with POSIX.2.
|
||||
|
||||
* Make now accepts long options. There is now an informative usage message
|
||||
that tells you what all the options are and what they do. Try `make --help'.
|
||||
|
||||
* There are two new directives: `export' and `unexport'. All variables are
|
||||
no longer automatically put into the environments of the commands that
|
||||
Make runs. Instead, only variables specified on the command line or in
|
||||
the environment are exported by default. To export others, use:
|
||||
export VARIABLE
|
||||
or you can define variables with:
|
||||
export VARIABLE = VALUE
|
||||
or:
|
||||
export VARIABLE := VALUE
|
||||
You can use just:
|
||||
export
|
||||
or:
|
||||
.EXPORT_ALL_VARIABLES:
|
||||
to get the old behavior. See the node `Variables/Recursion' in the manual
|
||||
for a full description.
|
||||
|
||||
* The commands from the `.DEFAULT' special target are only applied to
|
||||
targets which have no rules at all, not all targets with no commands.
|
||||
This change was made for compatibility with Unix make.
|
||||
|
||||
* All fatal error messages now contain `***', so they are easy to find in
|
||||
compilation logs.
|
||||
|
||||
* Dependency file names like `-lNAME' are now replaced with the actual file
|
||||
name found, as with files found by normal directory search (VPATH).
|
||||
The library file `libNAME.a' may now be found in the current directory,
|
||||
which is checked before VPATH; the standard set of directories (/lib,
|
||||
/usr/lib, /usr/local/lib) is now checked last.
|
||||
See the node `Libraries/Search' in the manual for full details.
|
||||
|
||||
* A single `include' directive can now specify more than one makefile to
|
||||
include, like this:
|
||||
include file1 file2
|
||||
You can also use shell file name patterns in an `include' directive:
|
||||
include *.mk
|
||||
|
||||
* The default directories to search for included makefiles, and for
|
||||
libraries specified with `-lNAME', are now set by configuration.
|
||||
|
||||
* You can now use blanks as well as colons to separate the directories in a
|
||||
search path for the `vpath' directive or the `VPATH' variable.
|
||||
|
||||
* You can now use variables and functions in the left hand side of a
|
||||
variable assignment, as in "$(foo)bar = value".
|
||||
|
||||
* The `MAKE' variable is always defined as `$(MAKE_COMMAND) $(MAKEOVERRIDES)'.
|
||||
The `MAKE_COMMAND' variable is now defined to the name with which make
|
||||
was invoked.
|
||||
|
||||
* The built-in rules for C++ compilation now use the variables `$(CXX)' and
|
||||
`$(CXXFLAGS)' instead of `$(C++)' and `$(C++FLAGS)'. The old names had
|
||||
problems with shells that cannot have `+' in environment variable names.
|
||||
|
||||
* The value of a recursively expanded variable is now expanded when putting
|
||||
it into the environment for child processes. This change was made for
|
||||
compatibility with Unix make.
|
||||
|
||||
* A rule with no targets before the `:' is now accepted and ignored.
|
||||
This change was made for compatibility with SunOS 4 make.
|
||||
We do not recommend that you write your makefiles to take advantage of this.
|
||||
|
||||
* The `-I' switch can now be used in MAKEFLAGS, and are put there
|
||||
automatically just like other switches.
|
||||
|
||||
Version 3.61
|
||||
|
||||
* Built-in rules for C++ source files with the `.C' suffix.
|
||||
We still recommend that you use `.cc' instead.
|
||||
|
||||
* If commands are given too many times for a single target,
|
||||
the last set given is used, and a warning message is printed.
|
||||
|
||||
* Error messages about makefiles are in standard GNU error format,
|
||||
so C-x ` in Emacs works on them.
|
||||
|
||||
* Dependencies of pattern rules which contain no % need not actually exist
|
||||
if they can be created (just like dependencies which do have a %).
|
||||
|
||||
Version 3.60
|
||||
|
||||
* A message is always printed when Make decides there is nothing to be done.
|
||||
It used to be that no message was printed for top-level phony targets
|
||||
(because "`phony' is up to date" isn't quite right). Now a different
|
||||
message "Nothing to be done for `phony'" is printed in that case.
|
||||
|
||||
* Archives on AIX now supposedly work.
|
||||
|
||||
* When the commands specified for .DEFAULT are used to update a target,
|
||||
the $< automatic variable is given the same value as $@ for that target.
|
||||
This is how Unix make behaves, and this behavior is mandated by POSIX.2.
|
||||
|
||||
Version 3.59
|
||||
|
||||
* The -n, -q, and -t options are not put in the `MAKEFLAGS' and `MFLAG'
|
||||
variables while remaking makefiles, so recursive makes done while remaking
|
||||
makefiles will behave properly.
|
||||
|
||||
* If the special target `.NOEXPORT' is specified in a makefile,
|
||||
only variables that came from the environment and variables
|
||||
defined on the command line are exported.
|
||||
|
||||
Version 3.58
|
||||
|
||||
* Suffix rules may have dependencies (which are ignored).
|
||||
|
||||
Version 3.57
|
||||
|
||||
* Dependencies of the form `-lLIB' are searched for as /usr/local/lib/libLIB.a
|
||||
as well as libLIB.a in /usr/lib, /lib, the current directory, and VPATH.
|
||||
|
||||
Version 3.55
|
||||
|
||||
* There is now a Unix man page for GNU Make. It is certainly not a replacement
|
||||
for the Texinfo manual, but it documents the basic functionality and the
|
||||
switches. For full documentation, you should still read the Texinfo manual.
|
||||
Thanks to Dennis Morse of Stanford University for contributing the initial
|
||||
version of this.
|
||||
|
||||
* Variables which are defined by default (e.g., `CC') will no longer be put
|
||||
into the environment for child processes. (If these variables are reset by the
|
||||
environment, makefiles, or the command line, they will still go into the
|
||||
environment.)
|
||||
|
||||
* Makefiles which have commands but no dependencies (and thus are always
|
||||
considered out of date and in need of remaking), will not be remade (if they
|
||||
were being remade only because they were makefiles). This means that GNU
|
||||
Make will no longer go into an infinite loop when fed the makefiles that
|
||||
`imake' (necessary to build X Windows) produces.
|
||||
|
||||
* There is no longer a warning for using the `vpath' directive with an explicit
|
||||
pathname (instead of a `%' pattern).
|
||||
|
||||
Version 3.51
|
||||
|
||||
* When removing intermediate files, only one `rm' command line is printed,
|
||||
listing all file names.
|
||||
|
||||
* There are now automatic variables `$(^D)', `$(^F)', `$(?D)', and `$(?F)'.
|
||||
These are the directory-only and file-only versions of `$^' and `$?'.
|
||||
|
||||
* Library dependencies given as `-lNAME' will use "libNAME.a" in the current
|
||||
directory if it exists.
|
||||
|
||||
* The automatic variable `$($/)' is no longer defined.
|
||||
|
||||
* Leading `+' characters on a command line make that line be executed even
|
||||
under -n, -t, or -q (as if the line contained `$(MAKE)').
|
||||
|
||||
* For command lines containing `$(MAKE)', `${MAKE}', or leading `+' characters,
|
||||
only those lines are executed, not their entire rules.
|
||||
(This is how Unix make behaves for lines containing `$(MAKE)' or `${MAKE}'.)
|
||||
|
||||
Version 3.50
|
||||
|
||||
* Filenames in rules will now have ~ and ~USER expanded.
|
||||
|
||||
* The `-p' output has been changed so it can be used as a makefile.
|
||||
(All information that isn't specified by makefiles is prefaced with comment
|
||||
characters.)
|
||||
|
||||
Version 3.49
|
||||
|
||||
* The % character can be quoted with backslash in implicit pattern rules,
|
||||
static pattern rules, `vpath' directives, and `patsubst', `filter', and
|
||||
`filter-out' functions. A warning is issued if a `vpath' directive's
|
||||
pattern contains no %.
|
||||
|
||||
* The `wildcard' variable expansion function now expands ~ and ~USER.
|
||||
|
||||
* Messages indicating failed commands now contain the target name:
|
||||
make: *** [target] Error 1
|
||||
|
||||
* The `-p' output format has been changed somewhat to look more like
|
||||
makefile rules and to give all information that Make has about files.
|
||||
|
||||
Version 3.48
|
||||
|
||||
Version 3.47
|
||||
|
||||
* The `-l' switch with no argument removes any previous load-average limit.
|
||||
|
||||
* When the `-w' switch is in effect, and Make has updated makefiles,
|
||||
it will write a `Leaving directory' messagfe before re-executing itself.
|
||||
This makes the `directory change tracking' changes to Emacs's compilation
|
||||
commands work properly.
|
||||
|
||||
Version 3.46
|
||||
|
||||
* The automatic variable `$*' is now defined for explicit rules,
|
||||
as it is in Unix make.
|
||||
|
||||
Version 3.45
|
||||
|
||||
* The `-j' switch is now put in the MAKEFLAGS and MFLAGS variables when
|
||||
specified without an argument (indicating infinite jobs).
|
||||
The `-l' switch is not always put in the MAKEFLAGS and MFLAGS variables.
|
||||
|
||||
* Make no longer checks hashed directories after running commands.
|
||||
The behavior implemented in 3.41 caused too much slowdown.
|
||||
|
||||
Version 3.44
|
||||
|
||||
* A dependency is NOT considered newer than its dependent if
|
||||
they have the same modification time. The behavior implemented
|
||||
in 3.43 conflicts with RCS.
|
||||
|
||||
Version 3.43
|
||||
|
||||
* Dependency loops are no longer fatal errors.
|
||||
|
||||
* A dependency is considered newer than its dependent if
|
||||
they have the same modification time.
|
||||
|
||||
Version 3.42
|
||||
|
||||
* The variables F77 and F77FLAGS are now set by default to $(FC) and
|
||||
$(FFLAGS). Makefiles designed for System V make may use these variables in
|
||||
explicit rules and expect them to be set. Unfortunately, there is no way to
|
||||
make setting these affect the Fortran implicit rules unless FC and FFLAGS
|
||||
are not used (and these are used by BSD make).
|
||||
|
||||
Version 3.41
|
||||
|
||||
* Make now checks to see if its hashed directories are changed by commands.
|
||||
Other makes that hash directories (Sun, 4.3 BSD) don't do this.
|
||||
|
||||
Version 3.39
|
||||
|
||||
* The `shell' function no longer captures standard error output.
|
||||
|
||||
Version 3.32
|
||||
|
||||
* A file beginning with a dot can be the default target if it also contains
|
||||
a slash (e.g., `../bin/foo'). (Unix make allows this as well.)
|
||||
|
||||
Version 3.31
|
||||
|
||||
* Archive member names are truncated to 15 characters.
|
||||
|
||||
* Yet more USG stuff.
|
||||
|
||||
* Minimal support for Microport System V (a 16-bit machine and a
|
||||
brain-damaged compiler). This has even lower priority than other USG
|
||||
support, so if it gets beyond trivial, I will take it out completely.
|
||||
|
||||
* Revamped default implicit rules (not much visible change).
|
||||
|
||||
* The -d and -p options can come from the environment.
|
||||
|
||||
Version 3.30
|
||||
|
||||
* Improved support for USG and HPUX (hopefully).
|
||||
|
||||
* A variable reference like `$(foo:a=b)', if `a' contains a `%', is
|
||||
equivalent to `$(patsubst a,b,$(foo))'.
|
||||
|
||||
* Defining .DEFAULT with no deps or commands clears its commands.
|
||||
|
||||
* New default implicit rules for .S (cpp, then as), and .sh (copy and make
|
||||
executable). All default implicit rules that use cpp (even indirectly), use
|
||||
$(CPPFLAGS).
|
||||
|
||||
Version 3.29
|
||||
|
||||
* Giving the -j option with no arguments gives you infinite jobs.
|
||||
|
||||
Version 3.28
|
||||
|
||||
* New option: "-l LOAD" says not to start any new jobs while others are
|
||||
running if the load average is not below LOAD (a floating-point number).
|
||||
|
||||
* There is support in place for implementations of remote command execution
|
||||
in Make. See the file remote.c.
|
||||
|
||||
Version 3.26
|
||||
|
||||
* No more than 10 directories will be kept open at once.
|
||||
(This number can be changed by redefining MAX_OPEN_DIRECTORIES in dir.c.)
|
||||
|
||||
Version 3.25
|
||||
|
||||
* Archive files will have their modification times recorded before doing
|
||||
anything that might change their modification times by updating an archive
|
||||
member.
|
||||
|
||||
Version 3.20
|
||||
|
||||
* The `MAKELEVEL' variable is defined for use by makefiles.
|
||||
|
||||
Version 3.19
|
||||
|
||||
* The recursion level indications in error messages are much shorter than
|
||||
they were in version 3.14.
|
||||
|
||||
Version 3.18
|
||||
|
||||
* Leading spaces before directives are ignored (as documented).
|
||||
|
||||
* Included makefiles can determine the default goal target.
|
||||
(System V Make does it this way, so we are being compatible).
|
||||
|
||||
Version 3.14.
|
||||
|
||||
* Variables that are defaults built into Make will not be put in the
|
||||
environment for children. This just saves some environment space and,
|
||||
except under -e, will be transparent to sub-makes.
|
||||
|
||||
* Error messages from sub-makes will indicate the level of recursion.
|
||||
|
||||
* Hopefully some speed-up for large directories due to a change in the
|
||||
directory hashing scheme.
|
||||
|
||||
* One child will always get a standard input that is usable.
|
||||
|
||||
* Default makefiles that don't exist will be remade and read in.
|
||||
|
||||
Version 3.13.
|
||||
|
||||
* Count parentheses inside expansion function calls so you can
|
||||
have nested calls: `$(sort $(foreach x,a b,$(x)))'.
|
||||
|
||||
Version 3.12.
|
||||
|
||||
* Several bug fixes, including USG and Sun386i support.
|
||||
|
||||
* `shell' function to expand shell commands a la `
|
||||
|
||||
* If the `-d' flag is given, version information will be printed.
|
||||
|
||||
* The `-c' option has been renamed to `-C' for compatibility with tar.
|
||||
|
||||
* The `-p' option no longer inhibits other normal operation.
|
||||
|
||||
* Makefiles will be updated and re-read if necessary.
|
||||
|
||||
* Can now run several commands at once (parallelism), -j option.
|
||||
|
||||
* Error messages will contain the level of Make recursion, if any.
|
||||
|
||||
* The `MAKEFLAGS' and `MFLAGS' variables will be scanned for options after
|
||||
makefiles are read.
|
||||
|
||||
* A double-colon rule with no dependencies will always have its commands run.
|
||||
(This is how both the BSD and System V versions of Make do it.)
|
||||
|
||||
Version 3.05
|
||||
|
||||
(Changes from versions 1 through 3.05 were never recorded. Sorry.)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Copyright information:
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to anyone to make or distribute verbatim copies
|
||||
of this document as received, in any medium, provided that the
|
||||
copyright notice and this permission notice are preserved,
|
||||
thus giving the recipient permission to redistribute in turn.
|
||||
|
||||
Permission is granted to distribute modified versions
|
||||
of this document, or of portions of it,
|
||||
under the above conditions, provided also that they
|
||||
carry prominent notices stating who last changed them.
|
||||
|
||||
Local variables:
|
||||
version-control: never
|
||||
end:
|
||||
@ -1,128 +0,0 @@
|
||||
# NOTE: If you have no `make' program at all to process this makefile, run
|
||||
# `build_w32.bat' instead.
|
||||
#
|
||||
# Copyright (C) 1988, 89, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Make is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU Make; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
#
|
||||
# NMakefile for GNU Make
|
||||
#
|
||||
|
||||
LINK = link
|
||||
CC = cl
|
||||
|
||||
OUTDIR=.
|
||||
MAKEFILE=NMakefile
|
||||
|
||||
# The cl switches we use:
|
||||
# /Fd<filename> renames program database file
|
||||
# /Fo<filename> creates an object file
|
||||
# /Fp<filename> specifies a precompiled header file name
|
||||
# /O2 creates fast code
|
||||
# /Od disables optimization
|
||||
# /W sets warning levels
|
||||
# /YX Automates precompiled header
|
||||
# /Zi Generates complete debugging information
|
||||
|
||||
CFLAGS_any = /nologo /W3 /YX /I . /I glob /D NETSCAPE /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H
|
||||
CFLAGS_debug = $(CFLAGS_any) /MLd /Zi /Od /D _DEBUG /FpWinDebug/make.pch /FoWinDebug/ /FdWinDebug/make.pdb
|
||||
CFLAGS_release = $(CFLAGS_any) /ML /O2 /D NDEBUG /FpWinRel/make.pch /FoWinRel/
|
||||
|
||||
LDFLAGS_debug = /NOLOGO /SUBSYSTEM:console\
|
||||
/INCREMENTAL:no /PDB:WinDebug/make.pdb \
|
||||
/OUT:WinDebug/make.exe /DEBUG
|
||||
LDFLAGS_release = /NOLOGO /SUBSYSTEM:console\
|
||||
/INCREMENTAL:no /OUT:WinRel/make.exe
|
||||
|
||||
all: Release Debug
|
||||
|
||||
Release:
|
||||
nmake /f $(MAKEFILE) LDFLAGS="$(LDFLAGS_release)" CFLAGS="$(CFLAGS_release)" OUTDIR=WinRel WinRel/make.exe
|
||||
Debug:
|
||||
nmake /f $(MAKEFILE) LDFLAGS="$(LDFLAGS_debug)" CFLAGS="$(CFLAGS_debug)" OUTDIR=WinDebug WinDebug/make.exe
|
||||
|
||||
clean:
|
||||
rmdir /s /q WinDebug WinRel
|
||||
|
||||
$(OUTDIR):
|
||||
if not exist .\$@\nul mkdir .\$@
|
||||
|
||||
#LIBS = kernel32.lib user32.lib advapi32.lib
|
||||
#LIBS = kernel32.lib
|
||||
|
||||
OBJS = \
|
||||
$(OUTDIR)/ar.obj \
|
||||
$(OUTDIR)/arscan.obj \
|
||||
$(OUTDIR)/commands.obj \
|
||||
$(OUTDIR)/default.obj \
|
||||
$(OUTDIR)/dir.obj \
|
||||
$(OUTDIR)/expand.obj \
|
||||
$(OUTDIR)/file.obj \
|
||||
$(OUTDIR)/function.obj \
|
||||
$(OUTDIR)/getloadavg.obj \
|
||||
$(OUTDIR)/getopt.obj \
|
||||
$(OUTDIR)/getopt1.obj \
|
||||
$(OUTDIR)/implicit.obj \
|
||||
$(OUTDIR)/job.obj \
|
||||
$(OUTDIR)/main.obj \
|
||||
$(OUTDIR)/misc.obj \
|
||||
$(OUTDIR)/read.obj \
|
||||
$(OUTDIR)/remake.obj \
|
||||
$(OUTDIR)/remote-stub.obj \
|
||||
$(OUTDIR)/rule.obj \
|
||||
$(OUTDIR)/signame.obj \
|
||||
$(OUTDIR)/variable.obj \
|
||||
$(OUTDIR)/version.obj \
|
||||
$(OUTDIR)/vpath.obj \
|
||||
$(OUTDIR)/glob.obj \
|
||||
$(OUTDIR)/fnmatch.obj
|
||||
|
||||
$(OUTDIR)/make.exe: $(OUTDIR) $(OBJS)
|
||||
$(LINK) @<<
|
||||
$(LDFLAGS) $(LIBS) $(OBJS)
|
||||
<<
|
||||
|
||||
.c{$(OUTDIR)}.obj:
|
||||
$(CC) $(CFLAGS) /c $<
|
||||
|
||||
$(OUTDIR)/ar.obj : ar.c make.h file.h dep.h
|
||||
$(OUTDIR)/arscan.obj : arscan.c make.h
|
||||
$(OUTDIR)/commands.obj : commands.c
|
||||
$(OUTDIR)/default.obj : default.c make.h rule.h dep.h file.h job.h commands.h variable.h
|
||||
$(OUTDIR)/dir.obj : dir.c make.h
|
||||
$(OUTDIR)/expand.obj : expand.c make.h file.h job.h commands.h variable.h
|
||||
$(OUTDIR)/file.obj : file.c make.h dep.h file.h job.h commands.h variable.h
|
||||
$(OUTDIR)/function.obj : function.c make.h file.h variable.h dep.h job.h commands.h
|
||||
$(OUTDIR)/getloadavg.obj : getloadavg.c
|
||||
$(OUTDIR)/getopt.obj : getopt.c
|
||||
$(OUTDIR)/getopt1.obj : getopt1.c getopt.h
|
||||
$(OUTDIR)/implicit.obj : implicit.c make.h rule.h dep.h file.h
|
||||
$(OUTDIR)/job.obj : job.c make.h job.h file.h commands.h variable.h
|
||||
$(OUTDIR)/main.obj : main.c make.h dep.h file.h variable.h job.h commands.h getopt.h
|
||||
$(OUTDIR)/misc.obj : misc.c make.h dep.h
|
||||
$(OUTDIR)/read.obj : read.c make.h dep.h file.h job.h commands.h variable.h glob/glob.h
|
||||
$(OUTDIR)/remake.obj : remake.c make.h file.h job.h commands.h dep.h
|
||||
$(OUTDIR)/remote-stub.obj : remote-stub.c make.h file.h job.h commands.h
|
||||
$(OUTDIR)/rule.obj : rule.c make.h dep.h file.h job.h commands.h variable.h rule.h
|
||||
$(OUTDIR)/signame.obj : signame.c signame.h
|
||||
$(OUTDIR)/variable.obj : variable.c make.h dep.h file.h job.h commands.h variable.h
|
||||
$(OUTDIR)/version.obj : version.c
|
||||
$(OUTDIR)/vpath.obj : vpath.c make.h file.h variable.h
|
||||
$(OUTDIR)/glob.obj : glob/glob.c
|
||||
$(CC) $(CFLAGS) /c glob/glob.c
|
||||
$(OUTDIR)/fnmatch.obj : glob/fnmatch.c
|
||||
$(CC) $(CFLAGS) /c glob/fnmatch.c
|
||||
@ -1,28 +0,0 @@
|
||||
This directory contains the 3.74 test release of GNU Make.
|
||||
All bugs reported for previous test releases have been fixed.
|
||||
Some bugs surely remain.
|
||||
|
||||
For general building and installation instructions, see the file INSTALL.
|
||||
If you need to build GNU Make and have no other `make' program to use,
|
||||
you can use the shell script `build.sh' instead. To do this, first run
|
||||
`configure' as described in INSTALL. Then, instead of typing `make' to
|
||||
build the program, type `sh build.sh'. This should compile the program
|
||||
in the current directory. Then you will have a Make program that you can
|
||||
use for `make install', or whatever else.
|
||||
|
||||
It has been reported that the XLC 1.2 compiler on AIX 3.2 is buggy such
|
||||
that if you compile make with `cc -O' on AIX 3.2, it will not work correctly.
|
||||
It is said that using `cc' without `-O' does work.
|
||||
|
||||
One area that is often a problem in configuration and porting is the code
|
||||
to check the system's current load average. To make it easier to test and
|
||||
debug this code, you can do `make check-loadavg' to see if it works
|
||||
properly on your system. (You must run `configure' beforehand, but you
|
||||
need not build Make itself to run this test.)
|
||||
|
||||
See the file NEWS for what has changed since previous releases.
|
||||
|
||||
GNU Make is fully documented in make.texinfo. See the section entitled
|
||||
`Problems and Bugs' for information on submitting bug reports.
|
||||
|
||||
GNU Make is free software. See the file COPYING for copying conditions.
|
||||
@ -1,16 +0,0 @@
|
||||
This directory contains the source files for the GNU make
|
||||
that is used to build some components (e.g., NSPR) on Win32.
|
||||
|
||||
This GNU make is based on version 3.74 and was ported to
|
||||
Win32 by Netscape engineers. Its default shell is shmsdos.exe,
|
||||
a lightweight shell written by Netscape engineers.
|
||||
|
||||
To build it, you need Microsoft Visual C++ and nmake. If
|
||||
you want to change the build number, which is displayed by
|
||||
the '-v' command line option, you can edit the value of the
|
||||
macro BUILD_NUMBER in main.c. Then, issue the command:
|
||||
nmake /f NMakefile
|
||||
The outputs are WinDebug\make.exe and WinRel\make.exe.
|
||||
Assuming you want to use the optmized executable file,
|
||||
copy WinRel\make.exe to a directory on your Path and
|
||||
rename it gmake.exe.
|
||||
@ -1,17 +0,0 @@
|
||||
/* Define to the name of the SCCS `get' command. */
|
||||
#undef SCCS_GET
|
||||
|
||||
/* Define this if the SCCS `get' command understands the `-G<file>' option. */
|
||||
#undef SCCS_GET_MINUS_G
|
||||
|
||||
/* Define this if the C library defines the variable `sys_siglist'. */
|
||||
#undef HAVE_SYS_SIGLIST
|
||||
|
||||
/* Define this if the C library defines the variable `_sys_siglist'. */
|
||||
#undef HAVE__SYS_SIGLIST
|
||||
|
||||
/* Define this if you have the `union wait' type in <sys/wait.h>. */
|
||||
#undef HAVE_UNION_WAIT
|
||||
|
||||
/* Define this if the POSIX.1 call `sysconf (_SC_OPEN_MAX)' works properly. */
|
||||
#undef HAVE_SYSCONF_OPEN_MAX
|
||||
@ -1,492 +0,0 @@
|
||||
/* alloca.c -- allocate automatically reclaimed memory
|
||||
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
This implementation of the PWB library alloca function,
|
||||
which is used to allocate space off the run-time stack so
|
||||
that it is automatically reclaimed upon procedure exit,
|
||||
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||
|
||||
There are some preprocessor constants that can
|
||||
be defined when compiling for your specific system, for
|
||||
improved efficiency; however, the defaults should be okay.
|
||||
|
||||
The general concept of this implementation is to keep
|
||||
track of all alloca-allocated blocks, and reclaim any
|
||||
that are found to be deeper in the stack than the current
|
||||
invocation. This heuristic does not reclaim storage as
|
||||
soon as it becomes invalid, but it will do so eventually.
|
||||
|
||||
As a special case, alloca(0) reclaims storage without
|
||||
allocating any. It is a good idea to use alloca(0) in
|
||||
your main control loop, etc. to force garbage collection. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
#include "blockinput.h"
|
||||
#endif
|
||||
|
||||
/* If compiling with GCC 2, this file's not needed. */
|
||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||
|
||||
/* If someone has defined alloca as a macro,
|
||||
there must be some other way alloca is supposed to work. */
|
||||
#ifndef alloca
|
||||
|
||||
#ifdef emacs
|
||||
#ifdef static
|
||||
/* actually, only want this if static is defined as ""
|
||||
-- this is for usg, in which emacs must undefine static
|
||||
in order to make unexec workable
|
||||
*/
|
||||
#ifndef STACK_DIRECTION
|
||||
you
|
||||
lose
|
||||
-- must know STACK_DIRECTION at compile-time
|
||||
#endif /* STACK_DIRECTION undefined */
|
||||
#endif /* static */
|
||||
#endif /* emacs */
|
||||
|
||||
/* If your stack is a linked list of frames, you have to
|
||||
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
long i00afunc ();
|
||||
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||
#else
|
||||
#define ADDRESS_FUNCTION(arg) &(arg)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
typedef void *pointer;
|
||||
#else
|
||||
typedef char *pointer;
|
||||
#endif
|
||||
|
||||
#define NULL 0
|
||||
|
||||
/* Different portions of Emacs need to call different versions of
|
||||
malloc. The Emacs executable needs alloca to call xmalloc, because
|
||||
ordinary malloc isn't protected from input signals. On the other
|
||||
hand, the utilities in lib-src need alloca to call malloc; some of
|
||||
them are very simple, and don't have an xmalloc routine.
|
||||
|
||||
Non-Emacs programs expect this to call use xmalloc.
|
||||
|
||||
Callers below should use malloc. */
|
||||
|
||||
#ifndef emacs
|
||||
#define malloc xmalloc
|
||||
#endif
|
||||
extern pointer malloc ();
|
||||
|
||||
/* Define STACK_DIRECTION if you know the direction of stack
|
||||
growth for your system; otherwise it will be automatically
|
||||
deduced at run-time.
|
||||
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
|
||||
#ifndef STACK_DIRECTION
|
||||
#define STACK_DIRECTION 0 /* Direction unknown. */
|
||||
#endif
|
||||
|
||||
#if STACK_DIRECTION != 0
|
||||
|
||||
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||
|
||||
#else /* STACK_DIRECTION == 0; need run-time code. */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
#define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction ()
|
||||
{
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION (dummy);
|
||||
|
||||
find_stack_direction (); /* Recurse once. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
else
|
||||
stack_dir = -1; /* Stack grew downward. */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* STACK_DIRECTION == 0 */
|
||||
|
||||
/* An "alloca header" is used to:
|
||||
(a) chain together all alloca'ed blocks;
|
||||
(b) keep track of stack depth.
|
||||
|
||||
It is very important that sizeof(header) agree with malloc
|
||||
alignment chunk size. The following default should work okay. */
|
||||
|
||||
#ifndef ALIGN_SIZE
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#endif
|
||||
|
||||
typedef union hdr
|
||||
{
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct
|
||||
{
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
} header;
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||
|
||||
/* Return a pointer to at least SIZE bytes of storage,
|
||||
which will be automatically reclaimed upon exit from
|
||||
the procedure that called alloca. Originally, this space
|
||||
was supposed to be taken from the current stack frame of the
|
||||
caller, but that method cannot be made to work for some
|
||||
implementations of C, for example under Gould's UTX/32. */
|
||||
|
||||
pointer
|
||||
alloca (size)
|
||||
unsigned size;
|
||||
{
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION (probe);
|
||||
|
||||
#if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction ();
|
||||
#endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca'd storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
#ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
#endif
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free ((pointer) hp); /* Collect garbage. */
|
||||
|
||||
hp = np; /* -> next header. */
|
||||
}
|
||||
else
|
||||
break; /* Rest are not deeper. */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
|
||||
#ifdef emacs
|
||||
UNBLOCK_INPUT;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
register pointer new = malloc (sizeof (header) + size);
|
||||
/* Address of header. */
|
||||
|
||||
((header *) new)->h.next = last_alloca_header;
|
||||
((header *) new)->h.deep = depth;
|
||||
|
||||
last_alloca_header = (header *) new;
|
||||
|
||||
/* User storage begins just after header. */
|
||||
|
||||
return (pointer) ((char *) new + sizeof (header));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef CRAY_STACK
|
||||
#define CRAY_STACK
|
||||
#ifndef CRAY2
|
||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||
struct stack_control_header
|
||||
{
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
};
|
||||
|
||||
/* The stack segment linkage control information occurs at
|
||||
the high-address end of a stack segment. (The stack
|
||||
grows from low addresses to high addresses.) The initial
|
||||
part of the stack segment linkage control information is
|
||||
0200 (octal) words. This provides for register storage
|
||||
for the routine which overflows the stack. */
|
||||
|
||||
struct stack_segment_linkage
|
||||
{
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
long ssa3;
|
||||
long ssa4;
|
||||
long ssa5;
|
||||
long ssa6;
|
||||
long ssa7;
|
||||
long sss0;
|
||||
long sss1;
|
||||
long sss2;
|
||||
long sss3;
|
||||
long sss4;
|
||||
long sss5;
|
||||
long sss6;
|
||||
long sss7;
|
||||
};
|
||||
|
||||
#else /* CRAY2 */
|
||||
/* The following structure defines the vector of words
|
||||
returned by the STKSTAT library routine. */
|
||||
struct stk_stat
|
||||
{
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
};
|
||||
|
||||
/* The following structure describes the data structure which trails
|
||||
any stack segment. I think that the description in 'asdef' is
|
||||
out of date. I only describe the parts that I am sure about. */
|
||||
|
||||
struct stk_trailer
|
||||
{
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
long unknown8;
|
||||
long unknown9;
|
||||
long unknown10;
|
||||
long unknown11;
|
||||
long unknown12;
|
||||
long unknown13;
|
||||
long unknown14;
|
||||
};
|
||||
|
||||
#endif /* CRAY2 */
|
||||
#endif /* not CRAY_STACK */
|
||||
|
||||
#ifdef CRAY2
|
||||
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||
I doubt that "lint" will like this much. */
|
||||
|
||||
static long
|
||||
i00afunc (long *address)
|
||||
{
|
||||
struct stk_stat status;
|
||||
struct stk_trailer *trailer;
|
||||
long *block, size;
|
||||
long result = 0;
|
||||
|
||||
/* We want to iterate through all of the segments. The first
|
||||
step is to get the stack status structure. We could do this
|
||||
more quickly and more directly, perhaps, by referencing the
|
||||
$LM00 common block, but I know that this works. */
|
||||
|
||||
STKSTAT (&status);
|
||||
|
||||
/* Set up the iteration. */
|
||||
|
||||
trailer = (struct stk_trailer *) (status.current_address
|
||||
+ status.current_size
|
||||
- 15);
|
||||
|
||||
/* There must be at least one stack segment. Therefore it is
|
||||
a fatal error if "trailer" is null. */
|
||||
|
||||
if (trailer == 0)
|
||||
abort ();
|
||||
|
||||
/* Discard segments that do not contain our argument address. */
|
||||
|
||||
while (trailer != 0)
|
||||
{
|
||||
block = (long *) trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort ();
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the result to the offset in this segment and add the sizes
|
||||
of all predecessor segments. */
|
||||
|
||||
result = address - block;
|
||||
|
||||
if (trailer == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (trailer->this_size <= 0)
|
||||
abort ();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
}
|
||||
while (trailer != 0);
|
||||
|
||||
/* We are done. Note that if you present a bogus address (one
|
||||
not in any segment), you will get a different number back, formed
|
||||
from subtracting the address of the first block. This is probably
|
||||
not what you want. */
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
#else /* not CRAY2 */
|
||||
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||
Determine the number of the cell within the stack,
|
||||
given the address of the cell. The purpose of this
|
||||
routine is to linearize, in some sense, stack addresses
|
||||
for alloca. */
|
||||
|
||||
static long
|
||||
i00afunc (long address)
|
||||
{
|
||||
long stkl = 0;
|
||||
|
||||
long size, pseg, this_segment, stack;
|
||||
long result = 0;
|
||||
|
||||
struct stack_segment_linkage *ssptr;
|
||||
|
||||
/* Register B67 contains the address of the end of the
|
||||
current stack segment. If you (as a subprogram) store
|
||||
your registers on the stack and find that you are past
|
||||
the contents of B67, you have overflowed the segment.
|
||||
|
||||
B67 also points to the stack segment linkage control
|
||||
area, which is what we are really interested in. */
|
||||
|
||||
stkl = CRAY_STACKSEG_END ();
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
|
||||
/* If one subtracts 'size' from the end of the segment,
|
||||
one has the address of the first word of the segment.
|
||||
|
||||
If this is not the first segment, 'pseg' will be
|
||||
nonzero. */
|
||||
|
||||
pseg = ssptr->sspseg;
|
||||
size = ssptr->sssize;
|
||||
|
||||
this_segment = stkl - size;
|
||||
|
||||
/* It is possible that calling this routine itself caused
|
||||
a stack overflow. Discard stack segments which do not
|
||||
contain the target address. */
|
||||
|
||||
while (!(this_segment <= address && address <= stkl))
|
||||
{
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||
#endif
|
||||
if (pseg == 0)
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
this_segment = stkl - size;
|
||||
}
|
||||
|
||||
result = address - this_segment;
|
||||
|
||||
/* If you subtract pseg from the current end of the stack,
|
||||
you get the address of the previous stack segment's end.
|
||||
This seems a little convoluted to me, but I'll bet you save
|
||||
a cycle somewhere. */
|
||||
|
||||
while (pseg != 0)
|
||||
{
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||
#endif
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
result += size;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
#endif /* not CRAY2 */
|
||||
#endif /* CRAY */
|
||||
|
||||
#endif /* no alloca */
|
||||
#endif /* not GCC version 2 */
|
||||
@ -1,317 +0,0 @@
|
||||
/* Interface to `ar' archives for GNU Make.
|
||||
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
|
||||
#include "file.h"
|
||||
#include "dep.h"
|
||||
#include <fnmatch.h>
|
||||
|
||||
/* Defined in arscan.c. */
|
||||
extern long int ar_scan ();
|
||||
extern int ar_member_touch ();
|
||||
extern int ar_name_equal ();
|
||||
|
||||
|
||||
/* Return nonzero if NAME is an archive-member reference, zero if not.
|
||||
An archive-member reference is a name like `lib(member)'.
|
||||
If a name like `lib((entry))' is used, a fatal error is signaled at
|
||||
the attempt to use this unsupported feature. */
|
||||
|
||||
int
|
||||
ar_name (name)
|
||||
char *name;
|
||||
{
|
||||
char *p = index (name, '('), *end = name + strlen (name) - 1;
|
||||
|
||||
if (p == 0 || p == name || *end != ')')
|
||||
return 0;
|
||||
|
||||
if (p[1] == '(' && end[-1] == ')')
|
||||
fatal ("attempt to use unsupported feature: `%s'", name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Parse the archive-member reference NAME into the archive and member names.
|
||||
Put the malloc'd archive name in *ARNAME_P if ARNAME_P is non-nil;
|
||||
put the malloc'd member name in *MEMNAME_P if MEMNAME_P is non-nil. */
|
||||
|
||||
void
|
||||
ar_parse_name (name, arname_p, memname_p)
|
||||
char *name, **arname_p, **memname_p;
|
||||
{
|
||||
char *p = index (name, '('), *end = name + strlen (name) - 1;
|
||||
|
||||
if (arname_p != 0)
|
||||
*arname_p = savestring (name, p - name);
|
||||
|
||||
if (memname_p != 0)
|
||||
*memname_p = savestring (p + 1, end - (p + 1));
|
||||
}
|
||||
|
||||
static long int ar_member_date_1 ();
|
||||
|
||||
/* Return the modtime of NAME. */
|
||||
|
||||
time_t
|
||||
ar_member_date (name)
|
||||
char *name;
|
||||
{
|
||||
char *arname;
|
||||
int arname_used = 0;
|
||||
char *memname;
|
||||
long int val;
|
||||
|
||||
ar_parse_name (name, &arname, &memname);
|
||||
|
||||
/* Make sure we know the modtime of the archive itself because we are
|
||||
likely to be called just before commands to remake a member are run,
|
||||
and they will change the archive itself.
|
||||
|
||||
But we must be careful not to enter_file the archive itself if it does
|
||||
not exist, because pattern_search assumes that files found in the data
|
||||
base exist or can be made. */
|
||||
{
|
||||
struct file *arfile;
|
||||
arfile = lookup_file (arname);
|
||||
if (arfile == 0 && file_exists_p (arname))
|
||||
{
|
||||
arfile = enter_file (arname);
|
||||
arname_used = 1;
|
||||
}
|
||||
|
||||
if (arfile != 0)
|
||||
(void) f_mtime (arfile, 0);
|
||||
}
|
||||
|
||||
val = ar_scan (arname, ar_member_date_1, (long int) memname);
|
||||
|
||||
if (!arname_used)
|
||||
free (arname);
|
||||
free (memname);
|
||||
|
||||
return (val <= 0 ? (time_t) -1 : (time_t) val);
|
||||
}
|
||||
|
||||
/* This function is called by `ar_scan' to find which member to look at. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static long int
|
||||
ar_member_date_1 (desc, mem, truncated,
|
||||
hdrpos, datapos, size, date, uid, gid, mode, name)
|
||||
int desc;
|
||||
char *mem;
|
||||
int truncated;
|
||||
long int hdrpos, datapos, size, date;
|
||||
int uid, gid, mode;
|
||||
char *name;
|
||||
{
|
||||
return ar_name_equal (name, mem, truncated) ? date : 0;
|
||||
}
|
||||
|
||||
/* Set the archive-member NAME's modtime to now. */
|
||||
|
||||
int
|
||||
ar_touch (name)
|
||||
char *name;
|
||||
{
|
||||
char *arname, *memname;
|
||||
int arname_used = 0;
|
||||
register int val;
|
||||
|
||||
ar_parse_name (name, &arname, &memname);
|
||||
|
||||
/* Make sure we know the modtime of the archive itself before we
|
||||
touch the member, since this will change the archive itself. */
|
||||
{
|
||||
struct file *arfile;
|
||||
arfile = lookup_file (arname);
|
||||
if (arfile == 0)
|
||||
{
|
||||
arfile = enter_file (arname);
|
||||
arname_used = 1;
|
||||
}
|
||||
|
||||
(void) f_mtime (arfile, 0);
|
||||
}
|
||||
|
||||
val = 1;
|
||||
switch (ar_member_touch (arname, memname))
|
||||
{
|
||||
case -1:
|
||||
error ("touch: Archive `%s' does not exist", arname);
|
||||
break;
|
||||
case -2:
|
||||
error ("touch: `%s' is not a valid archive", arname);
|
||||
break;
|
||||
case -3:
|
||||
perror_with_name ("touch: ", arname);
|
||||
break;
|
||||
case 1:
|
||||
error ("touch: Member `%s' does not exist in `%s'", memname, arname);
|
||||
break;
|
||||
case 0:
|
||||
val = 0;
|
||||
break;
|
||||
default:
|
||||
error ("touch: Bad return code from ar_member_touch on `%s'", name);
|
||||
}
|
||||
|
||||
if (!arname_used)
|
||||
free (arname);
|
||||
free (memname);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/* State of an `ar_glob' run, passed to `ar_glob_match'. */
|
||||
|
||||
struct ar_glob_state
|
||||
{
|
||||
char *arname;
|
||||
char *pattern;
|
||||
unsigned int size;
|
||||
struct nameseq *chain;
|
||||
unsigned int n;
|
||||
};
|
||||
|
||||
/* This function is called by `ar_scan' to match one archive
|
||||
element against the pattern in STATE. */
|
||||
|
||||
static long int
|
||||
ar_glob_match (desc, mem, truncated,
|
||||
hdrpos, datapos, size, date, uid, gid, mode,
|
||||
state)
|
||||
int desc;
|
||||
char *mem;
|
||||
int truncated;
|
||||
long int hdrpos, datapos, size, date;
|
||||
int uid, gid, mode;
|
||||
struct ar_glob_state *state;
|
||||
{
|
||||
if (fnmatch (state->pattern, mem, FNM_PATHNAME|FNM_PERIOD) == 0)
|
||||
{
|
||||
/* We have a match. Add it to the chain. */
|
||||
struct nameseq *new = (struct nameseq *) xmalloc (state->size);
|
||||
new->name = concat (state->arname, mem, ")");
|
||||
new->next = state->chain;
|
||||
state->chain = new;
|
||||
++state->n;
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/* Alphabetic sorting function for `qsort'. */
|
||||
|
||||
static int
|
||||
ar_glob_alphacompare (a, b)
|
||||
char **a, **b;
|
||||
{
|
||||
return strcmp (*a, *b);
|
||||
}
|
||||
|
||||
/* Return nonzero if PATTERN contains any metacharacters.
|
||||
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
|
||||
static int
|
||||
glob_pattern_p (pattern, quote)
|
||||
const char *pattern;
|
||||
const int quote;
|
||||
{
|
||||
register const char *p;
|
||||
int open = 0;
|
||||
|
||||
for (p = pattern; *p != '\0'; ++p)
|
||||
switch (*p)
|
||||
{
|
||||
case '?':
|
||||
case '*':
|
||||
return 1;
|
||||
|
||||
case '\\':
|
||||
if (quote)
|
||||
++p;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
open = 1;
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (open)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Glob for MEMBER_PATTERN in archive ARNAME.
|
||||
Return a malloc'd chain of matching elements (or nil if none). */
|
||||
|
||||
struct nameseq *
|
||||
ar_glob (arname, member_pattern, size)
|
||||
char *arname, *member_pattern;
|
||||
unsigned int size;
|
||||
{
|
||||
struct ar_glob_state state;
|
||||
char **names;
|
||||
struct nameseq *n;
|
||||
unsigned int i;
|
||||
|
||||
if (! glob_pattern_p (member_pattern, 1))
|
||||
return 0;
|
||||
|
||||
/* Scan the archive for matches.
|
||||
ar_glob_match will accumulate them in STATE.chain. */
|
||||
i = strlen (arname);
|
||||
state.arname = (char *) alloca (i + 2);
|
||||
bcopy (arname, state.arname, i);
|
||||
state.arname[i] = '(';
|
||||
state.arname[i + 1] = '\0';
|
||||
state.pattern = member_pattern;
|
||||
state.size = size;
|
||||
state.chain = 0;
|
||||
state.n = 0;
|
||||
(void) ar_scan (arname, ar_glob_match, (long int) &state);
|
||||
|
||||
if (state.chain == 0)
|
||||
return 0;
|
||||
|
||||
/* Now put the names into a vector for sorting. */
|
||||
names = (char **) alloca (state.n * sizeof (char *));
|
||||
i = 0;
|
||||
for (n = state.chain; n != 0; n = n->next)
|
||||
names[i++] = n->name;
|
||||
|
||||
/* Sort them alphabetically. */
|
||||
qsort ((char *) names, i, sizeof (*names), ar_glob_alphacompare);
|
||||
|
||||
/* Put them back into the chain in the sorted order. */
|
||||
i = 0;
|
||||
for (n = state.chain; n != 0; n = n->next)
|
||||
n->name = names[i++];
|
||||
|
||||
return state.chain;
|
||||
}
|
||||
|
||||
#endif /* Not NO_ARCHIVES. */
|
||||
@ -1,561 +0,0 @@
|
||||
/* Library function for scanning an archive file.
|
||||
Copyright (C) 1987, 89, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
|
||||
/* SCO Unix's compiler defines both of these. */
|
||||
#ifdef M_UNIX
|
||||
#undef M_XENIX
|
||||
#endif
|
||||
|
||||
/* On the sun386i and in System V rel 3, ar.h defines two different archive
|
||||
formats depending upon whether you have defined PORTAR (normal) or PORT5AR
|
||||
(System V Release 1). There is no default, one or the other must be defined
|
||||
to have a nonzero value. */
|
||||
|
||||
#if (!defined (PORTAR) || PORTAR == 0) && (!defined (PORT5AR) || PORT5AR == 0)
|
||||
#undef PORTAR
|
||||
#ifdef M_XENIX
|
||||
/* According to Jim Sievert <jas1@rsvl.unisys.com>, for SCO XENIX defining
|
||||
PORTAR to 1 gets the wrong archive format, and defining it to 0 gets the
|
||||
right one. */
|
||||
#define PORTAR 0
|
||||
#else
|
||||
#define PORTAR 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <ar.h>
|
||||
|
||||
/* Cray's <ar.h> apparently defines this. */
|
||||
#ifndef AR_HDR_SIZE
|
||||
#define AR_HDR_SIZE (sizeof (struct ar_hdr))
|
||||
#endif
|
||||
|
||||
/* Takes three arguments ARCHIVE, FUNCTION and ARG.
|
||||
|
||||
Open the archive named ARCHIVE, find its members one by one,
|
||||
and for each one call FUNCTION with the following arguments:
|
||||
archive file descriptor for reading the data,
|
||||
member name,
|
||||
member name might be truncated flag,
|
||||
member header position in file,
|
||||
member data position in file,
|
||||
member data size,
|
||||
member date,
|
||||
member uid,
|
||||
member gid,
|
||||
member protection mode,
|
||||
ARG.
|
||||
|
||||
The descriptor is poised to read the data of the member
|
||||
when FUNCTION is called. It does not matter how much
|
||||
data FUNCTION reads.
|
||||
|
||||
If FUNCTION returns nonzero, we immediately return
|
||||
what FUNCTION returned.
|
||||
|
||||
Returns -1 if archive does not exist,
|
||||
Returns -2 if archive has invalid format.
|
||||
Returns 0 if have scanned successfully. */
|
||||
|
||||
long int
|
||||
ar_scan (archive, function, arg)
|
||||
char *archive;
|
||||
long int (*function) ();
|
||||
long int arg;
|
||||
{
|
||||
#ifdef AIAMAG
|
||||
FL_HDR fl_header;
|
||||
#else
|
||||
int long_name = 0;
|
||||
#endif
|
||||
char *namemap = 0;
|
||||
register int desc = open (archive, O_RDONLY, 0);
|
||||
if (desc < 0)
|
||||
return -1;
|
||||
#ifdef SARMAG
|
||||
{
|
||||
char buf[SARMAG];
|
||||
register int nread = read (desc, buf, SARMAG);
|
||||
if (nread != SARMAG || bcmp (buf, ARMAG, SARMAG))
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef AIAMAG
|
||||
{
|
||||
register int nread = read (desc, (char *) &fl_header, FL_HSZ);
|
||||
if (nread != FL_HSZ || bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG))
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
#ifndef M_XENIX
|
||||
int buf;
|
||||
#else
|
||||
unsigned short int buf;
|
||||
#endif
|
||||
register int nread = read(desc, &buf, sizeof (buf));
|
||||
if (nread != sizeof (buf) || buf != ARMAG)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Now find the members one by one. */
|
||||
{
|
||||
#ifdef SARMAG
|
||||
register long int member_offset = SARMAG;
|
||||
#else
|
||||
#ifdef AIAMAG
|
||||
long int member_offset;
|
||||
long int last_member_offset;
|
||||
|
||||
sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
|
||||
sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
|
||||
#else
|
||||
#ifndef M_XENIX
|
||||
register long int member_offset = sizeof (int);
|
||||
#else /* Xenix. */
|
||||
register long int member_offset = sizeof (unsigned short int);
|
||||
#endif /* Not Xenix. */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
register int nread;
|
||||
struct ar_hdr member_header;
|
||||
#ifdef AIAMAG
|
||||
char name[256];
|
||||
int name_len;
|
||||
long int dateval;
|
||||
int uidval, gidval;
|
||||
long int data_offset;
|
||||
#else
|
||||
char namebuf[sizeof member_header.ar_name + 1];
|
||||
char *name;
|
||||
int is_namemap; /* Nonzero if this entry maps long names. */
|
||||
#endif
|
||||
long int eltsize;
|
||||
int eltmode;
|
||||
long int fnval;
|
||||
|
||||
if (lseek (desc, member_offset, 0) < 0)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
#ifdef AIAMAG
|
||||
#define AR_MEMHDR (AR_HDR_SIZE - sizeof (member_header._ar_name))
|
||||
nread = read (desc, (char *) &member_header, AR_MEMHDR);
|
||||
|
||||
if (nread != AR_MEMHDR)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
sscanf (member_header.ar_namlen, "%4d", &name_len);
|
||||
nread = read (desc, name, name_len);
|
||||
|
||||
if (nread != name_len)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
name[name_len] = 0;
|
||||
|
||||
sscanf (member_header.ar_date, "%12ld", &dateval);
|
||||
sscanf (member_header.ar_uid, "%12d", &uidval);
|
||||
sscanf (member_header.ar_gid, "%12d", &gidval);
|
||||
sscanf (member_header.ar_mode, "%12o", &eltmode);
|
||||
sscanf (member_header.ar_size, "%12ld", &eltsize);
|
||||
|
||||
if ((data_offset = member_offset + AR_MEMHDR + name_len + 2) % 2)
|
||||
++data_offset;
|
||||
|
||||
fnval =
|
||||
(*function) (desc, name, 0,
|
||||
member_offset, data_offset, eltsize,
|
||||
dateval, uidval, gidval,
|
||||
eltmode, arg);
|
||||
|
||||
#else /* Not AIAMAG. */
|
||||
nread = read (desc, (char *) &member_header, AR_HDR_SIZE);
|
||||
if (nread == 0)
|
||||
/* No data left means end of file; that is OK. */
|
||||
break;
|
||||
|
||||
if (nread != AR_HDR_SIZE
|
||||
#ifdef ARFMAG
|
||||
|| bcmp (member_header.ar_fmag, ARFMAG, 2)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
name = namebuf;
|
||||
bcopy (member_header.ar_name, name, sizeof member_header.ar_name);
|
||||
{
|
||||
register char *p = name + sizeof member_header.ar_name;
|
||||
do
|
||||
*p = '\0';
|
||||
while (p > name && *--p == ' ');
|
||||
|
||||
#ifndef AIAMAG
|
||||
/* If the member name is "//" or "ARFILENAMES/" this may be
|
||||
a list of file name mappings. The maximum file name
|
||||
length supported by the standard archive format is 14
|
||||
characters. This member will actually always be the
|
||||
first or second entry in the archive, but we don't check
|
||||
that. */
|
||||
is_namemap = (!strcmp (name, "//")
|
||||
|| !strcmp (name, "ARFILENAMES/"));
|
||||
#endif /* Not AIAMAG. */
|
||||
/* On some systems, there is a slash after each member name. */
|
||||
if (*p == '/')
|
||||
*p = '\0';
|
||||
|
||||
#ifndef AIAMAG
|
||||
/* If the member name starts with a space or a slash, this
|
||||
is an index into the file name mappings (used by GNU ar).
|
||||
Otherwise if the member name looks like #1/NUMBER the
|
||||
real member name appears in the element data (used by
|
||||
4.4BSD). */
|
||||
if (! is_namemap
|
||||
&& (name[0] == ' ' || name[0] == '/')
|
||||
&& namemap != 0)
|
||||
{
|
||||
name = namemap + atoi (name + 1);
|
||||
long_name = 1;
|
||||
}
|
||||
else if (name[0] == '#'
|
||||
&& name[1] == '1'
|
||||
&& name[2] == '/')
|
||||
{
|
||||
int namesize = atoi (name + 3);
|
||||
|
||||
name = (char *) alloca (namesize + 1);
|
||||
nread = read (desc, name, namesize);
|
||||
if (nread != namesize)
|
||||
{
|
||||
close (desc);
|
||||
return -2;
|
||||
}
|
||||
name[namesize] = '\0';
|
||||
|
||||
long_name = 1;
|
||||
}
|
||||
#endif /* Not AIAMAG. */
|
||||
}
|
||||
|
||||
#ifndef M_XENIX
|
||||
sscanf (member_header.ar_mode, "%o", &eltmode);
|
||||
eltsize = atol (member_header.ar_size);
|
||||
#else /* Xenix. */
|
||||
eltmode = (unsigned short int) member_header.ar_mode;
|
||||
eltsize = member_header.ar_size;
|
||||
#endif /* Not Xenix. */
|
||||
|
||||
fnval =
|
||||
(*function) (desc, name, ! long_name, member_offset,
|
||||
member_offset + AR_HDR_SIZE, eltsize,
|
||||
#ifndef M_XENIX
|
||||
atol (member_header.ar_date),
|
||||
atoi (member_header.ar_uid),
|
||||
atoi (member_header.ar_gid),
|
||||
#else /* Xenix. */
|
||||
member_header.ar_date,
|
||||
member_header.ar_uid,
|
||||
member_header.ar_gid,
|
||||
#endif /* Not Xenix. */
|
||||
eltmode, arg);
|
||||
|
||||
#endif /* AIAMAG. */
|
||||
|
||||
if (fnval)
|
||||
{
|
||||
(void) close (desc);
|
||||
return fnval;
|
||||
}
|
||||
|
||||
#ifdef AIAMAG
|
||||
if (member_offset == last_member_offset)
|
||||
/* End of the chain. */
|
||||
break;
|
||||
|
||||
sscanf (member_header.ar_nxtmem, "%12ld", &member_offset);
|
||||
|
||||
if (lseek (desc, member_offset, 0) != member_offset)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
#else
|
||||
|
||||
/* If this member maps archive names, we must read it in. The
|
||||
name map will always precede any members whose names must
|
||||
be mapped. */
|
||||
if (is_namemap)
|
||||
{
|
||||
char *clear;
|
||||
char *limit;
|
||||
|
||||
namemap = (char *) alloca (eltsize);
|
||||
nread = read (desc, namemap, eltsize);
|
||||
if (nread != eltsize)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* The names are separated by newlines. Some formats have
|
||||
a trailing slash. Null terminate the strings for
|
||||
convenience. */
|
||||
limit = namemap + eltsize;
|
||||
for (clear = namemap; clear < limit; clear++)
|
||||
{
|
||||
if (*clear == '\n')
|
||||
{
|
||||
*clear = '\0';
|
||||
if (clear[-1] == '/')
|
||||
clear[-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
is_namemap = 0;
|
||||
}
|
||||
|
||||
member_offset += AR_HDR_SIZE + eltsize;
|
||||
if (member_offset % 2 != 0)
|
||||
member_offset++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
close (desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return nonzero iff NAME matches MEM.
|
||||
If TRUNCATED is nonzero, MEM may be truncated to
|
||||
sizeof (struct ar_hdr.ar_name) - 1. */
|
||||
|
||||
int
|
||||
ar_name_equal (name, mem, truncated)
|
||||
char *name, *mem;
|
||||
int truncated;
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = rindex (name, '/');
|
||||
if (p != 0)
|
||||
name = p + 1;
|
||||
|
||||
/* We no longer use this kludge, since we
|
||||
now support long archive member names. */
|
||||
|
||||
#if 0 && !defined (AIAMAG) && !defined (APOLLO)
|
||||
|
||||
{
|
||||
/* `reallylongname.o' matches `reallylongnam.o'.
|
||||
If member names have a trailing slash, that's `reallylongna.o'. */
|
||||
|
||||
struct ar_hdr h;
|
||||
unsigned int max = sizeof (h.ar_name);
|
||||
unsigned int namelen, memlen;
|
||||
|
||||
if (strncmp (name, mem, max - 3))
|
||||
return 0;
|
||||
|
||||
namelen = strlen (name);
|
||||
memlen = strlen (mem);
|
||||
|
||||
if (namelen > memlen && memlen >= max - 1
|
||||
&& name[namelen - 2] == '.' && name[namelen - 1] == 'o'
|
||||
&& mem[memlen - 2] == '.' && mem[memlen - 1] == 'o')
|
||||
return 1;
|
||||
|
||||
if (namelen != memlen)
|
||||
return 0;
|
||||
|
||||
return (namelen < max - 3 || !strcmp (name + max - 3, mem + max - 3));
|
||||
}
|
||||
|
||||
#else /* AIX or APOLLO. */
|
||||
|
||||
if (truncated)
|
||||
{
|
||||
#ifdef AIAMAG
|
||||
/* TRUNCATED should never be set on this system. */
|
||||
abort ();
|
||||
#else
|
||||
struct ar_hdr hdr;
|
||||
return !strncmp (name, mem,
|
||||
sizeof (hdr.ar_name) -
|
||||
#if !defined (__hpux) && !defined (cray)
|
||||
1
|
||||
#else
|
||||
2
|
||||
#endif /* !__hpux && !cray */
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
return !strcmp (name, mem);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static long int
|
||||
ar_member_pos (desc, mem, truncated,
|
||||
hdrpos, datapos, size, date, uid, gid, mode, name)
|
||||
int desc;
|
||||
char *mem;
|
||||
int truncated;
|
||||
long int hdrpos, datapos, size, date;
|
||||
int uid, gid, mode;
|
||||
char *name;
|
||||
{
|
||||
if (!ar_name_equal (name, mem, truncated))
|
||||
return 0;
|
||||
return hdrpos;
|
||||
}
|
||||
|
||||
/* Set date of member MEMNAME in archive ARNAME to current time.
|
||||
Returns 0 if successful,
|
||||
-1 if file ARNAME does not exist,
|
||||
-2 if not a valid archive,
|
||||
-3 if other random system call error (including file read-only),
|
||||
1 if valid but member MEMNAME does not exist. */
|
||||
|
||||
int
|
||||
ar_member_touch (arname, memname)
|
||||
char *arname, *memname;
|
||||
{
|
||||
register long int pos = ar_scan (arname, ar_member_pos, (long int) memname);
|
||||
register int fd;
|
||||
struct ar_hdr ar_hdr;
|
||||
register int i;
|
||||
struct stat statbuf;
|
||||
|
||||
if (pos < 0)
|
||||
return (int) pos;
|
||||
if (!pos)
|
||||
return 1;
|
||||
|
||||
fd = open (arname, O_RDWR, 0666);
|
||||
if (fd < 0)
|
||||
return -3;
|
||||
/* Read in this member's header */
|
||||
if (lseek (fd, pos, 0) < 0)
|
||||
goto lose;
|
||||
if (AR_HDR_SIZE != read (fd, (char *) &ar_hdr, AR_HDR_SIZE))
|
||||
goto lose;
|
||||
/* Write back the header, thus touching the archive file. */
|
||||
if (lseek (fd, pos, 0) < 0)
|
||||
goto lose;
|
||||
if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE))
|
||||
goto lose;
|
||||
/* The file's mtime is the time we we want. */
|
||||
#ifdef EINTR
|
||||
while (fstat (fd, &statbuf) < 0 && errno == EINTR);
|
||||
#else
|
||||
fstat (fd, &statbuf);
|
||||
#endif
|
||||
#if defined(ARFMAG) || defined(AIAMAG)
|
||||
/* Advance member's time to that time */
|
||||
for (i = 0; i < sizeof ar_hdr.ar_date; i++)
|
||||
ar_hdr.ar_date[i] = ' ';
|
||||
sprintf (ar_hdr.ar_date, "%ld", (long int) statbuf.st_mtime);
|
||||
#ifdef AIAMAG
|
||||
ar_hdr.ar_date[strlen(ar_hdr.ar_date)] = ' ';
|
||||
#endif
|
||||
#else
|
||||
ar_hdr.ar_date = statbuf.st_mtime;
|
||||
#endif
|
||||
/* Write back this member's header */
|
||||
if (lseek (fd, pos, 0) < 0)
|
||||
goto lose;
|
||||
if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE))
|
||||
goto lose;
|
||||
close (fd);
|
||||
return 0;
|
||||
|
||||
lose:
|
||||
i = errno;
|
||||
close (fd);
|
||||
errno = i;
|
||||
return -3;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
long int
|
||||
describe_member (desc, name, truncated,
|
||||
hdrpos, datapos, size, date, uid, gid, mode)
|
||||
int desc;
|
||||
char *name;
|
||||
int truncated;
|
||||
long int hdrpos, datapos, size, date;
|
||||
int uid, gid, mode;
|
||||
{
|
||||
extern char *ctime ();
|
||||
|
||||
printf ("Member `%s'%s: %ld bytes at %ld (%ld).\n",
|
||||
name, truncated ? " (name might be truncated)" : "",
|
||||
size, hdrpos, datapos);
|
||||
printf (" Date %s", ctime (&date));
|
||||
printf (" uid = %d, gid = %d, mode = 0%o.\n", uid, gid, mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
ar_scan (argv[1], describe_member);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TEST. */
|
||||
|
||||
#endif /* NO_ARCHIVES. */
|
||||
@ -1,69 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Shell script to build GNU Make in the absence of any `make' program.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1993, 1994 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Make is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU Make; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# See Makefile.in for comments describing these variables.
|
||||
|
||||
srcdir='@srcdir@'
|
||||
CC='@CC@'
|
||||
CFLAGS='@CFLAGS@'
|
||||
CPPFLAGS='@CPPFLAGS@'
|
||||
LDFLAGS='@LDFLAGS@'
|
||||
defines='@DEFS@ -DLIBDIR="${libdir}" -DINCLUDEDIR="${includedir}"'
|
||||
ALLOCA='@ALLOCA@'
|
||||
LOADLIBES='@LIBS@'
|
||||
extras='@LIBOBJS@'
|
||||
REMOTE='@REMOTE@'
|
||||
|
||||
# Common prefix for machine-independent installed files.
|
||||
prefix='@prefix@'
|
||||
# Common prefix for machine-dependent installed files.
|
||||
exec_prefix='@exec_prefix@'
|
||||
# Directory to find libraries in for `-lXXX'.
|
||||
libdir=${exec_prefix}/lib
|
||||
# Directory to search by default for included makefiles.
|
||||
includedir=${prefix}/include
|
||||
|
||||
# Exit as soon as any command fails.
|
||||
set -e
|
||||
|
||||
# These are all the objects we need to link together.
|
||||
objs="commands.o job.o dir.o file.o misc.o main.o read.o remake.o rule.o implicit.o default.o variable.o expand.o function.o vpath.o version.o ar.o arscan.o signame.o getopt.o getopt1.o glob/glob.o glob/fnmatch.o remote-${REMOTE}.o ${extras} ${ALLOCA}"
|
||||
|
||||
# Compile the source files into those objects.
|
||||
for file in `echo ${objs} | sed 's/\.o/.c/g'`; do
|
||||
echo compiling ${file}...
|
||||
$CC $defines $CPPFLAGS $CFLAGS \
|
||||
-c -I. -I${srcdir} -I${srcdir}/glob ${srcdir}/$file
|
||||
done
|
||||
|
||||
# The object files were actually all put in the current directory.
|
||||
# Remove the source directory names from the list.
|
||||
srcobjs="$objs"
|
||||
objs=
|
||||
for obj in $srcobjs; do
|
||||
objs="$objs `basename $obj`"
|
||||
done
|
||||
|
||||
# Link all the objects together.
|
||||
echo linking make...
|
||||
$CC $LDFLAGS $objs $LOADLIBES -o make.new
|
||||
echo done
|
||||
mv -f make.new make
|
||||
@ -1,521 +0,0 @@
|
||||
/* Command processing for GNU Make.
|
||||
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "dep.h"
|
||||
#include "commands.h"
|
||||
#include "file.h"
|
||||
#include "variable.h"
|
||||
#include "job.h"
|
||||
|
||||
extern int remote_kill ();
|
||||
|
||||
#ifndef HAVE_UNISTD_H
|
||||
extern int getpid ();
|
||||
#endif
|
||||
|
||||
/* Set FILE's automatic variables up. */
|
||||
|
||||
static void
|
||||
set_file_variables (file)
|
||||
register struct file *file;
|
||||
{
|
||||
// register char *p;
|
||||
char *at, *percent, *star, *less;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
/* If the target is an archive member `lib(member)',
|
||||
then $@ is `lib' and $% is `member'. */
|
||||
|
||||
if (ar_name (file->name))
|
||||
{
|
||||
unsigned int len;
|
||||
p = index (file->name, '(');
|
||||
at = (char *) alloca (p - file->name + 1);
|
||||
bcopy (file->name, at, p - file->name);
|
||||
at[p - file->name] = '\0';
|
||||
len = strlen (p + 1);
|
||||
percent = (char *) alloca (len);
|
||||
bcopy (p + 1, percent, len - 1);
|
||||
percent[len - 1] = '\0';
|
||||
}
|
||||
else
|
||||
#endif /* NO_ARCHIVES. */
|
||||
{
|
||||
at = file->name;
|
||||
percent = "";
|
||||
}
|
||||
|
||||
/* $* is the stem from an implicit or static pattern rule. */
|
||||
if (file->stem == 0)
|
||||
{
|
||||
/* In Unix make, $* is set to the target name with
|
||||
any suffix in the .SUFFIXES list stripped off for
|
||||
explicit rules. We store this in the `stem' member. */
|
||||
register struct dep *d;
|
||||
char *name;
|
||||
unsigned int len;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (file->name))
|
||||
{
|
||||
name = index (file->name, '(') + 1;
|
||||
len = strlen (name) - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
name = file->name;
|
||||
len = strlen (name);
|
||||
}
|
||||
|
||||
for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next)
|
||||
{
|
||||
unsigned int slen = strlen (dep_name (d));
|
||||
if (len > slen && !strncmp (dep_name (d), name + (len - slen), slen))
|
||||
{
|
||||
file->stem = savestring (name, len - slen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d == 0)
|
||||
file->stem = "";
|
||||
}
|
||||
star = file->stem;
|
||||
|
||||
/* $< is the first dependency. */
|
||||
less = file->deps != 0 ? dep_name (file->deps) : "";
|
||||
|
||||
if (file->cmds == default_file->cmds)
|
||||
/* This file got its commands from .DEFAULT.
|
||||
In this case $< is the same as $@. */
|
||||
less = at;
|
||||
|
||||
#define DEFINE_VARIABLE(name, len, value) \
|
||||
(void) define_variable_for_file (name, len, value, o_automatic, 0, file)
|
||||
|
||||
/* Define the variables. */
|
||||
|
||||
DEFINE_VARIABLE ("<", 1, less);
|
||||
DEFINE_VARIABLE ("*", 1, star);
|
||||
DEFINE_VARIABLE ("@", 1, at);
|
||||
DEFINE_VARIABLE ("%", 1, percent);
|
||||
|
||||
/* Compute the values for $^, $+, and $?. */
|
||||
|
||||
{
|
||||
register unsigned int qmark_len, plus_len;
|
||||
char *caret_value, *plus_value;
|
||||
register char *cp;
|
||||
char *qmark_value;
|
||||
register char *qp;
|
||||
register struct dep *d;
|
||||
unsigned int len;
|
||||
|
||||
/* Compute first the value for $+, which is supposed to contain
|
||||
duplicate dependencies as they were listed in the makefile. */
|
||||
|
||||
plus_len = 0;
|
||||
for (d = file->deps; d != 0; d = d->next)
|
||||
plus_len += strlen (dep_name (d)) + 1;
|
||||
|
||||
len = plus_len == 0 ? 1 : plus_len;
|
||||
cp = plus_value = (char *) alloca (len);
|
||||
|
||||
qmark_len = plus_len; /* Will be this or less. */
|
||||
for (d = file->deps; d != 0; d = d->next)
|
||||
{
|
||||
char *c = dep_name (d);
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (c))
|
||||
{
|
||||
c = index (c, '(') + 1;
|
||||
len = strlen (c) - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
len = strlen (c);
|
||||
|
||||
bcopy (c, cp, len);
|
||||
cp += len;
|
||||
*cp++ = ' ';
|
||||
|
||||
if (! d->changed)
|
||||
qmark_len -= len + 1; /* Don't space in $? for this one. */
|
||||
}
|
||||
|
||||
/* Kill the last space and define the variable. */
|
||||
|
||||
cp[cp > plus_value ? -1 : 0] = '\0';
|
||||
DEFINE_VARIABLE ("+", 1, plus_value);
|
||||
|
||||
/* Make sure that no dependencies are repeated. This does not
|
||||
really matter for the purpose of updating targets, but it
|
||||
might make some names be listed twice for $^ and $?. */
|
||||
|
||||
uniquize_deps (file->deps);
|
||||
|
||||
/* Compute the values for $^ and $?. */
|
||||
|
||||
cp = caret_value = plus_value; /* Reuse the buffer; it's big enough. */
|
||||
len = qmark_len == 0 ? 1 : qmark_len;
|
||||
qp = qmark_value = (char *) alloca (len);
|
||||
|
||||
for (d = file->deps; d != 0; d = d->next)
|
||||
{
|
||||
char *c = dep_name (d);
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (c))
|
||||
{
|
||||
c = index (c, '(') + 1;
|
||||
len = strlen (c) - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
len = strlen (c);
|
||||
|
||||
bcopy (c, cp, len);
|
||||
cp += len;
|
||||
*cp++ = ' ';
|
||||
|
||||
if (d->changed)
|
||||
{
|
||||
bcopy (c, qp, len);
|
||||
qp += len;
|
||||
*qp++ = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
/* Kill the last spaces and define the variables. */
|
||||
|
||||
cp[cp > caret_value ? -1 : 0] = '\0';
|
||||
DEFINE_VARIABLE ("^", 1, caret_value);
|
||||
|
||||
qp[qp > qmark_value ? -1 : 0] = '\0';
|
||||
DEFINE_VARIABLE ("?", 1, qmark_value);
|
||||
}
|
||||
|
||||
#undef DEFINE_VARIABLE
|
||||
}
|
||||
|
||||
/* Chop CMDS up into individual command lines if necessary.
|
||||
Also set the `lines_flag' and `any_recurse' members. */
|
||||
|
||||
void
|
||||
chop_commands (cmds)
|
||||
register struct commands *cmds;
|
||||
{
|
||||
if (cmds != 0 && cmds->command_lines == 0)
|
||||
{
|
||||
/* Chop CMDS->commands up into lines in CMDS->command_lines.
|
||||
Also set the corresponding CMDS->lines_flags elements,
|
||||
and the CMDS->any_recurse flag. */
|
||||
register char *p;
|
||||
unsigned int nlines, idx;
|
||||
char **lines;
|
||||
|
||||
nlines = 5;
|
||||
lines = (char **) xmalloc (5 * sizeof (char *));
|
||||
idx = 0;
|
||||
p = cmds->commands;
|
||||
while (*p != '\0')
|
||||
{
|
||||
char *end = p;
|
||||
find_end:;
|
||||
end = index (end, '\n');
|
||||
if (end == 0)
|
||||
end = p + strlen (p);
|
||||
else if (end > p && end[-1] == '\\')
|
||||
{
|
||||
int backslash = 1;
|
||||
register char *b;
|
||||
for (b = end - 2; b >= p && *b == '\\'; --b)
|
||||
backslash = !backslash;
|
||||
if (backslash)
|
||||
{
|
||||
++end;
|
||||
goto find_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == nlines)
|
||||
{
|
||||
nlines += 2;
|
||||
lines = (char **) xrealloc ((char *) lines,
|
||||
nlines * sizeof (char *));
|
||||
}
|
||||
lines[idx++] = savestring (p, end - p);
|
||||
p = end;
|
||||
if (*p != '\0')
|
||||
++p;
|
||||
}
|
||||
|
||||
if (idx != nlines)
|
||||
{
|
||||
nlines = idx;
|
||||
lines = (char **) xrealloc ((char *) lines,
|
||||
nlines * sizeof (char *));
|
||||
}
|
||||
|
||||
cmds->ncommand_lines = nlines;
|
||||
cmds->command_lines = lines;
|
||||
|
||||
cmds->any_recurse = 0;
|
||||
cmds->lines_flags = (char *) xmalloc (nlines);
|
||||
for (idx = 0; idx < nlines; ++idx)
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
for (p = lines[idx];
|
||||
isblank (*p) || *p == '-' || *p == '@' || *p == '+';
|
||||
++p)
|
||||
switch (*p)
|
||||
{
|
||||
case '+':
|
||||
flags |= COMMANDS_RECURSE;
|
||||
break;
|
||||
case '@':
|
||||
flags |= COMMANDS_SILENT;
|
||||
break;
|
||||
case '-':
|
||||
flags |= COMMANDS_NOERROR;
|
||||
break;
|
||||
}
|
||||
if (!(flags & COMMANDS_RECURSE))
|
||||
{
|
||||
unsigned int len = strlen (p);
|
||||
if (sindex (p, len, "$(MAKE)", 7) != 0
|
||||
|| sindex (p, len, "${MAKE}", 7) != 0)
|
||||
flags |= COMMANDS_RECURSE;
|
||||
}
|
||||
|
||||
cmds->lines_flags[idx] = flags;
|
||||
cmds->any_recurse |= flags & COMMANDS_RECURSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Execute the commands to remake FILE. If they are currently executing,
|
||||
return or have already finished executing, just return. Otherwise,
|
||||
fork off a child process to run the first command line in the sequence. */
|
||||
|
||||
void
|
||||
execute_file_commands (file)
|
||||
struct file *file;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
/* Don't go through all the preparations if
|
||||
the commands are nothing but whitespace. */
|
||||
|
||||
for (p = file->cmds->commands; *p != '\0'; ++p)
|
||||
if (!isspace (*p) && *p != '-' && *p != '@')
|
||||
break;
|
||||
if (*p == '\0')
|
||||
{
|
||||
/* We are all out of commands.
|
||||
If we have gotten this far, all the previous commands
|
||||
have run successfully, so we have winning update status. */
|
||||
file->update_status = 0;
|
||||
notice_finished_file (file);
|
||||
return;
|
||||
}
|
||||
|
||||
/* First set the automatic variables according to this file. */
|
||||
|
||||
initialize_file_variables (file);
|
||||
|
||||
set_file_variables (file);
|
||||
|
||||
/* Start the commands running. */
|
||||
new_job (file);
|
||||
}
|
||||
|
||||
/* This is set while we are inside fatal_error_signal,
|
||||
so things can avoid nonreentrant operations. */
|
||||
|
||||
int handling_fatal_signal = 0;
|
||||
|
||||
/* Handle fatal signals. */
|
||||
|
||||
RETSIGTYPE
|
||||
fatal_error_signal (sig)
|
||||
int sig;
|
||||
{
|
||||
#if defined(__MSDOS__) || defined(NETSCAPE)
|
||||
remove_intermediates (1);
|
||||
exit (1);
|
||||
#else /* Not MSDOS. */
|
||||
handling_fatal_signal = 1;
|
||||
|
||||
/* Set the handling for this signal to the default.
|
||||
It is blocked now while we run this handler. */
|
||||
signal (sig, SIG_DFL);
|
||||
|
||||
/* A termination signal won't be sent to the entire
|
||||
process group, but it means we want to kill the children. */
|
||||
|
||||
if (sig == SIGTERM)
|
||||
{
|
||||
register struct child *c;
|
||||
for (c = children; c != 0; c = c->next)
|
||||
if (!c->remote)
|
||||
(void) kill (c->pid, SIGTERM);
|
||||
}
|
||||
|
||||
/* If we got a signal that means the user
|
||||
wanted to kill make, remove pending targets. */
|
||||
|
||||
if (sig == SIGTERM || sig == SIGINT || sig == SIGHUP || sig == SIGQUIT)
|
||||
{
|
||||
register struct child *c;
|
||||
|
||||
/* Remote children won't automatically get signals sent
|
||||
to the process group, so we must send them. */
|
||||
for (c = children; c != 0; c = c->next)
|
||||
if (c->remote)
|
||||
(void) remote_kill (c->pid, sig);
|
||||
|
||||
for (c = children; c != 0; c = c->next)
|
||||
delete_child_targets (c);
|
||||
|
||||
/* Clean up the children. We don't just use the call below because
|
||||
we don't want to print the "Waiting for children" message. */
|
||||
while (job_slots_used > 0)
|
||||
reap_children (1, 0);
|
||||
}
|
||||
else
|
||||
/* Wait for our children to die. */
|
||||
while (job_slots_used > 0)
|
||||
reap_children (1, 1);
|
||||
|
||||
/* Delete any non-precious intermediate files that were made. */
|
||||
|
||||
remove_intermediates (1);
|
||||
|
||||
if (sig == SIGQUIT)
|
||||
/* We don't want to send ourselves SIGQUIT, because it will
|
||||
cause a core dump. Just exit instead. */
|
||||
exit (1);
|
||||
|
||||
/* Signal the same code; this time it will really be fatal. The signal
|
||||
will be unblocked when we return and arrive then to kill us. */
|
||||
if (kill (getpid (), sig) < 0)
|
||||
pfatal_with_name ("kill");
|
||||
#endif /* MSDOS. */
|
||||
}
|
||||
|
||||
/* Delete FILE unless it's precious or not actually a file (phony),
|
||||
and it has changed on disk since we last stat'd it. */
|
||||
|
||||
static void
|
||||
delete_target (file, on_behalf_of)
|
||||
struct file *file;
|
||||
char *on_behalf_of;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (file->precious || file->phony)
|
||||
return;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (file->name))
|
||||
{
|
||||
if (ar_member_date (file->name) != file->last_mtime)
|
||||
{
|
||||
if (on_behalf_of)
|
||||
error ("*** [%s] Archive member `%s' may be bogus; not deleted",
|
||||
on_behalf_of, file->name);
|
||||
else
|
||||
error ("*** Archive member `%s' may be bogus; not deleted",
|
||||
file->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (safe_stat (file->name, &st) == 0
|
||||
&& S_ISREG (st.st_mode)
|
||||
&& (time_t) st.st_mtime != file->last_mtime)
|
||||
{
|
||||
if (on_behalf_of)
|
||||
error ("*** [%s] Deleting file `%s'", on_behalf_of, file->name);
|
||||
else
|
||||
error ("*** Deleting file `%s'", file->name);
|
||||
if (unlink (file->name) < 0)
|
||||
perror_with_name ("unlink: ", file->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Delete all non-precious targets of CHILD unless they were already deleted.
|
||||
Set the flag in CHILD to say they've been deleted. */
|
||||
|
||||
void
|
||||
delete_child_targets (child)
|
||||
struct child *child;
|
||||
{
|
||||
struct dep *d;
|
||||
|
||||
if (child->deleted)
|
||||
return;
|
||||
|
||||
/* Delete the target file if it changed. */
|
||||
delete_target (child->file, (char *) 0);
|
||||
|
||||
/* Also remove any non-precious targets listed in the `also_make' member. */
|
||||
for (d = child->file->also_make; d != 0; d = d->next)
|
||||
delete_target (d->file, child->file->name);
|
||||
|
||||
child->deleted = 1;
|
||||
}
|
||||
|
||||
/* Print out the commands in CMDS. */
|
||||
|
||||
void
|
||||
print_commands (cmds)
|
||||
register struct commands *cmds;
|
||||
{
|
||||
register char *s;
|
||||
|
||||
fputs ("# commands to execute", stdout);
|
||||
|
||||
if (cmds->filename == 0)
|
||||
puts (" (built-in):");
|
||||
else
|
||||
printf (" (from `%s', line %u):\n", cmds->filename, cmds->lineno);
|
||||
|
||||
s = cmds->commands;
|
||||
while (*s != '\0')
|
||||
{
|
||||
char *end;
|
||||
|
||||
while (isspace (*s))
|
||||
++s;
|
||||
|
||||
end = index (s, '\n');
|
||||
if (end == 0)
|
||||
end = s + strlen (s);
|
||||
|
||||
printf ("\t%.*s\n", (int) (end - s), s);
|
||||
|
||||
s = end;
|
||||
}
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
/* Definition of data structures describing shell commands for GNU Make.
|
||||
Copyright (C) 1988, 1989, 1991, 1993 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Structure that gives the commands to make a file
|
||||
and information about where these commands came from. */
|
||||
|
||||
struct commands
|
||||
{
|
||||
char *filename; /* File that contains commands. */
|
||||
unsigned int lineno; /* Line number in file. */
|
||||
char *commands; /* Commands text. */
|
||||
unsigned int ncommand_lines;/* Number of command lines. */
|
||||
char **command_lines; /* Commands chopped up into lines. */
|
||||
char *lines_flags; /* One set of flag bits for each line. */
|
||||
int any_recurse; /* Nonzero if any `lines_recurse' elt has */
|
||||
/* the COMMANDS_RECURSE bit set. */
|
||||
};
|
||||
|
||||
/* Bits in `lines_flags'. */
|
||||
#define COMMANDS_RECURSE 1 /* Recurses: + or $(MAKE). */
|
||||
#define COMMANDS_SILENT 2 /* Silent: @. */
|
||||
#define COMMANDS_NOERROR 4 /* No errors: -. */
|
||||
|
||||
extern void execute_file_commands ();
|
||||
extern void print_commands ();
|
||||
extern void delete_child_targets ();
|
||||
extern void chop_commands ();
|
||||
@ -1,275 +0,0 @@
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
#undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||
This function is required for alloca.c support on those systems. */
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define for DGUX with <sys/dg_sys_info.h>. */
|
||||
#undef DGUX
|
||||
|
||||
/* Define if the `getloadavg' function needs to be run setuid or setgid. */
|
||||
#undef GETLOADAVG_PRIVILEGED
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#define gid_t
|
||||
|
||||
/* Define if you have alloca, as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define if your system has its own `getloadavg' function. */
|
||||
#undef HAVE_GETLOADAVG
|
||||
|
||||
/* Define if you have the getmntent function. */
|
||||
#undef HAVE_GETMNTENT
|
||||
|
||||
/* Define if the `long double' type works. */
|
||||
#undef HAVE_LONG_DOUBLE
|
||||
|
||||
/* Define if you support file names longer than 14 characters. */
|
||||
#define HAVE_LONG_FILE_NAMES
|
||||
|
||||
/* Define if you have a working `mmap' system call. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if system calls automatically restart after interruption
|
||||
by a signal. */
|
||||
#undef HAVE_RESTARTABLE_SYSCALLS
|
||||
|
||||
/* Define if your struct stat has st_blksize. */
|
||||
#undef HAVE_ST_BLKSIZE
|
||||
|
||||
/* Define if your struct stat has st_blocks. */
|
||||
#undef HAVE_ST_BLOCKS
|
||||
|
||||
/* Define if you have the strcoll function and it is properly defined. */
|
||||
#undef HAVE_STRCOLL
|
||||
|
||||
/* Define if your struct stat has st_rdev. */
|
||||
#undef HAVE_ST_RDEV
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#define HAVE_STRFTIME
|
||||
|
||||
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if your struct tm has tm_zone. */
|
||||
#undef HAVE_TM_ZONE
|
||||
|
||||
/* Define if you don't have tm_zone but do have the external array
|
||||
tzname. */
|
||||
#define HAVE_TZNAME
|
||||
|
||||
/* Define if you have <unistd.h>. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if utime(file, NULL) sets file's timestamp to the present. */
|
||||
#define HAVE_UTIME_NULL
|
||||
|
||||
/* Define if you have <vfork.h>. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define if you have the wait3 system call. */
|
||||
#undef HAVE_WAIT3
|
||||
|
||||
/* Define if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define if your struct nlist has an n_un member. */
|
||||
#undef NLIST_NAME_UNION
|
||||
|
||||
/* Define if you have <nlist.h>. */
|
||||
#undef NLIST_STRUCT
|
||||
|
||||
/* Define if your C compiler doesn't accept -c and -o together. */
|
||||
#define NO_MINUS_C_MINUS_O
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#define pid_t int
|
||||
|
||||
/* Define if the system does not provide POSIX.1 features except
|
||||
with this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* Define if the setvbuf function takes the buffering type as its second
|
||||
argument and the buffer pointer as the third, as on System V
|
||||
before release 3. */
|
||||
#undef SETVBUF_REVERSED
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
#define STAT_MACROS_BROKEN
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS
|
||||
|
||||
/* Define on System V Release 4. */
|
||||
#undef SVR4
|
||||
|
||||
/* Define if `sys_siglist' is declared by <signal.h>. */
|
||||
#undef SYS_SIGLIST_DECLARED
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#define uid_t int
|
||||
|
||||
/* Define for Encore UMAX. */
|
||||
#undef UMAX
|
||||
|
||||
/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
|
||||
instead of <sys/cpustats.h>. */
|
||||
#undef UMAX4_3
|
||||
|
||||
/* Define vfork as fork if vfork does not work. */
|
||||
#undef vfork
|
||||
|
||||
/* Define to the name of the SCCS `get' command. */
|
||||
#define SCCS_GET "get"
|
||||
|
||||
/* Define this if the SCCS `get' command understands the `-G<file>' option. */
|
||||
#undef SCCS_GET_MINUS_G
|
||||
|
||||
/* Define this if the C library defines the variable `sys_siglist'. */
|
||||
#undef HAVE_SYS_SIGLIST
|
||||
|
||||
/* Define this if the C library defines the variable `_sys_siglist'. */
|
||||
#undef HAVE__SYS_SIGLIST
|
||||
|
||||
/* Define this if you have the `union wait' type in <sys/wait.h>. */
|
||||
#undef HAVE_UNION_WAIT
|
||||
|
||||
/* Define this if the POSIX.1 call `sysconf (_SC_OPEN_MAX)' works properly. */
|
||||
#undef HAVE_SYSCONF_OPEN_MAX
|
||||
|
||||
/* Define if you have the dup2 function. */
|
||||
#undef HAVE_DUP2
|
||||
|
||||
/* Define if you have the getcwd function. */
|
||||
#define HAVE_GETCWD
|
||||
|
||||
/* Define if you have the getdtablesize function. */
|
||||
#undef HAVE_GETDTABLESIZE
|
||||
|
||||
/* Define if you have the getgroups function. */
|
||||
#undef HAVE_GETGROUPS
|
||||
|
||||
/* Define if you have the mktemp function. */
|
||||
#undef HAVE_MKTEMP
|
||||
|
||||
/* Define if you have the psignal function. */
|
||||
#undef HAVE_PSIGNAL
|
||||
|
||||
/* Define if you have the setegid function. */
|
||||
#undef HAVE_SETEGID
|
||||
|
||||
/* Define if you have the seteuid function. */
|
||||
#undef HAVE_SETEUID
|
||||
|
||||
/* Define if you have the setlinebuf function. */
|
||||
#undef HAVE_SETLINEBUF
|
||||
|
||||
/* Define if you have the setregid function. */
|
||||
#undef HAVE_SETREGID
|
||||
|
||||
/* Define if you have the setreuid function. */
|
||||
#undef HAVE_SETREUID
|
||||
|
||||
/* Define if you have the sigsetmask function. */
|
||||
#undef HAVE_SIGSETMASK
|
||||
|
||||
/* Define if you have the strerror function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define if you have the strsignal function. */
|
||||
#undef HAVE_STRSIGNAL
|
||||
|
||||
/* Define if you have the wait3 function. */
|
||||
#undef HAVE_WAIT3
|
||||
|
||||
/* Define if you have the waitpid function. */
|
||||
#undef HAVE_WAITPID
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define if you have the <mach/mach.h> header file. */
|
||||
#undef HAVE_MACH_MACH_H
|
||||
|
||||
/* Define if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H
|
||||
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define if you have the <sys/timeb.h> header file. */
|
||||
#undef HAVE_SYS_TIMEB_H
|
||||
|
||||
/* Define if you have the <sys/wait.h> header file. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if you have the dgc library (-ldgc). */
|
||||
#undef HAVE_LIBDGC
|
||||
|
||||
/* Define if you have the sun library (-lsun). */
|
||||
#undef HAVE_LIBSUN
|
||||
|
||||
/* NETSCAPE: Under win32, define default libdir */
|
||||
#define LIBDIR "\\msvc20\\lib"
|
||||
#define NO_ARCHIVES
|
||||
#define HAVE_GLOB_H
|
||||
@ -1,270 +0,0 @@
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
#undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||
This function is required for alloca.c support on those systems. */
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define for DGUX with <sys/dg_sys_info.h>. */
|
||||
#undef DGUX
|
||||
|
||||
/* Define if the `getloadavg' function needs to be run setuid or setgid. */
|
||||
#undef GETLOADAVG_PRIVILEGED
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef gid_t
|
||||
|
||||
/* Define if you have alloca, as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define if your system has its own `getloadavg' function. */
|
||||
#undef HAVE_GETLOADAVG
|
||||
|
||||
/* Define if you have the getmntent function. */
|
||||
#undef HAVE_GETMNTENT
|
||||
|
||||
/* Define if the `long double' type works. */
|
||||
#undef HAVE_LONG_DOUBLE
|
||||
|
||||
/* Define if you support file names longer than 14 characters. */
|
||||
#undef HAVE_LONG_FILE_NAMES
|
||||
|
||||
/* Define if you have a working `mmap' system call. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if system calls automatically restart after interruption
|
||||
by a signal. */
|
||||
#undef HAVE_RESTARTABLE_SYSCALLS
|
||||
|
||||
/* Define if your struct stat has st_blksize. */
|
||||
#undef HAVE_ST_BLKSIZE
|
||||
|
||||
/* Define if your struct stat has st_blocks. */
|
||||
#undef HAVE_ST_BLOCKS
|
||||
|
||||
/* Define if you have the strcoll function and it is properly defined. */
|
||||
#undef HAVE_STRCOLL
|
||||
|
||||
/* Define if your struct stat has st_rdev. */
|
||||
#undef HAVE_ST_RDEV
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if your struct tm has tm_zone. */
|
||||
#undef HAVE_TM_ZONE
|
||||
|
||||
/* Define if you don't have tm_zone but do have the external array
|
||||
tzname. */
|
||||
#undef HAVE_TZNAME
|
||||
|
||||
/* Define if you have <unistd.h>. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if utime(file, NULL) sets file's timestamp to the present. */
|
||||
#undef HAVE_UTIME_NULL
|
||||
|
||||
/* Define if you have <vfork.h>. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define if you have the wait3 system call. */
|
||||
#undef HAVE_WAIT3
|
||||
|
||||
/* Define if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define if your struct nlist has an n_un member. */
|
||||
#undef NLIST_NAME_UNION
|
||||
|
||||
/* Define if you have <nlist.h>. */
|
||||
#undef NLIST_STRUCT
|
||||
|
||||
/* Define if your C compiler doesn't accept -c and -o together. */
|
||||
#undef NO_MINUS_C_MINUS_O
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define if the system does not provide POSIX.1 features except
|
||||
with this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* Define if the setvbuf function takes the buffering type as its second
|
||||
argument and the buffer pointer as the third, as on System V
|
||||
before release 3. */
|
||||
#undef SETVBUF_REVERSED
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
#undef STAT_MACROS_BROKEN
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define on System V Release 4. */
|
||||
#undef SVR4
|
||||
|
||||
/* Define if `sys_siglist' is declared by <signal.h>. */
|
||||
#undef SYS_SIGLIST_DECLARED
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef uid_t
|
||||
|
||||
/* Define for Encore UMAX. */
|
||||
#undef UMAX
|
||||
|
||||
/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
|
||||
instead of <sys/cpustats.h>. */
|
||||
#undef UMAX4_3
|
||||
|
||||
/* Define vfork as fork if vfork does not work. */
|
||||
#undef vfork
|
||||
|
||||
/* Define to the name of the SCCS `get' command. */
|
||||
#undef SCCS_GET
|
||||
|
||||
/* Define this if the SCCS `get' command understands the `-G<file>' option. */
|
||||
#undef SCCS_GET_MINUS_G
|
||||
|
||||
/* Define this if the C library defines the variable `sys_siglist'. */
|
||||
#undef HAVE_SYS_SIGLIST
|
||||
|
||||
/* Define this if the C library defines the variable `_sys_siglist'. */
|
||||
#undef HAVE__SYS_SIGLIST
|
||||
|
||||
/* Define this if you have the `union wait' type in <sys/wait.h>. */
|
||||
#undef HAVE_UNION_WAIT
|
||||
|
||||
/* Define this if the POSIX.1 call `sysconf (_SC_OPEN_MAX)' works properly. */
|
||||
#undef HAVE_SYSCONF_OPEN_MAX
|
||||
|
||||
/* Define if you have the dup2 function. */
|
||||
#undef HAVE_DUP2
|
||||
|
||||
/* Define if you have the getcwd function. */
|
||||
#undef HAVE_GETCWD
|
||||
|
||||
/* Define if you have the getdtablesize function. */
|
||||
#undef HAVE_GETDTABLESIZE
|
||||
|
||||
/* Define if you have the getgroups function. */
|
||||
#undef HAVE_GETGROUPS
|
||||
|
||||
/* Define if you have the mktemp function. */
|
||||
#undef HAVE_MKTEMP
|
||||
|
||||
/* Define if you have the psignal function. */
|
||||
#undef HAVE_PSIGNAL
|
||||
|
||||
/* Define if you have the setegid function. */
|
||||
#undef HAVE_SETEGID
|
||||
|
||||
/* Define if you have the seteuid function. */
|
||||
#undef HAVE_SETEUID
|
||||
|
||||
/* Define if you have the setlinebuf function. */
|
||||
#undef HAVE_SETLINEBUF
|
||||
|
||||
/* Define if you have the setregid function. */
|
||||
#undef HAVE_SETREGID
|
||||
|
||||
/* Define if you have the setreuid function. */
|
||||
#undef HAVE_SETREUID
|
||||
|
||||
/* Define if you have the sigsetmask function. */
|
||||
#undef HAVE_SIGSETMASK
|
||||
|
||||
/* Define if you have the strerror function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define if you have the strsignal function. */
|
||||
#undef HAVE_STRSIGNAL
|
||||
|
||||
/* Define if you have the wait3 function. */
|
||||
#undef HAVE_WAIT3
|
||||
|
||||
/* Define if you have the waitpid function. */
|
||||
#undef HAVE_WAITPID
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define if you have the <mach/mach.h> header file. */
|
||||
#undef HAVE_MACH_MACH_H
|
||||
|
||||
/* Define if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define if you have the <sys/timeb.h> header file. */
|
||||
#undef HAVE_SYS_TIMEB_H
|
||||
|
||||
/* Define if you have the <sys/wait.h> header file. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if you have the dgc library (-ldgc). */
|
||||
#undef HAVE_LIBDGC
|
||||
|
||||
/* Define if you have the sun library (-lsun). */
|
||||
#undef HAVE_LIBSUN
|
||||
@ -1,136 +0,0 @@
|
||||
/* Generated automatically from configure.in by autoheader. DO NOT EDIT! */
|
||||
|
||||
|
||||
|
||||
#define INCLUDEDIR "c:/djgpp/include"
|
||||
|
||||
#define LIBDIR "c:/djgpp/lib"
|
||||
|
||||
|
||||
|
||||
/* Define if you have dirent.h. */
|
||||
|
||||
#define DIRENT
|
||||
|
||||
|
||||
|
||||
/* Define if you have the strcoll function and it is properly defined. */
|
||||
|
||||
#define HAVE_STRCOLL
|
||||
|
||||
|
||||
|
||||
/* Define if you have unistd.h. */
|
||||
|
||||
#define HAVE_UNISTD_H
|
||||
|
||||
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
|
||||
#define RETSIGTYPE void
|
||||
|
||||
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
|
||||
#ifndef STDC_HEADERS
|
||||
|
||||
#define STDC_HEADERS
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Define if `sys_siglist' is declared by <signal.h>. */
|
||||
|
||||
#define SYS_SIGLIST_DECLARED
|
||||
|
||||
|
||||
|
||||
/* Define if you have getdtablesize. */
|
||||
|
||||
#define HAVE_GETDTABLESIZE
|
||||
|
||||
|
||||
|
||||
/* Define if you have dup2. */
|
||||
|
||||
#define HAVE_DUP2
|
||||
|
||||
|
||||
|
||||
/* Define if you have sys_siglist. */
|
||||
|
||||
#undef HAVE_SYS_SIGLIST
|
||||
|
||||
|
||||
|
||||
/* Define if you have _sys_siglist. */
|
||||
|
||||
#undef HAVE__SYS_SIGLIST
|
||||
|
||||
|
||||
|
||||
/* Define if you have psignal. */
|
||||
|
||||
#define HAVE_PSIGNAL
|
||||
|
||||
|
||||
|
||||
/* Define if you have getcwd. */
|
||||
|
||||
#define HAVE_GETCWD
|
||||
|
||||
|
||||
|
||||
/* Define if you have sigsetmask. */
|
||||
|
||||
#define HAVE_SIGSETMASK
|
||||
|
||||
|
||||
|
||||
/* Define if you have setlinebuf. */
|
||||
|
||||
#define HAVE_SETLINEBUF
|
||||
|
||||
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
|
||||
#define HAVE_LIMITS_H
|
||||
|
||||
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
|
||||
#define HAVE_FCNTL_H
|
||||
|
||||
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
|
||||
#define HAVE_STRING_H
|
||||
|
||||
|
||||
|
||||
/* Define if you have the <memory.h> header file. */
|
||||
|
||||
#define HAVE_MEMORY_H
|
||||
|
||||
|
||||
|
||||
/* Define if you have the `strerror' function. */
|
||||
|
||||
#define HAVE_STRERROR
|
||||
|
||||
|
||||
|
||||
#define SCCS_GET "get"
|
||||
|
||||
2991
buildtools/windows/source/make/configure
vendored
2991
buildtools/windows/source/make/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -1,88 +0,0 @@
|
||||
@echo off
|
||||
|
||||
echo Configuring MAKE for go32
|
||||
|
||||
rem This batch file assumes a unix-type "sed" program
|
||||
|
||||
|
||||
|
||||
update configh.dos config.h
|
||||
|
||||
|
||||
|
||||
echo # Makefile generated by "configure.bat"> Makefile
|
||||
|
||||
|
||||
|
||||
if exist config.sed del config.sed
|
||||
|
||||
|
||||
|
||||
echo ": try_sl ">> config.sed
|
||||
|
||||
echo "/\\$/ { ">> config.sed
|
||||
|
||||
echo " N ">> config.sed
|
||||
|
||||
echo " s/[ ]*\\\n[ ]*/ / ">> config.sed
|
||||
|
||||
echo " b try_sl ">> config.sed
|
||||
|
||||
echo "} ">> config.sed
|
||||
|
||||
|
||||
|
||||
echo "s/@srcdir@/./ ">> config.sed
|
||||
|
||||
echo "s/@CC@/gcc/ ">> config.sed
|
||||
|
||||
echo "s/@CFLAGS@/-O2 -g/ ">> config.sed
|
||||
|
||||
echo "s/@CPPFLAGS@/-DHAVE_CONFIG_H/ ">> config.sed
|
||||
|
||||
echo "s/@LDFLAGS@// ">> config.sed
|
||||
|
||||
echo "s/@RANLIB@/ranlib/ ">> config.sed
|
||||
|
||||
echo "s/@DEFS@// ">> config.sed
|
||||
|
||||
echo "s/@REMOTE@/stub/ ">> config.sed
|
||||
|
||||
echo "s/@ALLOCA@// ">> config.sed
|
||||
|
||||
echo "s/@LIBS@// ">> config.sed
|
||||
|
||||
echo "s/@LIBOBJS@// ">> config.sed
|
||||
|
||||
echo "s/@SET_MAKE@// ">> config.sed
|
||||
|
||||
echo "s/^Makefile *:/_Makefile:/ ">> config.sed
|
||||
|
||||
echo "s/^config.h *:/_config.h:/ ">> config.sed
|
||||
|
||||
echo "s/^defines *=.*$/defines =/ ">> config.sed
|
||||
|
||||
echo "/mv -f make.new make/d ">> config.sed
|
||||
|
||||
|
||||
|
||||
echo "s/cd glob; $(MAKE)/$(MAKE) -C glob/ ">> config.sed
|
||||
|
||||
|
||||
|
||||
sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
|
||||
|
||||
sed -f config2.sed Makefile.in >> Makefile
|
||||
|
||||
del config.sed
|
||||
|
||||
del config2.sed
|
||||
|
||||
|
||||
|
||||
cd glob
|
||||
|
||||
call configure
|
||||
|
||||
cd ..
|
||||
|
||||
@ -1,131 +0,0 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_REVISION([$Id: configure.in,v 1.1 1998-04-13 22:35:14 cyeh Exp $])
|
||||
AC_PREREQ(2.1)dnl dnl Minimum Autoconf version required.
|
||||
AC_INIT(vpath.c)dnl dnl A distinctive file to look for in srcdir.
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_SUBDIRS(glob) dnl Run configure in glob subdirectory.
|
||||
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_CPP dnl Later checks need this.
|
||||
AC_AIX
|
||||
AC_ISC_POSIX
|
||||
AC_MINIX
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_DIRENT
|
||||
AC_TYPE_UID_T dnl Also does gid_t.
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIGNAL
|
||||
AC_CHECK_HEADERS(unistd.h limits.h sys/param.h fcntl.h string.h memory.h \
|
||||
sys/timeb.h)
|
||||
AC_PROG_CC_C_O
|
||||
AC_C_CONST dnl getopt needs this.
|
||||
AC_HEADER_STAT
|
||||
|
||||
AC_SUBST(LIBOBJS)
|
||||
|
||||
AC_DEFUN(AC_CHECK_SYMBOL, [dnl
|
||||
AC_MSG_CHECKING(for $1)
|
||||
AC_CACHE_VAL(ac_cv_check_symbol_$1, [dnl
|
||||
AC_TRY_LINK(, [extern char *sys_siglist[]; puts(*sys_siglist);],
|
||||
ac_cv_check_symbol_$1=yes, ac_cv_check_symbol_$1=no)])
|
||||
if test "$ac_cv_check_symbol_$1" = yes; then
|
||||
changequote(,)dnl
|
||||
ac_tr_symbol=`echo $1 | tr '[a-z]' '[A-Z]'`
|
||||
changequote([,])dnl
|
||||
AC_DEFINE_UNQUOTED(HAVE_${ac_tr_symbol})
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_check_symbol_$1)])dnl
|
||||
|
||||
AC_CHECK_FUNCS(getdtablesize psignal mktemp \
|
||||
dup2 getcwd sigsetmask getgroups setlinebuf \
|
||||
seteuid setegid setreuid setregid strerror strsignal)
|
||||
AC_CHECK_SYMBOL(sys_siglist)
|
||||
AC_CHECK_SYMBOL(_sys_siglist)
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_VFORK
|
||||
AC_FUNC_SETVBUF_REVERSED
|
||||
AC_FUNC_GETLOADAVG
|
||||
AC_FUNC_STRCOLL
|
||||
|
||||
if test $ac_cv_func_getdtablesize = no; then
|
||||
AC_MSG_CHECKING(for sysconf (_SC_OPEN_MAX))
|
||||
AC_CACHE_VAL(make_cv_sysconf_open_max, [dnl
|
||||
AC_TRY_LINK([#include <unistd.h>], [int max = sysconf (_SC_OPEN_MAX);],
|
||||
[make_cv_sysconf_open_max=yes], [make_cv_sysconf_open_max=no])])
|
||||
if test $make_cv_sysconf_open_max = yes; then
|
||||
AC_DEFINE(HAVE_SYSCONF_OPEN_MAX)
|
||||
fi
|
||||
AC_MSG_RESULT($make_cv_sysconf_open_max)
|
||||
fi
|
||||
|
||||
# Check out the wait reality.
|
||||
AC_CHECK_HEADERS(sys/wait.h) AC_CHECK_FUNCS(waitpid wait3)
|
||||
AC_MSG_CHECKING(for union wait)
|
||||
AC_CACHE_VAL(make_cv_union_wait, [dnl
|
||||
AC_TRY_LINK([#include <sys/types.h>
|
||||
#include <sys/wait.h>],
|
||||
[union wait status; int pid; pid = wait (&status);
|
||||
#ifdef WEXITSTATUS
|
||||
/* Some POSIXoid systems have both the new-style macros and the old
|
||||
union wait type, and they do not work together. If union wait
|
||||
conflicts with WEXITSTATUS et al, we don't want to use it at all. */
|
||||
if (WEXITSTATUS (status) != 0) pid = -1;
|
||||
#ifdef WTERMSIG
|
||||
/* If we have WEXITSTATUS and WTERMSIG, just use them on ints. */
|
||||
-- blow chunks here --
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_WAITPID
|
||||
/* Make sure union wait works with waitpid. */
|
||||
pid = waitpid (-1, &status, 0);
|
||||
#endif
|
||||
],
|
||||
[make_cv_union_wait=yes], [make_cv_union_wait=no])])
|
||||
if test "$make_cv_union_wait" = yes; then
|
||||
AC_DEFINE(HAVE_UNION_WAIT)
|
||||
fi
|
||||
AC_MSG_RESULT($make_cv_union_wait)
|
||||
|
||||
AC_DECL_SYS_SIGLIST
|
||||
|
||||
# The presence of the following is not meant to imply
|
||||
# that make necessarily works on those systems.
|
||||
AC_CHECK_LIB(sun, getpwnam)
|
||||
|
||||
AC_SUBST(REMOTE) REMOTE=stub
|
||||
AC_ARG_WITH(customs, [export jobs with the Customs daemon (NOT SUPPORTED)],
|
||||
[REMOTE=cstms LIBS="$LIBS libcustoms.a"])
|
||||
|
||||
echo checking for location of SCCS get command
|
||||
if test -f /usr/sccs/get; then
|
||||
SCCS_GET=/usr/sccs/get
|
||||
AC_DEFINE(SCCS_GET, "/usr/sccs/get")
|
||||
else
|
||||
SCCS_GET=get
|
||||
AC_DEFINE(SCCS_GET, "get")
|
||||
fi
|
||||
ac_clean_files="$ac_clean_files s.conftest conftoast" # Remove these later.
|
||||
if ( /usr/sccs/admin -n s.conftest || admin -n s.conftest ) >/dev/null 2>&1 &&
|
||||
test -f s.conftest; then
|
||||
# We successfully created an SCCS file.
|
||||
echo checking if SCCS get command understands -G
|
||||
if $SCCS_GET -Gconftoast s.conftest >/dev/null 2>&1 &&
|
||||
test -f conftoast; then
|
||||
AC_DEFINE(SCCS_GET_MINUS_G)
|
||||
fi
|
||||
fi
|
||||
rm -f s.conftest conftoast
|
||||
|
||||
AC_OUTPUT(Makefile build.sh, [
|
||||
# Makefile uses this timestamp file to know when to remake Makefile,
|
||||
# build.sh, and glob/Makefile.
|
||||
touch stamp-config])
|
||||
|
||||
dnl Local Variables:
|
||||
dnl comment-start: "dnl "
|
||||
dnl comment-end: ""
|
||||
dnl comment-start-skip: "\\bdnl\\b\\s *"
|
||||
dnl compile-command: "make configure config.h.in"
|
||||
dnl End:
|
||||
@ -1,403 +0,0 @@
|
||||
/* Data base of default implicit rules for GNU Make.
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "rule.h"
|
||||
#include "dep.h"
|
||||
#include "file.h"
|
||||
#include "commands.h"
|
||||
#include "variable.h"
|
||||
|
||||
/* Define GCC_IS_NATIVE if gcc is the native development environment on
|
||||
your system (gcc/bison/flex vs cc/yacc/lex). */
|
||||
#ifdef __MSDOS__
|
||||
#define GCC_IS_NATIVE
|
||||
#endif
|
||||
|
||||
|
||||
/* This is the default list of suffixes for suffix rules.
|
||||
`.s' must come last, so that a `.o' file will be made from
|
||||
a `.c' or `.p' or ... file rather than from a .s file. */
|
||||
|
||||
static char default_suffixes[]
|
||||
= ".out .a .ln .o .c .cc .C .p .f .F .r .y .l .s .S \
|
||||
.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
|
||||
.w .ch .web .sh .elc .el";
|
||||
|
||||
static struct pspec default_pattern_rules[] =
|
||||
{
|
||||
{ "(%)", "%",
|
||||
"$(AR) $(ARFLAGS) $@ $<" },
|
||||
|
||||
/* The X.out rules are only in BSD's default set because
|
||||
BSD Make has no null-suffix rules, so `foo.out' and
|
||||
`foo' are the same thing. */
|
||||
{ "%.out", "%",
|
||||
"@rm -f $@ \n cp $< $@" },
|
||||
|
||||
/* Syntax is "ctangle foo.w foo.ch foo.c". */
|
||||
{ "%.c", "%.w %.ch",
|
||||
"$(CTANGLE) $^ $@" },
|
||||
{ "%.tex", "%.w %.ch",
|
||||
"$(CWEAVE) $^ $@" },
|
||||
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static struct pspec default_terminal_rules[] =
|
||||
{
|
||||
/* RCS. */
|
||||
{ "%", "%,v",
|
||||
"+$(CHECKOUT,v)" },
|
||||
{ "%", "RCS/%,v",
|
||||
"+$(CHECKOUT,v)" },
|
||||
|
||||
/* SCCS. */
|
||||
{ "%", "s.%",
|
||||
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
|
||||
{ "%", "SCCS/s.%",
|
||||
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
|
||||
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static char *default_suffix_rules[] =
|
||||
{
|
||||
".o",
|
||||
"$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".s",
|
||||
"$(LINK.s) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".S",
|
||||
"$(LINK.S) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".c",
|
||||
"$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".cc",
|
||||
"$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".C",
|
||||
"$(LINK.C) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".f",
|
||||
"$(LINK.f) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".p",
|
||||
"$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".F",
|
||||
"$(LINK.F) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".r",
|
||||
"$(LINK.r) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||
".mod",
|
||||
"$(COMPILE.mod) -o $@ -e $@ $^",
|
||||
|
||||
".def.sym",
|
||||
"$(COMPILE.def) -o $@ $<",
|
||||
|
||||
".sh",
|
||||
"cat $< >$@ \n chmod a+x $@",
|
||||
|
||||
".s.o",
|
||||
#if !defined(M_XENIX) || defined(__GNUC__)
|
||||
"$(COMPILE.s) -o $@ $<",
|
||||
#else /* Xenix. */
|
||||
"$(COMPILE.s) -o$@ $<",
|
||||
#endif /* Not Xenix. */
|
||||
".S.o",
|
||||
#if !defined(M_XENIX) || defined(__GNUC__)
|
||||
"$(COMPILE.S) -o $@ $<",
|
||||
#else /* Xenix. */
|
||||
"$(COMPILE.S) -o$@ $<",
|
||||
#endif /* Not Xenix. */
|
||||
".c.o",
|
||||
"$(COMPILE.c) $< $(OUTPUT_OPTION)",
|
||||
".cc.o",
|
||||
"$(COMPILE.cc) $< $(OUTPUT_OPTION)",
|
||||
".C.o",
|
||||
"$(COMPILE.C) $< $(OUTPUT_OPTION)",
|
||||
".f.o",
|
||||
"$(COMPILE.f) $< $(OUTPUT_OPTION)",
|
||||
".p.o",
|
||||
"$(COMPILE.p) $< $(OUTPUT_OPTION)",
|
||||
".F.o",
|
||||
"$(COMPILE.F) $< $(OUTPUT_OPTION)",
|
||||
".r.o",
|
||||
"$(COMPILE.r) $< $(OUTPUT_OPTION)",
|
||||
".mod.o",
|
||||
"$(COMPILE.mod) -o $@ $<",
|
||||
|
||||
".c.ln",
|
||||
"$(LINT.c) -C$* $<",
|
||||
".y.ln",
|
||||
#ifndef __MSDOS__
|
||||
"$(YACC.y) $< \n $(LINT.c) -C$* y.tab.c \n $(RM) y.tab.c",
|
||||
#else
|
||||
"$(YACC.y) $< \n $(LINT.c) -C$* y_tab.c \n $(RM) y_tab.c",
|
||||
#endif
|
||||
".l.ln",
|
||||
"@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c",
|
||||
|
||||
".y.c",
|
||||
#ifndef __MSDOS__
|
||||
"$(YACC.y) $< \n mv -f y.tab.c $@",
|
||||
#else
|
||||
"$(YACC.y) $< \n mv -f y_tab.c $@",
|
||||
#endif
|
||||
".l.c",
|
||||
"@$(RM) $@ \n $(LEX.l) $< > $@",
|
||||
|
||||
".F.f",
|
||||
"$(PREPROCESS.F) $< $(OUTPUT_OPTION)",
|
||||
".r.f",
|
||||
"$(PREPROCESS.r) $< $(OUTPUT_OPTION)",
|
||||
|
||||
/* This might actually make lex.yy.c if there's no %R%
|
||||
directive in $*.l, but in that case why were you
|
||||
trying to make $*.r anyway? */
|
||||
".l.r",
|
||||
"$(LEX.l) $< > $@ \n mv -f lex.yy.r $@",
|
||||
|
||||
".S.s",
|
||||
"$(PREPROCESS.S) $< > $@",
|
||||
|
||||
".texinfo.info",
|
||||
"$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@",
|
||||
|
||||
".texi.info",
|
||||
"$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@",
|
||||
|
||||
".txinfo.info",
|
||||
"$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@",
|
||||
|
||||
".tex.dvi",
|
||||
"$(TEX) $<",
|
||||
|
||||
".texinfo.dvi",
|
||||
"$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<",
|
||||
|
||||
".texi.dvi",
|
||||
"$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<",
|
||||
|
||||
".txinfo.dvi",
|
||||
"$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<",
|
||||
|
||||
".w.c",
|
||||
"$(CTANGLE) $< - $@", /* The `-' says there is no `.ch' file. */
|
||||
|
||||
".web.p",
|
||||
"$(TANGLE) $<",
|
||||
|
||||
".w.tex",
|
||||
"$(CWEAVE) $< - $@", /* The `-' says there is no `.ch' file. */
|
||||
|
||||
".web.tex",
|
||||
"$(WEAVE) $<",
|
||||
|
||||
0, 0,
|
||||
};
|
||||
|
||||
static char *default_variables[] =
|
||||
{
|
||||
"AR", "ar",
|
||||
"ARFLAGS", "rv",
|
||||
"AS", "as",
|
||||
#ifdef GCC_IS_NATIVE
|
||||
"CC", "gcc",
|
||||
"CXX", "gcc",
|
||||
#else
|
||||
"CC", "cc",
|
||||
"CXX", "g++",
|
||||
#endif
|
||||
|
||||
/* This expands to $(CO) $(COFLAGS) $< $@ if $@ does not exist,
|
||||
and to the empty string if $@ does exist. */
|
||||
"CHECKOUT,v",
|
||||
"$(patsubst $@-noexist,$(CO) $(COFLAGS) $< $@,\
|
||||
$(filter-out $@,$(firstword $(wildcard $@) $@-noexist)))",
|
||||
|
||||
"CO", "co",
|
||||
"CPP", "$(CC) -E",
|
||||
#ifdef CRAY
|
||||
"CF77PPFLAGS", "-P",
|
||||
"CF77PP", "/lib/cpp",
|
||||
"CFT", "cft77",
|
||||
"CF", "cf77",
|
||||
"FC", "$(CF)",
|
||||
#else /* Not CRAY. */
|
||||
#ifdef _IBMR2
|
||||
"FC", "xlf",
|
||||
#else
|
||||
#ifdef __convex__
|
||||
"FC", "fc",
|
||||
#else
|
||||
"FC", "f77",
|
||||
#endif /* __convex__ */
|
||||
#endif /* _IBMR2 */
|
||||
/* System V uses these, so explicit rules using them should work.
|
||||
However, there is no way to make implicit rules use them and FC. */
|
||||
"F77", "$(FC)",
|
||||
"F77FLAGS", "$(FFLAGS)",
|
||||
#endif /* Cray. */
|
||||
"GET", SCCS_GET,
|
||||
"LD", "ld",
|
||||
#ifdef GCC_IS_NATIVE
|
||||
"LEX", "flex",
|
||||
#else
|
||||
"LEX", "lex",
|
||||
#endif
|
||||
"LINT", "lint",
|
||||
"M2C", "m2c",
|
||||
#ifdef pyr
|
||||
"PC", "pascal",
|
||||
#else
|
||||
#ifdef CRAY
|
||||
"PC", "PASCAL",
|
||||
"SEGLDR", "segldr",
|
||||
#else
|
||||
"PC", "pc",
|
||||
#endif /* CRAY. */
|
||||
#endif /* pyr. */
|
||||
#ifdef GCC_IS_NATIVE
|
||||
"YACC", "bison -y",
|
||||
#else
|
||||
"YACC", "yacc", /* Or "bison -y" */
|
||||
#endif
|
||||
"MAKEINFO", "makeinfo",
|
||||
"TEX", "tex",
|
||||
"TEXI2DVI", "texi2dvi",
|
||||
"WEAVE", "weave",
|
||||
"CWEAVE", "cweave",
|
||||
"TANGLE", "tangle",
|
||||
"CTANGLE", "ctangle",
|
||||
|
||||
"RM", "rm -f",
|
||||
|
||||
"LINK.o", "$(CC) $(LDFLAGS) $(TARGET_ARCH)",
|
||||
"COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
|
||||
"LINK.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
|
||||
"COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
|
||||
"COMPILE.C", "$(COMPILE.cc)",
|
||||
"LINK.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
|
||||
"LINK.C", "$(LINK.cc)",
|
||||
"YACC.y", "$(YACC) $(YFLAGS)",
|
||||
"LEX.l", "$(LEX) $(LFLAGS) -t",
|
||||
"COMPILE.f", "$(FC) $(FFLAGS) $(TARGET_ARCH) -c",
|
||||
"LINK.f", "$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
|
||||
"COMPILE.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
|
||||
"LINK.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
|
||||
"COMPILE.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c",
|
||||
"LINK.r", "$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
|
||||
"COMPILE.def", "$(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH)",
|
||||
"COMPILE.mod", "$(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)",
|
||||
"COMPILE.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
|
||||
"LINK.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
|
||||
"LINK.s", "$(CC) $(ASFLAGS) $(LDFLAGS) $(TARGET_MACH)",
|
||||
"COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)",
|
||||
"LINK.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_MACH)",
|
||||
"COMPILE.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c",
|
||||
#if !defined(M_XENIX) || defined(__GNUC__)
|
||||
"PREPROCESS.S", "$(CC) -E $(CPPFLAGS)",
|
||||
#else /* Xenix. */
|
||||
"PREPROCESS.S", "$(CC) -EP $(CPPFLAGS)",
|
||||
#endif /* Not Xenix. */
|
||||
"PREPROCESS.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -F",
|
||||
"PREPROCESS.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -F",
|
||||
"LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
|
||||
|
||||
#ifndef NO_MINUS_C_MINUS_O
|
||||
#if !defined(M_XENIX) || defined(__GNUC__)
|
||||
"OUTPUT_OPTION", "-o $@",
|
||||
#else /* Xenix. */
|
||||
"OUTPUT_OPTION", "-Fo$@",
|
||||
#endif /* Not Xenix. */
|
||||
#endif
|
||||
|
||||
#ifdef SCCS_GET_MINUS_G
|
||||
"SCCS_OUTPUT_OPTION", "-G$@",
|
||||
#endif
|
||||
|
||||
0, 0
|
||||
};
|
||||
|
||||
/* Set up the default .SUFFIXES list. */
|
||||
|
||||
void
|
||||
set_default_suffixes ()
|
||||
{
|
||||
suffix_file = enter_file (".SUFFIXES");
|
||||
|
||||
if (no_builtin_rules_flag)
|
||||
(void) define_variable ("SUFFIXES", 8, "", o_default, 0);
|
||||
else
|
||||
{
|
||||
char *p = default_suffixes;
|
||||
suffix_file->deps = (struct dep *)
|
||||
multi_glob (parse_file_seq (&p, '\0', sizeof (struct dep), 1),
|
||||
sizeof (struct dep));
|
||||
(void) define_variable ("SUFFIXES", 8, default_suffixes, o_default, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enter the default suffix rules as file rules. This used to be done in
|
||||
install_default_implicit_rules, but that loses because we want the
|
||||
suffix rules installed before reading makefiles, and thee pattern rules
|
||||
installed after. */
|
||||
|
||||
void
|
||||
install_default_suffix_rules ()
|
||||
{
|
||||
register char **s;
|
||||
|
||||
if (no_builtin_rules_flag)
|
||||
return;
|
||||
|
||||
for (s = default_suffix_rules; *s != 0; s += 2)
|
||||
{
|
||||
register struct file *f = enter_file (s[0]);
|
||||
/* Don't clobber cmds given in a makefile if there were any. */
|
||||
if (f->cmds == 0)
|
||||
{
|
||||
f->cmds = (struct commands *) xmalloc (sizeof (struct commands));
|
||||
f->cmds->filename = 0;
|
||||
f->cmds->commands = s[1];
|
||||
f->cmds->command_lines = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Install the default pattern rules. */
|
||||
|
||||
void
|
||||
install_default_implicit_rules ()
|
||||
{
|
||||
register struct pspec *p;
|
||||
|
||||
if (no_builtin_rules_flag)
|
||||
return;
|
||||
|
||||
for (p = default_pattern_rules; p->target != 0; ++p)
|
||||
install_pattern_rule (p, 0);
|
||||
|
||||
for (p = default_terminal_rules; p->target != 0; ++p)
|
||||
install_pattern_rule (p, 1);
|
||||
}
|
||||
|
||||
void
|
||||
define_default_variables ()
|
||||
{
|
||||
register char **s;
|
||||
|
||||
for (s = default_variables; *s != 0; s += 2)
|
||||
(void) define_variable (s[0], strlen (s[0]), s[1], o_default, 1);
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
/* Definitions of dependency data structures for GNU Make.
|
||||
Copyright (C) 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Structure representing one dependency of a file.
|
||||
Each struct file's `deps' points to a chain of these,
|
||||
chained through the `next'.
|
||||
|
||||
Note that the first two words of this match a struct nameseq. */
|
||||
|
||||
struct dep
|
||||
{
|
||||
struct dep *next;
|
||||
char *name;
|
||||
struct file *file;
|
||||
int changed;
|
||||
};
|
||||
|
||||
|
||||
/* Structure used in chains of names, for parsing and globbing. */
|
||||
|
||||
struct nameseq
|
||||
{
|
||||
struct nameseq *next;
|
||||
char *name;
|
||||
};
|
||||
|
||||
|
||||
extern struct nameseq *multi_glob (), *parse_file_seq ();
|
||||
extern char *tilde_expand ();
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
extern struct nameseq *ar_glob ();
|
||||
#endif
|
||||
|
||||
#ifndef iAPX286
|
||||
#define dep_name(d) ((d)->name == 0 ? (d)->file->name : (d)->name)
|
||||
#else
|
||||
/* Buggy compiler can't hack this. */
|
||||
extern char *dep_name ();
|
||||
#endif
|
||||
|
||||
extern struct dep *read_all_makefiles ();
|
||||
|
||||
/* Flag bits for the second argument to `read_makefile'.
|
||||
These flags are saved in the `changed' field of each
|
||||
`struct dep' in the chain returned by `read_all_makefiles'. */
|
||||
#define RM_NO_DEFAULT_GOAL (1 << 0) /* Do not set default goal. */
|
||||
#define RM_INCLUDED (1 << 1) /* Search makefile search path. */
|
||||
#define RM_DONTCARE (1 << 2) /* No error if it doesn't exist. */
|
||||
#define RM_NO_TILDE (1 << 3) /* Don't expand ~ in file name. */
|
||||
#define RM_NOFLAG 0
|
||||
@ -1,760 +0,0 @@
|
||||
/* Directory hashing for GNU Make.
|
||||
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
|
||||
#ifdef NETSCAPE
|
||||
#include "windir.h"
|
||||
|
||||
DIR *opendir(char *pathp)
|
||||
{
|
||||
DIR *ret = (DIR *) malloc(sizeof(DIR));
|
||||
char path[_MAX_PATH];
|
||||
int l;
|
||||
|
||||
sprintf(path, "%s", pathp);
|
||||
l = strlen(path) - 1;
|
||||
path[strlen(pathp)] = '\0';
|
||||
if(path[strlen(path) - 1] != '\\')
|
||||
strcpy (path + strlen(path), "\\*.*");
|
||||
else
|
||||
strcat(path, "*.*");
|
||||
|
||||
ret->de.d_name = NULL;
|
||||
if( (ret->dp = FindFirstFile(path, &ret->fdata)) != INVALID_HANDLE_VALUE)
|
||||
return ret;
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dirent *readdir(DIR *ds)
|
||||
{
|
||||
if(FindNextFile(ds->dp, &ds->fdata) == FALSE)
|
||||
return NULL;
|
||||
if(ds->de.d_name)
|
||||
free(ds->de.d_name);
|
||||
ds->de.d_name = strdup(ds->fdata.cFileName);
|
||||
|
||||
return &ds->de;
|
||||
}
|
||||
|
||||
void closedir(DIR *ds)
|
||||
{
|
||||
FindClose(ds->dp);
|
||||
if(ds->de.d_name)
|
||||
free(ds->de.d_name);
|
||||
free(ds);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(NETSCAPE) && defined (POSIX) || defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__)
|
||||
#include <dirent.h>
|
||||
#ifndef __GNU_LIBRARY__
|
||||
#define D_NAMLEN(d) strlen((d)->d_name)
|
||||
#else /* GNU C library. */
|
||||
#define D_NAMLEN(d) ((d)->d_namlen)
|
||||
#endif /* Not GNU C library. */
|
||||
#else /* Not POSIX or HAVE_DIRENT_H. */
|
||||
#define direct dirent
|
||||
#define D_NAMLEN(d) (strlen(d->d_name))
|
||||
#ifdef HAVE_SYS_NDIR_H
|
||||
#include <sys/ndir.h>
|
||||
#endif /* HAVE_SYS_NDIR_H */
|
||||
#ifdef HAVE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#endif /* HAVE_SYS_DIR_H */
|
||||
#ifdef HAVE_NDIR_H
|
||||
#include <ndir.h>
|
||||
#endif /* HAVE_NDIR_H */
|
||||
#endif /* POSIX or HAVE_DIRENT_H or __GNU_LIBRARY__. */
|
||||
|
||||
#if defined (POSIX) && !defined (__GNU_LIBRARY__) || defined(NETSCAPE)
|
||||
/* Posix does not require that the d_ino field be present, and some
|
||||
systems do not provide it. */
|
||||
#define REAL_DIR_ENTRY(dp) 1
|
||||
#else
|
||||
#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
|
||||
#endif /* POSIX */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <ctype.h>
|
||||
|
||||
static char *
|
||||
dosify (filename)
|
||||
char *filename;
|
||||
{
|
||||
static char dos_filename[14];
|
||||
char *df;
|
||||
int i;
|
||||
|
||||
if (filename == 0)
|
||||
return 0;
|
||||
|
||||
if (strpbrk (filename, "\"*+,;<=>?[\\]|") != 0)
|
||||
return filename;
|
||||
|
||||
df = dos_filename;
|
||||
|
||||
/* First, transform the name part. */
|
||||
for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i)
|
||||
*df++ = tolower (*filename++);
|
||||
|
||||
/* Now skip to the next dot. */
|
||||
while (*filename != '\0' && *filename != '.')
|
||||
++filename;
|
||||
if (*filename != '\0')
|
||||
{
|
||||
*df++ = *filename++;
|
||||
for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i)
|
||||
*df++ = tolower (*filename++);
|
||||
}
|
||||
|
||||
/* Look for more dots. */
|
||||
while (*filename != '\0' && *filename != '.')
|
||||
++filename;
|
||||
if (*filename == '.')
|
||||
return filename;
|
||||
*df = 0;
|
||||
return dos_filename;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Hash table of directories. */
|
||||
|
||||
#ifndef DIRECTORY_BUCKETS
|
||||
#define DIRECTORY_BUCKETS 199
|
||||
#endif
|
||||
|
||||
struct directory_contents
|
||||
{
|
||||
struct directory_contents *next;
|
||||
|
||||
#ifdef NETSCAPE
|
||||
int dev; /* Device number of this dir. */
|
||||
/*
|
||||
* Inode means nothing on WIN32. Even file key information is
|
||||
* unreliable because it is random per file open and undefined
|
||||
* for remote filesystems. The most unique attribute I can
|
||||
* come up with is the fully qualified name of the directory. Beware
|
||||
* though, this is also unreliable. I'm open to suggestion on a better
|
||||
* way to emulate inode.
|
||||
*/
|
||||
char *path_key;
|
||||
int mtime; /* controls check for stale directory cache */
|
||||
#else
|
||||
int dev, ino; /* Device and inode numbers of this dir. */
|
||||
#endif
|
||||
|
||||
struct dirfile **files; /* Files in this directory. */
|
||||
DIR *dirstream; /* Stream reading this directory. */
|
||||
};
|
||||
|
||||
/* Table of directory contents hashed by device and inode number. */
|
||||
static struct directory_contents *directories_contents[DIRECTORY_BUCKETS];
|
||||
|
||||
struct directory
|
||||
{
|
||||
struct directory *next;
|
||||
|
||||
char *name; /* Name of the directory. */
|
||||
|
||||
/* The directory's contents. This data may be shared by several
|
||||
entries in the hash table, which refer to the same directory
|
||||
(identified uniquely by `dev' and `ino') under different names. */
|
||||
struct directory_contents *contents;
|
||||
};
|
||||
|
||||
/* Table of directories hashed by name. */
|
||||
static struct directory *directories[DIRECTORY_BUCKETS];
|
||||
|
||||
|
||||
/* Never have more than this many directories open at once. */
|
||||
|
||||
#define MAX_OPEN_DIRECTORIES 10
|
||||
|
||||
static unsigned int open_directories = 0;
|
||||
|
||||
|
||||
/* Hash table of files in each directory. */
|
||||
|
||||
struct dirfile
|
||||
{
|
||||
struct dirfile *next;
|
||||
char *name; /* Name of the file. */
|
||||
char impossible; /* This file is impossible. */
|
||||
};
|
||||
|
||||
#ifndef DIRFILE_BUCKETS
|
||||
#define DIRFILE_BUCKETS 107
|
||||
#endif
|
||||
|
||||
static int dir_contents_file_exists_p ();
|
||||
|
||||
/* Find the directory named NAME and return its `struct directory'. */
|
||||
|
||||
static struct directory *
|
||||
find_directory (name)
|
||||
register char *name;
|
||||
{
|
||||
register unsigned int hash = 0;
|
||||
register char *p;
|
||||
register struct directory *dir;
|
||||
#ifdef NETSCAPE
|
||||
char w32_path[_MAX_PATH];
|
||||
#endif
|
||||
|
||||
for (p = name; *p != '\0'; ++p)
|
||||
HASH (hash, *p);
|
||||
hash %= DIRECTORY_BUCKETS;
|
||||
|
||||
for (dir = directories[hash]; dir != 0; dir = dir->next)
|
||||
if (streq (dir->name, name))
|
||||
break;
|
||||
|
||||
if (dir == 0)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
/* The directory was not found. Create a new entry for it. */
|
||||
|
||||
dir = (struct directory *) xmalloc (sizeof (struct directory));
|
||||
dir->next = directories[hash];
|
||||
directories[hash] = dir;
|
||||
dir->name = savestring (name, p - name);
|
||||
|
||||
/* The directory is not in the name hash table.
|
||||
Find its device and inode numbers, and look it up by them. */
|
||||
|
||||
if (safe_stat (name, &st) < 0)
|
||||
/* Couldn't stat the directory. Mark this by
|
||||
setting the `contents' member to a nil pointer. */
|
||||
dir->contents = 0;
|
||||
else
|
||||
{
|
||||
/* Search the contents hash table; device and inode are the key. */
|
||||
|
||||
struct directory_contents *dc;
|
||||
|
||||
#ifdef NETSCAPE
|
||||
_fullpath (w32_path, name, sizeof (w32_path));
|
||||
hash = ((unsigned int) st.st_dev << 16) | (unsigned int) st.st_ctime;
|
||||
#else
|
||||
hash = ((unsigned int) st.st_dev << 16) | (unsigned int) st.st_ino;
|
||||
#endif
|
||||
hash %= DIRECTORY_BUCKETS;
|
||||
|
||||
for (dc = directories_contents[hash]; dc != 0; dc = dc->next)
|
||||
#ifdef NETSCAPE
|
||||
if (!strcmp(dc->path_key, w32_path))
|
||||
#else
|
||||
if (dc->dev == (int)st.st_dev && dc->ino == (int)st.st_ino)
|
||||
#endif
|
||||
break;
|
||||
|
||||
if (dc == 0)
|
||||
{
|
||||
/* Nope; this really is a directory we haven't seen before. */
|
||||
|
||||
dc = (struct directory_contents *)
|
||||
xmalloc (sizeof (struct directory_contents));
|
||||
|
||||
/* Enter it in the contents hash table. */
|
||||
dc->dev = st.st_dev;
|
||||
#ifdef NETSCAPE
|
||||
dc->path_key = strdup(w32_path);
|
||||
dc->mtime = st.st_mtime;
|
||||
#else
|
||||
dc->ino = st.st_ino;
|
||||
#endif
|
||||
dc->next = directories_contents[hash];
|
||||
directories_contents[hash] = dc;
|
||||
|
||||
dc->dirstream = opendir (name);
|
||||
if (dc->dirstream == 0)
|
||||
/* Couldn't open the directory. Mark this by
|
||||
setting the `files' member to a nil pointer. */
|
||||
dc->files = 0;
|
||||
else
|
||||
{
|
||||
/* Allocate an array of buckets for files and zero it. */
|
||||
dc->files = (struct dirfile **)
|
||||
xmalloc (sizeof (struct dirfile *) * DIRFILE_BUCKETS);
|
||||
bzero ((char *) dc->files,
|
||||
sizeof (struct dirfile *) * DIRFILE_BUCKETS);
|
||||
|
||||
/* Keep track of how many directories are open. */
|
||||
++open_directories;
|
||||
if (open_directories == MAX_OPEN_DIRECTORIES)
|
||||
/* We have too many directories open already.
|
||||
Read the entire directory and then close it. */
|
||||
(void) dir_contents_file_exists_p (dc, (char *) 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Point the name-hashed entry for DIR at its contents data. */
|
||||
dir->contents = dc;
|
||||
}
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
/* Return 1 if the name FILENAME is entered in DIR's hash table.
|
||||
FILENAME must contain no slashes. */
|
||||
|
||||
static int
|
||||
dir_contents_file_exists_p (dir, filename)
|
||||
register struct directory_contents *dir;
|
||||
register char *filename;
|
||||
{
|
||||
register unsigned int hash;
|
||||
register char *p;
|
||||
register struct dirfile *df;
|
||||
register struct dirent *d;
|
||||
#ifdef NETSCAPE
|
||||
struct stat st;
|
||||
int rehash = 0;
|
||||
#endif
|
||||
|
||||
if (dir == 0 || dir->files == 0)
|
||||
/* The directory could not be stat'd or opened. */
|
||||
return 0;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
filename = dosify (filename);
|
||||
#endif
|
||||
|
||||
hash = 0;
|
||||
if (filename != 0)
|
||||
{
|
||||
if (*filename == '\0')
|
||||
/* Checking if the directory exists. */
|
||||
return 1;
|
||||
|
||||
for (p = filename; *p != '\0'; ++p)
|
||||
HASH (hash, *p);
|
||||
hash %= DIRFILE_BUCKETS;
|
||||
|
||||
/* Search the list of hashed files. */
|
||||
|
||||
for (df = dir->files[hash]; df != 0; df = df->next)
|
||||
if (streq (df->name, filename))
|
||||
return !df->impossible;
|
||||
}
|
||||
|
||||
/* The file was not found in the hashed list.
|
||||
Try to read the directory further. */
|
||||
|
||||
#ifdef NETSCAPE
|
||||
if (dir->dirstream == 0)
|
||||
{
|
||||
/* Check to see if directory has changed since last read */
|
||||
if (dir->path_key &&
|
||||
stat(dir->path_key, &st) == 0 &&
|
||||
st.st_mtime > dir->mtime) {
|
||||
|
||||
/* reset date stamp to show most recent re-process */
|
||||
dir->mtime = st.st_mtime;
|
||||
|
||||
/* make sure directory can still be opened */
|
||||
dir->dirstream = opendir(dir->path_key);
|
||||
|
||||
if (dir->dirstream)
|
||||
rehash = 1;
|
||||
else
|
||||
return 0; /* couldn't re-read - fail */
|
||||
} else
|
||||
/* The directory has been all read in. */
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
if (dir->dirstream == 0)
|
||||
/* The directory has been all read in. */
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
while ((d = readdir (dir->dirstream)) != 0)
|
||||
{
|
||||
/* Enter the file in the hash table. */
|
||||
register unsigned int newhash = 0;
|
||||
unsigned int len;
|
||||
register unsigned int i;
|
||||
|
||||
if (!REAL_DIR_ENTRY (d))
|
||||
continue;
|
||||
|
||||
len = D_NAMLEN (d);
|
||||
while (d->d_name[len - 1] == '\0')
|
||||
--len;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
HASH (newhash, d->d_name[i]);
|
||||
newhash %= DIRFILE_BUCKETS;
|
||||
|
||||
#ifdef NETSCAPE
|
||||
/*
|
||||
* If re-reading a directory, check that this file isn't already
|
||||
* in the cache.
|
||||
*/
|
||||
if (rehash) {
|
||||
for (df = dir->files[newhash]; df != 0; df = df->next)
|
||||
if (streq(df->name, d->d_name))
|
||||
break;
|
||||
} else
|
||||
df = 0;
|
||||
|
||||
/*
|
||||
* If re-reading a directory, don't cache files that have
|
||||
* already been discovered.
|
||||
*/
|
||||
if (!df) {
|
||||
#endif
|
||||
df = (struct dirfile *) xmalloc (sizeof (struct dirfile));
|
||||
df->next = dir->files[newhash];
|
||||
dir->files[newhash] = df;
|
||||
df->name = savestring (d->d_name, len);
|
||||
df->impossible = 0;
|
||||
#ifdef NETSCAPE
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if the name matches the one we're searching for. */
|
||||
if (filename != 0
|
||||
&& newhash == hash && streq (d->d_name, filename))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If the directory has been completely read in,
|
||||
close the stream and reset the pointer to nil. */
|
||||
if (d == 0)
|
||||
{
|
||||
--open_directories;
|
||||
closedir (dir->dirstream);
|
||||
dir->dirstream = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return 1 if the name FILENAME in directory DIRNAME
|
||||
is entered in the dir hash table.
|
||||
FILENAME must contain no slashes. */
|
||||
|
||||
int
|
||||
dir_file_exists_p (dirname, filename)
|
||||
register char *dirname;
|
||||
register char *filename;
|
||||
{
|
||||
return dir_contents_file_exists_p (find_directory (dirname)->contents,
|
||||
filename);
|
||||
}
|
||||
|
||||
/* Return 1 if the file named NAME exists. */
|
||||
|
||||
int
|
||||
file_exists_p (name)
|
||||
register char *name;
|
||||
{
|
||||
char *dirend;
|
||||
char *dirname;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (name))
|
||||
return ar_member_date (name) != (time_t) -1;
|
||||
#endif
|
||||
|
||||
dirend = rindex (name, '/');
|
||||
if (dirend == 0)
|
||||
return dir_file_exists_p (".", name);
|
||||
|
||||
dirname = (char *) alloca (dirend - name + 1);
|
||||
bcopy (name, dirname, dirend - name);
|
||||
dirname[dirend - name] = '\0';
|
||||
return dir_file_exists_p (dirname, dirend + 1);
|
||||
}
|
||||
|
||||
/* Mark FILENAME as `impossible' for `file_impossible_p'.
|
||||
This means an attempt has been made to search for FILENAME
|
||||
as an intermediate file, and it has failed. */
|
||||
|
||||
void
|
||||
file_impossible (filename)
|
||||
register char *filename;
|
||||
{
|
||||
char *dirend;
|
||||
register char *p = filename;
|
||||
register unsigned int hash;
|
||||
register struct directory *dir;
|
||||
register struct dirfile *new;
|
||||
|
||||
dirend = rindex (p, '/');
|
||||
if (dirend == 0)
|
||||
dir = find_directory (".");
|
||||
else
|
||||
{
|
||||
char *dirname = (char *) alloca (dirend - p + 1);
|
||||
bcopy (p, dirname, dirend - p);
|
||||
dirname[dirend - p] = '\0';
|
||||
dir = find_directory (dirname);
|
||||
filename = p = dirend + 1;
|
||||
}
|
||||
|
||||
for (hash = 0; *p != '\0'; ++p)
|
||||
HASH (hash, *p);
|
||||
hash %= DIRFILE_BUCKETS;
|
||||
|
||||
if (dir->contents == 0)
|
||||
{
|
||||
/* The directory could not be stat'd. We allocate a contents
|
||||
structure for it, but leave it out of the contents hash table. */
|
||||
dir->contents = (struct directory_contents *)
|
||||
xmalloc (sizeof (struct directory_contents));
|
||||
#ifdef NETSCAPE
|
||||
dir->contents->dev = 0;
|
||||
dir->contents->path_key = NULL;
|
||||
dir->contents->mtime = 0;
|
||||
#else
|
||||
dir->contents->dev = dir->contents->ino = 0;
|
||||
#endif
|
||||
dir->contents->files = 0;
|
||||
dir->contents->dirstream = 0;
|
||||
}
|
||||
|
||||
if (dir->contents->files == 0)
|
||||
{
|
||||
/* The directory was not opened; we must allocate the hash buckets. */
|
||||
dir->contents->files = (struct dirfile **)
|
||||
xmalloc (sizeof (struct dirfile) * DIRFILE_BUCKETS);
|
||||
bzero ((char *) dir->contents->files,
|
||||
sizeof (struct dirfile) * DIRFILE_BUCKETS);
|
||||
}
|
||||
|
||||
/* Make a new entry and put it in the table. */
|
||||
|
||||
new = (struct dirfile *) xmalloc (sizeof (struct dirfile));
|
||||
new->next = dir->contents->files[hash];
|
||||
dir->contents->files[hash] = new;
|
||||
new->name = savestring (filename, strlen (filename));
|
||||
new->impossible = 1;
|
||||
}
|
||||
|
||||
/* Return nonzero if FILENAME has been marked impossible. */
|
||||
|
||||
int
|
||||
file_impossible_p (filename)
|
||||
char *filename;
|
||||
{
|
||||
char *dirend;
|
||||
register char *p = filename;
|
||||
register unsigned int hash;
|
||||
register struct directory_contents *dir;
|
||||
register struct dirfile *next;
|
||||
|
||||
dirend = rindex (filename, '/');
|
||||
if (dirend == 0)
|
||||
dir = find_directory (".")->contents;
|
||||
else
|
||||
{
|
||||
char *dirname = (char *) alloca (dirend - filename + 1);
|
||||
bcopy (p, dirname, dirend - p);
|
||||
dirname[dirend - p] = '\0';
|
||||
dir = find_directory (dirname)->contents;
|
||||
p = dirend + 1;
|
||||
}
|
||||
|
||||
if (dir == 0 || dir->files == 0)
|
||||
/* There are no files entered for this directory. */
|
||||
return 0;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
p = filename = dosify (p);
|
||||
#endif
|
||||
|
||||
for (hash = 0; *p != '\0'; ++p)
|
||||
HASH (hash, *p);
|
||||
hash %= DIRFILE_BUCKETS;
|
||||
|
||||
for (next = dir->files[hash]; next != 0; next = next->next)
|
||||
if (streq (filename, next->name))
|
||||
return next->impossible;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the already allocated name in the
|
||||
directory hash table that matches DIR. */
|
||||
|
||||
char *
|
||||
dir_name (dir)
|
||||
char *dir;
|
||||
{
|
||||
return find_directory (dir)->name;
|
||||
}
|
||||
|
||||
/* Print the data base of directories. */
|
||||
|
||||
void
|
||||
print_dir_data_base ()
|
||||
{
|
||||
register unsigned int i, dirs, files, impossible;
|
||||
register struct directory *dir;
|
||||
|
||||
puts ("\n# Directories\n");
|
||||
|
||||
dirs = files = impossible = 0;
|
||||
for (i = 0; i < DIRECTORY_BUCKETS; ++i)
|
||||
for (dir = directories[i]; dir != 0; dir = dir->next)
|
||||
{
|
||||
++dirs;
|
||||
if (dir->contents == 0)
|
||||
printf ("# %s: could not be stat'd.\n", dir->name);
|
||||
else if (dir->contents->files == 0)
|
||||
#ifdef NETSCAPE
|
||||
printf ("# %s (path_key %s, mtime %d): could not be opened.\n",
|
||||
dir->name, dir->contents->path_key, dir->contents->mtime);
|
||||
#else
|
||||
printf ("# %s (device %d, inode %d): could not be opened.\n",
|
||||
dir->name, dir->contents->dev, dir->contents->ino);
|
||||
#endif
|
||||
else
|
||||
{
|
||||
register unsigned int f = 0, im = 0;
|
||||
register unsigned int j;
|
||||
register struct dirfile *df;
|
||||
for (j = 0; j < DIRFILE_BUCKETS; ++j)
|
||||
for (df = dir->contents->files[j]; df != 0; df = df->next)
|
||||
if (df->impossible)
|
||||
++im;
|
||||
else
|
||||
++f;
|
||||
#ifdef NETSCAPE
|
||||
printf ("# %s (device %d, path_key %s, mtime %d): ",
|
||||
dir->name, dir->contents->dev,
|
||||
dir->contents->path_key, dir->contents->mtime);
|
||||
#else
|
||||
printf ("# %s (device %d, inode %d): ",
|
||||
dir->name, dir->contents->dev, dir->contents->ino);
|
||||
#endif
|
||||
if (f == 0)
|
||||
fputs ("No", stdout);
|
||||
else
|
||||
printf ("%u", f);
|
||||
fputs (" files, ", stdout);
|
||||
if (im == 0)
|
||||
fputs ("no", stdout);
|
||||
else
|
||||
printf ("%u", im);
|
||||
fputs (" impossibilities", stdout);
|
||||
if (dir->contents->dirstream == 0)
|
||||
puts (".");
|
||||
else
|
||||
puts (" so far.");
|
||||
files += f;
|
||||
impossible += im;
|
||||
}
|
||||
}
|
||||
|
||||
fputs ("\n# ", stdout);
|
||||
if (files == 0)
|
||||
fputs ("No", stdout);
|
||||
else
|
||||
printf ("%u", files);
|
||||
fputs (" files, ", stdout);
|
||||
if (impossible == 0)
|
||||
fputs ("no", stdout);
|
||||
else
|
||||
printf ("%u", impossible);
|
||||
printf (" impossibilities in %u directories.\n", dirs);
|
||||
}
|
||||
|
||||
/* Hooks for globbing. */
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
/* Structure describing state of iterating through a directory hash table. */
|
||||
|
||||
struct dirstream
|
||||
{
|
||||
struct directory_contents *contents; /* The directory being read. */
|
||||
|
||||
unsigned int bucket; /* Current hash bucket. */
|
||||
struct dirfile *elt; /* Current elt in bucket. */
|
||||
};
|
||||
|
||||
/* Forward declarations. */
|
||||
static __ptr_t open_dirstream __P ((const char *));
|
||||
static const char *read_dirstream __P ((__ptr_t));
|
||||
|
||||
static __ptr_t
|
||||
open_dirstream (directory)
|
||||
const char *directory;
|
||||
{
|
||||
struct dirstream *new;
|
||||
struct directory *dir = find_directory (directory);
|
||||
|
||||
if (dir->contents == 0 || dir->contents->files == 0)
|
||||
/* DIR->contents is nil if the directory could not be stat'd.
|
||||
DIR->contents->files is nil if it could not be opened. */
|
||||
return 0;
|
||||
|
||||
/* Read all the contents of the directory now. There is no benefit
|
||||
in being lazy, since glob will want to see every file anyway. */
|
||||
|
||||
(void) dir_contents_file_exists_p (dir->contents, (char *) 0);
|
||||
|
||||
new = (struct dirstream *) xmalloc (sizeof (struct dirstream));
|
||||
new->contents = dir->contents;
|
||||
new->bucket = 0;
|
||||
new->elt = new->contents->files[0];
|
||||
|
||||
return (__ptr_t) new;
|
||||
}
|
||||
|
||||
static const char *
|
||||
read_dirstream (stream)
|
||||
__ptr_t stream;
|
||||
{
|
||||
struct dirstream *const ds = (struct dirstream *) stream;
|
||||
register struct dirfile *df;
|
||||
|
||||
while (ds->bucket < DIRFILE_BUCKETS)
|
||||
{
|
||||
while ((df = ds->elt) != 0)
|
||||
{
|
||||
ds->elt = df->next;
|
||||
if (!df->impossible)
|
||||
return df->name;
|
||||
}
|
||||
if (++ds->bucket == DIRFILE_BUCKETS)
|
||||
break;
|
||||
ds->elt = ds->contents->files[ds->bucket];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
init_dir ()
|
||||
{
|
||||
__glob_opendir_hook = open_dirstream;
|
||||
__glob_readdir_hook = read_dirstream;
|
||||
__glob_closedir_hook = (void (*) __P ((__ptr_t stream))) free;
|
||||
}
|
||||
@ -1,456 +0,0 @@
|
||||
/* Variable expansion functions for GNU Make.
|
||||
Copyright (C) 1988, 89, 91, 92, 93, 95 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "commands.h"
|
||||
#include "file.h"
|
||||
#include "variable.h"
|
||||
|
||||
/* The next two describe the variable output buffer.
|
||||
This buffer is used to hold the variable-expansion of a line of the
|
||||
makefile. It is made bigger with realloc whenever it is too small.
|
||||
variable_buffer_length is the size currently allocated.
|
||||
variable_buffer is the address of the buffer. */
|
||||
|
||||
static unsigned int variable_buffer_length;
|
||||
static char *variable_buffer;
|
||||
|
||||
/* Subroutine of variable_expand and friends:
|
||||
The text to add is LENGTH chars starting at STRING to the variable_buffer.
|
||||
The text is added to the buffer at PTR, and the updated pointer into
|
||||
the buffer is returned as the value. Thus, the value returned by
|
||||
each call to variable_buffer_output should be the first argument to
|
||||
the following call. */
|
||||
|
||||
char *
|
||||
variable_buffer_output (ptr, string, length)
|
||||
char *ptr, *string;
|
||||
unsigned int length;
|
||||
{
|
||||
register unsigned int newlen = length + (ptr - variable_buffer);
|
||||
|
||||
if (newlen > variable_buffer_length)
|
||||
{
|
||||
unsigned int offset = ptr - variable_buffer;
|
||||
variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length
|
||||
? newlen + 100
|
||||
: 2 * variable_buffer_length);
|
||||
variable_buffer = (char *) xrealloc (variable_buffer,
|
||||
variable_buffer_length);
|
||||
ptr = variable_buffer + offset;
|
||||
}
|
||||
|
||||
bcopy (string, ptr, length);
|
||||
return ptr + length;
|
||||
}
|
||||
|
||||
/* Return a pointer to the beginning of the variable buffer. */
|
||||
|
||||
static char *
|
||||
initialize_variable_output ()
|
||||
{
|
||||
/* If we don't have a variable output buffer yet, get one. */
|
||||
|
||||
if (variable_buffer == 0)
|
||||
{
|
||||
variable_buffer_length = 200;
|
||||
variable_buffer = (char *) xmalloc (variable_buffer_length);
|
||||
variable_buffer[0] = '\0';
|
||||
}
|
||||
|
||||
return variable_buffer;
|
||||
}
|
||||
|
||||
/* Recursively expand V. The returned string is malloc'd. */
|
||||
|
||||
char *
|
||||
recursively_expand (v)
|
||||
register struct variable *v;
|
||||
{
|
||||
char *value;
|
||||
|
||||
if (v->expanding)
|
||||
{
|
||||
/* Expanding V causes infinite recursion. Lose. */
|
||||
if (reading_filename == 0)
|
||||
fatal ("Recursive variable `%s' references itself (eventually)",
|
||||
v->name);
|
||||
else
|
||||
makefile_fatal
|
||||
(reading_filename, *reading_lineno_ptr,
|
||||
"Recursive variable `%s' references itself (eventually)",
|
||||
v->name);
|
||||
}
|
||||
|
||||
v->expanding = 1;
|
||||
value = allocated_variable_expand (v->value);
|
||||
v->expanding = 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Warn that NAME is an undefined variable. */
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#endif
|
||||
static void
|
||||
warn_undefined (name, length)
|
||||
char *name;
|
||||
unsigned int length;
|
||||
{
|
||||
if (warn_undefined_variables_flag)
|
||||
{
|
||||
static const char warnmsg[] = "warning: undefined variable `%.*s'";
|
||||
if (reading_filename != 0)
|
||||
makefile_error (reading_filename, *reading_lineno_ptr,
|
||||
warnmsg, length, name);
|
||||
else
|
||||
error (warnmsg, length, name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Expand a simple reference to variable NAME, which is LENGTH chars long. */
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#endif
|
||||
static char *
|
||||
reference_variable (o, name, length)
|
||||
char *o;
|
||||
char *name;
|
||||
unsigned int length;
|
||||
{
|
||||
register struct variable *v = lookup_variable (name, length);
|
||||
|
||||
if (v == 0)
|
||||
warn_undefined (name, length);
|
||||
|
||||
if (v != 0 && *v->value != '\0')
|
||||
{
|
||||
char *value = (v->recursive ? recursively_expand (v) : v->value);
|
||||
o = variable_buffer_output (o, value, strlen (value));
|
||||
if (v->recursive)
|
||||
free (value);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
/* Scan LINE for variable references and expansion-function calls.
|
||||
Build in `variable_buffer' the result of expanding the references and calls.
|
||||
Return the address of the resulting string, which is null-terminated
|
||||
and is valid only until the next time this function is called. */
|
||||
|
||||
char *
|
||||
variable_expand (line)
|
||||
register char *line;
|
||||
{
|
||||
register struct variable *v;
|
||||
register char *p, *o, *p1;
|
||||
|
||||
p = line;
|
||||
o = initialize_variable_output ();
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Copy all following uninteresting chars all at once to the
|
||||
variable output buffer, and skip them. Uninteresting chars end
|
||||
at the next $ or the end of the input. */
|
||||
|
||||
p1 = index (p, '$');
|
||||
|
||||
o = variable_buffer_output (o, p, p1 != 0 ? p1 - p : strlen (p) + 1);
|
||||
|
||||
if (p1 == 0)
|
||||
break;
|
||||
p = p1 + 1;
|
||||
|
||||
/* Dispatch on the char that follows the $. */
|
||||
|
||||
switch (*p)
|
||||
{
|
||||
case '$':
|
||||
/* $$ seen means output one $ to the variable output buffer. */
|
||||
o = variable_buffer_output (o, p, 1);
|
||||
break;
|
||||
|
||||
case '(':
|
||||
case '{':
|
||||
/* $(...) or ${...} is the general case of substitution. */
|
||||
{
|
||||
char openparen = *p;
|
||||
char closeparen = (openparen == '(') ? ')' : '}';
|
||||
register char *beg = p + 1;
|
||||
int free_beg = 0;
|
||||
char *op, *begp;
|
||||
char *end, *colon;
|
||||
|
||||
op = o;
|
||||
begp = p;
|
||||
if (handle_function (&op, &begp))
|
||||
{
|
||||
o = op;
|
||||
p = begp;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Is there a variable reference inside the parens or braces?
|
||||
If so, expand it before expanding the entire reference. */
|
||||
|
||||
end = index (beg, closeparen);
|
||||
if (end == 0)
|
||||
{
|
||||
/* Unterminated variable reference. */
|
||||
if (reading_filename != 0)
|
||||
makefile_fatal (reading_filename, *reading_lineno_ptr,
|
||||
"unterminated variable reference");
|
||||
else
|
||||
fatal ("unterminated variable reference");
|
||||
}
|
||||
p1 = lindex (beg, end, '$');
|
||||
if (p1 != 0)
|
||||
{
|
||||
/* BEG now points past the opening paren or brace.
|
||||
Count parens or braces until it is matched. */
|
||||
int count = 0;
|
||||
for (p = beg; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == openparen)
|
||||
++count;
|
||||
else if (*p == closeparen && --count < 0)
|
||||
break;
|
||||
}
|
||||
/* If COUNT is >= 0, there were unmatched opening parens
|
||||
or braces, so we go to the simple case of a variable name
|
||||
such as `$($(a)'. */
|
||||
if (count < 0)
|
||||
{
|
||||
beg = expand_argument (beg, p); /* Expand the name. */
|
||||
free_beg = 1; /* Remember to free BEG when finished. */
|
||||
end = index (beg, '\0');
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Advance P to the end of this reference. After we are
|
||||
finished expanding this one, P will be incremented to
|
||||
continue the scan. */
|
||||
p = end;
|
||||
|
||||
/* This is not a reference to a built-in function and
|
||||
any variable references inside are now expanded.
|
||||
Is the resultant text a substitution reference? */
|
||||
|
||||
colon = lindex (beg, end, ':');
|
||||
if (colon != 0)
|
||||
{
|
||||
/* This looks like a substitution reference: $(FOO:A=B). */
|
||||
char *subst_beg, *subst_end, *replace_beg, *replace_end;
|
||||
|
||||
subst_beg = colon + 1;
|
||||
subst_end = index (subst_beg, '=');
|
||||
if (subst_end == 0)
|
||||
/* There is no = in sight. Punt on the substitution
|
||||
reference and treat this as a variable name containing
|
||||
a colon, in the code below. */
|
||||
colon = 0;
|
||||
else
|
||||
{
|
||||
replace_beg = subst_end + 1;
|
||||
replace_end = end;
|
||||
|
||||
/* Extract the variable name before the colon
|
||||
and look up that variable. */
|
||||
v = lookup_variable (beg, colon - beg);
|
||||
if (v == 0)
|
||||
warn_undefined (beg, colon - beg);
|
||||
|
||||
if (v != 0 && *v->value != '\0')
|
||||
{
|
||||
char *value = (v->recursive ? recursively_expand (v)
|
||||
: v->value);
|
||||
char *pattern, *percent;
|
||||
if (free_beg)
|
||||
{
|
||||
*subst_end = '\0';
|
||||
pattern = subst_beg;
|
||||
}
|
||||
else
|
||||
{
|
||||
pattern = (char *) alloca (subst_end - subst_beg
|
||||
+ 1);
|
||||
bcopy (subst_beg, pattern, subst_end - subst_beg);
|
||||
pattern[subst_end - subst_beg] = '\0';
|
||||
}
|
||||
percent = find_percent (pattern);
|
||||
if (percent != 0)
|
||||
{
|
||||
char *replace;
|
||||
if (free_beg)
|
||||
{
|
||||
*replace_end = '\0';
|
||||
replace = replace_beg;
|
||||
}
|
||||
else
|
||||
{
|
||||
replace = (char *) alloca (replace_end
|
||||
- replace_beg
|
||||
+ 1);
|
||||
bcopy (replace_beg, replace,
|
||||
replace_end - replace_beg);
|
||||
replace[replace_end - replace_beg] = '\0';
|
||||
}
|
||||
|
||||
o = patsubst_expand (o, value, pattern, replace,
|
||||
percent, (char *) 0);
|
||||
}
|
||||
else
|
||||
o = subst_expand (o, value,
|
||||
pattern, replace_beg,
|
||||
strlen (pattern),
|
||||
end - replace_beg,
|
||||
0, 1);
|
||||
if (v->recursive)
|
||||
free (value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (colon == 0)
|
||||
/* This is an ordinary variable reference.
|
||||
Look up the value of the variable. */
|
||||
o = reference_variable (o, beg, end - beg);
|
||||
|
||||
if (free_beg)
|
||||
free (beg);
|
||||
}
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isblank (p[-1]))
|
||||
break;
|
||||
|
||||
/* A $ followed by a random char is a variable reference:
|
||||
$a is equivalent to $(a). */
|
||||
{
|
||||
/* We could do the expanding here, but this way
|
||||
avoids code repetition at a small performance cost. */
|
||||
char name[5];
|
||||
name[0] = '$';
|
||||
name[1] = '(';
|
||||
name[2] = *p;
|
||||
name[3] = ')';
|
||||
name[4] = '\0';
|
||||
p1 = allocated_variable_expand (name);
|
||||
o = variable_buffer_output (o, p1, strlen (p1));
|
||||
free (p1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p == '\0')
|
||||
break;
|
||||
else
|
||||
++p;
|
||||
}
|
||||
|
||||
(void) variable_buffer_output (o, "", 1);
|
||||
return initialize_variable_output ();
|
||||
}
|
||||
|
||||
/* Expand an argument for an expansion function.
|
||||
The text starting at STR and ending at END is variable-expanded
|
||||
into a null-terminated string that is returned as the value.
|
||||
This is done without clobbering `variable_buffer' or the current
|
||||
variable-expansion that is in progress. */
|
||||
|
||||
char *
|
||||
expand_argument (str, end)
|
||||
char *str, *end;
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (*end == '\0')
|
||||
tmp = str;
|
||||
else
|
||||
{
|
||||
tmp = (char *) alloca (end - str + 1);
|
||||
bcopy (str, tmp, end - str);
|
||||
tmp[end - str] = '\0';
|
||||
}
|
||||
|
||||
return allocated_variable_expand (tmp);
|
||||
}
|
||||
|
||||
/* Expand LINE for FILE. Error messages refer to the file and line where
|
||||
FILE's commands were found. Expansion uses FILE's variable set list. */
|
||||
|
||||
char *
|
||||
variable_expand_for_file (line, file)
|
||||
char *line;
|
||||
register struct file *file;
|
||||
{
|
||||
char *result;
|
||||
struct variable_set_list *save;
|
||||
|
||||
if (file == 0)
|
||||
return variable_expand (line);
|
||||
|
||||
save = current_variable_set_list;
|
||||
current_variable_set_list = file->variables;
|
||||
reading_filename = file->cmds->filename;
|
||||
reading_lineno_ptr = &file->cmds->lineno;
|
||||
result = variable_expand (line);
|
||||
current_variable_set_list = save;
|
||||
reading_filename = 0;
|
||||
reading_lineno_ptr = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Like variable_expand_for_file, but the returned string is malloc'd.
|
||||
This function is called a lot. It wants to be efficient. */
|
||||
|
||||
char *
|
||||
allocated_variable_expand_for_file (line, file)
|
||||
char *line;
|
||||
struct file *file;
|
||||
{
|
||||
char *value;
|
||||
|
||||
char *obuf = variable_buffer;
|
||||
unsigned int olen = variable_buffer_length;
|
||||
|
||||
variable_buffer = 0;
|
||||
|
||||
value = variable_expand_for_file (line, file);
|
||||
|
||||
#if 0
|
||||
/* Waste a little memory and save time. */
|
||||
value = xrealloc (value, strlen (value))
|
||||
#endif
|
||||
|
||||
variable_buffer = obuf;
|
||||
variable_buffer_length = olen;
|
||||
|
||||
return value;
|
||||
}
|
||||
@ -1,566 +0,0 @@
|
||||
/* Target file hash table management for GNU Make.
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "commands.h"
|
||||
#include "dep.h"
|
||||
#include "file.h"
|
||||
#include "variable.h"
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
/* Hash table of files the makefile knows how to make. */
|
||||
|
||||
#ifndef FILE_BUCKETS
|
||||
#define FILE_BUCKETS 1007
|
||||
#endif
|
||||
static struct file *files[FILE_BUCKETS];
|
||||
|
||||
/* Number of files with the `intermediate' flag set. */
|
||||
|
||||
unsigned int num_intermediates = 0;
|
||||
|
||||
|
||||
/* Access the hash table of all file records.
|
||||
lookup_file given a name, return the struct file * for that name,
|
||||
or nil if there is none.
|
||||
enter_file similar, but create one if there is none. */
|
||||
|
||||
struct file *
|
||||
lookup_file (name)
|
||||
char *name;
|
||||
{
|
||||
register struct file *f;
|
||||
register char *n;
|
||||
register unsigned int hashval;
|
||||
|
||||
if (*name == '\0')
|
||||
abort ();
|
||||
|
||||
/* This is also done in parse_file_seq, so this is redundant
|
||||
for names read from makefiles. It is here for names passed
|
||||
on the command line. */
|
||||
while (name[0] == '.' && name[1] == '/' && name[2] != '\0')
|
||||
{
|
||||
name += 2;
|
||||
while (*name == '/')
|
||||
/* Skip following slashes: ".//foo" is "foo", not "/foo". */
|
||||
++name;
|
||||
}
|
||||
|
||||
if (*name == '\0')
|
||||
/* It was all slashes after a dot. */
|
||||
name = "./";
|
||||
|
||||
hashval = 0;
|
||||
for (n = name; *n != '\0'; ++n)
|
||||
HASH (hashval, *n);
|
||||
hashval %= FILE_BUCKETS;
|
||||
|
||||
for (f = files[hashval]; f != 0; f = f->next)
|
||||
if (streq (f->name, name))
|
||||
return f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct file *
|
||||
enter_file (name)
|
||||
char *name;
|
||||
{
|
||||
register struct file *f, *new;
|
||||
register char *n;
|
||||
register unsigned int hashval;
|
||||
|
||||
if (*name == '\0')
|
||||
abort ();
|
||||
|
||||
hashval = 0;
|
||||
for (n = name; *n != '\0'; ++n)
|
||||
HASH (hashval, *n);
|
||||
hashval %= FILE_BUCKETS;
|
||||
|
||||
for (f = files[hashval]; f != 0; f = f->next)
|
||||
if (streq (f->name, name))
|
||||
break;
|
||||
|
||||
if (f != 0 && !f->double_colon)
|
||||
return f;
|
||||
|
||||
new = (struct file *) xmalloc (sizeof (struct file));
|
||||
bzero ((char *) new, sizeof (struct file));
|
||||
new->name = name;
|
||||
new->update_status = -1;
|
||||
|
||||
if (f == 0)
|
||||
{
|
||||
/* This is a completely new file. */
|
||||
new->next = files[hashval];
|
||||
files[hashval] = new;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There is already a double-colon entry for this file. */
|
||||
new->double_colon = f;
|
||||
while (f->prev != 0)
|
||||
f = f->prev;
|
||||
f->prev = new;
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Rename FILE to NAME. This is not as simple as resetting
|
||||
the `name' member, since it must be put in a new hash bucket,
|
||||
and possibly merged with an existing file called NAME. */
|
||||
|
||||
void
|
||||
rename_file (file, name)
|
||||
register struct file *file;
|
||||
char *name;
|
||||
{
|
||||
char *oldname = file->name;
|
||||
register unsigned int oldhash;
|
||||
register char *n;
|
||||
|
||||
while (file->renamed != 0)
|
||||
file = file->renamed;
|
||||
|
||||
/* Find the hash values of the old and new names. */
|
||||
|
||||
oldhash = 0;
|
||||
for (n = oldname; *n != '\0'; ++n)
|
||||
HASH (oldhash, *n);
|
||||
|
||||
file_hash_enter (file, name, oldhash, file->name);
|
||||
}
|
||||
|
||||
void
|
||||
file_hash_enter (file, name, oldhash, oldname)
|
||||
register struct file *file;
|
||||
char *name;
|
||||
unsigned int oldhash;
|
||||
char *oldname;
|
||||
{
|
||||
unsigned int oldbucket = oldhash % FILE_BUCKETS;
|
||||
register unsigned int newhash, newbucket;
|
||||
struct file *oldfile;
|
||||
register char *n;
|
||||
register struct file *f;
|
||||
|
||||
newhash = 0;
|
||||
for (n = name; *n != '\0'; ++n)
|
||||
HASH (newhash, *n);
|
||||
newbucket = newhash % FILE_BUCKETS;
|
||||
|
||||
/* Look for an existing file under the new name. */
|
||||
|
||||
for (oldfile = files[newbucket]; oldfile != 0; oldfile = oldfile->next)
|
||||
if (streq (oldfile->name, name))
|
||||
break;
|
||||
|
||||
if (oldhash != 0 && (newbucket != oldbucket || oldfile != 0))
|
||||
{
|
||||
/* Remove FILE from its hash bucket. */
|
||||
|
||||
struct file *lastf = 0;
|
||||
|
||||
for (f = files[oldbucket]; f != file; f = f->next)
|
||||
lastf = f;
|
||||
|
||||
if (lastf == 0)
|
||||
files[oldbucket] = f->next;
|
||||
else
|
||||
lastf->next = f->next;
|
||||
}
|
||||
|
||||
/* Give FILE its new name. */
|
||||
|
||||
file->name = name;
|
||||
for (f = file->double_colon; f != 0; f = f->prev)
|
||||
f->name = name;
|
||||
|
||||
if (oldfile == 0)
|
||||
{
|
||||
/* There is no existing file with the new name. */
|
||||
|
||||
if (newbucket != oldbucket)
|
||||
{
|
||||
/* Put FILE in its new hash bucket. */
|
||||
file->next = files[newbucket];
|
||||
files[newbucket] = file;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There is an existing file with the new name.
|
||||
We must merge FILE into the existing file. */
|
||||
|
||||
register struct dep *d;
|
||||
|
||||
if (file->cmds != 0)
|
||||
{
|
||||
if (oldfile->cmds == 0)
|
||||
oldfile->cmds = file->cmds;
|
||||
else if (file->cmds != oldfile->cmds)
|
||||
{
|
||||
/* We have two sets of commands. We will go with the
|
||||
one given in the rule explicitly mentioning this name,
|
||||
but give a message to let the user know what's going on. */
|
||||
if (oldfile->cmds->filename != 0)
|
||||
makefile_error (file->cmds->filename, file->cmds->lineno,
|
||||
"Commands were specified for \
|
||||
file `%s' at %s:%u,",
|
||||
oldname, oldfile->cmds->filename,
|
||||
oldfile->cmds->lineno);
|
||||
else
|
||||
makefile_error (file->cmds->filename, file->cmds->lineno,
|
||||
"Commands for file `%s' were found by \
|
||||
implicit rule search,",
|
||||
oldname);
|
||||
makefile_error (file->cmds->filename, file->cmds->lineno,
|
||||
"but `%s' is now considered the same file \
|
||||
as `%s'.",
|
||||
oldname, name);
|
||||
makefile_error (file->cmds->filename, file->cmds->lineno,
|
||||
"Commands for `%s' will be ignored \
|
||||
in favor of those for `%s'.",
|
||||
name, oldname);
|
||||
}
|
||||
}
|
||||
|
||||
/* Merge the dependencies of the two files. */
|
||||
|
||||
d = oldfile->deps;
|
||||
if (d == 0)
|
||||
oldfile->deps = file->deps;
|
||||
else
|
||||
{
|
||||
while (d->next != 0)
|
||||
d = d->next;
|
||||
d->next = file->deps;
|
||||
}
|
||||
|
||||
merge_variable_set_lists (&oldfile->variables, file->variables);
|
||||
|
||||
if (oldfile->double_colon && !file->double_colon)
|
||||
fatal ("can't rename single-colon `%s' to double-colon `%s'",
|
||||
oldname, name);
|
||||
if (!oldfile->double_colon && file->double_colon)
|
||||
fatal ("can't rename double-colon `%s' to single-colon `%s'",
|
||||
oldname, name);
|
||||
|
||||
if (file->last_mtime > oldfile->last_mtime)
|
||||
/* %%% Kludge so -W wins on a file that gets vpathized. */
|
||||
oldfile->last_mtime = file->last_mtime;
|
||||
|
||||
#define MERGE(field) oldfile->field |= file->field
|
||||
MERGE (precious);
|
||||
MERGE (tried_implicit);
|
||||
MERGE (updating);
|
||||
MERGE (updated);
|
||||
MERGE (is_target);
|
||||
MERGE (cmd_target);
|
||||
MERGE (phony);
|
||||
#undef MERGE
|
||||
|
||||
file->renamed = oldfile;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all nonprecious intermediate files.
|
||||
If SIG is nonzero, this was caused by a fatal signal,
|
||||
meaning that a different message will be printed, and
|
||||
the message will go to stderr rather than stdout. */
|
||||
|
||||
void
|
||||
remove_intermediates (sig)
|
||||
int sig;
|
||||
{
|
||||
register int i;
|
||||
register struct file *f;
|
||||
char doneany;
|
||||
|
||||
if (question_flag || touch_flag)
|
||||
return;
|
||||
if (sig && just_print_flag)
|
||||
return;
|
||||
|
||||
doneany = 0;
|
||||
for (i = 0; i < FILE_BUCKETS; ++i)
|
||||
for (f = files[i]; f != 0; f = f->next)
|
||||
if (f->intermediate && (f->dontcare || !f->precious))
|
||||
{
|
||||
int status;
|
||||
if (f->update_status == -1)
|
||||
/* If nothing would have created this file yet,
|
||||
don't print an "rm" command for it. */
|
||||
continue;
|
||||
else if (just_print_flag)
|
||||
status = 0;
|
||||
else
|
||||
{
|
||||
status = unlink (f->name);
|
||||
if (status < 0 && errno == ENOENT)
|
||||
continue;
|
||||
}
|
||||
if (!f->dontcare)
|
||||
{
|
||||
if (sig)
|
||||
error ("*** Deleting intermediate file `%s'", f->name);
|
||||
else if (!silent_flag)
|
||||
{
|
||||
if (! doneany)
|
||||
{
|
||||
fputs ("rm ", stdout);
|
||||
doneany = 1;
|
||||
}
|
||||
else
|
||||
putchar (' ');
|
||||
fputs (f->name, stdout);
|
||||
fflush (stdout);
|
||||
}
|
||||
if (status < 0)
|
||||
perror_with_name ("unlink: ", f->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (doneany && !sig)
|
||||
{
|
||||
putchar ('\n');
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/* For each dependency of each file, make the `struct dep' point
|
||||
at the appropriate `struct file' (which may have to be created).
|
||||
|
||||
Also mark the files depended on by .PRECIOUS and .PHONY. */
|
||||
|
||||
void
|
||||
snap_deps ()
|
||||
{
|
||||
register struct file *f, *f2;
|
||||
register struct dep *d;
|
||||
register int i;
|
||||
|
||||
/* Enter each dependency name as a file. */
|
||||
for (i = 0; i < FILE_BUCKETS; ++i)
|
||||
for (f = files[i]; f != 0; f = f->next)
|
||||
for (f2 = f; f2 != 0; f2 = f2->prev)
|
||||
for (d = f2->deps; d != 0; d = d->next)
|
||||
if (d->name != 0)
|
||||
{
|
||||
d->file = lookup_file (d->name);
|
||||
if (d->file == 0)
|
||||
d->file = enter_file (d->name);
|
||||
else
|
||||
free (d->name);
|
||||
d->name = 0;
|
||||
}
|
||||
|
||||
for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
f2->precious = 1;
|
||||
|
||||
for (f = lookup_file (".PHONY"); f != 0; f = f->prev)
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
{
|
||||
/* Mark this file as phony and nonexistent. */
|
||||
f2->phony = 1;
|
||||
f2->last_mtime = (time_t) -1;
|
||||
}
|
||||
|
||||
f = lookup_file (".EXPORT_ALL_VARIABLES");
|
||||
if (f != 0 && f->is_target)
|
||||
export_all_variables = 1;
|
||||
|
||||
f = lookup_file (".IGNORE");
|
||||
if (f != 0 && f->is_target)
|
||||
{
|
||||
if (f->deps == 0)
|
||||
ignore_errors_flag = 1;
|
||||
else
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
f2->command_flags |= COMMANDS_NOERROR;
|
||||
}
|
||||
|
||||
f = lookup_file (".SILENT");
|
||||
if (f != 0 && f->is_target)
|
||||
{
|
||||
if (f->deps == 0)
|
||||
silent_flag = 1;
|
||||
else
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
f2->command_flags |= COMMANDS_SILENT;
|
||||
}
|
||||
|
||||
f = lookup_file (".POSIX");
|
||||
if (f != 0 && f->is_target)
|
||||
posix_pedantic = 1;
|
||||
}
|
||||
|
||||
/* Set the `command_state' member of FILE and all its `also_make's. */
|
||||
|
||||
void
|
||||
set_command_state (file, state)
|
||||
struct file *file;
|
||||
int state;
|
||||
{
|
||||
struct dep *d;
|
||||
|
||||
file->command_state = state;
|
||||
|
||||
for (d = file->also_make; d != 0; d = d->next)
|
||||
d->file->command_state = state;
|
||||
}
|
||||
|
||||
/* Print the data base of files. */
|
||||
|
||||
static void
|
||||
print_file (f)
|
||||
struct file *f;
|
||||
{
|
||||
register struct dep *d;
|
||||
|
||||
putchar ('\n');
|
||||
if (!f->is_target)
|
||||
puts ("# Not a target:");
|
||||
printf ("%s:%s", f->name, f->double_colon ? ":" : "");
|
||||
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
printf (" %s", dep_name (d));
|
||||
putchar ('\n');
|
||||
|
||||
if (f->precious)
|
||||
puts ("# Precious file (dependency of .PRECIOUS).");
|
||||
if (f->phony)
|
||||
puts ("# Phony target (dependency of .PHONY).");
|
||||
if (f->cmd_target)
|
||||
puts ("# Command-line target.");
|
||||
if (f->dontcare)
|
||||
puts ("# A default or MAKEFILES makefile.");
|
||||
printf ("# Implicit rule search has%s been done.\n",
|
||||
f->tried_implicit ? "" : " not");
|
||||
if (f->stem != 0)
|
||||
printf ("# Implicit/static pattern stem: `%s'\n", f->stem);
|
||||
if (f->intermediate)
|
||||
puts ("# File is an intermediate dependency.");
|
||||
if (f->also_make != 0)
|
||||
{
|
||||
fputs ("# Also makes:", stdout);
|
||||
for (d = f->also_make; d != 0; d = d->next)
|
||||
printf (" %s", dep_name (d));
|
||||
putchar ('\n');
|
||||
}
|
||||
if (f->last_mtime == (time_t) 0)
|
||||
puts ("# Modification time never checked.");
|
||||
else if (f->last_mtime == (time_t) -1)
|
||||
puts ("# File does not exist.");
|
||||
else
|
||||
printf ("# Last modified %.24s (%ld)\n",
|
||||
ctime (&f->last_mtime), (long int) f->last_mtime);
|
||||
printf ("# File has%s been updated.\n",
|
||||
f->updated ? "" : " not");
|
||||
switch (f->command_state)
|
||||
{
|
||||
case cs_running:
|
||||
puts ("# Commands currently running (THIS IS A BUG).");
|
||||
break;
|
||||
case cs_deps_running:
|
||||
puts ("# Dependencies commands running (THIS IS A BUG).");
|
||||
break;
|
||||
case cs_not_started:
|
||||
case cs_finished:
|
||||
switch (f->update_status)
|
||||
{
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
puts ("# Successfully updated.");
|
||||
break;
|
||||
case 1:
|
||||
assert (question_flag);
|
||||
puts ("# Needs to be updated (-q is set).");
|
||||
break;
|
||||
case 2:
|
||||
puts ("# Failed to be updated.");
|
||||
break;
|
||||
default:
|
||||
puts ("# Invalid value in `update_status' member!");
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
abort ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
puts ("# Invalid value in `command_state' member!");
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (f->variables != 0)
|
||||
print_file_variables (f);
|
||||
|
||||
if (f->cmds != 0)
|
||||
print_commands (f->cmds);
|
||||
}
|
||||
|
||||
void
|
||||
print_file_data_base ()
|
||||
{
|
||||
register unsigned int i, nfiles, per_bucket;
|
||||
register struct file *file;
|
||||
|
||||
puts ("\n# Files");
|
||||
|
||||
per_bucket = nfiles = 0;
|
||||
for (i = 0; i < FILE_BUCKETS; ++i)
|
||||
{
|
||||
register unsigned int this_bucket = 0;
|
||||
|
||||
for (file = files[i]; file != 0; file = file->next)
|
||||
{
|
||||
register struct file *f;
|
||||
|
||||
++this_bucket;
|
||||
|
||||
for (f = file; f != 0; f = f->prev)
|
||||
print_file (f);
|
||||
}
|
||||
|
||||
nfiles += this_bucket;
|
||||
if (this_bucket > per_bucket)
|
||||
per_bucket = this_bucket;
|
||||
}
|
||||
|
||||
if (nfiles == 0)
|
||||
puts ("\n# No files.");
|
||||
else
|
||||
{
|
||||
printf ("\n# %u files in %u hash buckets.\n", nfiles, FILE_BUCKETS);
|
||||
#ifndef NO_FLOAT
|
||||
printf ("# average %.1f files per bucket, max %u files in one bucket.\n",
|
||||
((double) nfiles) / ((double) FILE_BUCKETS) * 100.0, per_bucket);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1,111 +0,0 @@
|
||||
/* Definition of target file data structures for GNU Make.
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Structure that represents the info on one file
|
||||
that the makefile says how to make.
|
||||
All of these are chained together through `next'. */
|
||||
|
||||
struct file
|
||||
{
|
||||
struct file *next;
|
||||
char *name;
|
||||
struct dep *deps;
|
||||
struct commands *cmds; /* Commands to execute for this target. */
|
||||
int command_flags; /* Flags OR'd in for cmds; see commands.h. */
|
||||
char *stem; /* Implicit stem, if an implicit
|
||||
rule has been used */
|
||||
struct dep *also_make; /* Targets that are made by making this. */
|
||||
time_t last_mtime; /* File's modtime, if already known. */
|
||||
struct file *prev; /* Previous entry for same file name;
|
||||
used when there are multiple double-colon
|
||||
entries for the same file. */
|
||||
|
||||
/* File that this file was renamed to. After any time that a
|
||||
file could be renamed, call `check_renamed' (below). */
|
||||
struct file *renamed;
|
||||
|
||||
/* List of variable sets used for this file. */
|
||||
struct variable_set_list *variables;
|
||||
|
||||
/* Immediate dependent that caused this target to be remade,
|
||||
or nil if there isn't one. */
|
||||
struct file *parent;
|
||||
|
||||
/* For a double-colon entry, this is the first double-colon entry for
|
||||
the same file. Otherwise this is null. */
|
||||
struct file *double_colon;
|
||||
|
||||
short int update_status; /* Status of the last attempt to update,
|
||||
or -1 if none has been made. */
|
||||
|
||||
enum /* State of the commands. */
|
||||
{ /* Note: It is important that cs_not_started be zero. */
|
||||
cs_not_started, /* Not yet started. */
|
||||
cs_deps_running, /* Dep commands running. */
|
||||
cs_running, /* Commands running. */
|
||||
cs_finished /* Commands finished. */
|
||||
} command_state ENUM_BITFIELD (2);
|
||||
|
||||
unsigned int precious:1; /* Non-0 means don't delete file on quit */
|
||||
unsigned int tried_implicit:1; /* Nonzero if have searched
|
||||
for implicit rule for making
|
||||
this file; don't search again. */
|
||||
unsigned int updating:1; /* Nonzero while updating deps of this file */
|
||||
unsigned int updated:1; /* Nonzero if this file has been remade. */
|
||||
unsigned int is_target:1; /* Nonzero if file is described as target. */
|
||||
unsigned int cmd_target:1; /* Nonzero if file was given on cmd line. */
|
||||
unsigned int phony:1; /* Nonzero if this is a phony file
|
||||
i.e., a dependency of .PHONY. */
|
||||
unsigned int intermediate:1;/* Nonzero if this is an intermediate file. */
|
||||
unsigned int dontcare:1; /* Nonzero if no complaint is to be made if
|
||||
this target cannot be remade. */
|
||||
};
|
||||
|
||||
/* Number of intermediate files entered. */
|
||||
|
||||
extern unsigned int num_intermediates;
|
||||
|
||||
extern struct file *default_goal_file, *suffix_file, *default_file;
|
||||
|
||||
|
||||
extern struct file *lookup_file (), *enter_file ();
|
||||
extern void remove_intermediates (), snap_deps ();
|
||||
extern void rename_file (), file_hash_enter ();
|
||||
extern void set_command_state ();
|
||||
|
||||
|
||||
extern time_t f_mtime ();
|
||||
#define file_mtime_1(f, v) \
|
||||
((f)->last_mtime != (time_t) 0 ? (f)->last_mtime : f_mtime ((f), v))
|
||||
#define file_mtime(f) file_mtime_1 ((f), 1)
|
||||
#define file_mtime_no_search(f) file_mtime_1 ((f), 0)
|
||||
|
||||
/* Modtime value to use for `infinitely new'. We used to get the current time
|
||||
from the system and use that whenever we wanted `new'. But that causes
|
||||
trouble when the machine running make and the machine holding a file have
|
||||
different ideas about what time it is; and can also lose for `force'
|
||||
targets, which need to be considered newer than anything that depends on
|
||||
them, even if said dependents' modtimes are in the future.
|
||||
|
||||
NOTE: This assumes 32-bit `time_t's, but I cannot think of a portable way
|
||||
to produce the largest representable integer of a given signed type. */
|
||||
#define NEW_MTIME ((time_t) 0x7fffffff)
|
||||
|
||||
|
||||
#define check_renamed(file) \
|
||||
while ((file)->renamed != 0) (file) = (file)->renamed /* No ; here. */
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,938 +0,0 @@
|
||||
/* Get the system load averages.
|
||||
Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994, 1995
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Compile-time symbols that this file uses:
|
||||
|
||||
FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist.
|
||||
KERNEL_FILE Pathname of the kernel to nlist.
|
||||
LDAV_CVT() Scale the load average from the kernel.
|
||||
Returns a double.
|
||||
LDAV_SYMBOL Name of kernel symbol giving load average.
|
||||
LOAD_AVE_TYPE Type of the load average array in the kernel.
|
||||
Must be defined unless one of
|
||||
apollo, DGUX, NeXT, or UMAX is defined;
|
||||
otherwise, no load average is available.
|
||||
NLIST_STRUCT Include nlist.h, not a.out.h, and
|
||||
the nlist n_name element is a pointer,
|
||||
not an array.
|
||||
NLIST_NAME_UNION struct nlist has an n_un member, not n_name.
|
||||
LINUX_LDAV_FILE [__linux__]: File containing load averages.
|
||||
|
||||
Specific system predefines this file uses, aside from setting
|
||||
default values if not emacs:
|
||||
|
||||
apollo
|
||||
BSD Real BSD, not just BSD-like.
|
||||
DGUX
|
||||
eunice UNIX emulator under VMS.
|
||||
hpux
|
||||
NeXT
|
||||
sgi
|
||||
sequent Sequent Dynix 3.x.x (BSD)
|
||||
_SEQUENT_ Sequent DYNIX/ptx 1.x.x (SYSV)
|
||||
sony_news NEWS-OS (works at least for 4.1C)
|
||||
UMAX
|
||||
UMAX4_3
|
||||
VMS
|
||||
__linux__ Linux: assumes /proc filesystem mounted.
|
||||
Support from Michael K. Johnson.
|
||||
__NetBSD__ NetBSD: assumes /kern filesystem mounted.
|
||||
|
||||
In addition, to avoid nesting many #ifdefs, we internally set
|
||||
LDAV_DONE to indicate that the load average has been computed.
|
||||
|
||||
We also #define LDAV_PRIVILEGED if a program will require
|
||||
special installation to be able to call getloadavg. */
|
||||
|
||||
/* This should always be first. */
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Both the Emacs and non-Emacs sections want this. Some
|
||||
configuration files' definitions for the LOAD_AVE_CVT macro (like
|
||||
sparc.h's) use macros like FSCALE, defined here. */
|
||||
#ifdef unix
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Exclude all the code except the test program at the end
|
||||
if the system has its own `getloadavg' function.
|
||||
|
||||
The declaration of `errno' is needed by the test program
|
||||
as well as the function itself, so it comes first. */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETLOADAVG
|
||||
|
||||
|
||||
/* The existing Emacs configuration files define a macro called
|
||||
LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and
|
||||
returns the load average multiplied by 100. What we actually want
|
||||
is a macro called LDAV_CVT, which returns the load average as an
|
||||
unmultiplied double.
|
||||
|
||||
For backwards compatibility, we'll define LDAV_CVT in terms of
|
||||
LOAD_AVE_CVT, but future machine config files should just define
|
||||
LDAV_CVT directly. */
|
||||
|
||||
#if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT)
|
||||
#define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0)
|
||||
#endif
|
||||
|
||||
#if !defined (BSD) && defined (ultrix)
|
||||
/* Ultrix behaves like BSD on Vaxen. */
|
||||
#define BSD
|
||||
#endif
|
||||
|
||||
#ifdef NeXT
|
||||
/* NeXT in the 2.{0,1,2} releases defines BSD in <sys/param.h>, which
|
||||
conflicts with the definition understood in this file, that this
|
||||
really is BSD. */
|
||||
#undef BSD
|
||||
|
||||
/* NeXT defines FSCALE in <sys/param.h>. However, we take FSCALE being
|
||||
defined to mean that the nlist method should be used, which is not true. */
|
||||
#undef FSCALE
|
||||
#endif
|
||||
|
||||
/* Set values that are different from the defaults, which are
|
||||
set a little farther down with #ifndef. */
|
||||
|
||||
|
||||
/* Some shorthands. */
|
||||
|
||||
#if defined (HPUX) && !defined (hpux)
|
||||
#define hpux
|
||||
#endif
|
||||
|
||||
#if defined(hp300) && !defined(hpux)
|
||||
#define MORE_BSD
|
||||
#endif
|
||||
|
||||
#if defined(ultrix) && defined(mips)
|
||||
#define decstation
|
||||
#endif
|
||||
|
||||
#if defined(sun) && defined(SVR4)
|
||||
#define SUNOS_5
|
||||
#endif
|
||||
|
||||
#if defined (__osf__) && (defined (__alpha) || defined (__alpha__))
|
||||
#define OSF_ALPHA
|
||||
#include <sys/table.h>
|
||||
#endif
|
||||
|
||||
#if defined (__osf__) && (defined (mips) || defined (__mips__))
|
||||
#define OSF_MIPS
|
||||
#include <sys/table.h>
|
||||
#endif
|
||||
|
||||
/* UTek's /bin/cc on the 4300 has no architecture specific cpp define by
|
||||
default, but _MACH_IND_SYS_TYPES is defined in <sys/types.h>. Combine
|
||||
that with a couple of other things and we'll have a unique match. */
|
||||
#if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES)
|
||||
#define tek4300 /* Define by emacs, but not by other users. */
|
||||
#endif
|
||||
|
||||
|
||||
/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */
|
||||
#ifndef LOAD_AVE_TYPE
|
||||
|
||||
#ifdef MORE_BSD
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#ifdef sun
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#ifdef decstation
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#ifdef _SEQUENT_
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#ifdef sgi
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#ifdef SVR4
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#ifdef sony_news
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#ifdef sequent
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#ifdef OSF_ALPHA
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#if defined (ardent) && defined (titan)
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#ifdef tek4300
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#if defined(alliant) && defined(i860) /* Alliant FX/2800 */
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
#define LOAD_AVE_TYPE long
|
||||
#endif
|
||||
|
||||
#endif /* No LOAD_AVE_TYPE. */
|
||||
|
||||
#ifdef OSF_ALPHA
|
||||
/* <sys/param.h> defines an incorrect value for FSCALE on Alpha OSF/1,
|
||||
according to ghazi@noc.rutgers.edu. */
|
||||
#undef FSCALE
|
||||
#define FSCALE 1024.0
|
||||
#endif
|
||||
|
||||
#if defined(alliant) && defined(i860) /* Alliant FX/2800 */
|
||||
/* <sys/param.h> defines an incorrect value for FSCALE on an
|
||||
Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu. */
|
||||
#undef FSCALE
|
||||
#define FSCALE 100.0
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef FSCALE
|
||||
|
||||
/* SunOS and some others define FSCALE in sys/param.h. */
|
||||
|
||||
#ifdef MORE_BSD
|
||||
#define FSCALE 2048.0
|
||||
#endif
|
||||
|
||||
#if defined(MIPS) || defined(SVR4) || defined(decstation)
|
||||
#define FSCALE 256
|
||||
#endif
|
||||
|
||||
#if defined (sgi) || defined (sequent)
|
||||
/* Sometimes both MIPS and sgi are defined, so FSCALE was just defined
|
||||
above under #ifdef MIPS. But we want the sgi value. */
|
||||
#undef FSCALE
|
||||
#define FSCALE 1000.0
|
||||
#endif
|
||||
|
||||
#if defined (ardent) && defined (titan)
|
||||
#define FSCALE 65536.0
|
||||
#endif
|
||||
|
||||
#ifdef tek4300
|
||||
#define FSCALE 100.0
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
#define FSCALE 65536.0
|
||||
#endif
|
||||
|
||||
#endif /* Not FSCALE. */
|
||||
|
||||
#if !defined (LDAV_CVT) && defined (FSCALE)
|
||||
#define LDAV_CVT(n) (((double) (n)) / FSCALE)
|
||||
#endif
|
||||
|
||||
/* VAX C can't handle multi-line #ifs, or lines longer that 256 characters. */
|
||||
#ifndef NLIST_STRUCT
|
||||
|
||||
#ifdef MORE_BSD
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#ifdef sun
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#ifdef decstation
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#ifdef hpux
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#if defined (_SEQUENT_) || defined (sequent)
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#ifdef sgi
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#ifdef SVR4
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#ifdef sony_news
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#ifdef OSF_ALPHA
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#if defined (ardent) && defined (titan)
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#ifdef tek4300
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#ifdef butterfly
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#if defined(alliant) && defined(i860) /* Alliant FX/2800 */
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
#define NLIST_STRUCT
|
||||
#endif
|
||||
|
||||
#endif /* defined (NLIST_STRUCT) */
|
||||
|
||||
|
||||
#if defined(sgi) || (defined(mips) && !defined(BSD))
|
||||
#define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31))
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined (KERNEL_FILE) && defined (sequent)
|
||||
#define KERNEL_FILE "/dynix"
|
||||
#endif
|
||||
|
||||
#if !defined (KERNEL_FILE) && defined (hpux)
|
||||
#define KERNEL_FILE "/hp-ux"
|
||||
#endif
|
||||
|
||||
#if !defined(KERNEL_FILE) && (defined(_SEQUENT_) || defined(MIPS) || defined(SVR4) || defined(ISC) || defined (sgi) || defined(SVR4) || (defined (ardent) && defined (titan)))
|
||||
#define KERNEL_FILE "/unix"
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined (LDAV_SYMBOL) && defined (alliant)
|
||||
#define LDAV_SYMBOL "_Loadavg"
|
||||
#endif
|
||||
|
||||
#if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX))
|
||||
#define LDAV_SYMBOL "avenrun"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* LOAD_AVE_TYPE should only get defined if we're going to use the
|
||||
nlist method. */
|
||||
#if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL))
|
||||
#define LOAD_AVE_TYPE double
|
||||
#endif
|
||||
|
||||
#ifdef LOAD_AVE_TYPE
|
||||
|
||||
#ifndef VMS
|
||||
#ifndef NLIST_STRUCT
|
||||
#include <a.out.h>
|
||||
#else /* NLIST_STRUCT */
|
||||
#include <nlist.h>
|
||||
#endif /* NLIST_STRUCT */
|
||||
|
||||
#ifdef SUNOS_5
|
||||
#include <fcntl.h>
|
||||
#include <kvm.h>
|
||||
#endif
|
||||
|
||||
#ifndef KERNEL_FILE
|
||||
#define KERNEL_FILE "/vmunix"
|
||||
#endif /* KERNEL_FILE */
|
||||
|
||||
#ifndef LDAV_SYMBOL
|
||||
#define LDAV_SYMBOL "_avenrun"
|
||||
#endif /* LDAV_SYMBOL */
|
||||
|
||||
#else /* VMS */
|
||||
|
||||
#ifndef eunice
|
||||
#include <iodef.h>
|
||||
#include <descrip.h>
|
||||
#else /* eunice */
|
||||
#include <vms/iodef.h>
|
||||
#endif /* eunice */
|
||||
#endif /* VMS */
|
||||
|
||||
#ifndef LDAV_CVT
|
||||
#define LDAV_CVT(n) ((double) (n))
|
||||
#endif /* !LDAV_CVT */
|
||||
|
||||
#endif /* LOAD_AVE_TYPE */
|
||||
|
||||
#ifdef NeXT
|
||||
#ifdef HAVE_MACH_MACH_H
|
||||
#include <mach/mach.h>
|
||||
#else
|
||||
#include <mach.h>
|
||||
#endif
|
||||
#endif /* NeXT */
|
||||
|
||||
#ifdef sgi
|
||||
#include <sys/sysmp.h>
|
||||
#endif /* sgi */
|
||||
|
||||
#ifdef UMAX
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#ifdef UMAX_43
|
||||
#include <machine/cpu.h>
|
||||
#include <inq_stats/statistics.h>
|
||||
#include <inq_stats/sysstats.h>
|
||||
#include <inq_stats/cpustats.h>
|
||||
#include <inq_stats/procstats.h>
|
||||
#else /* Not UMAX_43. */
|
||||
#include <sys/sysdefs.h>
|
||||
#include <sys/statistics.h>
|
||||
#include <sys/sysstats.h>
|
||||
#include <sys/cpudefs.h>
|
||||
#include <sys/cpustats.h>
|
||||
#include <sys/procstats.h>
|
||||
#endif /* Not UMAX_43. */
|
||||
#endif /* UMAX */
|
||||
|
||||
#ifdef DGUX
|
||||
#include <sys/dg_sys_info.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION)
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
/* Avoid static vars inside a function since in HPUX they dump as pure. */
|
||||
|
||||
#ifdef NeXT
|
||||
static processor_set_t default_set;
|
||||
static int getloadavg_initialized;
|
||||
#endif /* NeXT */
|
||||
|
||||
#ifdef UMAX
|
||||
static unsigned int cpus = 0;
|
||||
static unsigned int samples;
|
||||
#endif /* UMAX */
|
||||
|
||||
#ifdef DGUX
|
||||
static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */
|
||||
#endif /* DGUX */
|
||||
|
||||
#ifdef LOAD_AVE_TYPE
|
||||
/* File descriptor open to /dev/kmem or VMS load ave driver. */
|
||||
static int channel;
|
||||
/* Nonzero iff channel is valid. */
|
||||
static int getloadavg_initialized;
|
||||
/* Offset in kmem to seek to read load average, or 0 means invalid. */
|
||||
static long offset;
|
||||
|
||||
#if !defined(VMS) && !defined(sgi)
|
||||
static struct nlist nl[2];
|
||||
#endif /* Not VMS or sgi */
|
||||
|
||||
#ifdef SUNOS_5
|
||||
static kvm_t *kd;
|
||||
#endif /* SUNOS_5 */
|
||||
|
||||
#endif /* LOAD_AVE_TYPE */
|
||||
|
||||
/* Put the 1 minute, 5 minute and 15 minute load averages
|
||||
into the first NELEM elements of LOADAVG.
|
||||
Return the number written (never more than 3, but may be less than NELEM),
|
||||
or -1 if an error occurred. */
|
||||
|
||||
int
|
||||
getloadavg (loadavg, nelem)
|
||||
double loadavg[];
|
||||
int nelem;
|
||||
{
|
||||
int elem = 0; /* Return value. */
|
||||
|
||||
#ifdef NO_GET_LOAD_AVG
|
||||
#define LDAV_DONE
|
||||
/* Set errno to zero to indicate that there was no particular error;
|
||||
this function just can't work at all on this system. */
|
||||
errno = 0;
|
||||
elem = -1;
|
||||
#endif
|
||||
|
||||
#if !defined (LDAV_DONE) && defined (__linux__)
|
||||
#define LDAV_DONE
|
||||
#undef LOAD_AVE_TYPE
|
||||
|
||||
#ifndef LINUX_LDAV_FILE
|
||||
#define LINUX_LDAV_FILE "/proc/loadavg"
|
||||
#endif
|
||||
|
||||
char ldavgbuf[40];
|
||||
double load_ave[3];
|
||||
int fd, count;
|
||||
|
||||
fd = open (LINUX_LDAV_FILE, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
count = read (fd, ldavgbuf, 40);
|
||||
(void) close (fd);
|
||||
if (count <= 0)
|
||||
return -1;
|
||||
|
||||
count = sscanf (ldavgbuf, "%lf %lf %lf",
|
||||
&load_ave[0], &load_ave[1], &load_ave[2]);
|
||||
if (count < 1)
|
||||
return -1;
|
||||
|
||||
for (elem = 0; elem < nelem && elem < count; elem++)
|
||||
loadavg[elem] = load_ave[elem];
|
||||
|
||||
return elem;
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
#if !defined (LDAV_DONE) && defined (__NetBSD__)
|
||||
#define LDAV_DONE
|
||||
#undef LOAD_AVE_TYPE
|
||||
|
||||
#ifndef NETBSD_LDAV_FILE
|
||||
#define NETBSD_LDAV_FILE "/kern/loadavg"
|
||||
#endif
|
||||
|
||||
unsigned long int load_ave[3], scale;
|
||||
int count;
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen (NETBSD_LDAV_FILE, "r");
|
||||
if (fp == NULL)
|
||||
return -1;
|
||||
count = fscanf (fp, "%lu %lu %lu %lu\n",
|
||||
&load_ave[0], &load_ave[1], &load_ave[2],
|
||||
&scale);
|
||||
(void) fclose (fp);
|
||||
if (count != 4)
|
||||
return -1;
|
||||
|
||||
for (elem = 0; elem < nelem; elem++)
|
||||
loadavg[elem] = (double) load_ave[elem] / (double) scale;
|
||||
|
||||
return elem;
|
||||
|
||||
#endif /* __NetBSD__ */
|
||||
|
||||
#if !defined (LDAV_DONE) && defined (NeXT)
|
||||
#define LDAV_DONE
|
||||
/* The NeXT code was adapted from iscreen 3.2. */
|
||||
|
||||
host_t host;
|
||||
struct processor_set_basic_info info;
|
||||
unsigned info_count;
|
||||
|
||||
/* We only know how to get the 1-minute average for this system,
|
||||
so even if the caller asks for more than 1, we only return 1. */
|
||||
|
||||
if (!getloadavg_initialized)
|
||||
{
|
||||
if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
|
||||
getloadavg_initialized = 1;
|
||||
}
|
||||
|
||||
if (getloadavg_initialized)
|
||||
{
|
||||
info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
|
||||
if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
|
||||
(processor_set_info_t) &info, &info_count)
|
||||
!= KERN_SUCCESS)
|
||||
getloadavg_initialized = 0;
|
||||
else
|
||||
{
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = (double) info.load_average / LOAD_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!getloadavg_initialized)
|
||||
return -1;
|
||||
#endif /* NeXT */
|
||||
|
||||
#if !defined (LDAV_DONE) && defined (UMAX)
|
||||
#define LDAV_DONE
|
||||
/* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
|
||||
have a /dev/kmem. Information about the workings of the running kernel
|
||||
can be gathered with inq_stats system calls.
|
||||
We only know how to get the 1-minute average for this system. */
|
||||
|
||||
struct proc_summary proc_sum_data;
|
||||
struct stat_descr proc_info;
|
||||
double load;
|
||||
register unsigned int i, j;
|
||||
|
||||
if (cpus == 0)
|
||||
{
|
||||
register unsigned int c, i;
|
||||
struct cpu_config conf;
|
||||
struct stat_descr desc;
|
||||
|
||||
desc.sd_next = 0;
|
||||
desc.sd_subsys = SUBSYS_CPU;
|
||||
desc.sd_type = CPUTYPE_CONFIG;
|
||||
desc.sd_addr = (char *) &conf;
|
||||
desc.sd_size = sizeof conf;
|
||||
|
||||
if (inq_stats (1, &desc))
|
||||
return -1;
|
||||
|
||||
c = 0;
|
||||
for (i = 0; i < conf.config_maxclass; ++i)
|
||||
{
|
||||
struct class_stats stats;
|
||||
bzero ((char *) &stats, sizeof stats);
|
||||
|
||||
desc.sd_type = CPUTYPE_CLASS;
|
||||
desc.sd_objid = i;
|
||||
desc.sd_addr = (char *) &stats;
|
||||
desc.sd_size = sizeof stats;
|
||||
|
||||
if (inq_stats (1, &desc))
|
||||
return -1;
|
||||
|
||||
c += stats.class_numcpus;
|
||||
}
|
||||
cpus = c;
|
||||
samples = cpus < 2 ? 3 : (2 * cpus / 3);
|
||||
}
|
||||
|
||||
proc_info.sd_next = 0;
|
||||
proc_info.sd_subsys = SUBSYS_PROC;
|
||||
proc_info.sd_type = PROCTYPE_SUMMARY;
|
||||
proc_info.sd_addr = (char *) &proc_sum_data;
|
||||
proc_info.sd_size = sizeof (struct proc_summary);
|
||||
proc_info.sd_sizeused = 0;
|
||||
|
||||
if (inq_stats (1, &proc_info) != 0)
|
||||
return -1;
|
||||
|
||||
load = proc_sum_data.ps_nrunnable;
|
||||
j = 0;
|
||||
for (i = samples - 1; i > 0; --i)
|
||||
{
|
||||
load += proc_sum_data.ps_nrun[j];
|
||||
if (j++ == PS_NRUNSIZE)
|
||||
j = 0;
|
||||
}
|
||||
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = load / samples / cpus;
|
||||
#endif /* UMAX */
|
||||
|
||||
#if !defined (LDAV_DONE) && defined (DGUX)
|
||||
#define LDAV_DONE
|
||||
/* This call can return -1 for an error, but with good args
|
||||
it's not supposed to fail. The first argument is for no
|
||||
apparent reason of type `long int *'. */
|
||||
dg_sys_info ((long int *) &load_info,
|
||||
DG_SYS_INFO_LOAD_INFO_TYPE,
|
||||
DG_SYS_INFO_LOAD_VERSION_0);
|
||||
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = load_info.one_minute;
|
||||
if (nelem > 1)
|
||||
loadavg[elem++] = load_info.five_minute;
|
||||
if (nelem > 2)
|
||||
loadavg[elem++] = load_info.fifteen_minute;
|
||||
#endif /* DGUX */
|
||||
|
||||
#if !defined (LDAV_DONE) && defined (apollo)
|
||||
#define LDAV_DONE
|
||||
/* Apollo code from lisch@mentorg.com (Ray Lischner).
|
||||
|
||||
This system call is not documented. The load average is obtained as
|
||||
three long integers, for the load average over the past minute,
|
||||
five minutes, and fifteen minutes. Each value is a scaled integer,
|
||||
with 16 bits of integer part and 16 bits of fraction part.
|
||||
|
||||
I'm not sure which operating system first supported this system call,
|
||||
but I know that SR10.2 supports it. */
|
||||
|
||||
extern void proc1_$get_loadav ();
|
||||
unsigned long load_ave[3];
|
||||
|
||||
proc1_$get_loadav (load_ave);
|
||||
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = load_ave[0] / 65536.0;
|
||||
if (nelem > 1)
|
||||
loadavg[elem++] = load_ave[1] / 65536.0;
|
||||
if (nelem > 2)
|
||||
loadavg[elem++] = load_ave[2] / 65536.0;
|
||||
#endif /* apollo */
|
||||
|
||||
#if !defined (LDAV_DONE) && defined (OSF_MIPS)
|
||||
#define LDAV_DONE
|
||||
|
||||
struct tbl_loadavg load_ave;
|
||||
table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
|
||||
loadavg[elem++]
|
||||
= (load_ave.tl_lscale == 0
|
||||
? load_ave.tl_avenrun.d[0]
|
||||
: (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
|
||||
#endif /* OSF_MIPS */
|
||||
|
||||
#if !defined (LDAV_DONE) && defined (OSF_ALPHA)
|
||||
#define LDAV_DONE
|
||||
|
||||
struct tbl_loadavg load_ave;
|
||||
table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
|
||||
for (elem = 0; elem < nelem; elem++)
|
||||
loadavg[elem]
|
||||
= (load_ave.tl_lscale == 0
|
||||
? load_ave.tl_avenrun.d[elem]
|
||||
: (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
|
||||
#endif /* OSF_ALPHA */
|
||||
|
||||
#if !defined (LDAV_DONE) && defined (VMS)
|
||||
/* VMS specific code -- read from the Load Ave driver. */
|
||||
|
||||
LOAD_AVE_TYPE load_ave[3];
|
||||
static int getloadavg_initialized = 0;
|
||||
#ifdef eunice
|
||||
struct
|
||||
{
|
||||
int dsc$w_length;
|
||||
char *dsc$a_pointer;
|
||||
} descriptor;
|
||||
#endif
|
||||
|
||||
/* Ensure that there is a channel open to the load ave device. */
|
||||
if (!getloadavg_initialized)
|
||||
{
|
||||
/* Attempt to open the channel. */
|
||||
#ifdef eunice
|
||||
descriptor.dsc$w_length = 18;
|
||||
descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE";
|
||||
#else
|
||||
$DESCRIPTOR (descriptor, "LAV0:");
|
||||
#endif
|
||||
if (sys$assign (&descriptor, &channel, 0, 0) & 1)
|
||||
getloadavg_initialized = 1;
|
||||
}
|
||||
|
||||
/* Read the load average vector. */
|
||||
if (getloadavg_initialized
|
||||
&& !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0,
|
||||
load_ave, 12, 0, 0, 0, 0) & 1))
|
||||
{
|
||||
sys$dassgn (channel);
|
||||
getloadavg_initialized = 0;
|
||||
}
|
||||
|
||||
if (!getloadavg_initialized)
|
||||
return -1;
|
||||
#endif /* VMS */
|
||||
|
||||
#if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS)
|
||||
|
||||
/* UNIX-specific code -- read the average from /dev/kmem. */
|
||||
|
||||
#define LDAV_PRIVILEGED /* This code requires special installation. */
|
||||
|
||||
LOAD_AVE_TYPE load_ave[3];
|
||||
|
||||
/* Get the address of LDAV_SYMBOL. */
|
||||
if (offset == 0)
|
||||
{
|
||||
#ifndef sgi
|
||||
#ifndef NLIST_STRUCT
|
||||
strcpy (nl[0].n_name, LDAV_SYMBOL);
|
||||
strcpy (nl[1].n_name, "");
|
||||
#else /* NLIST_STRUCT */
|
||||
#ifdef NLIST_NAME_UNION
|
||||
nl[0].n_un.n_name = LDAV_SYMBOL;
|
||||
nl[1].n_un.n_name = 0;
|
||||
#else /* not NLIST_NAME_UNION */
|
||||
nl[0].n_name = LDAV_SYMBOL;
|
||||
nl[1].n_name = 0;
|
||||
#endif /* not NLIST_NAME_UNION */
|
||||
#endif /* NLIST_STRUCT */
|
||||
|
||||
#ifndef SUNOS_5
|
||||
if (
|
||||
#ifndef _AIX
|
||||
nlist (KERNEL_FILE, nl)
|
||||
#else /* _AIX */
|
||||
knlist (nl, 1, sizeof (nl[0]))
|
||||
#endif
|
||||
>= 0)
|
||||
/* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i. */
|
||||
{
|
||||
#ifdef FIXUP_KERNEL_SYMBOL_ADDR
|
||||
FIXUP_KERNEL_SYMBOL_ADDR (nl);
|
||||
#endif
|
||||
offset = nl[0].n_value;
|
||||
}
|
||||
#endif /* !SUNOS_5 */
|
||||
#else /* sgi */
|
||||
int ldav_off;
|
||||
|
||||
ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
|
||||
if (ldav_off != -1)
|
||||
offset = (long) ldav_off & 0x7fffffff;
|
||||
#endif /* sgi */
|
||||
}
|
||||
|
||||
/* Make sure we have /dev/kmem open. */
|
||||
if (!getloadavg_initialized)
|
||||
{
|
||||
#ifndef SUNOS_5
|
||||
channel = open ("/dev/kmem", 0);
|
||||
if (channel >= 0)
|
||||
getloadavg_initialized = 1;
|
||||
#else /* SUNOS_5 */
|
||||
/* We pass 0 for the kernel, corefile, and swapfile names
|
||||
to use the currently running kernel. */
|
||||
kd = kvm_open (0, 0, 0, O_RDONLY, 0);
|
||||
if (kd != 0)
|
||||
{
|
||||
/* nlist the currently running kernel. */
|
||||
kvm_nlist (kd, nl);
|
||||
offset = nl[0].n_value;
|
||||
getloadavg_initialized = 1;
|
||||
}
|
||||
#endif /* SUNOS_5 */
|
||||
}
|
||||
|
||||
/* If we can, get the load average values. */
|
||||
if (offset && getloadavg_initialized)
|
||||
{
|
||||
/* Try to read the load. */
|
||||
#ifndef SUNOS_5
|
||||
if (lseek (channel, offset, 0) == -1L
|
||||
|| read (channel, (char *) load_ave, sizeof (load_ave))
|
||||
!= sizeof (load_ave))
|
||||
{
|
||||
close (channel);
|
||||
getloadavg_initialized = 0;
|
||||
}
|
||||
#else /* SUNOS_5 */
|
||||
if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
|
||||
!= sizeof (load_ave))
|
||||
{
|
||||
kvm_close (kd);
|
||||
getloadavg_initialized = 0;
|
||||
}
|
||||
#endif /* SUNOS_5 */
|
||||
}
|
||||
|
||||
if (offset == 0 || !getloadavg_initialized)
|
||||
return -1;
|
||||
#endif /* LOAD_AVE_TYPE and not VMS */
|
||||
|
||||
#if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */
|
||||
if (nelem > 0)
|
||||
loadavg[elem++] = LDAV_CVT (load_ave[0]);
|
||||
if (nelem > 1)
|
||||
loadavg[elem++] = LDAV_CVT (load_ave[1]);
|
||||
if (nelem > 2)
|
||||
loadavg[elem++] = LDAV_CVT (load_ave[2]);
|
||||
|
||||
#define LDAV_DONE
|
||||
#endif /* !LDAV_DONE && LOAD_AVE_TYPE */
|
||||
|
||||
#ifdef LDAV_DONE
|
||||
return elem;
|
||||
#else
|
||||
/* Set errno to zero to indicate that there was no particular error;
|
||||
this function just can't work at all on this system. */
|
||||
errno = 0;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* ! HAVE_GETLOADAVG */
|
||||
|
||||
#ifdef TEST
|
||||
void
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int naptime = 0;
|
||||
|
||||
if (argc > 1)
|
||||
naptime = atoi (argv[1]);
|
||||
|
||||
while (1)
|
||||
{
|
||||
double avg[3];
|
||||
int loads;
|
||||
|
||||
errno = 0; /* Don't be misled if it doesn't set errno. */
|
||||
loads = getloadavg (avg, 3);
|
||||
if (loads == -1)
|
||||
{
|
||||
perror ("Error getting load average");
|
||||
exit (1);
|
||||
}
|
||||
if (loads > 0)
|
||||
printf ("1-minute: %f ", avg[0]);
|
||||
if (loads > 1)
|
||||
printf ("5-minute: %f ", avg[1]);
|
||||
if (loads > 2)
|
||||
printf ("15-minute: %f ", avg[2]);
|
||||
if (loads > 0)
|
||||
putchar ('\n');
|
||||
|
||||
if (naptime == 0)
|
||||
break;
|
||||
sleep (naptime);
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
#endif /* TEST */
|
||||
@ -1,763 +0,0 @@
|
||||
/* Getopt for GNU.
|
||||
NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
||||
Ditto for AIX 3.2 and <stdlib.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* This is for other GNU distributions with internationalized messages.
|
||||
The GNU C Library itself does not yet support such messages. */
|
||||
#if HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# define gettext(msgid) (msgid)
|
||||
#endif
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As `getopt' works, it permutes the elements of ARGV so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
char *optarg = NULL;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
/* XXX 1003.2 says this must be 1 before any call. */
|
||||
int optind = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
int optopt = '?';
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
/* Value of POSIXLY_CORRECT environment variable. */
|
||||
static char *posixly_correct;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
char *getenv ();
|
||||
|
||||
static char *
|
||||
my_index (str, chr)
|
||||
const char *str;
|
||||
int chr;
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (char *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If using GCC, we can safely declare strlen this way.
|
||||
If not using GCC, it is ok not to declare it. */
|
||||
#ifdef __GNUC__
|
||||
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
|
||||
That was relevant to code that was here before. */
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
/* gcc with -traditional declares the built-in strlen to return int,
|
||||
and has done so at least since version 2.4.5. -- rms. */
|
||||
extern int strlen (const char *);
|
||||
#endif /* not __STDC__ */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = optind;
|
||||
char *tem;
|
||||
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
but it consists of two parts that need to be swapped next. */
|
||||
|
||||
while (top > middle && middle > bottom)
|
||||
{
|
||||
if (top - middle > middle - bottom)
|
||||
{
|
||||
/* Bottom segment is the short one. */
|
||||
int len = middle - bottom;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the top part of the top segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||
argv[top - (middle - bottom) + i] = tem;
|
||||
}
|
||||
/* Exclude the moved bottom segment from further swapping. */
|
||||
top -= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Top segment is the short one. */
|
||||
int len = top - middle;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the bottom part of the bottom segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[middle + i];
|
||||
argv[middle + i] = tem;
|
||||
}
|
||||
/* Exclude the moved top segment from further swapping. */
|
||||
bottom += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Initialize the internal data when the first call is made. */
|
||||
|
||||
static const char *
|
||||
_getopt_initialize (optstring)
|
||||
const char *optstring;
|
||||
{
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT");
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (posixly_correct != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
|
||||
return optstring;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If `getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If `getopt' finds another option character, it returns that character,
|
||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `getopt' returns `EOF'.
|
||||
Then `optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set `opterr' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||
|
||||
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||
handling the non-option ARGV-elements.
|
||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||
|
||||
Long-named options begin with `--' instead of `-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a `=', or else the in next ARGV-element.
|
||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||
`flag' field is nonzero, the value of the option's `val' field
|
||||
if the `flag' field is zero.
|
||||
|
||||
The elements of ARGV aren't really const, because we permute them.
|
||||
But we pretend they're const in the prototype to be compatible
|
||||
with other systems.
|
||||
|
||||
LONGOPTS is a vector of `struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
|
||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||
It is only valid when a long-named option has been found by the most
|
||||
recent call.
|
||||
|
||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||
long-named options. */
|
||||
|
||||
int
|
||||
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
const struct option *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
optarg = NULL;
|
||||
|
||||
if (optind == 0)
|
||||
{
|
||||
optstring = _getopt_initialize (optstring);
|
||||
optind = 1; /* Don't scan ARGV[0], the program name. */
|
||||
}
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
/* Advance to the next ARGV-element. */
|
||||
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* The special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
optarg = argv[optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Skip the initial punctuation. */
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
/* Decode the current option-ARGV-element. */
|
||||
|
||||
/* Check whether the ARGV-element is a long option.
|
||||
|
||||
If long_only and the ARGV-element has the form "-f", where f is
|
||||
a valid short option, don't consider it an abbreviated form of
|
||||
a long option that starts with f. Otherwise there would be no
|
||||
way to give the -f short option.
|
||||
|
||||
On the other hand, if there's a long option "fubar" and
|
||||
the ARGV-element is "-fu", do consider that an abbreviation of
|
||||
the long option, just like "--fu", and not "-f" with arg "u".
|
||||
|
||||
This distinction seems to be the most useful approach. */
|
||||
|
||||
if (longopts != NULL
|
||||
&& (argv[optind][1] == '-'
|
||||
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
|
||||
{
|
||||
char *nameend;
|
||||
const struct option *p;
|
||||
const struct option *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
int indfound;
|
||||
int option_index;
|
||||
|
||||
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
|
||||
/* Test all long options for either exact match
|
||||
or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if ((size_t)(nameend - nextchar) == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second or later nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, gettext ("%s: option `%s' is ambiguous\n"),
|
||||
argv[0], argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*nameend)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
optarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
gettext ("%s: option `--%s' doesn't allow an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
gettext ("%s: option `%c%s' doesn't allow an argument\n"),
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr,
|
||||
gettext ("%s: option `%s' requires an argument\n"),
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr, gettext ("%s: unrecognized option `--%s'\n"),
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, gettext ("%s: unrecognized option `%c%s'\n"),
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = (char *) "";
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next short option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = my_index (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (posixly_correct)
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, gettext ("%s: illegal option -- %c\n"),
|
||||
argv[0], c);
|
||||
else
|
||||
fprintf (stderr, gettext ("%s: invalid option -- %c\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr,
|
||||
gettext ("%s: option requires an argument -- %c\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
optarg = argv[optind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
return _getopt_internal (argc, argv, optstring,
|
||||
(const struct option *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
|
||||
c = getopt (argc, argv, "abc:d:0123456789");
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
@ -1,129 +0,0 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
#if defined (__STDC__) && __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
#if defined (__STDC__) && __STDC__
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
#endif /* __GNU_LIBRARY__ */
|
||||
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
extern int getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H */
|
||||
@ -1,180 +0,0 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *getenv ();
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
@ -1,705 +0,0 @@
|
||||
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#if defined (_AIX) && !defined (__GNUC__)
|
||||
#pragma alloca
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef NETSCAPE
|
||||
#include "windir.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#ifndef POSIX
|
||||
#ifdef _POSIX_VERSION
|
||||
#define POSIX
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (POSIX) || defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__)
|
||||
#include <dirent.h>
|
||||
#ifndef __GNU_LIBRARY__
|
||||
#define D_NAMLEN(d) strlen((d)->d_name)
|
||||
#else /* GNU C library. */
|
||||
#define D_NAMLEN(d) ((d)->d_namlen)
|
||||
#endif /* Not GNU C library. */
|
||||
#else /* Not POSIX or HAVE_DIRENT_H. */
|
||||
#define direct dirent
|
||||
#define D_NAMLEN(d) ((d)->d_namlen)
|
||||
#ifdef HAVE_SYS_NDIR_H
|
||||
#include <sys/ndir.h>
|
||||
#endif /* HAVE_SYS_NDIR_H */
|
||||
#ifdef HAVE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#endif /* HAVE_SYS_DIR_H */
|
||||
#ifdef HAVE_NDIR_H
|
||||
#include <ndir.h>
|
||||
#endif /* HAVE_NDIR_H */
|
||||
#endif /* POSIX or HAVE_DIRENT_H or __GNU_LIBRARY__. */
|
||||
|
||||
#if defined(NETSCAPE) || defined (POSIX) && !defined (__GNU_LIBRARY__)
|
||||
/* Posix does not require that the d_ino field be present, and some
|
||||
systems do not provide it. */
|
||||
#define REAL_DIR_ENTRY(dp) 1
|
||||
#else
|
||||
#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
|
||||
#endif /* POSIX */
|
||||
|
||||
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__))
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define ANSI_STRING
|
||||
#else /* No standard headers. */
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#define ANSI_STRING
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#ifdef HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
|
||||
extern char *malloc (), *realloc ();
|
||||
extern void free ();
|
||||
|
||||
extern void qsort ();
|
||||
extern void abort (), exit ();
|
||||
|
||||
#endif /* Standard headers. */
|
||||
|
||||
#ifndef ANSI_STRING
|
||||
|
||||
#ifndef bzero
|
||||
extern void bzero ();
|
||||
#endif
|
||||
#ifndef bcopy
|
||||
extern void bcopy ();
|
||||
#endif
|
||||
|
||||
#define memcpy(d, s, n) bcopy ((s), (d), (n))
|
||||
#define strrchr rindex
|
||||
/* memset is only used for zero here, but let's be paranoid. */
|
||||
#define memset(s, better_be_zero, n) \
|
||||
((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
|
||||
#endif /* Not ANSI_STRING. */
|
||||
|
||||
#ifndef HAVE_STRCOLL
|
||||
#define strcoll strcmp
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(__GNU_LIBRARY__) && !defined(NETSCAPE)
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#endif
|
||||
static char *
|
||||
my_realloc (p, n)
|
||||
char *p;
|
||||
unsigned int n;
|
||||
{
|
||||
/* These casts are the for sake of the broken Ultrix compiler,
|
||||
which warns of illegal pointer combinations otherwise. */
|
||||
if (p == NULL)
|
||||
return (char *) malloc (n);
|
||||
return (char *) realloc (p, n);
|
||||
}
|
||||
#define realloc my_realloc
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(__alloca) && !defined(__GNU_LIBRARY__)
|
||||
|
||||
#ifdef __GNUC__
|
||||
#undef alloca
|
||||
#define alloca(n) __builtin_alloca (n)
|
||||
#else /* Not GCC. */
|
||||
#if defined (sparc) || defined (HAVE_ALLOCA_H)
|
||||
#include <alloca.h>
|
||||
#elif defined(NETSCAPE)
|
||||
#include <malloc.h>
|
||||
#else /* Not sparc or HAVE_ALLOCA_H. */
|
||||
#ifndef _AIX
|
||||
extern char *alloca ();
|
||||
#endif /* Not _AIX. */
|
||||
#endif /* sparc or HAVE_ALLOCA_H. */
|
||||
#endif /* GCC. */
|
||||
|
||||
#define __alloca alloca
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __GNU_LIBRARY__
|
||||
#define __lstat lstat
|
||||
#ifndef HAVE_LSTAT
|
||||
#define lstat stat
|
||||
#endif
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
#undef S_ISDIR
|
||||
#endif
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef STDC_HEADERS
|
||||
#undef size_t
|
||||
#define size_t unsigned int
|
||||
#endif
|
||||
|
||||
/* Some system header files erroneously define these.
|
||||
We want our own definitions from <fnmatch.h> to take precedence. */
|
||||
#undef FNM_PATHNAME
|
||||
#undef FNM_NOESCAPE
|
||||
#undef FNM_PERIOD
|
||||
#include <fnmatch.h>
|
||||
|
||||
/* Some system header files erroneously define these.
|
||||
We want our own definitions from <glob.h> to take precedence. */
|
||||
#undef GLOB_ERR
|
||||
#undef GLOB_MARK
|
||||
#undef GLOB_NOSORT
|
||||
#undef GLOB_DOOFFS
|
||||
#undef GLOB_NOCHECK
|
||||
#undef GLOB_APPEND
|
||||
#undef GLOB_NOESCAPE
|
||||
#undef GLOB_PERIOD
|
||||
#include <glob.h>
|
||||
|
||||
__ptr_t (*__glob_opendir_hook) __P ((const char *directory));
|
||||
const char *(*__glob_readdir_hook) __P ((__ptr_t stream));
|
||||
void (*__glob_closedir_hook) __P ((__ptr_t stream));
|
||||
|
||||
static int glob_pattern_p __P ((const char *pattern, int quote));
|
||||
static int glob_in_dir __P ((const char *pattern, const char *directory,
|
||||
int flags,
|
||||
int (*errfunc) __P ((const char *, int)),
|
||||
glob_t *pglob));
|
||||
static int prefix_array __P ((const char *prefix, char **array, size_t n));
|
||||
int collated_compare __P ((const void *elem1, const void *elem2));
|
||||
|
||||
/* Do glob searching for PATTERN, placing results in PGLOB.
|
||||
The bits defined above may be set in FLAGS.
|
||||
If a directory cannot be opened or read and ERRFUNC is not nil,
|
||||
it is called with the pathname that caused the error, and the
|
||||
`errno' value from the failing call; if it returns non-zero
|
||||
`glob' returns GLOB_ABEND; if it returns zero, the error is ignored.
|
||||
If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
|
||||
Otherwise, `glob' returns zero. */
|
||||
int
|
||||
glob (pattern, flags, errfunc, pglob)
|
||||
const char *pattern;
|
||||
int flags;
|
||||
int (*errfunc) __P ((const char *, int));
|
||||
glob_t *pglob;
|
||||
{
|
||||
const char *filename;
|
||||
char *dirname;
|
||||
size_t dirlen;
|
||||
int status;
|
||||
int oldcount;
|
||||
|
||||
if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find the filename. */
|
||||
filename = strrchr (pattern, '/');
|
||||
if (filename == NULL)
|
||||
{
|
||||
filename = pattern;
|
||||
dirname = (char *) ".";
|
||||
dirlen = 0;
|
||||
}
|
||||
else if (filename == pattern)
|
||||
{
|
||||
/* "/pattern". */
|
||||
dirname = (char *) "/";
|
||||
dirlen = 1;
|
||||
++filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
dirlen = filename - pattern;
|
||||
dirname = (char *) __alloca (dirlen + 1);
|
||||
memcpy (dirname, pattern, dirlen);
|
||||
dirname[dirlen] = '\0';
|
||||
++filename;
|
||||
}
|
||||
|
||||
if (filename[0] == '\0' && dirlen > 1)
|
||||
/* "pattern/". Expand "pattern", appending slashes. */
|
||||
{
|
||||
int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
|
||||
if (val == 0)
|
||||
pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK);
|
||||
return val;
|
||||
}
|
||||
|
||||
if (!(flags & GLOB_APPEND))
|
||||
{
|
||||
pglob->gl_pathc = 0;
|
||||
pglob->gl_pathv = NULL;
|
||||
}
|
||||
|
||||
oldcount = pglob->gl_pathc;
|
||||
|
||||
if (glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
|
||||
{
|
||||
/* The directory name contains metacharacters, so we
|
||||
have to glob for the directory, and then glob for
|
||||
the pattern in each directory found. */
|
||||
glob_t dirs;
|
||||
register int i;
|
||||
|
||||
status = glob (dirname,
|
||||
((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) |
|
||||
GLOB_NOSORT),
|
||||
errfunc, &dirs);
|
||||
if (status != 0)
|
||||
return status;
|
||||
|
||||
/* We have successfully globbed the preceding directory name.
|
||||
For each name we found, call glob_in_dir on it and FILENAME,
|
||||
appending the results to PGLOB. */
|
||||
for (i = 0; i < dirs.gl_pathc; ++i)
|
||||
{
|
||||
int oldcount;
|
||||
|
||||
#ifdef SHELL
|
||||
{
|
||||
/* Make globbing interruptible in the bash shell. */
|
||||
extern int interrupt_state;
|
||||
|
||||
if (interrupt_state)
|
||||
{
|
||||
globfree (&dirs);
|
||||
globfree (&files);
|
||||
return GLOB_ABEND;
|
||||
}
|
||||
}
|
||||
#endif /* SHELL. */
|
||||
|
||||
oldcount = pglob->gl_pathc;
|
||||
status = glob_in_dir (filename, dirs.gl_pathv[i],
|
||||
(flags | GLOB_APPEND) & ~GLOB_NOCHECK,
|
||||
errfunc, pglob);
|
||||
if (status == GLOB_NOMATCH)
|
||||
/* No matches in this directory. Try the next. */
|
||||
continue;
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
globfree (&dirs);
|
||||
globfree (pglob);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Stick the directory on the front of each name. */
|
||||
if (prefix_array (dirs.gl_pathv[i],
|
||||
&pglob->gl_pathv[oldcount],
|
||||
pglob->gl_pathc - oldcount))
|
||||
{
|
||||
globfree (&dirs);
|
||||
globfree (pglob);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
}
|
||||
|
||||
flags |= GLOB_MAGCHAR;
|
||||
|
||||
if (pglob->gl_pathc == oldcount)
|
||||
/* No matches. */
|
||||
if (flags & GLOB_NOCHECK)
|
||||
{
|
||||
size_t len = strlen (pattern) + 1;
|
||||
char *patcopy = (char *) malloc (len);
|
||||
if (patcopy == NULL)
|
||||
return GLOB_NOSPACE;
|
||||
memcpy (patcopy, pattern, len);
|
||||
|
||||
pglob->gl_pathv
|
||||
= (char **) realloc (pglob->gl_pathv,
|
||||
(pglob->gl_pathc +
|
||||
((flags & GLOB_DOOFFS) ?
|
||||
pglob->gl_offs : 0) +
|
||||
1 + 1) *
|
||||
sizeof (char *));
|
||||
if (pglob->gl_pathv == NULL)
|
||||
{
|
||||
free (patcopy);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
|
||||
if (flags & GLOB_DOOFFS)
|
||||
while (pglob->gl_pathc < pglob->gl_offs)
|
||||
pglob->gl_pathv[pglob->gl_pathc++] = NULL;
|
||||
|
||||
pglob->gl_pathv[pglob->gl_pathc++] = patcopy;
|
||||
pglob->gl_pathv[pglob->gl_pathc] = NULL;
|
||||
pglob->gl_flags = flags;
|
||||
}
|
||||
else
|
||||
return GLOB_NOMATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
|
||||
if (status != 0)
|
||||
return status;
|
||||
|
||||
if (dirlen > 0)
|
||||
{
|
||||
/* Stick the directory on the front of each name. */
|
||||
if (prefix_array (dirname,
|
||||
&pglob->gl_pathv[oldcount],
|
||||
pglob->gl_pathc - oldcount))
|
||||
{
|
||||
globfree (pglob);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & GLOB_MARK)
|
||||
{
|
||||
/* Append slashes to directory names. glob_in_dir has already
|
||||
allocated the extra character for us. */
|
||||
int i;
|
||||
struct stat st;
|
||||
for (i = oldcount; i < pglob->gl_pathc; ++i)
|
||||
if (__lstat (pglob->gl_pathv[i], &st) == 0 &&
|
||||
S_ISDIR (st.st_mode))
|
||||
strcat (pglob->gl_pathv[i], "/");
|
||||
}
|
||||
|
||||
if (!(flags & GLOB_NOSORT))
|
||||
/* Sort the vector. */
|
||||
#if 0
|
||||
qsort ((__ptr_t) &pglob->gl_pathv[oldcount],
|
||||
pglob->gl_pathc - oldcount,
|
||||
sizeof (char *), collated_compare);
|
||||
#else
|
||||
qsort ( &pglob->gl_pathv[oldcount],
|
||||
(size_t)(pglob->gl_pathc - oldcount),
|
||||
sizeof (char *), collated_compare);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Free storage allocated in PGLOB by a previous `glob' call. */
|
||||
void
|
||||
globfree (pglob)
|
||||
register glob_t *pglob;
|
||||
{
|
||||
if (pglob->gl_pathv != NULL)
|
||||
{
|
||||
register int i;
|
||||
for (i = 0; i < pglob->gl_pathc; ++i)
|
||||
if (pglob->gl_pathv[i] != NULL)
|
||||
free ((__ptr_t) pglob->gl_pathv[i]);
|
||||
free ((__ptr_t) pglob->gl_pathv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Do a collated comparison of A and B. */
|
||||
int
|
||||
collated_compare (const void *elem1, const void *elem2)
|
||||
{
|
||||
const __ptr_t a = (const __ptr_t)elem1;
|
||||
const __ptr_t b = (const __ptr_t)elem1;
|
||||
const char *const s1 = *(const char *const * const) a;
|
||||
const char *const s2 = *(const char *const * const) b;
|
||||
|
||||
if (s1 == s2)
|
||||
return 0;
|
||||
if (s1 == NULL)
|
||||
return 1;
|
||||
if (s2 == NULL)
|
||||
return -1;
|
||||
return strcoll (s1, s2);
|
||||
}
|
||||
|
||||
|
||||
/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
|
||||
elements in place. Return nonzero if out of memory, zero if successful.
|
||||
A slash is inserted between DIRNAME and each elt of ARRAY,
|
||||
unless DIRNAME is just "/". Each old element of ARRAY is freed. */
|
||||
static int
|
||||
prefix_array (dirname, array, n)
|
||||
const char *dirname;
|
||||
char **array;
|
||||
size_t n;
|
||||
{
|
||||
register size_t i;
|
||||
size_t dirlen = strlen (dirname);
|
||||
|
||||
if (dirlen == 1 && dirname[0] == '/')
|
||||
/* DIRNAME is just "/", so normal prepending would get us "//foo".
|
||||
We want "/foo" instead, so don't prepend any chars from DIRNAME. */
|
||||
dirlen = 0;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
size_t eltlen = strlen (array[i]) + 1;
|
||||
char *new = (char *) malloc (dirlen + 1 + eltlen);
|
||||
if (new == NULL)
|
||||
{
|
||||
while (i > 0)
|
||||
free ((__ptr_t) array[--i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy (new, dirname, dirlen);
|
||||
new[dirlen] = '/';
|
||||
memcpy (&new[dirlen + 1], array[i], eltlen);
|
||||
free ((__ptr_t) array[i]);
|
||||
array[i] = new;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return nonzero if PATTERN contains any metacharacters.
|
||||
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
|
||||
static int
|
||||
glob_pattern_p (pattern, quote)
|
||||
const char *pattern;
|
||||
int quote;
|
||||
{
|
||||
register const char *p;
|
||||
int open = 0;
|
||||
|
||||
for (p = pattern; *p != '\0'; ++p)
|
||||
switch (*p)
|
||||
{
|
||||
case '?':
|
||||
case '*':
|
||||
return 1;
|
||||
|
||||
case '\\':
|
||||
if (quote)
|
||||
++p;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
open = 1;
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (open)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Like `glob', but PATTERN is a final pathname component,
|
||||
and matches are searched for in DIRECTORY.
|
||||
The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
|
||||
The GLOB_APPEND flag is assumed to be set (always appends). */
|
||||
static int
|
||||
glob_in_dir (pattern, directory, flags, errfunc, pglob)
|
||||
const char *pattern;
|
||||
const char *directory;
|
||||
int flags;
|
||||
int (*errfunc) __P ((const char *, int));
|
||||
glob_t *pglob;
|
||||
{
|
||||
__ptr_t stream;
|
||||
|
||||
struct globlink
|
||||
{
|
||||
struct globlink *next;
|
||||
char *name;
|
||||
};
|
||||
struct globlink *names = NULL;
|
||||
size_t nfound = 0;
|
||||
|
||||
if (!glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)))
|
||||
{
|
||||
stream = NULL;
|
||||
flags |= GLOB_NOCHECK;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= GLOB_MAGCHAR;
|
||||
|
||||
stream = (__glob_opendir_hook ? (*__glob_opendir_hook) (directory)
|
||||
: (__ptr_t) opendir (directory));
|
||||
if (stream == NULL)
|
||||
{
|
||||
if ((errfunc != NULL && (*errfunc) (directory, errno)) ||
|
||||
(flags & GLOB_ERR))
|
||||
return GLOB_ABEND;
|
||||
}
|
||||
else
|
||||
while (1)
|
||||
{
|
||||
const char *name;
|
||||
size_t len;
|
||||
|
||||
if (__glob_readdir_hook)
|
||||
{
|
||||
name = (*__glob_readdir_hook) (stream);
|
||||
if (name == NULL)
|
||||
break;
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct dirent *d = readdir ((DIR *) stream);
|
||||
if (d == NULL)
|
||||
break;
|
||||
if (! REAL_DIR_ENTRY (d))
|
||||
continue;
|
||||
name = d->d_name;
|
||||
#ifdef HAVE_D_NAMLEN
|
||||
len = d->d_namlen;
|
||||
#else
|
||||
len = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (fnmatch (pattern, name,
|
||||
(!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) |
|
||||
((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)) == 0)
|
||||
{
|
||||
struct globlink *new
|
||||
= (struct globlink *) __alloca (sizeof (struct globlink));
|
||||
if (len == 0)
|
||||
len = strlen (name);
|
||||
new->name
|
||||
= (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1);
|
||||
if (new->name == NULL)
|
||||
goto memory_error;
|
||||
memcpy ((__ptr_t) new->name, name, len);
|
||||
new->name[len] = '\0';
|
||||
new->next = names;
|
||||
names = new;
|
||||
++nfound;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nfound == 0 && (flags & GLOB_NOCHECK))
|
||||
{
|
||||
size_t len = strlen (pattern);
|
||||
nfound = 1;
|
||||
names = (struct globlink *) __alloca (sizeof (struct globlink));
|
||||
names->next = NULL;
|
||||
names->name = (char *) malloc (len + 1);
|
||||
if (names->name == NULL)
|
||||
goto memory_error;
|
||||
memcpy (names->name, pattern, len);
|
||||
names->name[len] = '\0';
|
||||
}
|
||||
|
||||
pglob->gl_pathv
|
||||
= (char **) realloc (pglob->gl_pathv,
|
||||
(pglob->gl_pathc +
|
||||
((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
|
||||
nfound + 1) *
|
||||
sizeof (char *));
|
||||
if (pglob->gl_pathv == NULL)
|
||||
goto memory_error;
|
||||
|
||||
if (flags & GLOB_DOOFFS)
|
||||
while (pglob->gl_pathc < pglob->gl_offs)
|
||||
pglob->gl_pathv[pglob->gl_pathc++] = NULL;
|
||||
|
||||
for (; names != NULL; names = names->next)
|
||||
pglob->gl_pathv[pglob->gl_pathc++] = names->name;
|
||||
pglob->gl_pathv[pglob->gl_pathc] = NULL;
|
||||
|
||||
pglob->gl_flags = flags;
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
int save = errno;
|
||||
if (__glob_closedir_hook)
|
||||
(*__glob_closedir_hook) (stream);
|
||||
else
|
||||
(void) closedir ((DIR *) stream);
|
||||
errno = save;
|
||||
}
|
||||
return nfound == 0 ? GLOB_NOMATCH : 0;
|
||||
|
||||
memory_error:
|
||||
{
|
||||
int save = errno;
|
||||
if (__glob_closedir_hook)
|
||||
(*__glob_closedir_hook) (stream);
|
||||
else
|
||||
(void) closedir ((DIR *) stream);
|
||||
errno = save;
|
||||
}
|
||||
while (names != NULL)
|
||||
{
|
||||
if (names->name != NULL)
|
||||
free ((__ptr_t) names->name);
|
||||
names = names->next;
|
||||
}
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
@ -1,481 +0,0 @@
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
@ -1,28 +0,0 @@
|
||||
#
|
||||
# GNU Makefile for building gmake.exe on WIN32
|
||||
# This makefile compiles the files in the glob subdirectory.
|
||||
#
|
||||
|
||||
CSRCS = fnmatch.c glob.c
|
||||
|
||||
OBJS = $(CSRCS:.c=.obj)
|
||||
|
||||
CC = cl
|
||||
|
||||
CFLAGS = $(CC_SWITCHES) $(INCLUDES) $(DEFINES) $(CC_OUTPUTS)
|
||||
|
||||
CC_SWITCHES = -nologo -ML -W3 -O2
|
||||
|
||||
INCLUDES = -I. -I..
|
||||
|
||||
DEFINES = -DWIN32 -DNDEBUG -D_CONSOLE -DNETSCAPE -DHAVE_CONFIG_H
|
||||
|
||||
CC_OUTPUTS = -Fpglob.pch -YX -c
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
%.obj: %.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJS) glob.pch
|
||||
@ -1,66 +0,0 @@
|
||||
# Makefile for standalone distribution of libglob.a (fnmatch, glob).
|
||||
|
||||
# Copyright (C) 1991, 92, 93, 94, 95 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Library General Public License
|
||||
# as published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Library General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this library; see the file COPYING.LIB. If
|
||||
# not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
# Cambridge, MA 02139, USA.
|
||||
|
||||
# Ultrix 2.2 make doesn't expand the value of VPATH.
|
||||
VPATH = @srcdir@
|
||||
# This must repeat the value, because configure will remove `VPATH = .'.
|
||||
srcdir = @srcdir@
|
||||
|
||||
CC = @CC@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
|
||||
# Information determined by configure.
|
||||
DEFS = @DEFS@
|
||||
|
||||
# How to invoke ar.
|
||||
AR = @AR@
|
||||
ARFLAGS = rv
|
||||
|
||||
# How to invoke ranlib.
|
||||
RANLIB = @RANLIB@
|
||||
|
||||
.PHONY: all
|
||||
all: libglob.a
|
||||
|
||||
libglob.a: glob.o fnmatch.o
|
||||
$(AR) $(ARFLAGS) $@ glob.o fnmatch.o
|
||||
$(RANLIB) $@
|
||||
|
||||
# For some reason, Unix make wants the dependencies on the source files.
|
||||
# Otherwise it refuses to use an implicit rule!
|
||||
# And, get this: it doesn't work to use $(srcdir)/foo.c!!
|
||||
glob.o: $(srcdir)/glob.h $(srcdir)/fnmatch.h glob.c
|
||||
fnmatch.o: $(srcdir)/fnmatch.h fnmatch.c
|
||||
|
||||
.c.o:
|
||||
$(CC) -I. -I$(srcdir) -c \
|
||||
$(DEFS) $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION)
|
||||
|
||||
.PHONY: clean realclean glob-clean glob-realclean distclean
|
||||
clean glob-clean:
|
||||
-rm -f libglob.a *.o core
|
||||
distclean glob-realclean: clean
|
||||
-rm -f TAGS tags Makefile config.status config.h config.log
|
||||
realcean: distclean
|
||||
|
||||
# For inside the C library.
|
||||
glob.tar glob.tar.Z:
|
||||
$(MAKE) -C .. $@
|
||||
1547
buildtools/windows/source/make/glob/configure
vendored
1547
buildtools/windows/source/make/glob/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -1,52 +0,0 @@
|
||||
@echo off
|
||||
|
||||
echo Configuring glob for GO32
|
||||
|
||||
rem This batch file assumes a unix-type "sed" program
|
||||
|
||||
|
||||
|
||||
echo # Makefile generated by "configure.bat"> Makefile
|
||||
|
||||
|
||||
|
||||
if exist config.sed del config.sed
|
||||
|
||||
|
||||
|
||||
echo "s/@srcdir@/./ ">> config.sed
|
||||
|
||||
echo "s/@CC@/gcc/ ">> config.sed
|
||||
|
||||
echo "s/@CFLAGS@/-O2 -g/ ">> config.sed
|
||||
|
||||
echo "s/@CPPFLAGS@/-DHAVE_CONFIG_H -I../ ">> config.sed
|
||||
|
||||
echo "s/@AR@/ar/ ">> config.sed
|
||||
|
||||
echo "s/@RANLIB@/ranlib/ ">> config.sed
|
||||
|
||||
echo "s/@LDFLAGS@// ">> config.sed
|
||||
|
||||
echo "s/@DEFS@// ">> config.sed
|
||||
|
||||
echo "s/@ALLOCA@// ">> config.sed
|
||||
|
||||
echo "s/@LIBS@// ">> config.sed
|
||||
|
||||
echo "s/@LIBOBJS@// ">> config.sed
|
||||
|
||||
echo "s/^Makefile *:/_Makefile:/ ">> config.sed
|
||||
|
||||
echo "s/^config.h *:/_config.h:/ ">> config.sed
|
||||
|
||||
|
||||
|
||||
sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
|
||||
|
||||
sed -f config2.sed Makefile.in >> Makefile
|
||||
|
||||
del config.sed
|
||||
|
||||
del config2.sed
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(fnmatch.c) dnl A distinctive file to look for in srcdir.
|
||||
AC_PREREQ(2.1) dnl Minimum Autoconf version required.
|
||||
AC_PROG_CC
|
||||
AC_CHECK_PROG(AR, ar, ar, ar)
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_CPP dnl Later checks need this.
|
||||
dnl These two want to come early.
|
||||
AC_AIX
|
||||
AC_MINIX
|
||||
AC_ISC_POSIX
|
||||
AC_CONST
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(memory.h unistd.h string.h)
|
||||
AC_HEADER_DIRENT
|
||||
AC_FUNC_CLOSEDIR_VOID
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_STRCOLL
|
||||
AC_OUTPUT(Makefile)
|
||||
@ -1,200 +0,0 @@
|
||||
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
int
|
||||
fnmatch (pattern, string, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int flags;
|
||||
{
|
||||
register const char *p = pattern, *n = string;
|
||||
register char c;
|
||||
|
||||
/* Note that this evalutes C many times. */
|
||||
#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
c = FOLD (c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_FILE_NAME) && *n == '/')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE))
|
||||
{
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD (*n) != c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
|
||||
if (((flags & FNM_FILE_NAME) && *n == '/') ||
|
||||
(c == '?' && *n == '\0'))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (c == '\0')
|
||||
return 0;
|
||||
|
||||
{
|
||||
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
|
||||
c1 = FOLD (c1);
|
||||
for (--p; *n != '\0'; ++n)
|
||||
if ((c == '[' || FOLD (*n) == c1) &&
|
||||
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
|
||||
return 0;
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
case '[':
|
||||
{
|
||||
/* Nonzero if the sense of the character class is inverted. */
|
||||
register int not;
|
||||
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
not = (*p == '!' || *p == '^');
|
||||
if (not)
|
||||
++p;
|
||||
|
||||
c = *p++;
|
||||
for (;;)
|
||||
{
|
||||
register char cstart = c, cend = c;
|
||||
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
cstart = cend = *p++;
|
||||
|
||||
cstart = cend = FOLD (cstart);
|
||||
|
||||
if (c == '\0')
|
||||
/* [ (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
|
||||
if ((flags & FNM_FILE_NAME) && c == '/')
|
||||
/* [/] can never match. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (c == '-' && *p != ']')
|
||||
{
|
||||
cend = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && cend == '\\')
|
||||
cend = *p++;
|
||||
if (cend == '\0')
|
||||
return FNM_NOMATCH;
|
||||
cend = FOLD (cend);
|
||||
|
||||
c = *p++;
|
||||
}
|
||||
|
||||
if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
|
||||
goto matched;
|
||||
|
||||
if (c == ']')
|
||||
break;
|
||||
}
|
||||
if (!not)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
matched:;
|
||||
/* Skip the rest of the [...] that already matched. */
|
||||
while (c != ']')
|
||||
{
|
||||
if (c == '\0')
|
||||
/* [... (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
if (not)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c != FOLD (*n))
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
if (*n == '\0')
|
||||
return 0;
|
||||
|
||||
if ((flags & FNM_LEADING_DIR) && *n == '/')
|
||||
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
|
||||
return 0;
|
||||
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
@ -1,67 +0,0 @@
|
||||
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _FNMATCH_H
|
||||
|
||||
#define _FNMATCH_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
|
||||
#undef __P
|
||||
#define __P(protos) protos
|
||||
#else /* Not C++ or ANSI C. */
|
||||
#undef __P
|
||||
#define __P(protos) ()
|
||||
/* We can get away without defining `const' here only because in this file
|
||||
it is used only inside the prototype for `fnmatch', which is elided in
|
||||
non-ANSI C where `const' is problematical. */
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
|
||||
/* We #undef these before defining them because some losing systems
|
||||
(HP-UX A.08.07 for example) define these in <unistd.h>. */
|
||||
#undef FNM_PATHNAME
|
||||
#undef FNM_NOESCAPE
|
||||
#undef FNM_PERIOD
|
||||
|
||||
/* Bits set in the FLAGS argument to `fnmatch'. */
|
||||
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
||||
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
|
||||
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
|
||||
|
||||
#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
|
||||
#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
|
||||
#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
|
||||
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||
#endif
|
||||
|
||||
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
|
||||
#define FNM_NOMATCH 1
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN,
|
||||
returning zero if it matches, FNM_NOMATCH if not. */
|
||||
extern int fnmatch __P ((const char *__pattern, const char *__string,
|
||||
int __flags));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* fnmatch.h */
|
||||
@ -1,705 +0,0 @@
|
||||
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#if defined (_AIX) && !defined (__GNUC__)
|
||||
#pragma alloca
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef NETSCAPE
|
||||
#include "windir.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#ifndef POSIX
|
||||
#ifdef _POSIX_VERSION
|
||||
#define POSIX
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (POSIX) || defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__)
|
||||
#include <dirent.h>
|
||||
#ifndef __GNU_LIBRARY__
|
||||
#define D_NAMLEN(d) strlen((d)->d_name)
|
||||
#else /* GNU C library. */
|
||||
#define D_NAMLEN(d) ((d)->d_namlen)
|
||||
#endif /* Not GNU C library. */
|
||||
#else /* Not POSIX or HAVE_DIRENT_H. */
|
||||
#define direct dirent
|
||||
#define D_NAMLEN(d) ((d)->d_namlen)
|
||||
#ifdef HAVE_SYS_NDIR_H
|
||||
#include <sys/ndir.h>
|
||||
#endif /* HAVE_SYS_NDIR_H */
|
||||
#ifdef HAVE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#endif /* HAVE_SYS_DIR_H */
|
||||
#ifdef HAVE_NDIR_H
|
||||
#include <ndir.h>
|
||||
#endif /* HAVE_NDIR_H */
|
||||
#endif /* POSIX or HAVE_DIRENT_H or __GNU_LIBRARY__. */
|
||||
|
||||
#if defined(NETSCAPE) || defined (POSIX) && !defined (__GNU_LIBRARY__)
|
||||
/* Posix does not require that the d_ino field be present, and some
|
||||
systems do not provide it. */
|
||||
#define REAL_DIR_ENTRY(dp) 1
|
||||
#else
|
||||
#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
|
||||
#endif /* POSIX */
|
||||
|
||||
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__))
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define ANSI_STRING
|
||||
#else /* No standard headers. */
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#define ANSI_STRING
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#ifdef HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
|
||||
extern char *malloc (), *realloc ();
|
||||
extern void free ();
|
||||
|
||||
extern void qsort ();
|
||||
extern void abort (), exit ();
|
||||
|
||||
#endif /* Standard headers. */
|
||||
|
||||
#ifndef ANSI_STRING
|
||||
|
||||
#ifndef bzero
|
||||
extern void bzero ();
|
||||
#endif
|
||||
#ifndef bcopy
|
||||
extern void bcopy ();
|
||||
#endif
|
||||
|
||||
#define memcpy(d, s, n) bcopy ((s), (d), (n))
|
||||
#define strrchr rindex
|
||||
/* memset is only used for zero here, but let's be paranoid. */
|
||||
#define memset(s, better_be_zero, n) \
|
||||
((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
|
||||
#endif /* Not ANSI_STRING. */
|
||||
|
||||
#ifndef HAVE_STRCOLL
|
||||
#define strcoll strcmp
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(__GNU_LIBRARY__) && !defined(NETSCAPE)
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#endif
|
||||
static char *
|
||||
my_realloc (p, n)
|
||||
char *p;
|
||||
unsigned int n;
|
||||
{
|
||||
/* These casts are the for sake of the broken Ultrix compiler,
|
||||
which warns of illegal pointer combinations otherwise. */
|
||||
if (p == NULL)
|
||||
return (char *) malloc (n);
|
||||
return (char *) realloc (p, n);
|
||||
}
|
||||
#define realloc my_realloc
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(__alloca) && !defined(__GNU_LIBRARY__)
|
||||
|
||||
#ifdef __GNUC__
|
||||
#undef alloca
|
||||
#define alloca(n) __builtin_alloca (n)
|
||||
#else /* Not GCC. */
|
||||
#if defined (sparc) || defined (HAVE_ALLOCA_H)
|
||||
#include <alloca.h>
|
||||
#elif defined(NETSCAPE)
|
||||
#include <malloc.h>
|
||||
#else /* Not sparc or HAVE_ALLOCA_H. */
|
||||
#ifndef _AIX
|
||||
extern char *alloca ();
|
||||
#endif /* Not _AIX. */
|
||||
#endif /* sparc or HAVE_ALLOCA_H. */
|
||||
#endif /* GCC. */
|
||||
|
||||
#define __alloca alloca
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __GNU_LIBRARY__
|
||||
#define __lstat lstat
|
||||
#ifndef HAVE_LSTAT
|
||||
#define lstat stat
|
||||
#endif
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
#undef S_ISDIR
|
||||
#endif
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef STDC_HEADERS
|
||||
#undef size_t
|
||||
#define size_t unsigned int
|
||||
#endif
|
||||
|
||||
/* Some system header files erroneously define these.
|
||||
We want our own definitions from <fnmatch.h> to take precedence. */
|
||||
#undef FNM_PATHNAME
|
||||
#undef FNM_NOESCAPE
|
||||
#undef FNM_PERIOD
|
||||
#include <fnmatch.h>
|
||||
|
||||
/* Some system header files erroneously define these.
|
||||
We want our own definitions from <glob.h> to take precedence. */
|
||||
#undef GLOB_ERR
|
||||
#undef GLOB_MARK
|
||||
#undef GLOB_NOSORT
|
||||
#undef GLOB_DOOFFS
|
||||
#undef GLOB_NOCHECK
|
||||
#undef GLOB_APPEND
|
||||
#undef GLOB_NOESCAPE
|
||||
#undef GLOB_PERIOD
|
||||
#include <glob.h>
|
||||
|
||||
__ptr_t (*__glob_opendir_hook) __P ((const char *directory));
|
||||
const char *(*__glob_readdir_hook) __P ((__ptr_t stream));
|
||||
void (*__glob_closedir_hook) __P ((__ptr_t stream));
|
||||
|
||||
static int glob_pattern_p __P ((const char *pattern, int quote));
|
||||
static int glob_in_dir __P ((const char *pattern, const char *directory,
|
||||
int flags,
|
||||
int (*errfunc) __P ((const char *, int)),
|
||||
glob_t *pglob));
|
||||
static int prefix_array __P ((const char *prefix, char **array, size_t n));
|
||||
int collated_compare __P ((const void *elem1, const void *elem2));
|
||||
|
||||
/* Do glob searching for PATTERN, placing results in PGLOB.
|
||||
The bits defined above may be set in FLAGS.
|
||||
If a directory cannot be opened or read and ERRFUNC is not nil,
|
||||
it is called with the pathname that caused the error, and the
|
||||
`errno' value from the failing call; if it returns non-zero
|
||||
`glob' returns GLOB_ABEND; if it returns zero, the error is ignored.
|
||||
If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
|
||||
Otherwise, `glob' returns zero. */
|
||||
int
|
||||
glob (pattern, flags, errfunc, pglob)
|
||||
const char *pattern;
|
||||
int flags;
|
||||
int (*errfunc) __P ((const char *, int));
|
||||
glob_t *pglob;
|
||||
{
|
||||
const char *filename;
|
||||
char *dirname;
|
||||
size_t dirlen;
|
||||
int status;
|
||||
int oldcount;
|
||||
|
||||
if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find the filename. */
|
||||
filename = strrchr (pattern, '/');
|
||||
if (filename == NULL)
|
||||
{
|
||||
filename = pattern;
|
||||
dirname = (char *) ".";
|
||||
dirlen = 0;
|
||||
}
|
||||
else if (filename == pattern)
|
||||
{
|
||||
/* "/pattern". */
|
||||
dirname = (char *) "/";
|
||||
dirlen = 1;
|
||||
++filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
dirlen = filename - pattern;
|
||||
dirname = (char *) __alloca (dirlen + 1);
|
||||
memcpy (dirname, pattern, dirlen);
|
||||
dirname[dirlen] = '\0';
|
||||
++filename;
|
||||
}
|
||||
|
||||
if (filename[0] == '\0' && dirlen > 1)
|
||||
/* "pattern/". Expand "pattern", appending slashes. */
|
||||
{
|
||||
int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
|
||||
if (val == 0)
|
||||
pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK);
|
||||
return val;
|
||||
}
|
||||
|
||||
if (!(flags & GLOB_APPEND))
|
||||
{
|
||||
pglob->gl_pathc = 0;
|
||||
pglob->gl_pathv = NULL;
|
||||
}
|
||||
|
||||
oldcount = pglob->gl_pathc;
|
||||
|
||||
if (glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
|
||||
{
|
||||
/* The directory name contains metacharacters, so we
|
||||
have to glob for the directory, and then glob for
|
||||
the pattern in each directory found. */
|
||||
glob_t dirs;
|
||||
register int i;
|
||||
|
||||
status = glob (dirname,
|
||||
((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) |
|
||||
GLOB_NOSORT),
|
||||
errfunc, &dirs);
|
||||
if (status != 0)
|
||||
return status;
|
||||
|
||||
/* We have successfully globbed the preceding directory name.
|
||||
For each name we found, call glob_in_dir on it and FILENAME,
|
||||
appending the results to PGLOB. */
|
||||
for (i = 0; i < dirs.gl_pathc; ++i)
|
||||
{
|
||||
int oldcount;
|
||||
|
||||
#ifdef SHELL
|
||||
{
|
||||
/* Make globbing interruptible in the bash shell. */
|
||||
extern int interrupt_state;
|
||||
|
||||
if (interrupt_state)
|
||||
{
|
||||
globfree (&dirs);
|
||||
globfree (&files);
|
||||
return GLOB_ABEND;
|
||||
}
|
||||
}
|
||||
#endif /* SHELL. */
|
||||
|
||||
oldcount = pglob->gl_pathc;
|
||||
status = glob_in_dir (filename, dirs.gl_pathv[i],
|
||||
(flags | GLOB_APPEND) & ~GLOB_NOCHECK,
|
||||
errfunc, pglob);
|
||||
if (status == GLOB_NOMATCH)
|
||||
/* No matches in this directory. Try the next. */
|
||||
continue;
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
globfree (&dirs);
|
||||
globfree (pglob);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Stick the directory on the front of each name. */
|
||||
if (prefix_array (dirs.gl_pathv[i],
|
||||
&pglob->gl_pathv[oldcount],
|
||||
pglob->gl_pathc - oldcount))
|
||||
{
|
||||
globfree (&dirs);
|
||||
globfree (pglob);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
}
|
||||
|
||||
flags |= GLOB_MAGCHAR;
|
||||
|
||||
if (pglob->gl_pathc == oldcount)
|
||||
/* No matches. */
|
||||
if (flags & GLOB_NOCHECK)
|
||||
{
|
||||
size_t len = strlen (pattern) + 1;
|
||||
char *patcopy = (char *) malloc (len);
|
||||
if (patcopy == NULL)
|
||||
return GLOB_NOSPACE;
|
||||
memcpy (patcopy, pattern, len);
|
||||
|
||||
pglob->gl_pathv
|
||||
= (char **) realloc (pglob->gl_pathv,
|
||||
(pglob->gl_pathc +
|
||||
((flags & GLOB_DOOFFS) ?
|
||||
pglob->gl_offs : 0) +
|
||||
1 + 1) *
|
||||
sizeof (char *));
|
||||
if (pglob->gl_pathv == NULL)
|
||||
{
|
||||
free (patcopy);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
|
||||
if (flags & GLOB_DOOFFS)
|
||||
while (pglob->gl_pathc < pglob->gl_offs)
|
||||
pglob->gl_pathv[pglob->gl_pathc++] = NULL;
|
||||
|
||||
pglob->gl_pathv[pglob->gl_pathc++] = patcopy;
|
||||
pglob->gl_pathv[pglob->gl_pathc] = NULL;
|
||||
pglob->gl_flags = flags;
|
||||
}
|
||||
else
|
||||
return GLOB_NOMATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
|
||||
if (status != 0)
|
||||
return status;
|
||||
|
||||
if (dirlen > 0)
|
||||
{
|
||||
/* Stick the directory on the front of each name. */
|
||||
if (prefix_array (dirname,
|
||||
&pglob->gl_pathv[oldcount],
|
||||
pglob->gl_pathc - oldcount))
|
||||
{
|
||||
globfree (pglob);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & GLOB_MARK)
|
||||
{
|
||||
/* Append slashes to directory names. glob_in_dir has already
|
||||
allocated the extra character for us. */
|
||||
int i;
|
||||
struct stat st;
|
||||
for (i = oldcount; i < pglob->gl_pathc; ++i)
|
||||
if (__lstat (pglob->gl_pathv[i], &st) == 0 &&
|
||||
S_ISDIR (st.st_mode))
|
||||
strcat (pglob->gl_pathv[i], "/");
|
||||
}
|
||||
|
||||
if (!(flags & GLOB_NOSORT))
|
||||
/* Sort the vector. */
|
||||
#if 0
|
||||
qsort ((__ptr_t) &pglob->gl_pathv[oldcount],
|
||||
pglob->gl_pathc - oldcount,
|
||||
sizeof (char *), collated_compare);
|
||||
#else
|
||||
qsort ( &pglob->gl_pathv[oldcount],
|
||||
(size_t)(pglob->gl_pathc - oldcount),
|
||||
sizeof (char *), collated_compare);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Free storage allocated in PGLOB by a previous `glob' call. */
|
||||
void
|
||||
globfree (pglob)
|
||||
register glob_t *pglob;
|
||||
{
|
||||
if (pglob->gl_pathv != NULL)
|
||||
{
|
||||
register int i;
|
||||
for (i = 0; i < pglob->gl_pathc; ++i)
|
||||
if (pglob->gl_pathv[i] != NULL)
|
||||
free ((__ptr_t) pglob->gl_pathv[i]);
|
||||
free ((__ptr_t) pglob->gl_pathv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Do a collated comparison of A and B. */
|
||||
int
|
||||
collated_compare (const void *elem1, const void *elem2)
|
||||
{
|
||||
const __ptr_t a = (const __ptr_t)elem1;
|
||||
const __ptr_t b = (const __ptr_t)elem1;
|
||||
const char *const s1 = *(const char *const * const) a;
|
||||
const char *const s2 = *(const char *const * const) b;
|
||||
|
||||
if (s1 == s2)
|
||||
return 0;
|
||||
if (s1 == NULL)
|
||||
return 1;
|
||||
if (s2 == NULL)
|
||||
return -1;
|
||||
return strcoll (s1, s2);
|
||||
}
|
||||
|
||||
|
||||
/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
|
||||
elements in place. Return nonzero if out of memory, zero if successful.
|
||||
A slash is inserted between DIRNAME and each elt of ARRAY,
|
||||
unless DIRNAME is just "/". Each old element of ARRAY is freed. */
|
||||
static int
|
||||
prefix_array (dirname, array, n)
|
||||
const char *dirname;
|
||||
char **array;
|
||||
size_t n;
|
||||
{
|
||||
register size_t i;
|
||||
size_t dirlen = strlen (dirname);
|
||||
|
||||
if (dirlen == 1 && dirname[0] == '/')
|
||||
/* DIRNAME is just "/", so normal prepending would get us "//foo".
|
||||
We want "/foo" instead, so don't prepend any chars from DIRNAME. */
|
||||
dirlen = 0;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
size_t eltlen = strlen (array[i]) + 1;
|
||||
char *new = (char *) malloc (dirlen + 1 + eltlen);
|
||||
if (new == NULL)
|
||||
{
|
||||
while (i > 0)
|
||||
free ((__ptr_t) array[--i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy (new, dirname, dirlen);
|
||||
new[dirlen] = '/';
|
||||
memcpy (&new[dirlen + 1], array[i], eltlen);
|
||||
free ((__ptr_t) array[i]);
|
||||
array[i] = new;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return nonzero if PATTERN contains any metacharacters.
|
||||
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
|
||||
static int
|
||||
glob_pattern_p (pattern, quote)
|
||||
const char *pattern;
|
||||
int quote;
|
||||
{
|
||||
register const char *p;
|
||||
int open = 0;
|
||||
|
||||
for (p = pattern; *p != '\0'; ++p)
|
||||
switch (*p)
|
||||
{
|
||||
case '?':
|
||||
case '*':
|
||||
return 1;
|
||||
|
||||
case '\\':
|
||||
if (quote)
|
||||
++p;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
open = 1;
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (open)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Like `glob', but PATTERN is a final pathname component,
|
||||
and matches are searched for in DIRECTORY.
|
||||
The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
|
||||
The GLOB_APPEND flag is assumed to be set (always appends). */
|
||||
static int
|
||||
glob_in_dir (pattern, directory, flags, errfunc, pglob)
|
||||
const char *pattern;
|
||||
const char *directory;
|
||||
int flags;
|
||||
int (*errfunc) __P ((const char *, int));
|
||||
glob_t *pglob;
|
||||
{
|
||||
__ptr_t stream;
|
||||
|
||||
struct globlink
|
||||
{
|
||||
struct globlink *next;
|
||||
char *name;
|
||||
};
|
||||
struct globlink *names = NULL;
|
||||
size_t nfound = 0;
|
||||
|
||||
if (!glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)))
|
||||
{
|
||||
stream = NULL;
|
||||
flags |= GLOB_NOCHECK;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= GLOB_MAGCHAR;
|
||||
|
||||
stream = (__glob_opendir_hook ? (*__glob_opendir_hook) (directory)
|
||||
: (__ptr_t) opendir (directory));
|
||||
if (stream == NULL)
|
||||
{
|
||||
if ((errfunc != NULL && (*errfunc) (directory, errno)) ||
|
||||
(flags & GLOB_ERR))
|
||||
return GLOB_ABEND;
|
||||
}
|
||||
else
|
||||
while (1)
|
||||
{
|
||||
const char *name;
|
||||
size_t len;
|
||||
|
||||
if (__glob_readdir_hook)
|
||||
{
|
||||
name = (*__glob_readdir_hook) (stream);
|
||||
if (name == NULL)
|
||||
break;
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct dirent *d = readdir ((DIR *) stream);
|
||||
if (d == NULL)
|
||||
break;
|
||||
if (! REAL_DIR_ENTRY (d))
|
||||
continue;
|
||||
name = d->d_name;
|
||||
#ifdef HAVE_D_NAMLEN
|
||||
len = d->d_namlen;
|
||||
#else
|
||||
len = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (fnmatch (pattern, name,
|
||||
(!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) |
|
||||
((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)) == 0)
|
||||
{
|
||||
struct globlink *new
|
||||
= (struct globlink *) __alloca (sizeof (struct globlink));
|
||||
if (len == 0)
|
||||
len = strlen (name);
|
||||
new->name
|
||||
= (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1);
|
||||
if (new->name == NULL)
|
||||
goto memory_error;
|
||||
memcpy ((__ptr_t) new->name, name, len);
|
||||
new->name[len] = '\0';
|
||||
new->next = names;
|
||||
names = new;
|
||||
++nfound;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nfound == 0 && (flags & GLOB_NOCHECK))
|
||||
{
|
||||
size_t len = strlen (pattern);
|
||||
nfound = 1;
|
||||
names = (struct globlink *) __alloca (sizeof (struct globlink));
|
||||
names->next = NULL;
|
||||
names->name = (char *) malloc (len + 1);
|
||||
if (names->name == NULL)
|
||||
goto memory_error;
|
||||
memcpy (names->name, pattern, len);
|
||||
names->name[len] = '\0';
|
||||
}
|
||||
|
||||
pglob->gl_pathv
|
||||
= (char **) realloc (pglob->gl_pathv,
|
||||
(pglob->gl_pathc +
|
||||
((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
|
||||
nfound + 1) *
|
||||
sizeof (char *));
|
||||
if (pglob->gl_pathv == NULL)
|
||||
goto memory_error;
|
||||
|
||||
if (flags & GLOB_DOOFFS)
|
||||
while (pglob->gl_pathc < pglob->gl_offs)
|
||||
pglob->gl_pathv[pglob->gl_pathc++] = NULL;
|
||||
|
||||
for (; names != NULL; names = names->next)
|
||||
pglob->gl_pathv[pglob->gl_pathc++] = names->name;
|
||||
pglob->gl_pathv[pglob->gl_pathc] = NULL;
|
||||
|
||||
pglob->gl_flags = flags;
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
int save = errno;
|
||||
if (__glob_closedir_hook)
|
||||
(*__glob_closedir_hook) (stream);
|
||||
else
|
||||
(void) closedir ((DIR *) stream);
|
||||
errno = save;
|
||||
}
|
||||
return nfound == 0 ? GLOB_NOMATCH : 0;
|
||||
|
||||
memory_error:
|
||||
{
|
||||
int save = errno;
|
||||
if (__glob_closedir_hook)
|
||||
(*__glob_closedir_hook) (stream);
|
||||
else
|
||||
(void) closedir ((DIR *) stream);
|
||||
errno = save;
|
||||
}
|
||||
while (names != NULL)
|
||||
{
|
||||
if (names->name != NULL)
|
||||
free ((__ptr_t) names->name);
|
||||
names = names->next;
|
||||
}
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
@ -1,97 +0,0 @@
|
||||
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _GLOB_H
|
||||
|
||||
#define _GLOB_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#undef __ptr_t
|
||||
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
|
||||
#undef __P
|
||||
#define __P(protos) protos
|
||||
#define __ptr_t void *
|
||||
#else /* Not C++ or ANSI C. */
|
||||
#undef __P
|
||||
#define __P(protos) ()
|
||||
#undef const
|
||||
#define const
|
||||
#define __ptr_t char *
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
/* Bits set in the FLAGS argument to `glob'. */
|
||||
#define GLOB_ERR (1 << 0)/* Return on read errors. */
|
||||
#define GLOB_MARK (1 << 1)/* Append a slash to each name. */
|
||||
#define GLOB_NOSORT (1 << 2)/* Don't sort the names. */
|
||||
#define GLOB_DOOFFS (1 << 3)/* Insert PGLOB->gl_offs NULLs. */
|
||||
#define GLOB_NOCHECK (1 << 4)/* If nothing matches, return the pattern. */
|
||||
#define GLOB_APPEND (1 << 5)/* Append to results of a previous call. */
|
||||
#define GLOB_NOESCAPE (1 << 6)/* Backslashes don't quote metacharacters. */
|
||||
#define GLOB_PERIOD (1 << 7)/* Leading `.' can be matched by metachars. */
|
||||
#define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
|
||||
GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND|GLOB_PERIOD)
|
||||
|
||||
#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_BSD_SOURCE)
|
||||
#define GLOB_MAGCHAR (1 << 8)/* Set in gl_flags if any metachars seen. */
|
||||
#endif
|
||||
|
||||
/* Error returns from `glob'. */
|
||||
#define GLOB_NOSPACE 1 /* Ran out of memory. */
|
||||
#define GLOB_ABEND 2 /* Read error. */
|
||||
#define GLOB_NOMATCH 3 /* No matches found. */
|
||||
|
||||
/* Structure describing a globbing run. */
|
||||
typedef struct
|
||||
{
|
||||
int gl_pathc; /* Count of paths matched by the pattern. */
|
||||
char **gl_pathv; /* List of matched pathnames. */
|
||||
int gl_offs; /* Slots to reserve in `gl_pathv'. */
|
||||
int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */
|
||||
} glob_t;
|
||||
|
||||
/* Do glob searching for PATTERN, placing results in PGLOB.
|
||||
The bits defined above may be set in FLAGS.
|
||||
If a directory cannot be opened or read and ERRFUNC is not nil,
|
||||
it is called with the pathname that caused the error, and the
|
||||
`errno' value from the failing call; if it returns non-zero
|
||||
`glob' returns GLOB_ABEND; if it returns zero, the error is ignored.
|
||||
If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
|
||||
Otherwise, `glob' returns zero. */
|
||||
extern int glob __P ((const char *__pattern, int __flags,
|
||||
int (*__errfunc) __P ((const char *, int)),
|
||||
glob_t *__pglob));
|
||||
|
||||
/* Free storage allocated in PGLOB by a previous `glob' call. */
|
||||
extern void globfree __P ((glob_t *__pglob));
|
||||
|
||||
|
||||
#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
|
||||
/* If they are not NULL, `glob' uses these functions to read directories. */
|
||||
extern __ptr_t (*__glob_opendir_hook) __P ((const char *__directory));
|
||||
extern const char *(*__glob_readdir_hook) __P ((__ptr_t __stream));
|
||||
extern void (*__glob_closedir_hook) __P ((__ptr_t __stream));
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* glob.h */
|
||||
@ -1,590 +0,0 @@
|
||||
/* Implicit rule searching for GNU Make.
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "rule.h"
|
||||
#include "dep.h"
|
||||
#include "file.h"
|
||||
|
||||
static int pattern_search ();
|
||||
|
||||
/* For a FILE which has no commands specified, try to figure out some
|
||||
from the implicit pattern rules.
|
||||
Returns 1 if a suitable implicit rule was found,
|
||||
after modifying FILE to contain the appropriate commands and deps,
|
||||
or returns 0 if no implicit rule was found. */
|
||||
|
||||
int
|
||||
try_implicit_rule (file, depth)
|
||||
struct file *file;
|
||||
unsigned int depth;
|
||||
{
|
||||
DEBUGPR ("Looking for an implicit rule for `%s'.\n");
|
||||
|
||||
/* The order of these searches was previously reversed. My logic now is
|
||||
that since the non-archive search uses more information in the target
|
||||
(the archive search omits the archive name), it is more specific and
|
||||
should come first. */
|
||||
|
||||
if (pattern_search (file, 0, depth, 0))
|
||||
return 1;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
/* If this is an archive member reference, use just the
|
||||
archive member name to search for implicit rules. */
|
||||
if (ar_name (file->name))
|
||||
{
|
||||
DEBUGPR ("Looking for archive-member implicit rule for `%s'.\n");
|
||||
if (pattern_search (file, 1, depth, 0))
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DEBUGP2(msg, a1, a2) \
|
||||
do { \
|
||||
if (debug_flag) \
|
||||
{ print_spaces (depth); printf (msg, a1, a2); fflush (stdout); } \
|
||||
} while (0)
|
||||
|
||||
/* Search the pattern rules for a rule with an existing dependency to make
|
||||
FILE. If a rule is found, the appropriate commands and deps are put in FILE
|
||||
and 1 is returned. If not, 0 is returned.
|
||||
|
||||
If ARCHIVE is nonzero, FILE->name is of the form "LIB(MEMBER)". A rule for
|
||||
"(MEMBER)" will be searched for, and "(MEMBER)" will not be chopped up into
|
||||
directory and filename parts.
|
||||
|
||||
If an intermediate file is found by pattern search, the intermediate file
|
||||
is set up as a target by the recursive call and is also made a dependency
|
||||
of FILE.
|
||||
|
||||
DEPTH is used for debugging messages. */
|
||||
|
||||
static int
|
||||
pattern_search (file, archive, depth, recursions)
|
||||
struct file *file;
|
||||
int archive;
|
||||
unsigned int depth;
|
||||
unsigned int recursions;
|
||||
{
|
||||
/* Filename we are searching for a rule for. */
|
||||
char *filename = archive ? index (file->name, '(') : file->name;
|
||||
|
||||
/* Length of FILENAME. */
|
||||
unsigned int namelen = strlen (filename);
|
||||
|
||||
/* The last slash in FILENAME (or nil if there is none). */
|
||||
char *lastslash;
|
||||
|
||||
/* This is a file-object used as an argument in
|
||||
recursive calls. It never contains any data
|
||||
except during a recursive call. */
|
||||
struct file *intermediate_file = 0;
|
||||
|
||||
/* List of dependencies found recursively. */
|
||||
struct file **intermediate_files
|
||||
= (struct file **) alloca (max_pattern_deps * sizeof (struct file *));
|
||||
|
||||
/* List of the patterns used to find intermediate files. */
|
||||
char **intermediate_patterns
|
||||
= (char **) alloca (max_pattern_deps * sizeof (char *));
|
||||
|
||||
/* This buffer records all the dependencies actually found for a rule. */
|
||||
char **found_files = (char **) alloca (max_pattern_deps * sizeof (char *));
|
||||
/* Number of dep names now in FOUND_FILES. */
|
||||
unsigned int deps_found;
|
||||
|
||||
/* Names of possible dependencies are constructed in this buffer. */
|
||||
register char *depname = (char *) alloca (namelen + max_pattern_dep_length);
|
||||
|
||||
/* The start and length of the stem of FILENAME for the current rule. */
|
||||
register char *stem;
|
||||
register unsigned int stemlen;
|
||||
|
||||
/* Buffer in which we store all the rules that are possibly applicable. */
|
||||
struct rule **tryrules
|
||||
= (struct rule **) alloca (num_pattern_rules * max_pattern_targets
|
||||
* sizeof (struct rule *));
|
||||
|
||||
/* Number of valid elements in TRYRULES. */
|
||||
unsigned int nrules;
|
||||
|
||||
/* The numbers of the rule targets of each rule
|
||||
in TRYRULES that matched the target file. */
|
||||
unsigned int *matches
|
||||
= (unsigned int *) alloca (num_pattern_rules * sizeof (unsigned int));
|
||||
|
||||
/* Each element is nonzero if LASTSLASH was used in
|
||||
matching the corresponding element of TRYRULES. */
|
||||
char *checked_lastslash
|
||||
= (char *) alloca (num_pattern_rules * sizeof (char));
|
||||
|
||||
/* The index in TRYRULES of the rule we found. */
|
||||
unsigned int foundrule;
|
||||
|
||||
/* Nonzero if should consider intermediate files as dependencies. */
|
||||
int intermed_ok;
|
||||
|
||||
/* Nonzero if we have matched a pattern-rule target
|
||||
that is not just `%'. */
|
||||
int specific_rule_matched = 0;
|
||||
|
||||
register unsigned int i;
|
||||
register struct rule *rule;
|
||||
register struct dep *dep;
|
||||
|
||||
char *p;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
if (archive || ar_name (filename))
|
||||
lastslash = 0;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Set LASTSLASH to point at the last slash in FILENAME
|
||||
but not counting any slash at the end. (foo/bar/ counts as
|
||||
bar/ in directory foo/, not empty in directory foo/bar/.) */
|
||||
lastslash = rindex (filename, '/');
|
||||
if (lastslash != 0 && lastslash[1] == '\0')
|
||||
lastslash = 0;
|
||||
}
|
||||
|
||||
/* First see which pattern rules match this target
|
||||
and may be considered. Put them in TRYRULES. */
|
||||
|
||||
nrules = 0;
|
||||
for (rule = pattern_rules; rule != 0; rule = rule->next)
|
||||
{
|
||||
/* If the pattern rule has deps but no commands, ignore it.
|
||||
Users cancel built-in rules by redefining them without commands. */
|
||||
if (rule->deps != 0 && rule->cmds == 0)
|
||||
continue;
|
||||
|
||||
/* If this rule is in use by a parent pattern_search,
|
||||
don't use it here. */
|
||||
if (rule->in_use)
|
||||
{
|
||||
DEBUGP2 ("Avoiding implicit rule recursion.%s%s\n", "", "");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; rule->targets[i] != 0; ++i)
|
||||
{
|
||||
char *target = rule->targets[i];
|
||||
char *suffix = rule->suffixes[i];
|
||||
int check_lastslash;
|
||||
|
||||
/* Rules that can match any filename and are not terminal
|
||||
are ignored if we're recursing, so that they cannot be
|
||||
intermediate files. */
|
||||
if (recursions > 0 && target[1] == '\0' && !rule->terminal)
|
||||
continue;
|
||||
|
||||
if (rule->lens[i] > namelen)
|
||||
/* It can't possibly match. */
|
||||
continue;
|
||||
|
||||
/* From the lengths of the filename and the pattern parts,
|
||||
find the stem: the part of the filename that matches the %. */
|
||||
stem = filename + (suffix - target - 1);
|
||||
stemlen = namelen - rule->lens[i] + 1;
|
||||
|
||||
/* Set CHECK_LASTSLASH if FILENAME contains a directory
|
||||
prefix and the target pattern does not contain a slash. */
|
||||
|
||||
check_lastslash = lastslash != 0 && index (target, '/') == 0;
|
||||
if (check_lastslash)
|
||||
{
|
||||
/* In that case, don't include the
|
||||
directory prefix in STEM here. */
|
||||
unsigned int difference = lastslash - filename + 1;
|
||||
if (difference > stemlen)
|
||||
continue;
|
||||
stemlen -= difference;
|
||||
stem += difference;
|
||||
}
|
||||
|
||||
/* Check that the rule pattern matches the text before the stem. */
|
||||
if (check_lastslash)
|
||||
{
|
||||
if (stem > (lastslash + 1)
|
||||
&& strncmp (target, lastslash + 1, stem - lastslash - 1))
|
||||
continue;
|
||||
}
|
||||
else if (stem > filename
|
||||
&& strncmp (target, filename, stem - filename))
|
||||
continue;
|
||||
|
||||
/* Check that the rule pattern matches the text after the stem.
|
||||
We could test simply use streq, but this way we compare the
|
||||
first two characters immediately. This saves time in the very
|
||||
common case where the first character matches because it is a
|
||||
period. */
|
||||
if (*suffix != stem[stemlen]
|
||||
|| (*suffix != '\0' && !streq (&suffix[1], &stem[(int)stemlen + 1])))
|
||||
continue;
|
||||
|
||||
/* Record if we match a rule that not all filenames will match. */
|
||||
if (target[1] != '\0')
|
||||
specific_rule_matched = 1;
|
||||
|
||||
/* A rule with no dependencies and no commands exists solely to set
|
||||
specific_rule_matched when it matches. Don't try to use it. */
|
||||
if (rule->deps == 0 && rule->cmds == 0)
|
||||
continue;
|
||||
|
||||
/* Record this rule in TRYRULES and the index of the matching
|
||||
target in MATCHES. If several targets of the same rule match,
|
||||
that rule will be in TRYRULES more than once. */
|
||||
tryrules[nrules] = rule;
|
||||
matches[nrules] = i;
|
||||
checked_lastslash[nrules] = check_lastslash;
|
||||
++nrules;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have found a matching rule that won't match all filenames,
|
||||
retroactively reject any non-"terminal" rules that do always match. */
|
||||
if (specific_rule_matched)
|
||||
for (i = 0; i < nrules; ++i)
|
||||
if (!tryrules[i]->terminal)
|
||||
{
|
||||
register unsigned int j;
|
||||
for (j = 0; tryrules[i]->targets[j] != 0; ++j)
|
||||
if (tryrules[i]->targets[j][1] == '\0')
|
||||
break;
|
||||
if (tryrules[i]->targets[j] != 0)
|
||||
tryrules[i] = 0;
|
||||
}
|
||||
|
||||
/* Try each rule once without intermediate files, then once with them. */
|
||||
for (intermed_ok = 0; intermed_ok == !!intermed_ok; ++intermed_ok)
|
||||
{
|
||||
/* Try each pattern rule till we find one that applies.
|
||||
If it does, copy the names of its dependencies (as substituted)
|
||||
and store them in FOUND_FILES. DEPS_FOUND is the number of them. */
|
||||
|
||||
for (i = 0; i < nrules; i++)
|
||||
{
|
||||
int check_lastslash;
|
||||
|
||||
rule = tryrules[i];
|
||||
|
||||
/* RULE is nil when we discover that a rule,
|
||||
already placed in TRYRULES, should not be applied. */
|
||||
if (rule == 0)
|
||||
continue;
|
||||
|
||||
/* Reject any terminal rules if we're
|
||||
looking to make intermediate files. */
|
||||
if (intermed_ok && rule->terminal)
|
||||
continue;
|
||||
|
||||
/* Mark this rule as in use so a recursive
|
||||
pattern_search won't try to use it. */
|
||||
rule->in_use = 1;
|
||||
|
||||
/* From the lengths of the filename and the matching pattern parts,
|
||||
find the stem: the part of the filename that matches the %. */
|
||||
stem = filename
|
||||
+ (rule->suffixes[matches[i]] - rule->targets[matches[i]]) - 1;
|
||||
stemlen = namelen - rule->lens[matches[i]] + 1;
|
||||
check_lastslash = checked_lastslash[i];
|
||||
if (check_lastslash)
|
||||
{
|
||||
stem += lastslash - filename + 1;
|
||||
stemlen -= (lastslash - filename) + 1;
|
||||
}
|
||||
|
||||
DEBUGP2 ("Trying pattern rule with stem `%.*s'.\n",
|
||||
(int) stemlen, stem);
|
||||
|
||||
/* Try each dependency; see if it "exists". */
|
||||
|
||||
deps_found = 0;
|
||||
for (dep = rule->deps; dep != 0; dep = dep->next)
|
||||
{
|
||||
/* If the dependency name has a %, substitute the stem. */
|
||||
p = index (dep_name (dep), '%');
|
||||
if (p != 0)
|
||||
{
|
||||
register unsigned int i;
|
||||
if (check_lastslash)
|
||||
{
|
||||
/* Copy directory name from the original FILENAME. */
|
||||
i = lastslash - filename + 1;
|
||||
bcopy (filename, depname, i);
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
bcopy (dep_name (dep), depname + i, p - dep_name (dep));
|
||||
i += p - dep_name (dep);
|
||||
bcopy (stem, depname + i, stemlen);
|
||||
i += stemlen;
|
||||
strcpy (depname + i, p + 1);
|
||||
p = depname;
|
||||
}
|
||||
else
|
||||
p = dep_name (dep);
|
||||
|
||||
/* P is now the actual dependency name as substituted. */
|
||||
|
||||
if (file_impossible_p (p))
|
||||
{
|
||||
/* If this dependency has already been ruled
|
||||
"impossible", then the rule fails and don't
|
||||
bother trying it on the second pass either
|
||||
since we know that will fail too. */
|
||||
DEBUGP2 ("Rejecting impossible %s dependency `%s'.\n",
|
||||
p == depname ? "implicit" : "rule", p);
|
||||
tryrules[i] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
intermediate_files[deps_found] = 0;
|
||||
|
||||
DEBUGP2 ("Trying %s dependency `%s'.\n",
|
||||
p == depname ? "implicit" : "rule", p);
|
||||
|
||||
/* The DEP->changed flag says that this dependency resides in a
|
||||
nonexistent directory. So we normally can skip looking for
|
||||
the file. However, if CHECK_LASTSLASH is set, then the
|
||||
dependency file we are actually looking for is in a different
|
||||
directory (the one gotten by prepending FILENAME's directory),
|
||||
so it might actually exist. */
|
||||
|
||||
if ((!dep->changed || check_lastslash)
|
||||
&& (lookup_file (p) != 0 || file_exists_p (p)))
|
||||
{
|
||||
found_files[deps_found++] = savestring (p, strlen (p));
|
||||
continue;
|
||||
}
|
||||
/* This code, given FILENAME = "lib/foo.o", dependency name
|
||||
"lib/foo.c", and VPATH=src, searches for "src/lib/foo.c". */
|
||||
if (vpath_search (&p, (time_t *) 0))
|
||||
{
|
||||
DEBUGP2 ("Found dependency as `%s'.%s\n", p, "");
|
||||
found_files[deps_found++] = p;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We could not find the file in any place we should look.
|
||||
Try to make this dependency as an intermediate file,
|
||||
but only on the second pass. */
|
||||
|
||||
if (intermed_ok)
|
||||
{
|
||||
if (intermediate_file == 0)
|
||||
intermediate_file
|
||||
= (struct file *) alloca (sizeof (struct file));
|
||||
|
||||
DEBUGP2 ("Looking for a rule with %s file `%s'.\n",
|
||||
"intermediate", p);
|
||||
|
||||
bzero ((char *) intermediate_file, sizeof (struct file));
|
||||
intermediate_file->name = p;
|
||||
if (pattern_search (intermediate_file, 0, depth + 1,
|
||||
recursions + 1))
|
||||
{
|
||||
p = savestring (p, strlen (p));
|
||||
intermediate_patterns[deps_found]
|
||||
= intermediate_file->name;
|
||||
intermediate_file->name = p;
|
||||
intermediate_files[deps_found] = intermediate_file;
|
||||
intermediate_file = 0;
|
||||
/* Allocate an extra copy to go in FOUND_FILES,
|
||||
because every elt of FOUND_FILES is consumed
|
||||
or freed later. */
|
||||
found_files[deps_found] = savestring (p, strlen (p));
|
||||
++deps_found;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If we have tried to find P as an intermediate
|
||||
file and failed, mark that name as impossible
|
||||
so we won't go through the search again later. */
|
||||
file_impossible (p);
|
||||
}
|
||||
|
||||
/* A dependency of this rule does not exist.
|
||||
Therefore, this rule fails. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* This rule is no longer `in use' for recursive searches. */
|
||||
rule->in_use = 0;
|
||||
|
||||
if (dep != 0)
|
||||
{
|
||||
/* This pattern rule does not apply.
|
||||
If some of its dependencies succeeded,
|
||||
free the data structure describing them. */
|
||||
while (deps_found-- > 0)
|
||||
{
|
||||
register struct file *f = intermediate_files[deps_found];
|
||||
free (found_files[deps_found]);
|
||||
if (f != 0
|
||||
&& (f->stem < f->name
|
||||
|| f->stem > f->name + strlen (f->name)))
|
||||
free (f->stem);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* This pattern rule does apply. Stop looking for one. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we found an applicable rule without
|
||||
intermediate files, don't try with them. */
|
||||
if (i < nrules)
|
||||
break;
|
||||
|
||||
rule = 0;
|
||||
}
|
||||
|
||||
/* RULE is nil if the loop went all the way
|
||||
through the list and everything failed. */
|
||||
if (rule == 0)
|
||||
return 0;
|
||||
|
||||
foundrule = i;
|
||||
|
||||
/* If we are recursing, store the pattern that matched
|
||||
FILENAME in FILE->name for use in upper levels. */
|
||||
|
||||
if (recursions > 0)
|
||||
/* Kludge-o-matic */
|
||||
file->name = rule->targets[matches[foundrule]];
|
||||
|
||||
/* FOUND_FILES lists the dependencies for the rule we found.
|
||||
This includes the intermediate files, if any.
|
||||
Convert them into entries on the deps-chain of FILE. */
|
||||
|
||||
while (deps_found-- > 0)
|
||||
{
|
||||
register char *s;
|
||||
|
||||
if (intermediate_files[deps_found] != 0)
|
||||
{
|
||||
/* If we need to use an intermediate file,
|
||||
make sure it is entered as a target, with the info that was
|
||||
found for it in the recursive pattern_search call.
|
||||
We know that the intermediate file did not already exist as
|
||||
a target; therefore we can assume that the deps and cmds
|
||||
of F below are null before we change them. */
|
||||
|
||||
struct file *imf = intermediate_files[deps_found];
|
||||
register struct file *f = enter_file (imf->name);
|
||||
f->deps = imf->deps;
|
||||
f->cmds = imf->cmds;
|
||||
f->stem = imf->stem;
|
||||
imf = lookup_file (intermediate_patterns[deps_found]);
|
||||
if (imf != 0 && imf->precious)
|
||||
f->precious = 1;
|
||||
f->intermediate = 1;
|
||||
f->tried_implicit = 1;
|
||||
for (dep = f->deps; dep != 0; dep = dep->next)
|
||||
{
|
||||
dep->file = enter_file (dep->name);
|
||||
dep->name = 0;
|
||||
dep->file->tried_implicit |= dep->changed;
|
||||
}
|
||||
num_intermediates++;
|
||||
}
|
||||
|
||||
dep = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
s = found_files[deps_found];
|
||||
if (recursions == 0)
|
||||
{
|
||||
dep->name = 0;
|
||||
dep->file = lookup_file (s);
|
||||
if (dep->file == 0)
|
||||
/* enter_file consumes S's storage. */
|
||||
dep->file = enter_file (s);
|
||||
else
|
||||
/* A copy of S is already allocated in DEP->file->name.
|
||||
So we can free S. */
|
||||
free (s);
|
||||
}
|
||||
else
|
||||
{
|
||||
dep->name = s;
|
||||
dep->file = 0;
|
||||
dep->changed = 0;
|
||||
}
|
||||
if (intermediate_files[deps_found] == 0 && tryrules[foundrule]->terminal)
|
||||
{
|
||||
/* If the file actually existed (was not an intermediate file),
|
||||
and the rule that found it was a terminal one, then we want
|
||||
to mark the found file so that it will not have implicit rule
|
||||
search done for it. If we are not entering a `struct file' for
|
||||
it now, we indicate this with the `changed' flag. */
|
||||
if (dep->file == 0)
|
||||
dep->changed = 1;
|
||||
else
|
||||
dep->file->tried_implicit = 1;
|
||||
}
|
||||
dep->next = file->deps;
|
||||
file->deps = dep;
|
||||
}
|
||||
|
||||
if (!checked_lastslash[foundrule])
|
||||
/* Always allocate new storage, since STEM might be
|
||||
on the stack for an intermediate file. */
|
||||
file->stem = savestring (stem, stemlen);
|
||||
else
|
||||
{
|
||||
/* We want to prepend the directory from
|
||||
the original FILENAME onto the stem. */
|
||||
file->stem = (char *) xmalloc (((lastslash + 1) - filename)
|
||||
+ stemlen + 1);
|
||||
bcopy (filename, file->stem, (lastslash + 1) - filename);
|
||||
bcopy (stem, file->stem + ((lastslash + 1) - filename), stemlen);
|
||||
file->stem[((lastslash + 1) - filename) + stemlen] = '\0';
|
||||
}
|
||||
|
||||
file->cmds = rule->cmds;
|
||||
|
||||
/* Put the targets other than the one that
|
||||
matched into FILE's `also_make' member. */
|
||||
|
||||
/* If there was only one target, there is nothing to do. */
|
||||
if (rule->targets[1] != 0)
|
||||
for (i = 0; rule->targets[i] != 0; ++i)
|
||||
if (i != matches[foundrule])
|
||||
{
|
||||
struct dep *new = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
new->name = p = (char *) xmalloc (rule->lens[i] + stemlen + 1);
|
||||
bcopy (rule->targets[i], p,
|
||||
rule->suffixes[i] - rule->targets[i] - 1);
|
||||
p += rule->suffixes[i] - rule->targets[i] - 1;
|
||||
bcopy (stem, p, stemlen);
|
||||
p += stemlen;
|
||||
bcopy (rule->suffixes[i], p,
|
||||
rule->lens[i] - (rule->suffixes[i] - rule->targets[i]) + 1);
|
||||
new->file = enter_file (new->name);
|
||||
new->next = file->also_make;
|
||||
file->also_make = new;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1,238 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
#
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
tranformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
instcmd=mkdir
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
then
|
||||
true
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d $dst ]
|
||||
then
|
||||
dst="$dst"/`basename $src`
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
|
||||
pathcomp=''
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp="${pathcomp}${1}"
|
||||
shift
|
||||
|
||||
if [ ! -d "${pathcomp}" ] ;
|
||||
then
|
||||
$mkdirprog "${pathcomp}"
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd $src $dsttmp &&
|
||||
|
||||
trap "rm -f ${dsttmp}" 0 &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
exit 0
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,67 +0,0 @@
|
||||
/* Definitions for managing subprocesses in GNU Make.
|
||||
Copyright (C) 1992, 1993 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Structure describing a running or dead child process. */
|
||||
|
||||
struct child
|
||||
{
|
||||
struct child *next; /* Link in the chain. */
|
||||
|
||||
struct file *file; /* File being remade. */
|
||||
|
||||
char **environment; /* Environment for commands. */
|
||||
|
||||
char **command_lines; /* Array of variable-expanded cmd lines. */
|
||||
unsigned int command_line; /* Index into above. */
|
||||
char *command_ptr; /* Ptr into command_lines[command_line]. */
|
||||
|
||||
pid_t pid; /* Child process's ID number. */
|
||||
unsigned int remote:1; /* Nonzero if executing remotely. */
|
||||
|
||||
unsigned int noerror:1; /* Nonzero if commands contained a `-'. */
|
||||
|
||||
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
|
||||
unsigned int deleted:1; /* Nonzero if targets have been deleted. */
|
||||
};
|
||||
|
||||
extern struct child *children;
|
||||
|
||||
extern void new_job ();
|
||||
extern void reap_children ();
|
||||
extern void start_waiting_jobs ();
|
||||
|
||||
extern char **construct_command_argv ();
|
||||
extern void child_execute_job ();
|
||||
extern void exec_command ();
|
||||
|
||||
extern unsigned int job_slots_used;
|
||||
|
||||
#ifdef POSIX
|
||||
extern void unblock_sigs ();
|
||||
#else
|
||||
#ifdef HAVE_SIGSETMASK
|
||||
extern int fatal_signal_mask;
|
||||
#define unblock_sigs() sigsetmask (0)
|
||||
#else
|
||||
#define unblock_sigs()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef NETSCAPE
|
||||
extern int ns_spawn (char **argv, char **envp, int *exitCode);
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,656 +0,0 @@
|
||||
@comment This file is included by both standards.texi and make.texinfo.
|
||||
@comment It was broken out of standards.texi on 1/6/93 by roland.
|
||||
|
||||
@node Makefile Conventions
|
||||
@chapter Makefile Conventions
|
||||
@comment standards.texi does not print an index, but make.texinfo does.
|
||||
@cindex makefile, conventions for
|
||||
@cindex conventions for makefiles
|
||||
@cindex standards for makefiles
|
||||
|
||||
This chapter describes conventions for writing the Makefiles for GNU programs.
|
||||
|
||||
@menu
|
||||
* Makefile Basics::
|
||||
* Utilities in Makefiles::
|
||||
* Standard Targets::
|
||||
* Command Variables::
|
||||
* Directory Variables::
|
||||
@end menu
|
||||
|
||||
@node Makefile Basics
|
||||
@section General Conventions for Makefiles
|
||||
|
||||
Every Makefile should contain this line:
|
||||
|
||||
@example
|
||||
SHELL = /bin/sh
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
to avoid trouble on systems where the @code{SHELL} variable might be
|
||||
inherited from the environment. (This is never a problem with GNU
|
||||
@code{make}.)
|
||||
|
||||
Different @code{make} programs have incompatible suffix lists and
|
||||
implicit rules, and this sometimes creates confusion or misbehavior. So
|
||||
it is a good idea to set the suffix list explicitly using only the
|
||||
suffixes you need in the particular Makefile, like this:
|
||||
|
||||
@example
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
The first line clears out the suffix list, the second introduces all
|
||||
suffixes which may be subject to implicit rules in this Makefile.
|
||||
|
||||
Don't assume that @file{.} is in the path for command execution. When
|
||||
you need to run programs that are a part of your package during the
|
||||
make, please make sure that it uses @file{./} if the program is built as
|
||||
part of the make or @file{$(srcdir)/} if the file is an unchanging part
|
||||
of the source code. Without one of these prefixes, the current search
|
||||
path is used.
|
||||
|
||||
The distinction between @file{./} and @file{$(srcdir)/} is important
|
||||
when using the @samp{--srcdir} option to @file{configure}. A rule of
|
||||
the form:
|
||||
|
||||
@smallexample
|
||||
foo.1 : foo.man sedscript
|
||||
sed -e sedscript foo.man > foo.1
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
will fail when the current directory is not the source directory,
|
||||
because @file{foo.man} and @file{sedscript} are not in the current
|
||||
directory.
|
||||
|
||||
When using GNU @code{make}, relying on @samp{VPATH} to find the source
|
||||
file will work in the case where there is a single dependency file,
|
||||
since the @file{make} automatic variable @samp{$<} will represent the
|
||||
source file wherever it is. (Many versions of @code{make} set @samp{$<}
|
||||
only in implicit rules.) A makefile target like
|
||||
|
||||
@smallexample
|
||||
foo.o : bar.c
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
should instead be written as
|
||||
|
||||
@smallexample
|
||||
foo.o : bar.c
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@@
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
in order to allow @samp{VPATH} to work correctly. When the target has
|
||||
multiple dependencies, using an explicit @samp{$(srcdir)} is the easiest
|
||||
way to make the rule work well. For example, the target above for
|
||||
@file{foo.1} is best written as:
|
||||
|
||||
@smallexample
|
||||
foo.1 : foo.man sedscript
|
||||
sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@@
|
||||
@end smallexample
|
||||
|
||||
@node Utilities in Makefiles
|
||||
@section Utilities in Makefiles
|
||||
|
||||
Write the Makefile commands (and any shell scripts, such as
|
||||
@code{configure}) to run in @code{sh}, not in @code{csh}. Don't use any
|
||||
special features of @code{ksh} or @code{bash}.
|
||||
|
||||
The @code{configure} script and the Makefile rules for building and
|
||||
installation should not use any utilities directly except these:
|
||||
|
||||
@example
|
||||
cat cmp cp echo egrep expr grep
|
||||
ln mkdir mv pwd rm rmdir sed test touch
|
||||
@end example
|
||||
|
||||
Stick to the generally supported options for these programs. For
|
||||
example, don't use @samp{mkdir -p}, convenient as it may be, because
|
||||
most systems don't support it.
|
||||
|
||||
The Makefile rules for building and installation can also use compilers
|
||||
and related programs, but should do so via @code{make} variables so that the
|
||||
user can substitute alternatives. Here are some of the programs we
|
||||
mean:
|
||||
|
||||
@example
|
||||
ar bison cc flex install ld lex
|
||||
make makeinfo ranlib texi2dvi yacc
|
||||
@end example
|
||||
|
||||
Use the following @code{make} variables:
|
||||
|
||||
@example
|
||||
$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LEX)
|
||||
$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)
|
||||
@end example
|
||||
|
||||
When you use @code{ranlib}, you should make sure nothing bad happens if
|
||||
the system does not have @code{ranlib}. Arrange to ignore an error
|
||||
from that command, and print a message before the command to tell the
|
||||
user that failure of the @code{ranlib} command does not mean a problem.
|
||||
|
||||
If you use symbolic links, you should implement a fallback for systems
|
||||
that don't have symbolic links.
|
||||
|
||||
It is ok to use other utilities in Makefile portions (or scripts)
|
||||
intended only for particular systems where you know those utilities to
|
||||
exist.
|
||||
|
||||
@node Standard Targets
|
||||
@section Standard Targets for Users
|
||||
|
||||
All GNU programs should have the following targets in their Makefiles:
|
||||
|
||||
@table @samp
|
||||
@item all
|
||||
Compile the entire program. This should be the default target. This
|
||||
target need not rebuild any documentation files; Info files should
|
||||
normally be included in the distribution, and DVI files should be made
|
||||
only when explicitly asked for.
|
||||
|
||||
@item install
|
||||
Compile the program and copy the executables, libraries, and so on to
|
||||
the file names where they should reside for actual use. If there is a
|
||||
simple test to verify that a program is properly installed, this target
|
||||
should run that test.
|
||||
|
||||
If possible, write the @code{install} target rule so that it does not
|
||||
modify anything in the directory where the program was built, provided
|
||||
@samp{make all} has just been done. This is convenient for building the
|
||||
program under one user name and installing it under another.
|
||||
|
||||
The commands should create all the directories in which files are to be
|
||||
installed, if they don't already exist. This includes the directories
|
||||
specified as the values of the variables @code{prefix} and
|
||||
@code{exec_prefix}, as well as all subdirectories that are needed.
|
||||
One way to do this is by means of an @code{installdirs} target
|
||||
as described below.
|
||||
|
||||
Use @samp{-} before any command for installing a man page, so that
|
||||
@code{make} will ignore any errors. This is in case there are systems
|
||||
that don't have the Unix man page documentation system installed.
|
||||
|
||||
The way to install Info files is to copy them into @file{$(infodir)}
|
||||
with @code{$(INSTALL_DATA)} (@pxref{Command Variables}), and then run
|
||||
the @code{install-info} program if it is present. @code{install-info}
|
||||
is a script that edits the Info @file{dir} file to add or update the
|
||||
menu entry for the given Info file; it will be part of the Texinfo package.
|
||||
Here is a sample rule to install an Info file:
|
||||
|
||||
@comment This example has been carefully formatted for the Make manual.
|
||||
@comment Please do not reformat it without talking to roland@gnu.ai.mit.edu.
|
||||
@smallexample
|
||||
$(infodir)/foo.info: foo.info
|
||||
# There may be a newer info file in . than in srcdir.
|
||||
-if test -f foo.info; then d=.; \
|
||||
else d=$(srcdir); fi; \
|
||||
$(INSTALL_DATA) $$d/foo.info $@@; \
|
||||
# Run install-info only if it exists.
|
||||
# Use `if' instead of just prepending `-' to the
|
||||
# line so we notice real errors from install-info.
|
||||
# We use `$(SHELL) -c' because some shells do not
|
||||
# fail gracefully when there is an unknown command.
|
||||
if $(SHELL) -c 'install-info --version' \
|
||||
>/dev/null 2>&1; then \
|
||||
install-info --infodir=$(infodir) $$d/foo.info; \
|
||||
else true; fi
|
||||
@end smallexample
|
||||
|
||||
@item uninstall
|
||||
Delete all the installed files that the @samp{install} target would
|
||||
create (but not the noninstalled files such as @samp{make all} would
|
||||
create).
|
||||
|
||||
This rule should not modify the directories where compilation is done,
|
||||
only the directories where files are installed.
|
||||
|
||||
@comment The gratuitous blank line here is to make the table look better
|
||||
@comment in the printed Make manual. Please leave it in.
|
||||
@item clean
|
||||
|
||||
Delete all files from the current directory that are normally created by
|
||||
building the program. Don't delete the files that record the
|
||||
configuration. Also preserve files that could be made by building, but
|
||||
normally aren't because the distribution comes with them.
|
||||
|
||||
Delete @file{.dvi} files here if they are not part of the distribution.
|
||||
|
||||
@item distclean
|
||||
Delete all files from the current directory that are created by
|
||||
configuring or building the program. If you have unpacked the source
|
||||
and built the program without creating any other files, @samp{make
|
||||
distclean} should leave only the files that were in the distribution.
|
||||
|
||||
@item mostlyclean
|
||||
Like @samp{clean}, but may refrain from deleting a few files that people
|
||||
normally don't want to recompile. For example, the @samp{mostlyclean}
|
||||
target for GCC does not delete @file{libgcc.a}, because recompiling it
|
||||
is rarely necessary and takes a lot of time.
|
||||
|
||||
@item maintainer-clean
|
||||
Delete almost everything from the current directory that can be
|
||||
reconstructed with this Makefile. This typically includes everything
|
||||
deleted by @code{distclean}, plus more: C source files produced by
|
||||
Bison, tags tables, Info files, and so on.
|
||||
|
||||
The reason we say ``almost everything'' is that @samp{make
|
||||
maintainer-clean} should not delete @file{configure} even if
|
||||
@file{configure} can be remade using a rule in the Makefile. More
|
||||
generally, @samp{make maintainer-clean} should not delete anything that
|
||||
needs to exist in order to run @file{configure} and then begin to build
|
||||
the program. This is the only exception; @code{maintainer-clean} should
|
||||
delete everything else that can be rebuilt.
|
||||
|
||||
The @samp{maintainer-clean} is intended to be used by a maintainer of
|
||||
the package, not by ordinary users. You may need special tools to
|
||||
reconstruct some of the files that @samp{make maintainer-clean} deletes.
|
||||
Since these files are normally included in the distribution, we don't
|
||||
take care to make them easy to reconstruct. If you find you need to
|
||||
unpack the full distribution again, don't blame us.
|
||||
|
||||
To help make users aware of this, the commands for
|
||||
@code{maintainer-clean} should start with these two:
|
||||
|
||||
@example
|
||||
@@echo "This command is intended for maintainers to use;"
|
||||
@@echo "it deletes files that may require special tools to rebuild."
|
||||
@end example
|
||||
|
||||
@item TAGS
|
||||
Update a tags table for this program.
|
||||
|
||||
@item info
|
||||
Generate any Info files needed. The best way to write the rules is as
|
||||
follows:
|
||||
|
||||
@smallexample
|
||||
info: foo.info
|
||||
|
||||
foo.info: foo.texi chap1.texi chap2.texi
|
||||
$(MAKEINFO) $(srcdir)/foo.texi
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
You must define the variable @code{MAKEINFO} in the Makefile. It should
|
||||
run the @code{makeinfo} program, which is part of the Texinfo
|
||||
distribution.
|
||||
|
||||
@item dvi
|
||||
Generate DVI files for all TeXinfo documentation.
|
||||
For example:
|
||||
|
||||
@smallexample
|
||||
dvi: foo.dvi
|
||||
|
||||
foo.dvi: foo.texi chap1.texi chap2.texi
|
||||
$(TEXI2DVI) $(srcdir)/foo.texi
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
You must define the variable @code{TEXI2DVI} in the Makefile. It should
|
||||
run the program @code{texi2dvi}, which is part of the Texinfo
|
||||
distribution. Alternatively, write just the dependencies, and allow GNU
|
||||
Make to provide the command.
|
||||
|
||||
@item dist
|
||||
Create a distribution tar file for this program. The tar file should be
|
||||
set up so that the file names in the tar file start with a subdirectory
|
||||
name which is the name of the package it is a distribution for. This
|
||||
name can include the version number.
|
||||
|
||||
For example, the distribution tar file of GCC version 1.40 unpacks into
|
||||
a subdirectory named @file{gcc-1.40}.
|
||||
|
||||
The easiest way to do this is to create a subdirectory appropriately
|
||||
named, use @code{ln} or @code{cp} to install the proper files in it, and
|
||||
then @code{tar} that subdirectory.
|
||||
|
||||
The @code{dist} target should explicitly depend on all non-source files
|
||||
that are in the distribution, to make sure they are up to date in the
|
||||
distribution.
|
||||
@xref{Releases, , Making Releases, standards, GNU Coding Standards}.
|
||||
|
||||
@item check
|
||||
Perform self-tests (if any). The user must build the program before
|
||||
running the tests, but need not install the program; you should write
|
||||
the self-tests so that they work when the program is built but not
|
||||
installed.
|
||||
@end table
|
||||
|
||||
The following targets are suggested as conventional names, for programs
|
||||
in which they are useful.
|
||||
|
||||
@table @code
|
||||
@item installcheck
|
||||
Perform installation tests (if any). The user must build and install
|
||||
the program before running the tests. You should not assume that
|
||||
@file{$(bindir)} is in the search path.
|
||||
|
||||
@item installdirs
|
||||
It's useful to add a target named @samp{installdirs} to create the
|
||||
directories where files are installed, and their parent directories.
|
||||
There is a script called @file{mkinstalldirs} which is convenient for
|
||||
this; find it in the Texinfo package.@c It's in /gd/gnu/lib/mkinstalldirs.
|
||||
You can use a rule like this:
|
||||
|
||||
@comment This has been carefully formatted to look decent in the Make manual.
|
||||
@comment Please be sure not to make it extend any further to the right.--roland
|
||||
@smallexample
|
||||
# Make sure all installation directories (e.g. $(bindir))
|
||||
# actually exist by making them if necessary.
|
||||
installdirs: mkinstalldirs
|
||||
$(srcdir)/mkinstalldirs $(bindir) $(datadir) \
|
||||
$(libdir) $(infodir) \
|
||||
$(mandir)
|
||||
@end smallexample
|
||||
|
||||
This rule should not modify the directories where compilation is done.
|
||||
It should do nothing but create installation directories.
|
||||
@end table
|
||||
|
||||
@node Command Variables
|
||||
@section Variables for Specifying Commands
|
||||
|
||||
Makefiles should provide variables for overriding certain commands, options,
|
||||
and so on.
|
||||
|
||||
In particular, you should run most utility programs via variables.
|
||||
Thus, if you use Bison, have a variable named @code{BISON} whose default
|
||||
value is set with @samp{BISON = bison}, and refer to it with
|
||||
@code{$(BISON)} whenever you need to use Bison.
|
||||
|
||||
File management utilities such as @code{ln}, @code{rm}, @code{mv}, and
|
||||
so on, need not be referred to through variables in this way, since users
|
||||
don't need to replace them with other programs.
|
||||
|
||||
Each program-name variable should come with an options variable that is
|
||||
used to supply options to the program. Append @samp{FLAGS} to the
|
||||
program-name variable name to get the options variable name---for
|
||||
example, @code{BISONFLAGS}. (The name @code{CFLAGS} is an exception to
|
||||
this rule, but we keep it because it is standard.) Use @code{CPPFLAGS}
|
||||
in any compilation command that runs the preprocessor, and use
|
||||
@code{LDFLAGS} in any compilation command that does linking as well as
|
||||
in any direct use of @code{ld}.
|
||||
|
||||
If there are C compiler options that @emph{must} be used for proper
|
||||
compilation of certain files, do not include them in @code{CFLAGS}.
|
||||
Users expect to be able to specify @code{CFLAGS} freely themselves.
|
||||
Instead, arrange to pass the necessary options to the C compiler
|
||||
independently of @code{CFLAGS}, by writing them explicitly in the
|
||||
compilation commands or by defining an implicit rule, like this:
|
||||
|
||||
@smallexample
|
||||
CFLAGS = -g
|
||||
ALL_CFLAGS = -I. $(CFLAGS)
|
||||
.c.o:
|
||||
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
|
||||
@end smallexample
|
||||
|
||||
Do include the @samp{-g} option in @code{CFLAGS}, because that is not
|
||||
@emph{required} for proper compilation. You can consider it a default
|
||||
that is only recommended. If the package is set up so that it is
|
||||
compiled with GCC by default, then you might as well include @samp{-O}
|
||||
in the default value of @code{CFLAGS} as well.
|
||||
|
||||
Put @code{CFLAGS} last in the compilation command, after other variables
|
||||
containing compiler options, so the user can use @code{CFLAGS} to
|
||||
override the others.
|
||||
|
||||
Every Makefile should define the variable @code{INSTALL}, which is the
|
||||
basic command for installing a file into the system.
|
||||
|
||||
Every Makefile should also define the variables @code{INSTALL_PROGRAM}
|
||||
and @code{INSTALL_DATA}. (The default for each of these should be
|
||||
@code{$(INSTALL)}.) Then it should use those variables as the commands
|
||||
for actual installation, for executables and nonexecutables
|
||||
respectively. Use these variables as follows:
|
||||
|
||||
@example
|
||||
$(INSTALL_PROGRAM) foo $(bindir)/foo
|
||||
$(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
Always use a file name, not a directory name, as the second argument of
|
||||
the installation commands. Use a separate command for each file to be
|
||||
installed.
|
||||
|
||||
@node Directory Variables
|
||||
@section Variables for Installation Directories
|
||||
|
||||
Installation directories should always be named by variables, so it is
|
||||
easy to install in a nonstandard place. The standard names for these
|
||||
variables are described below. They are based on a standard filesystem
|
||||
layout; variants of it are used in SVR4, 4.4BSD, Linux, Ultrix v4, and
|
||||
other modern operating systems.
|
||||
|
||||
These two variables set the root for the installation. All the other
|
||||
installation directories should be subdirectories of one of these two,
|
||||
and nothing should be directly installed into these two directories.
|
||||
|
||||
@table @samp
|
||||
@item prefix
|
||||
A prefix used in constructing the default values of the variables listed
|
||||
below. The default value of @code{prefix} should be @file{/usr/local}
|
||||
When building the complete GNU system, the prefix will be empty and
|
||||
@file{/usr} will be a symbolic link to @file{/}.
|
||||
|
||||
@item exec_prefix
|
||||
A prefix used in constructing the default values of some of the
|
||||
variables listed below. The default value of @code{exec_prefix} should
|
||||
be @code{$(prefix)}.
|
||||
|
||||
Generally, @code{$(exec_prefix)} is used for directories that contain
|
||||
machine-specific files (such as executables and subroutine libraries),
|
||||
while @code{$(prefix)} is used directly for other directories.
|
||||
@end table
|
||||
|
||||
Executable programs are installed in one of the following directories.
|
||||
|
||||
@table @samp
|
||||
@item bindir
|
||||
The directory for installing executable programs that users can run.
|
||||
This should normally be @file{/usr/local/bin}, but write it as
|
||||
@file{$(exec_prefix)/bin}.
|
||||
|
||||
@item sbindir
|
||||
The directory for installing executable programs that can be run from
|
||||
the shell, but are only generally useful to system administrators. This
|
||||
should normally be @file{/usr/local/sbin}, but write it as
|
||||
@file{$(exec_prefix)/sbin}.
|
||||
|
||||
@item libexecdir
|
||||
@comment This paragraph adjusted to avoid overfull hbox --roland 5jul94
|
||||
The directory for installing executable programs to be run by other
|
||||
programs rather than by users. This directory should normally be
|
||||
@file{/usr/local/libexec}, but write it as @file{$(exec_prefix)/libexec}.
|
||||
@end table
|
||||
|
||||
Data files used by the program during its execution are divided into
|
||||
categories in two ways.
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Some files are normally modified by programs; others are never normally
|
||||
modified (though users may edit some of these).
|
||||
|
||||
@item
|
||||
Some files are architecture-independent and can be shared by all
|
||||
machines at a site; some are architecture-dependent and can be shared
|
||||
only by machines of the same kind and operating system; others may never
|
||||
be shared between two machines.
|
||||
@end itemize
|
||||
|
||||
This makes for six different possibilities. However, we want to
|
||||
discourage the use of architecture-dependent files, aside from of object
|
||||
files and libraries. It is much cleaner to make other data files
|
||||
architecture-independent, and it is generally not hard.
|
||||
|
||||
Therefore, here are the variables makefiles should use to specify
|
||||
directories:
|
||||
|
||||
@table @samp
|
||||
@item datadir
|
||||
The directory for installing read-only architecture independent data
|
||||
files. This should normally be @file{/usr/local/share}, but write it as
|
||||
@file{$(prefix)/share}. As a special exception, see @file{$(infodir)}
|
||||
and @file{$(includedir)} below.
|
||||
|
||||
@item sysconfdir
|
||||
The directory for installing read-only data files that pertain to a
|
||||
single machine--that is to say, files for configuring a host. Mailer
|
||||
and network configuration files, @file{/etc/passwd}, and so forth belong
|
||||
here. All the files in this directory should be ordinary ASCII text
|
||||
files. This directory should normally be @file{/usr/local/etc}, but
|
||||
write it as @file{$(prefix)/etc}.
|
||||
|
||||
@c rewritten to avoid overfull hbox --tower
|
||||
Do not install executables
|
||||
@c here
|
||||
in this directory (they probably
|
||||
belong in @file{$(libexecdir)} or @file{$(sbindir))}. Also do not
|
||||
install files that are modified in the normal course of their use
|
||||
(programs whose purpose is to change the configuration of the system
|
||||
excluded). Those probably belong in @file{$(localstatedir)}.
|
||||
|
||||
@item sharedstatedir
|
||||
The directory for installing architecture-independent data files which
|
||||
the programs modify while they run. This should normally be
|
||||
@file{/usr/local/com}, but write it as @file{$(prefix)/com}.
|
||||
|
||||
@item localstatedir
|
||||
The directory for installing data files which the programs modify while
|
||||
they run, and that pertain to one specific machine. Users should never
|
||||
need to modify files in this directory to configure the package's
|
||||
operation; put such configuration information in separate files that go
|
||||
in @file{datadir} or @file{$(sysconfdir)}. @file{$(localstatedir)}
|
||||
should normally be @file{/usr/local/var}, but write it as
|
||||
@file{$(prefix)/var}.
|
||||
|
||||
@item libdir
|
||||
The directory for object files and libraries of object code. Do not
|
||||
install executables here, they probably belong in @file{$(libexecdir)}
|
||||
instead. The value of @code{libdir} should normally be
|
||||
@file{/usr/local/lib}, but write it as @file{$(exec_prefix)/lib}.
|
||||
|
||||
@item infodir
|
||||
The directory for installing the Info files for this package. By
|
||||
default, it should be @file{/usr/local/info}, but it should be written
|
||||
as @file{$(prefix)/info}.
|
||||
|
||||
@item includedir
|
||||
@c rewritten to avoid overfull hbox --roland
|
||||
The directory for installing header files to be included by user
|
||||
programs with the C @samp{#include} preprocessor directive. This
|
||||
should normally be @file{/usr/local/include}, but write it as
|
||||
@file{$(prefix)/include}.
|
||||
|
||||
Most compilers other than GCC do not look for header files in
|
||||
@file{/usr/local/include}. So installing the header files this way is
|
||||
only useful with GCC. Sometimes this is not a problem because some
|
||||
libraries are only really intended to work with GCC. But some libraries
|
||||
are intended to work with other compilers. They should install their
|
||||
header files in two places, one specified by @code{includedir} and one
|
||||
specified by @code{oldincludedir}.
|
||||
|
||||
@item oldincludedir
|
||||
The directory for installing @samp{#include} header files for use with
|
||||
compilers other than GCC. This should normally be @file{/usr/include}.
|
||||
|
||||
The Makefile commands should check whether the value of
|
||||
@code{oldincludedir} is empty. If it is, they should not try to use
|
||||
it; they should cancel the second installation of the header files.
|
||||
|
||||
A package should not replace an existing header in this directory unless
|
||||
the header came from the same package. Thus, if your Foo package
|
||||
provides a header file @file{foo.h}, then it should install the header
|
||||
file in the @code{oldincludedir} directory if either (1) there is no
|
||||
@file{foo.h} there or (2) the @file{foo.h} that exists came from the Foo
|
||||
package.
|
||||
|
||||
To tell whether @file{foo.h} came from the Foo package, put a magic
|
||||
string in the file---part of a comment---and grep for that string.
|
||||
@end table
|
||||
|
||||
Unix-style man pages are installed in one of the following:
|
||||
|
||||
@table @samp
|
||||
@item mandir
|
||||
The directory for installing the man pages (if any) for this package.
|
||||
It should include the suffix for the proper section of the
|
||||
manual---usually @samp{1} for a utility. It will normally be
|
||||
@file{/usr/local/man/man1}, but you should write it as
|
||||
@file{$(prefix)/man/man1}.
|
||||
|
||||
@item man1dir
|
||||
The directory for installing section 1 man pages.
|
||||
@item man2dir
|
||||
The directory for installing section 2 man pages.
|
||||
@item @dots{}
|
||||
Use these names instead of @samp{mandir} if the package needs to install man
|
||||
pages in more than one section of the manual.
|
||||
|
||||
@strong{Don't make the primary documentation for any GNU software be a
|
||||
man page. Write a manual in Texinfo instead. Man pages are just for
|
||||
the sake of people running GNU software on Unix, which is a secondary
|
||||
application only.}
|
||||
|
||||
@item manext
|
||||
The file name extension for the installed man page. This should contain
|
||||
a period followed by the appropriate digit; it should normally be @samp{.1}.
|
||||
|
||||
@item man1ext
|
||||
The file name extension for installed section 1 man pages.
|
||||
@item man2ext
|
||||
The file name extension for installed section 2 man pages.
|
||||
@item @dots{}
|
||||
Use these names instead of @samp{manext} if the package needs to install man
|
||||
pages in more than one section of the manual.
|
||||
@end table
|
||||
|
||||
And finally, you should set the following variable:
|
||||
|
||||
@table @samp
|
||||
@item srcdir
|
||||
The directory for the sources being compiled. The value of this
|
||||
variable is normally inserted by the @code{configure} shell script.
|
||||
@end table
|
||||
|
||||
For example:
|
||||
|
||||
@smallexample
|
||||
@c I have changed some of the comments here slightly to fix an overfull
|
||||
@c hbox, so the make manual can format correctly. --roland
|
||||
# Common prefix for installation directories.
|
||||
# NOTE: This directory must exist when you start the install.
|
||||
prefix = /usr/local
|
||||
exec_prefix = $(prefix)
|
||||
# Where to put the executable for the command `gcc'.
|
||||
bindir = $(exec_prefix)/bin
|
||||
# Where to put the directories used by the compiler.
|
||||
libexecdir = $(exec_prefix)/libexec
|
||||
# Where to put the Info files.
|
||||
infodir = $(prefix)/info
|
||||
@end smallexample
|
||||
|
||||
If your program installs a large number of files into one of the
|
||||
standard user-specified directories, it might be useful to group them
|
||||
into a subdirectory particular to that program. If you do this, you
|
||||
should write the @code{install} rule to create these subdirectories.
|
||||
|
||||
Do not expect the user to include the subdirectory name in the value of
|
||||
any of the variables listed above. The idea of having a uniform set of
|
||||
variable names for installation directories is to enable the user to
|
||||
specify the exact same values for several different GNU packages. In
|
||||
order for this to be useful, all the packages must be designed so that
|
||||
they will work sensibly when the user does so.
|
||||
|
||||
@ -1,354 +0,0 @@
|
||||
'xrdef {Overview-title}{Overview of \code {make}}
|
||||
'xrdef {Overview-pg}{1}
|
||||
'xrdef {Overview-snt}{Chapter'tie1}
|
||||
'xrdef {Reading-title}{How to Read This Manual}
|
||||
'xrdef {Reading-pg}{1}
|
||||
'xrdef {Reading-snt}{Section'tie1.1}
|
||||
'xrdef {Bugs-title}{Problems and Bugs}
|
||||
'xrdef {Bugs-pg}{2}
|
||||
'xrdef {Bugs-snt}{Section'tie1.2}
|
||||
'xrdef {Introduction-title}{An Introduction to Makefiles}
|
||||
'xrdef {Introduction-pg}{5}
|
||||
'xrdef {Introduction-snt}{Chapter'tie2}
|
||||
'xrdef {Rule Introduction-title}{What a Rule Looks Like}
|
||||
'xrdef {Rule Introduction-pg}{5}
|
||||
'xrdef {Rule Introduction-snt}{Section'tie2.1}
|
||||
'xrdef {Simple Makefile-title}{A Simple Makefile}
|
||||
'xrdef {Simple Makefile-pg}{6}
|
||||
'xrdef {Simple Makefile-snt}{Section'tie2.2}
|
||||
'xrdef {How Make Works-title}{How \code {make} Processes a Makefile}
|
||||
'xrdef {How Make Works-pg}{8}
|
||||
'xrdef {How Make Works-snt}{Section'tie2.3}
|
||||
'xrdef {Variables Simplify-title}{Variables Make Makefiles Simpler}
|
||||
'xrdef {Variables Simplify-pg}{9}
|
||||
'xrdef {Variables Simplify-snt}{Section'tie2.4}
|
||||
'xrdef {make Deduces-title}{Letting \code {make} Deduce the Commands}
|
||||
'xrdef {make Deduces-pg}{10}
|
||||
'xrdef {make Deduces-snt}{Section'tie2.5}
|
||||
'xrdef {Combine By Dependency-title}{Another Style of Makefile}
|
||||
'xrdef {Combine By Dependency-pg}{11}
|
||||
'xrdef {Combine By Dependency-snt}{Section'tie2.6}
|
||||
'xrdef {Cleanup-title}{Rules for Cleaning the Directory}
|
||||
'xrdef {Cleanup-pg}{12}
|
||||
'xrdef {Cleanup-snt}{Section'tie2.7}
|
||||
'xrdef {Makefiles-title}{Writing Makefiles}
|
||||
'xrdef {Makefiles-pg}{13}
|
||||
'xrdef {Makefiles-snt}{Chapter'tie3}
|
||||
'xrdef {Makefile Contents-title}{What Makefiles Contain}
|
||||
'xrdef {Makefile Contents-pg}{13}
|
||||
'xrdef {Makefile Contents-snt}{Section'tie3.1}
|
||||
'xrdef {Makefile Names-title}{What Name to Give Your Makefile}
|
||||
'xrdef {Makefile Names-pg}{14}
|
||||
'xrdef {Makefile Names-snt}{Section'tie3.2}
|
||||
'xrdef {Include-title}{Including Other Makefiles}
|
||||
'xrdef {Include-pg}{14}
|
||||
'xrdef {Include-snt}{Section'tie3.3}
|
||||
'xrdef {MAKEFILES Variable-title}{The Variable \code {MAKEFILES}}
|
||||
'xrdef {MAKEFILES Variable-pg}{16}
|
||||
'xrdef {MAKEFILES Variable-snt}{Section'tie3.4}
|
||||
'xrdef {Remaking Makefiles-title}{How Makefiles Are Remade}
|
||||
'xrdef {Remaking Makefiles-pg}{16}
|
||||
'xrdef {Remaking Makefiles-snt}{Section'tie3.5}
|
||||
'xrdef {Overriding Makefiles-title}{Overriding Part of Another Makefile}
|
||||
'xrdef {Overriding Makefiles-pg}{18}
|
||||
'xrdef {Overriding Makefiles-snt}{Section'tie3.6}
|
||||
'xrdef {Rules-title}{Writing Rules}
|
||||
'xrdef {Rules-pg}{19}
|
||||
'xrdef {Rules-snt}{Chapter'tie4}
|
||||
'xrdef {Rule Syntax-title}{Rule Syntax}
|
||||
'xrdef {Rule Syntax-pg}{19}
|
||||
'xrdef {Rule Syntax-snt}{Section'tie4.1}
|
||||
'xrdef {Wildcards-title}{Using Wildcard Characters in File Names}
|
||||
'xrdef {Wildcards-pg}{20}
|
||||
'xrdef {Wildcards-snt}{Section'tie4.2}
|
||||
'xrdef {Wildcard Examples-title}{Wildcard Examples}
|
||||
'xrdef {Wildcard Examples-pg}{21}
|
||||
'xrdef {Wildcard Examples-snt}{Section'tie4.2.1}
|
||||
'xrdef {Wildcard Pitfall-title}{Pitfalls of Using Wildcards}
|
||||
'xrdef {Wildcard Pitfall-pg}{22}
|
||||
'xrdef {Wildcard Pitfall-snt}{Section'tie4.2.2}
|
||||
'xrdef {Wildcard Function-title}{The Function \code {wildcard}}
|
||||
'xrdef {Wildcard Function-pg}{22}
|
||||
'xrdef {Wildcard Function-snt}{Section'tie4.2.3}
|
||||
'xrdef {Directory Search-title}{Searching Directories for Dependencies}
|
||||
'xrdef {Directory Search-pg}{23}
|
||||
'xrdef {Directory Search-snt}{Section'tie4.3}
|
||||
'xrdef {General Search-title}{\code {VPATH}: Search Path for All Dependencies}
|
||||
'xrdef {General Search-pg}{23}
|
||||
'xrdef {General Search-snt}{Section'tie4.3.1}
|
||||
'xrdef {Selective Search-title}{The \code {vpath} Directive}
|
||||
'xrdef {Selective Search-pg}{24}
|
||||
'xrdef {Selective Search-snt}{Section'tie4.3.2}
|
||||
'xrdef {Commands/Search-title}{Writing Shell Commands with Directory Search}
|
||||
'xrdef {Commands/Search-pg}{26}
|
||||
'xrdef {Commands/Search-snt}{Section'tie4.3.3}
|
||||
'xrdef {Implicit/Search-title}{Directory Search and Implicit Rules}
|
||||
'xrdef {Implicit/Search-pg}{27}
|
||||
'xrdef {Implicit/Search-snt}{Section'tie4.3.4}
|
||||
'xrdef {Libraries/Search-title}{Directory Search for Link Libraries}
|
||||
'xrdef {Libraries/Search-pg}{27}
|
||||
'xrdef {Libraries/Search-snt}{Section'tie4.3.5}
|
||||
'xrdef {Phony Targets-title}{Phony Targets}
|
||||
'xrdef {Phony Targets-pg}{28}
|
||||
'xrdef {Phony Targets-snt}{Section'tie4.4}
|
||||
'xrdef {Force Targets-title}{Rules without Commands or Dependencies}
|
||||
'xrdef {Force Targets-pg}{30}
|
||||
'xrdef {Force Targets-snt}{Section'tie4.5}
|
||||
'xrdef {Empty Targets-title}{Empty Target Files to Record Events}
|
||||
'xrdef {Empty Targets-pg}{30}
|
||||
'xrdef {Empty Targets-snt}{Section'tie4.6}
|
||||
'xrdef {Special Targets-title}{Special Built-in Target Names}
|
||||
'xrdef {Special Targets-pg}{31}
|
||||
'xrdef {Special Targets-snt}{Section'tie4.7}
|
||||
'xrdef {Multiple Targets-title}{Multiple Targets in a Rule}
|
||||
'xrdef {Multiple Targets-pg}{32}
|
||||
'xrdef {Multiple Targets-snt}{Section'tie4.8}
|
||||
'xrdef {Multiple Rules-title}{Multiple Rules for One Target}
|
||||
'xrdef {Multiple Rules-pg}{33}
|
||||
'xrdef {Multiple Rules-snt}{Section'tie4.9}
|
||||
'xrdef {Static Pattern-title}{Static Pattern Rules}
|
||||
'xrdef {Static Pattern-pg}{34}
|
||||
'xrdef {Static Pattern-snt}{Section'tie4.10}
|
||||
'xrdef {Static Usage-title}{Syntax of Static Pattern Rules}
|
||||
'xrdef {Static Usage-pg}{34}
|
||||
'xrdef {Static Usage-snt}{Section'tie4.10.1}
|
||||
'xrdef {Static versus Implicit-title}{Static Pattern Rules versus Implicit Rules}
|
||||
'xrdef {Static versus Implicit-pg}{36}
|
||||
'xrdef {Static versus Implicit-snt}{Section'tie4.10.2}
|
||||
'xrdef {Double-Colon-title}{Double-Colon Rules}
|
||||
'xrdef {Double-Colon-pg}{37}
|
||||
'xrdef {Double-Colon-snt}{Section'tie4.11}
|
||||
'xrdef {Automatic Dependencies-title}{Generating Dependencies Automatically}
|
||||
'xrdef {Automatic Dependencies-pg}{37}
|
||||
'xrdef {Automatic Dependencies-snt}{Section'tie4.12}
|
||||
'xrdef {Commands-title}{Writing the Commands in Rules}
|
||||
'xrdef {Commands-pg}{41}
|
||||
'xrdef {Commands-snt}{Chapter'tie5}
|
||||
'xrdef {Echoing-title}{Command Echoing}
|
||||
'xrdef {Echoing-pg}{41}
|
||||
'xrdef {Echoing-snt}{Section'tie5.1}
|
||||
'xrdef {Execution-title}{Command Execution}
|
||||
'xrdef {Execution-pg}{42}
|
||||
'xrdef {Execution-snt}{Section'tie5.2}
|
||||
'xrdef {Parallel-title}{Parallel Execution}
|
||||
'xrdef {Parallel-pg}{42}
|
||||
'xrdef {Parallel-snt}{Section'tie5.3}
|
||||
'xrdef {Errors-title}{Errors in Commands}
|
||||
'xrdef {Errors-pg}{44}
|
||||
'xrdef {Errors-snt}{Section'tie5.4}
|
||||
'xrdef {Interrupts-title}{Interrupting or Killing \code {make}}
|
||||
'xrdef {Interrupts-pg}{45}
|
||||
'xrdef {Interrupts-snt}{Section'tie5.5}
|
||||
'xrdef {Recursion-title}{Recursive Use of \code {make}}
|
||||
'xrdef {Recursion-pg}{46}
|
||||
'xrdef {Recursion-snt}{Section'tie5.6}
|
||||
'xrdef {MAKE Variable-title}{How the \code {MAKE} Variable Works}
|
||||
'xrdef {MAKE Variable-pg}{46}
|
||||
'xrdef {MAKE Variable-snt}{Section'tie5.6.1}
|
||||
'xrdef {Variables/Recursion-title}{Communicating Variables to a Sub-\code {make}}
|
||||
'xrdef {Variables/Recursion-pg}{47}
|
||||
'xrdef {Variables/Recursion-snt}{Section'tie5.6.2}
|
||||
'xrdef {Options/Recursion-title}{Communicating Options to a Sub-\code {make}}
|
||||
'xrdef {Options/Recursion-pg}{50}
|
||||
'xrdef {Options/Recursion-snt}{Section'tie5.6.3}
|
||||
'xrdef {-w Option-title}{The \samp {--print-directory} Option}
|
||||
'xrdef {-w Option-pg}{52}
|
||||
'xrdef {-w Option-snt}{Section'tie5.6.4}
|
||||
'xrdef {Sequences-title}{Defining Canned Command Sequences}
|
||||
'xrdef {Sequences-pg}{52}
|
||||
'xrdef {Sequences-snt}{Section'tie5.7}
|
||||
'xrdef {Empty Commands-title}{Using Empty Commands}
|
||||
'xrdef {Empty Commands-pg}{54}
|
||||
'xrdef {Empty Commands-snt}{Section'tie5.8}
|
||||
'xrdef {Using Variables-title}{How to Use Variables}
|
||||
'xrdef {Using Variables-pg}{55}
|
||||
'xrdef {Using Variables-snt}{Chapter'tie6}
|
||||
'xrdef {Reference-title}{Basics of Variable References}
|
||||
'xrdef {Reference-pg}{55}
|
||||
'xrdef {Reference-snt}{Section'tie6.1}
|
||||
'xrdef {Flavors-title}{The Two Flavors of Variables}
|
||||
'xrdef {Flavors-pg}{56}
|
||||
'xrdef {Flavors-snt}{Section'tie6.2}
|
||||
'xrdef {Advanced-title}{Advanced Features for Reference to Variables}
|
||||
'xrdef {Advanced-pg}{59}
|
||||
'xrdef {Advanced-snt}{Section'tie6.3}
|
||||
'xrdef {Substitution Refs-title}{Substitution References}
|
||||
'xrdef {Substitution Refs-pg}{59}
|
||||
'xrdef {Substitution Refs-snt}{Section'tie6.3.1}
|
||||
'xrdef {Computed Names-title}{Computed Variable Names}
|
||||
'xrdef {Computed Names-pg}{60}
|
||||
'xrdef {Computed Names-snt}{Section'tie6.3.2}
|
||||
'xrdef {Values-title}{How Variables Get Their Values}
|
||||
'xrdef {Values-pg}{63}
|
||||
'xrdef {Values-snt}{Section'tie6.4}
|
||||
'xrdef {Setting-title}{Setting Variables}
|
||||
'xrdef {Setting-pg}{63}
|
||||
'xrdef {Setting-snt}{Section'tie6.5}
|
||||
'xrdef {Appending-title}{Appending More Text to Variables}
|
||||
'xrdef {Appending-pg}{64}
|
||||
'xrdef {Appending-snt}{Section'tie6.6}
|
||||
'xrdef {Override Directive-title}{The \code {override} Directive}
|
||||
'xrdef {Override Directive-pg}{66}
|
||||
'xrdef {Override Directive-snt}{Section'tie6.7}
|
||||
'xrdef {Defining-title}{Defining Variables Verbatim}
|
||||
'xrdef {Defining-pg}{67}
|
||||
'xrdef {Defining-snt}{Section'tie6.8}
|
||||
'xrdef {Environment-title}{Variables from the Environment}
|
||||
'xrdef {Environment-pg}{68}
|
||||
'xrdef {Environment-snt}{Section'tie6.9}
|
||||
'xrdef {Conditionals-title}{Conditional Parts of Makefiles}
|
||||
'xrdef {Conditionals-pg}{71}
|
||||
'xrdef {Conditionals-snt}{Chapter'tie7}
|
||||
'xrdef {Conditional Example-title}{Example of a Conditional}
|
||||
'xrdef {Conditional Example-pg}{71}
|
||||
'xrdef {Conditional Example-snt}{Section'tie7.1}
|
||||
'xrdef {Conditional Syntax-title}{Syntax of Conditionals}
|
||||
'xrdef {Conditional Syntax-pg}{72}
|
||||
'xrdef {Conditional Syntax-snt}{Section'tie7.2}
|
||||
'xrdef {Testing Flags-title}{Conditionals that Test Flags}
|
||||
'xrdef {Testing Flags-pg}{75}
|
||||
'xrdef {Testing Flags-snt}{Section'tie7.3}
|
||||
'xrdef {Functions-title}{Functions for Transforming Text}
|
||||
'xrdef {Functions-pg}{77}
|
||||
'xrdef {Functions-snt}{Chapter'tie8}
|
||||
'xrdef {Syntax of Functions-title}{Function Call Syntax}
|
||||
'xrdef {Syntax of Functions-pg}{77}
|
||||
'xrdef {Syntax of Functions-snt}{Section'tie8.1}
|
||||
'xrdef {Text Functions-title}{Functions for String Substitution and Analysis}
|
||||
'xrdef {Text Functions-pg}{78}
|
||||
'xrdef {Text Functions-snt}{Section'tie8.2}
|
||||
'xrdef {Filename Functions-title}{Functions for File Names}
|
||||
'xrdef {Filename Functions-pg}{81}
|
||||
'xrdef {Filename Functions-snt}{Section'tie8.3}
|
||||
'xrdef {Foreach Function-title}{The \code {foreach} Function}
|
||||
'xrdef {Foreach Function-pg}{83}
|
||||
'xrdef {Foreach Function-snt}{Section'tie8.4}
|
||||
'xrdef {Origin Function-title}{The \code {origin} Function}
|
||||
'xrdef {Origin Function-pg}{85}
|
||||
'xrdef {Origin Function-snt}{Section'tie8.5}
|
||||
'xrdef {Shell Function-title}{The \code {shell} Function}
|
||||
'xrdef {Shell Function-pg}{87}
|
||||
'xrdef {Shell Function-snt}{Section'tie8.6}
|
||||
'xrdef {Running-title}{How to Run \code {make}}
|
||||
'xrdef {Running-pg}{89}
|
||||
'xrdef {Running-snt}{Chapter'tie9}
|
||||
'xrdef {Makefile Arguments-title}{Arguments to Specify the Makefile}
|
||||
'xrdef {Makefile Arguments-pg}{89}
|
||||
'xrdef {Makefile Arguments-snt}{Section'tie9.1}
|
||||
'xrdef {Goals-title}{Arguments to Specify the Goals}
|
||||
'xrdef {Goals-pg}{90}
|
||||
'xrdef {Goals-snt}{Section'tie9.2}
|
||||
'xrdef {Instead of Execution-title}{Instead of Executing the Commands}
|
||||
'xrdef {Instead of Execution-pg}{91}
|
||||
'xrdef {Instead of Execution-snt}{Section'tie9.3}
|
||||
'xrdef {Avoiding Compilation-title}{Avoiding Recompilation of Some Files}
|
||||
'xrdef {Avoiding Compilation-pg}{93}
|
||||
'xrdef {Avoiding Compilation-snt}{Section'tie9.4}
|
||||
'xrdef {Overriding-title}{Overriding Variables}
|
||||
'xrdef {Overriding-pg}{94}
|
||||
'xrdef {Overriding-snt}{Section'tie9.5}
|
||||
'xrdef {Testing-title}{Testing the Compilation of a Program}
|
||||
'xrdef {Testing-pg}{95}
|
||||
'xrdef {Testing-snt}{Section'tie9.6}
|
||||
'xrdef {Options Summary-title}{Summary of Options}
|
||||
'xrdef {Options Summary-pg}{95}
|
||||
'xrdef {Options Summary-snt}{Section'tie9.7}
|
||||
'xrdef {Implicit Rules-title}{Using Implicit Rules}
|
||||
'xrdef {Implicit Rules-pg}{101}
|
||||
'xrdef {Implicit Rules-snt}{Chapter'tie10}
|
||||
'xrdef {Using Implicit-title}{Using Implicit Rules}
|
||||
'xrdef {Using Implicit-pg}{101}
|
||||
'xrdef {Using Implicit-snt}{Section'tie10.1}
|
||||
'xrdef {Catalogue of Rules-title}{Catalogue of Implicit Rules}
|
||||
'xrdef {Catalogue of Rules-pg}{103}
|
||||
'xrdef {Catalogue of Rules-snt}{Section'tie10.2}
|
||||
'xrdef {Implicit Variables-title}{Variables Used by Implicit Rules}
|
||||
'xrdef {Implicit Variables-pg}{106}
|
||||
'xrdef {Implicit Variables-snt}{Section'tie10.3}
|
||||
'xrdef {Chained Rules-title}{Chains of Implicit Rules}
|
||||
'xrdef {Chained Rules-pg}{108}
|
||||
'xrdef {Chained Rules-snt}{Section'tie10.4}
|
||||
'xrdef {Pattern Rules-title}{Defining and Redefining Pattern Rules}
|
||||
'xrdef {Pattern Rules-pg}{109}
|
||||
'xrdef {Pattern Rules-snt}{Section'tie10.5}
|
||||
'xrdef {Pattern Intro-title}{Introduction to Pattern Rules}
|
||||
'xrdef {Pattern Intro-pg}{110}
|
||||
'xrdef {Pattern Intro-snt}{Section'tie10.5.1}
|
||||
'xrdef {Pattern Examples-title}{Pattern Rule Examples}
|
||||
'xrdef {Pattern Examples-pg}{111}
|
||||
'xrdef {Pattern Examples-snt}{Section'tie10.5.2}
|
||||
'xrdef {Automatic-title}{Automatic Variables}
|
||||
'xrdef {Automatic-pg}{112}
|
||||
'xrdef {Automatic-snt}{Section'tie10.5.3}
|
||||
'xrdef {Pattern Match-title}{How Patterns Match}
|
||||
'xrdef {Pattern Match-pg}{114}
|
||||
'xrdef {Pattern Match-snt}{Section'tie10.5.4}
|
||||
'xrdef {Match-Anything Rules-title}{Match-Anything Pattern Rules}
|
||||
'xrdef {Match-Anything Rules-pg}{115}
|
||||
'xrdef {Match-Anything Rules-snt}{Section'tie10.5.5}
|
||||
'xrdef {Canceling Rules-title}{Canceling Implicit Rules}
|
||||
'xrdef {Canceling Rules-pg}{116}
|
||||
'xrdef {Canceling Rules-snt}{Section'tie10.5.6}
|
||||
'xrdef {Last Resort-title}{Defining Last-Resort Default Rules}
|
||||
'xrdef {Last Resort-pg}{116}
|
||||
'xrdef {Last Resort-snt}{Section'tie10.6}
|
||||
'xrdef {Suffix Rules-title}{Old-Fashioned Suffix Rules}
|
||||
'xrdef {Suffix Rules-pg}{117}
|
||||
'xrdef {Suffix Rules-snt}{Section'tie10.7}
|
||||
'xrdef {Search Algorithm-title}{Implicit Rule Search Algorithm}
|
||||
'xrdef {Search Algorithm-pg}{119}
|
||||
'xrdef {Search Algorithm-snt}{Section'tie10.8}
|
||||
'xrdef {Archives-title}{Using \code {make} to Update Archive Files}
|
||||
'xrdef {Archives-pg}{121}
|
||||
'xrdef {Archives-snt}{Chapter'tie11}
|
||||
'xrdef {Archive Members-title}{Archive Members as Targets}
|
||||
'xrdef {Archive Members-pg}{121}
|
||||
'xrdef {Archive Members-snt}{Section'tie11.1}
|
||||
'xrdef {Archive Update-title}{Implicit Rule for Archive Member Targets}
|
||||
'xrdef {Archive Update-pg}{122}
|
||||
'xrdef {Archive Update-snt}{Section'tie11.2}
|
||||
'xrdef {Archive Symbols-title}{Updating Archive Symbol Directories}
|
||||
'xrdef {Archive Symbols-pg}{123}
|
||||
'xrdef {Archive Symbols-snt}{Section'tie11.2.1}
|
||||
'xrdef {Archive Pitfalls-title}{Dangers When Using Archives}
|
||||
'xrdef {Archive Pitfalls-pg}{123}
|
||||
'xrdef {Archive Pitfalls-snt}{Section'tie11.3}
|
||||
'xrdef {Archive Suffix Rules-title}{Suffix Rules for Archive Files}
|
||||
'xrdef {Archive Suffix Rules-pg}{124}
|
||||
'xrdef {Archive Suffix Rules-snt}{Section'tie11.4}
|
||||
'xrdef {Features-title}{Features of GNU \code {make}}
|
||||
'xrdef {Features-pg}{125}
|
||||
'xrdef {Features-snt}{Chapter'tie12}
|
||||
'xrdef {Missing-title}{Incompatibilities and Missing Features}
|
||||
'xrdef {Missing-pg}{129}
|
||||
'xrdef {Missing-snt}{Chapter'tie13}
|
||||
'xrdef {Makefile Conventions-title}{Makefile Conventions}
|
||||
'xrdef {Makefile Conventions-pg}{131}
|
||||
'xrdef {Makefile Conventions-snt}{Chapter'tie14}
|
||||
'xrdef {Makefile Basics-title}{General Conventions for Makefiles}
|
||||
'xrdef {Makefile Basics-pg}{131}
|
||||
'xrdef {Makefile Basics-snt}{Section'tie14.1}
|
||||
'xrdef {Utilities in Makefiles-title}{Utilities in Makefiles}
|
||||
'xrdef {Utilities in Makefiles-pg}{132}
|
||||
'xrdef {Utilities in Makefiles-snt}{Section'tie14.2}
|
||||
'xrdef {Standard Targets-title}{Standard Targets for Users}
|
||||
'xrdef {Standard Targets-pg}{133}
|
||||
'xrdef {Standard Targets-snt}{Section'tie14.3}
|
||||
'xrdef {Command Variables-title}{Variables for Specifying Commands}
|
||||
'xrdef {Command Variables-pg}{136}
|
||||
'xrdef {Command Variables-snt}{Section'tie14.4}
|
||||
'xrdef {Directory Variables-title}{Variables for Installation Directories}
|
||||
'xrdef {Directory Variables-pg}{138}
|
||||
'xrdef {Directory Variables-snt}{Section'tie14.5}
|
||||
'xrdef {Quick Reference-title}{Quick Reference}
|
||||
'xrdef {Quick Reference-pg}{143}
|
||||
'xrdef {Quick Reference-snt}{Appendix'tie'char65{}}
|
||||
'xrdef {Complex Makefile-title}{Complex Makefile Example}
|
||||
'xrdef {Complex Makefile-pg}{149}
|
||||
'xrdef {Complex Makefile-snt}{Appendix'tie'char66{}}
|
||||
'xrdef {Concept Index-title}{Index of Concepts}
|
||||
'xrdef {Concept Index-pg}{155}
|
||||
'xrdef {Concept Index-snt}{}
|
||||
'xrdef {Name Index-title}{Index of Functions, Variables, & Directives}
|
||||
'xrdef {Name Index-pg}{165}
|
||||
'xrdef {Name Index-snt}{}
|
||||
@ -1,701 +0,0 @@
|
||||
\entry {POSIX}{1}{POSIX}
|
||||
\entry {IEEE Standard 1003.2}{1}{IEEE Standard 1003.2}
|
||||
\entry {standards conformance}{1}{standards conformance}
|
||||
\entry {reporting bugs}{2}{reporting bugs}
|
||||
\entry {bugs, reporting}{2}{bugs, reporting}
|
||||
\entry {problems and bugs, reporting}{2}{problems and bugs, reporting}
|
||||
\entry {makefile}{5}{makefile}
|
||||
\entry {recompilation}{5}{recompilation}
|
||||
\entry {editor}{5}{editor}
|
||||
\entry {rule, introduction to}{5}{rule, introduction to}
|
||||
\entry {makefile rule parts}{5}{makefile rule parts}
|
||||
\entry {parts of makefile rule}{5}{parts of makefile rule}
|
||||
\entry {targets, introduction to}{5}{targets, introduction to}
|
||||
\entry {dependencies, introduction to}{5}{dependencies, introduction to}
|
||||
\entry {commands, introduction to}{5}{commands, introduction to}
|
||||
\entry {tabs in rules}{5}{tabs in rules}
|
||||
\entry {simple makefile}{6}{simple makefile}
|
||||
\entry {makefile, simple}{6}{makefile, simple}
|
||||
\entry {continuation lines}{7}{continuation lines}
|
||||
\entry {{\tt\indexbackslash } (backslash), for continuation lines}{7}{\code {{\tt\indexbackslash }} (backslash), for continuation lines}
|
||||
\entry {backslash ({\tt\indexbackslash }), for continuation lines}{7}{backslash (\code {{\tt\indexbackslash }}), for continuation lines}
|
||||
\entry {quoting newline, in makefile}{7}{quoting newline, in makefile}
|
||||
\entry {newline, quoting, in makefile}{7}{newline, quoting, in makefile}
|
||||
\entry {shell command}{8}{shell command}
|
||||
\entry {clean target}{8}{\code {clean} target}
|
||||
\entry {rm (shell command)}{8}{\code {rm} (shell command)}
|
||||
\entry {processing a makefile}{8}{processing a makefile}
|
||||
\entry {makefile, how make processes}{8}{makefile, how \code {make} processes}
|
||||
\entry {default goal}{8}{default goal}
|
||||
\entry {goal, default}{8}{goal, default}
|
||||
\entry {goal}{8}{goal}
|
||||
\entry {relinking}{9}{relinking}
|
||||
\entry {variables}{9}{variables}
|
||||
\entry {simplifying with variables}{9}{simplifying with variables}
|
||||
\entry {objects}{9}{\code {objects}}
|
||||
\entry {OBJECTS}{9}{\code {OBJECTS}}
|
||||
\entry {objs}{9}{\code {objs}}
|
||||
\entry {OBJS}{9}{\code {OBJS}}
|
||||
\entry {obj}{9}{\code {obj}}
|
||||
\entry {OBJ}{9}{\code {OBJ}}
|
||||
\entry {deducing commands (implicit rules)}{10}{deducing commands (implicit rules)}
|
||||
\entry {implicit rule, introduction to}{10}{implicit rule, introduction to}
|
||||
\entry {rule, implicit, introduction to}{10}{rule, implicit, introduction to}
|
||||
\entry {combining rules by dependency}{11}{combining rules by dependency}
|
||||
\entry {cleaning up}{12}{cleaning up}
|
||||
\entry {removing, to clean up}{12}{removing, to clean up}
|
||||
\entry {clean target}{12}{\code {clean} target}
|
||||
\entry {makefile, how to write}{13}{makefile, how to write}
|
||||
\entry {rule, explicit, definition of}{13}{rule, explicit, definition of}
|
||||
\entry {explicit rule, definition of}{13}{explicit rule, definition of}
|
||||
\entry {rule, implicit, definition of}{13}{rule, implicit, definition of}
|
||||
\entry {implicit rule, definition of}{13}{implicit rule, definition of}
|
||||
\entry {variable definition}{13}{variable definition}
|
||||
\entry {directive}{13}{directive}
|
||||
\entry {comments, in makefile}{13}{comments, in makefile}
|
||||
\entry {# (comments), in makefile}{13}{\code {#} (comments), in makefile}
|
||||
\entry {makefile name}{14}{makefile name}
|
||||
\entry {name of makefile}{14}{name of makefile}
|
||||
\entry {default makefile name}{14}{default makefile name}
|
||||
\entry {file name of makefile}{14}{file name of makefile}
|
||||
\entry {README}{14}{\code {README}}
|
||||
\entry {-f}{14}{\code {-f}}
|
||||
\entry {--file}{14}{\code {--file}}
|
||||
\entry {--makefile}{14}{\code {--makefile}}
|
||||
\entry {specifying makefile name}{14}{specifying makefile name}
|
||||
\entry {makefile name, how to specify}{14}{makefile name, how to specify}
|
||||
\entry {name of makefile, how to specify}{14}{name of makefile, how to specify}
|
||||
\entry {file name of makefile, how to specify}{14}{file name of makefile, how to specify}
|
||||
\entry {including other makefiles}{14}{including other makefiles}
|
||||
\entry {makefile, including}{14}{makefile, including}
|
||||
\entry {shell file name pattern (in include)}{14}{shell file name pattern (in \code {include})}
|
||||
\entry {shell wildcards (in include)}{14}{shell wildcards (in \code {include})}
|
||||
\entry {wildcard, in include}{14}{wildcard, in \code {include}}
|
||||
\entry {dependencies, automatic generation}{15}{dependencies, automatic generation}
|
||||
\entry {automatic generation of dependencies}{15}{automatic generation of dependencies}
|
||||
\entry {generating dependencies automatically}{15}{generating dependencies automatically}
|
||||
\entry {-I}{15}{\code {-I}}
|
||||
\entry {--include-dir}{15}{\code {--include-dir}}
|
||||
\entry {makefile, and MAKEFILES variable}{16}{makefile, and \code {MAKEFILES} variable}
|
||||
\entry {including (MAKEFILES variable)}{16}{including (\code {MAKEFILES} variable)}
|
||||
\entry {recursion, and MAKEFILES variable}{16}{recursion, and \code {MAKEFILES} variable}
|
||||
\entry {updating makefiles}{16}{updating makefiles}
|
||||
\entry {remaking makefiles}{16}{remaking makefiles}
|
||||
\entry {makefile, remaking of}{16}{makefile, remaking of}
|
||||
\entry {overriding makefiles}{18}{overriding makefiles}
|
||||
\entry {makefile, overriding}{18}{makefile, overriding}
|
||||
\entry {match-anything rule, used to override}{18}{match-anything rule, used to override}
|
||||
\entry {writing rules}{19}{writing rules}
|
||||
\entry {rule, how to write}{19}{rule, how to write}
|
||||
\entry {target}{19}{target}
|
||||
\entry {dependency}{19}{dependency}
|
||||
\entry {default goal}{19}{default goal}
|
||||
\entry {goal, default}{19}{goal, default}
|
||||
\entry {rule syntax}{19}{rule syntax}
|
||||
\entry {syntax of rules}{19}{syntax of rules}
|
||||
\entry {targets}{19}{targets}
|
||||
\entry {rule targets}{19}{rule targets}
|
||||
\entry {commands}{19}{commands}
|
||||
\entry {tab character (in commands)}{19}{tab character (in commands)}
|
||||
\entry {dollar sign ($), in rules}{20}{dollar sign (\code {$}), in rules}
|
||||
\entry {$, in rules}{20}{\code {$}, in rules}
|
||||
\entry {rule, and $}{20}{rule, and \code {$}}
|
||||
\entry {dependencies}{20}{dependencies}
|
||||
\entry {rule dependencies}{20}{rule dependencies}
|
||||
\entry {wildcard}{20}{wildcard}
|
||||
\entry {file name with wildcards}{20}{file name with wildcards}
|
||||
\entry {globbing (wildcards)}{20}{globbing (wildcards)}
|
||||
\entry {* (wildcard character)}{20}{\code {*} (wildcard character)}
|
||||
\entry {? (wildcard character)}{20}{\code {?} (wildcard character)}
|
||||
\entry {[...{}] (wildcard characters)}{20}{\code {[\dots {}]} (wildcard characters)}
|
||||
\entry {{\tt\char'176} (tilde)}{20}{\code {{\tt\char'176}} (tilde)}
|
||||
\entry {tilde ({\tt\char'176})}{20}{tilde (\code {{\tt\char'176}})}
|
||||
\entry {home directory}{20}{home directory}
|
||||
\entry {rm (shell command)}{21}{\code {rm} (shell command)}
|
||||
\entry {print target}{21}{\code {print} target}
|
||||
\entry {lpr (shell command)}{21}{\code {lpr} (shell command)}
|
||||
\entry {touch (shell command)}{21}{\code {touch} (shell command)}
|
||||
\entry {wildcard pitfalls}{22}{wildcard pitfalls}
|
||||
\entry {pitfalls of wildcards}{22}{pitfalls of wildcards}
|
||||
\entry {mistakes with wildcards}{22}{mistakes with wildcards}
|
||||
\entry {errors with wildcards}{22}{errors with wildcards}
|
||||
\entry {problems with wildcards}{22}{problems with wildcards}
|
||||
\entry {vpath}{23}{vpath}
|
||||
\entry {search path for dependencies (VPATH)}{23}{search path for dependencies (\code {VPATH})}
|
||||
\entry {directory search (VPATH)}{23}{directory search (\code {VPATH})}
|
||||
\entry {%, quoting in vpath}{25}{\code {%}, quoting in \code {vpath}}
|
||||
\entry {%, quoting with {\tt\indexbackslash } (backslash)}{25}{\code {%}, quoting with \code {{\tt\indexbackslash }} (backslash)}
|
||||
\entry {{\tt\indexbackslash } (backslash), to quote %}{25}{\code {{\tt\indexbackslash }} (backslash), to quote \code {%}}
|
||||
\entry {backslash ({\tt\indexbackslash }), to quote %}{25}{backslash (\code {{\tt\indexbackslash }}), to quote \code {%}}
|
||||
\entry {quoting %, in vpath}{25}{quoting \code {%}, in \code {vpath}}
|
||||
\entry {shell command, and directory search}{26}{shell command, and directory search}
|
||||
\entry {directory search (VPATH), and shell commands}{26}{directory search (\code {VPATH}), and shell commands}
|
||||
\entry {VPATH, and implicit rules}{27}{\code {VPATH}, and implicit rules}
|
||||
\entry {directory search (VPATH), and implicit rules}{27}{directory search (\code {VPATH}), and implicit rules}
|
||||
\entry {search path for dependencies (VPATH), and implicit rules}{27}{search path for dependencies (\code {VPATH}), and implicit rules}
|
||||
\entry {implicit rule, and directory search}{27}{implicit rule, and directory search}
|
||||
\entry {implicit rule, and VPATH}{27}{implicit rule, and \code {VPATH}}
|
||||
\entry {rule, implicit, and directory search}{27}{rule, implicit, and directory search}
|
||||
\entry {rule, implicit, and VPATH}{27}{rule, implicit, and \code {VPATH}}
|
||||
\entry {link libraries, and directory search}{27}{link libraries, and directory search}
|
||||
\entry {libraries for linking, directory search}{27}{libraries for linking, directory search}
|
||||
\entry {directory search (VPATH), and link libraries}{27}{directory search (\code {VPATH}), and link libraries}
|
||||
\entry {VPATH, and link libraries}{27}{\code {VPATH}, and link libraries}
|
||||
\entry {search path for dependencies (VPATH), and link libraries}{27}{search path for dependencies (\code {VPATH}), and link libraries}
|
||||
\entry {-l (library search)}{27}{\code {-l} (library search)}
|
||||
\entry {phony targets}{28}{phony targets}
|
||||
\entry {targets, phony}{28}{targets, phony}
|
||||
\entry {targets without a file}{28}{targets without a file}
|
||||
\entry {rm (shell command)}{28}{\code {rm} (shell command)}
|
||||
\entry {force targets}{30}{force targets}
|
||||
\entry {targets, force}{30}{targets, force}
|
||||
\entry {FORCE}{30}{\code {FORCE}}
|
||||
\entry {rule, no commands or dependencies}{30}{rule, no commands or dependencies}
|
||||
\entry {empty targets}{30}{empty targets}
|
||||
\entry {targets, empty}{30}{targets, empty}
|
||||
\entry {recording events with empty targets}{30}{recording events with empty targets}
|
||||
\entry {print target}{30}{\code {print} target}
|
||||
\entry {lpr (shell command)}{30}{\code {lpr} (shell command)}
|
||||
\entry {touch (shell command)}{30}{\code {touch} (shell command)}
|
||||
\entry {special targets}{31}{special targets}
|
||||
\entry {built-in special targets}{31}{built-in special targets}
|
||||
\entry {targets, built-in special}{31}{targets, built-in special}
|
||||
\entry {precious targets}{31}{precious targets}
|
||||
\entry {preserving with .PRECIOUS}{31}{preserving with \code {.PRECIOUS}}
|
||||
\entry {multiple targets}{32}{multiple targets}
|
||||
\entry {several targets in a rule}{32}{several targets in a rule}
|
||||
\entry {targets, multiple}{32}{targets, multiple}
|
||||
\entry {rule, with multiple targets}{32}{rule, with multiple targets}
|
||||
\entry {multiple rules for one target}{33}{multiple rules for one target}
|
||||
\entry {several rules for one target}{33}{several rules for one target}
|
||||
\entry {rule, multiple for one target}{33}{rule, multiple for one target}
|
||||
\entry {target, multiple rules for one}{33}{target, multiple rules for one}
|
||||
\entry {static pattern rule}{34}{static pattern rule}
|
||||
\entry {rule, static pattern}{34}{rule, static pattern}
|
||||
\entry {pattern rules, static (not implicit)}{34}{pattern rules, static (not implicit)}
|
||||
\entry {varying dependencies}{34}{varying dependencies}
|
||||
\entry {dependencies, varying (static pattern)}{34}{dependencies, varying (static pattern)}
|
||||
\entry {static pattern rule, syntax of}{34}{static pattern rule, syntax of}
|
||||
\entry {pattern rules, static, syntax of}{34}{pattern rules, static, syntax of}
|
||||
\entry {target pattern, static (not implicit)}{35}{target pattern, static (not implicit)}
|
||||
\entry {stem}{35}{stem}
|
||||
\entry {dependency pattern, static (not implicit)}{35}{dependency pattern, static (not implicit)}
|
||||
\entry {%, quoting in static pattern}{35}{\code {%}, quoting in static pattern}
|
||||
\entry {%, quoting with {\tt\indexbackslash } (backslash)}{35}{\code {%}, quoting with \code {{\tt\indexbackslash }} (backslash)}
|
||||
\entry {{\tt\indexbackslash } (backslash), to quote %}{35}{\code {{\tt\indexbackslash }} (backslash), to quote \code {%}}
|
||||
\entry {backslash ({\tt\indexbackslash }), to quote %}{35}{backslash (\code {{\tt\indexbackslash }}), to quote \code {%}}
|
||||
\entry {quoting %, in static pattern}{35}{quoting \code {%}, in static pattern}
|
||||
\entry {rule, static pattern versus implicit}{36}{rule, static pattern versus implicit}
|
||||
\entry {static pattern rule, versus implicit}{36}{static pattern rule, versus implicit}
|
||||
\entry {double-colon rules}{37}{double-colon rules}
|
||||
\entry {rule, double-colon (::)}{37}{rule, double-colon (\code {::})}
|
||||
\entry {multiple rules for one target (::)}{37}{multiple rules for one target (\code {::})}
|
||||
\entry {:: rules (double-colon)}{37}{\code {::} rules (double-colon)}
|
||||
\entry {dependencies, automatic generation}{37}{dependencies, automatic generation}
|
||||
\entry {automatic generation of dependencies}{37}{automatic generation of dependencies}
|
||||
\entry {generating dependencies automatically}{37}{generating dependencies automatically}
|
||||
\entry {#include}{38}{\code {#include}}
|
||||
\entry {-M (to compiler)}{38}{\code {-M} (to compiler)}
|
||||
\entry {make depend}{38}{\code {make depend}}
|
||||
\entry {-e (shell flag)}{39}{\code {-e} (shell flag)}
|
||||
\entry {-MM (to GNU compiler)}{39}{\code {-MM} (to GNU compiler)}
|
||||
\entry {sed (shell command)}{39}{\code {sed} (shell command)}
|
||||
\entry {.d}{39}{\code {.d}}
|
||||
\entry {commands, how to write}{41}{commands, how to write}
|
||||
\entry {rule commands}{41}{rule commands}
|
||||
\entry {writing rule commands}{41}{writing rule commands}
|
||||
\entry {comments, in commands}{41}{comments, in commands}
|
||||
\entry {commands, comments in}{41}{commands, comments in}
|
||||
\entry {# (comments), in commands}{41}{\code {#} (comments), in commands}
|
||||
\entry {echoing of commands}{41}{echoing of commands}
|
||||
\entry {silent operation}{41}{silent operation}
|
||||
\entry {{\tt\char'100} (in commands)}{41}{\code {{\tt\char'100}} (in commands)}
|
||||
\entry {commands, echoing}{41}{commands, echoing}
|
||||
\entry {printing of commands}{41}{printing of commands}
|
||||
\entry {-n}{41}{\code {-n}}
|
||||
\entry {--just-print}{41}{\code {--just-print}}
|
||||
\entry {--dry-run}{41}{\code {--dry-run}}
|
||||
\entry {--recon}{41}{\code {--recon}}
|
||||
\entry {-s}{41}{\code {-s}}
|
||||
\entry {--silent}{41}{\code {--silent}}
|
||||
\entry {--quiet}{41}{\code {--quiet}}
|
||||
\entry {commands, execution}{42}{commands, execution}
|
||||
\entry {execution, of commands}{42}{execution, of commands}
|
||||
\entry {shell command, execution}{42}{shell command, execution}
|
||||
\entry {cd (shell command)}{42}{\code {cd} (shell command)}
|
||||
\entry {commands, backslash ({\tt\indexbackslash }) in}{42}{commands, backslash (\code {{\tt\indexbackslash }}) in}
|
||||
\entry {commands, quoting newlines in}{42}{commands, quoting newlines in}
|
||||
\entry {backslash ({\tt\indexbackslash }), in commands}{42}{backslash (\code {{\tt\indexbackslash }}), in commands}
|
||||
\entry {{\tt\indexbackslash } (backslash), in commands}{42}{\code {{\tt\indexbackslash }} (backslash), in commands}
|
||||
\entry {quoting newline, in commands}{42}{quoting newline, in commands}
|
||||
\entry {newline, quoting, in commands}{42}{newline, quoting, in commands}
|
||||
\entry {environment, SHELL in}{42}{environment, \code {SHELL} in}
|
||||
\entry {commands, execution in parallel}{42}{commands, execution in parallel}
|
||||
\entry {parallel execution}{42}{parallel execution}
|
||||
\entry {execution, in parallel}{42}{execution, in parallel}
|
||||
\entry {job slots}{42}{job slots}
|
||||
\entry {-j}{42}{\code {-j}}
|
||||
\entry {--jobs}{42}{\code {--jobs}}
|
||||
\entry {broken pipe}{43}{broken pipe}
|
||||
\entry {standard input}{43}{standard input}
|
||||
\entry {load average}{43}{load average}
|
||||
\entry {limiting jobs based on load}{43}{limiting jobs based on load}
|
||||
\entry {jobs, limiting based on load}{43}{jobs, limiting based on load}
|
||||
\entry {-l (load average)}{43}{\code {-l} (load average)}
|
||||
\entry {--max-load}{43}{\code {--max-load}}
|
||||
\entry {--load-average}{43}{\code {--load-average}}
|
||||
\entry {errors (in commands)}{44}{errors (in commands)}
|
||||
\entry {commands, errors in}{44}{commands, errors in}
|
||||
\entry {exit status (errors)}{44}{exit status (errors)}
|
||||
\entry {- (in commands)}{44}{\code {-} (in commands)}
|
||||
\entry {rm (shell command)}{44}{\code {rm} (shell command)}
|
||||
\entry {-i}{44}{\code {-i}}
|
||||
\entry {--ignore-errors}{44}{\code {--ignore-errors}}
|
||||
\entry {-k}{45}{\code {-k}}
|
||||
\entry {--keep-going}{45}{\code {--keep-going}}
|
||||
\entry {Emacs (M-x compile)}{45}{Emacs (\code {M-x compile})}
|
||||
\entry {deletion of target files}{45}{deletion of target files}
|
||||
\entry {removal of target files}{45}{removal of target files}
|
||||
\entry {target, deleting on error}{45}{target, deleting on error}
|
||||
\entry {interrupt}{45}{interrupt}
|
||||
\entry {signal}{45}{signal}
|
||||
\entry {deletion of target files}{45}{deletion of target files}
|
||||
\entry {removal of target files}{45}{removal of target files}
|
||||
\entry {target, deleting on interrupt}{45}{target, deleting on interrupt}
|
||||
\entry {killing (interruption)}{45}{killing (interruption)}
|
||||
\entry {recursion}{46}{recursion}
|
||||
\entry {subdirectories, recursion for}{46}{subdirectories, recursion for}
|
||||
\entry {-C}{46}{\code {-C}}
|
||||
\entry {--directory}{46}{\code {--directory}}
|
||||
\entry {recursion, and MAKE variable}{46}{recursion, and \code {MAKE} variable}
|
||||
\entry {cd (shell command)}{47}{\code {cd} (shell command)}
|
||||
\entry {-t, and recursion}{47}{\code {-t}, and recursion}
|
||||
\entry {recursion, and -t}{47}{recursion, and \code {-t}}
|
||||
\entry {--touch, and recursion}{47}{\code {--touch}, and recursion}
|
||||
\entry {sub-make}{47}{sub-\code {make}}
|
||||
\entry {environment, and recursion}{47}{environment, and recursion}
|
||||
\entry {exporting variables}{47}{exporting variables}
|
||||
\entry {variables, environment}{47}{variables, environment}
|
||||
\entry {variables, exporting}{47}{variables, exporting}
|
||||
\entry {recursion, and environment}{47}{recursion, and environment}
|
||||
\entry {recursion, and variables}{47}{recursion, and variables}
|
||||
\entry {compatibility in exporting}{49}{compatibility in exporting}
|
||||
\entry {recursion, level of}{49}{recursion, level of}
|
||||
\entry {options, and recursion}{50}{options, and recursion}
|
||||
\entry {recursion, and options}{50}{recursion, and options}
|
||||
\entry {command line variable definitions, and recursion}{50}{command line variable definitions, and recursion}
|
||||
\entry {variables, command line, and recursion}{50}{variables, command line, and recursion}
|
||||
\entry {recursion, and command line variable definitions}{50}{recursion, and command line variable definitions}
|
||||
\entry {-C, and recursion}{50}{\code {-C}, and recursion}
|
||||
\entry {-f, and recursion}{50}{\code {-f}, and recursion}
|
||||
\entry {-o, and recursion}{50}{\code {-o}, and recursion}
|
||||
\entry {-W, and recursion}{50}{\code {-W}, and recursion}
|
||||
\entry {--directory, and recursion}{50}{\code {--directory}, and recursion}
|
||||
\entry {--file, and recursion}{50}{\code {--file}, and recursion}
|
||||
\entry {--old-file, and recursion}{50}{\code {--old-file}, and recursion}
|
||||
\entry {--assume-old, and recursion}{50}{\code {--assume-old}, and recursion}
|
||||
\entry {--assume-new, and recursion}{50}{\code {--assume-new}, and recursion}
|
||||
\entry {--new-file, and recursion}{50}{\code {--new-file}, and recursion}
|
||||
\entry {recursion, and -C}{50}{recursion, and \code {-C}}
|
||||
\entry {recursion, and -f}{50}{recursion, and \code {-f}}
|
||||
\entry {recursion, and -o}{50}{recursion, and \code {-o}}
|
||||
\entry {recursion, and -W}{50}{recursion, and \code {-W}}
|
||||
\entry {-j, and recursion}{50}{\code {-j}, and recursion}
|
||||
\entry {--jobs, and recursion}{50}{\code {--jobs}, and recursion}
|
||||
\entry {recursion, and -j}{50}{recursion, and \code {-j}}
|
||||
\entry {job slots, and recursion}{50}{job slots, and recursion}
|
||||
\entry {Arg list too long}{51}{Arg list too long}
|
||||
\entry {E2BIG}{51}{E2BIG}
|
||||
\entry {POSIX.2}{51}{POSIX.2}
|
||||
\entry {setting options from environment}{51}{setting options from environment}
|
||||
\entry {options, setting from environment}{51}{options, setting from environment}
|
||||
\entry {setting options in makefiles}{51}{setting options in makefiles}
|
||||
\entry {options, setting in makefiles}{51}{options, setting in makefiles}
|
||||
\entry {directories, printing them}{52}{directories, printing them}
|
||||
\entry {printing directories}{52}{printing directories}
|
||||
\entry {recursion, and printing directories}{52}{recursion, and printing directories}
|
||||
\entry {-C, and -w}{52}{\code {-C}, and \code {-w}}
|
||||
\entry {--directory, and --print-directory}{52}{\code {--directory}, and \code {--print-directory}}
|
||||
\entry {recursion, and -w}{52}{recursion, and \code {-w}}
|
||||
\entry {-w, and -C}{52}{\code {-w}, and \code {-C}}
|
||||
\entry {-w, and recursion}{52}{\code {-w}, and recursion}
|
||||
\entry {--print-directory, and --directory}{52}{\code {--print-directory}, and \code {--directory}}
|
||||
\entry {--print-directory, and recursion}{52}{\code {--print-directory}, and recursion}
|
||||
\entry {--no-print-directory}{52}{\code {--no-print-directory}}
|
||||
\entry {--print-directory, disabling}{52}{\code {--print-directory}, disabling}
|
||||
\entry {-w, disabling}{52}{\code {-w}, disabling}
|
||||
\entry {sequences of commands}{52}{sequences of commands}
|
||||
\entry {commands, sequences of}{52}{commands, sequences of}
|
||||
\entry {yacc}{53}{\code {yacc}}
|
||||
\entry {{\tt\char'100}, and define}{53}{{\tt\char'100}, and \code {define}}
|
||||
\entry {-, and define}{53}{-, and \code {define}}
|
||||
\entry {{\tt\char43}, and define}{53}{{\tt\char43}, and \code {define}}
|
||||
\entry {empty commands}{54}{empty commands}
|
||||
\entry {commands, empty}{54}{commands, empty}
|
||||
\entry {variable}{55}{variable}
|
||||
\entry {value}{55}{value}
|
||||
\entry {recursive variable expansion}{55}{recursive variable expansion}
|
||||
\entry {simple variable expansion}{55}{simple variable expansion}
|
||||
\entry {macro}{55}{macro}
|
||||
\entry {variables, how to reference}{55}{variables, how to reference}
|
||||
\entry {reference to variables}{55}{reference to variables}
|
||||
\entry {$, in variable reference}{55}{\code {$}, in variable reference}
|
||||
\entry {dollar sign ($), in variable reference}{55}{dollar sign (\code {$}), in variable reference}
|
||||
\entry {flavors of variables}{56}{flavors of variables}
|
||||
\entry {recursive variable expansion}{56}{recursive variable expansion}
|
||||
\entry {variables, flavors}{56}{variables, flavors}
|
||||
\entry {recursively expanded variables}{56}{recursively expanded variables}
|
||||
\entry {variables, recursively expanded}{56}{variables, recursively expanded}
|
||||
\entry {=}{56}{=}
|
||||
\entry {loops in variable expansion}{57}{loops in variable expansion}
|
||||
\entry {variables, loops in expansion}{57}{variables, loops in expansion}
|
||||
\entry {simply expanded variables}{57}{simply expanded variables}
|
||||
\entry {variables, simply expanded}{57}{variables, simply expanded}
|
||||
\entry {:=}{57}{:=}
|
||||
\entry {spaces, in variable values}{58}{spaces, in variable values}
|
||||
\entry {whitespace, in variable values}{58}{whitespace, in variable values}
|
||||
\entry {variables, spaces in values}{58}{variables, spaces in values}
|
||||
\entry {reference to variables}{59}{reference to variables}
|
||||
\entry {modified variable reference}{59}{modified variable reference}
|
||||
\entry {substitution variable reference}{59}{substitution variable reference}
|
||||
\entry {variables, modified reference}{59}{variables, modified reference}
|
||||
\entry {variables, substitution reference}{59}{variables, substitution reference}
|
||||
\entry {variables, substituting suffix in}{59}{variables, substituting suffix in}
|
||||
\entry {suffix, substituting in variables}{59}{suffix, substituting in variables}
|
||||
\entry {nested variable reference}{60}{nested variable reference}
|
||||
\entry {computed variable name}{60}{computed variable name}
|
||||
\entry {variables, computed names}{60}{variables, computed names}
|
||||
\entry {variables, nested references}{60}{variables, nested references}
|
||||
\entry {variables, $ in name}{60}{variables, \samp {$} in name}
|
||||
\entry {$, in variable name}{60}{\code {$}, in variable name}
|
||||
\entry {dollar sign ($), in variable name}{60}{dollar sign (\code {$}), in variable name}
|
||||
\entry {variables, how they get their values}{63}{variables, how they get their values}
|
||||
\entry {value, how a variable gets it}{63}{value, how a variable gets it}
|
||||
\entry {setting variables}{63}{setting variables}
|
||||
\entry {variables, setting}{63}{variables, setting}
|
||||
\entry {=}{63}{=}
|
||||
\entry {:=}{63}{:=}
|
||||
\entry {{\tt\char43}=}{64}{{\tt\char43}=}
|
||||
\entry {appending to variables}{64}{appending to variables}
|
||||
\entry {variables, appending to}{64}{variables, appending to}
|
||||
\entry {overriding with override}{66}{overriding with \code {override}}
|
||||
\entry {variables, overriding}{66}{variables, overriding}
|
||||
\entry {verbatim variable definition}{67}{verbatim variable definition}
|
||||
\entry {defining variables verbatim}{67}{defining variables verbatim}
|
||||
\entry {variables, defining verbatim}{67}{variables, defining verbatim}
|
||||
\entry {variables, environment}{68}{variables, environment}
|
||||
\entry {environment}{68}{environment}
|
||||
\entry {conditionals}{71}{conditionals}
|
||||
\entry {functions}{77}{functions}
|
||||
\entry {$, in function call}{77}{\code {$}, in function call}
|
||||
\entry {dollar sign ($), in function call}{77}{dollar sign (\code {$}), in function call}
|
||||
\entry {arguments of functions}{77}{arguments of functions}
|
||||
\entry {functions, syntax of}{77}{functions, syntax of}
|
||||
\entry {functions, for text}{78}{functions, for text}
|
||||
\entry {%, quoting in patsubst}{78}{\code {%}, quoting in \code {patsubst}}
|
||||
\entry {%, quoting with {\tt\indexbackslash } (backslash)}{78}{\code {%}, quoting with \code {{\tt\indexbackslash }} (backslash)}
|
||||
\entry {{\tt\indexbackslash } (backslash), to quote %}{78}{\code {{\tt\indexbackslash }} (backslash), to quote \code {%}}
|
||||
\entry {backslash ({\tt\indexbackslash }), to quote %}{78}{backslash (\code {{\tt\indexbackslash }}), to quote \code {%}}
|
||||
\entry {quoting %, in patsubst}{78}{quoting \code {%}, in \code {patsubst}}
|
||||
\entry {stripping whitespace}{79}{stripping whitespace}
|
||||
\entry {whitespace, stripping}{79}{whitespace, stripping}
|
||||
\entry {spaces, stripping}{79}{spaces, stripping}
|
||||
\entry {searching for strings}{79}{searching for strings}
|
||||
\entry {finding strings}{79}{finding strings}
|
||||
\entry {strings, searching for}{79}{strings, searching for}
|
||||
\entry {filtering words}{80}{filtering words}
|
||||
\entry {words, filtering}{80}{words, filtering}
|
||||
\entry {filtering out words}{80}{filtering out words}
|
||||
\entry {words, filtering out}{80}{words, filtering out}
|
||||
\entry {sorting words}{80}{sorting words}
|
||||
\entry {removing duplicate words}{80}{removing duplicate words}
|
||||
\entry {duplicate words, removing}{80}{duplicate words, removing}
|
||||
\entry {words, removing duplicates}{80}{words, removing duplicates}
|
||||
\entry {functions, for file names}{81}{functions, for file names}
|
||||
\entry {file name functions}{81}{file name functions}
|
||||
\entry {directory part}{81}{directory part}
|
||||
\entry {file name, directory part}{81}{file name, directory part}
|
||||
\entry {file name, nondirectory part}{81}{file name, nondirectory part}
|
||||
\entry {nondirectory part}{81}{nondirectory part}
|
||||
\entry {suffix, function to find}{82}{suffix, function to find}
|
||||
\entry {file name suffix}{82}{file name suffix}
|
||||
\entry {basename}{82}{basename}
|
||||
\entry {file name, basename of}{82}{file name, basename of}
|
||||
\entry {suffix, adding}{82}{suffix, adding}
|
||||
\entry {file name suffix, adding}{82}{file name suffix, adding}
|
||||
\entry {prefix, adding}{82}{prefix, adding}
|
||||
\entry {file name prefix, adding}{82}{file name prefix, adding}
|
||||
\entry {joining lists of words}{82}{joining lists of words}
|
||||
\entry {words, joining lists}{82}{words, joining lists}
|
||||
\entry {words, selecting}{83}{words, selecting}
|
||||
\entry {selecting words}{83}{selecting words}
|
||||
\entry {words, finding number}{83}{words, finding number}
|
||||
\entry {words, extracting first}{83}{words, extracting first}
|
||||
\entry {wildcard, function}{83}{wildcard, function}
|
||||
\entry {words, iterating over}{83}{words, iterating over}
|
||||
\entry {variables, origin of}{85}{variables, origin of}
|
||||
\entry {origin of variable}{85}{origin of variable}
|
||||
\entry {commands, expansion}{87}{commands, expansion}
|
||||
\entry {backquotes}{87}{backquotes}
|
||||
\entry {shell command, function for}{87}{shell command, function for}
|
||||
\entry {--file}{89}{\code {--file}}
|
||||
\entry {--makefile}{89}{\code {--makefile}}
|
||||
\entry {-f}{89}{\code {-f}}
|
||||
\entry {goal, how to specify}{90}{goal, how to specify}
|
||||
\entry {all (standard target)}{91}{\code {all} \r {(standard target)}}
|
||||
\entry {clean (standard target)}{91}{\code {clean} \r {(standard target)}}
|
||||
\entry {mostlyclean (standard target)}{91}{\code {mostlyclean} \r {(standard target)}}
|
||||
\entry {distclean (standard target)}{91}{\code {distclean} \r {(standard target)}}
|
||||
\entry {realclean (standard target)}{91}{\code {realclean} \r {(standard target)}}
|
||||
\entry {clobber (standard target)}{91}{\code {clobber} \r {(standard target)}}
|
||||
\entry {install (standard target)}{91}{\code {install} \r {(standard target)}}
|
||||
\entry {print (standard target)}{91}{\code {print} \r {(standard target)}}
|
||||
\entry {tar (standard target)}{91}{\code {tar} \r {(standard target)}}
|
||||
\entry {shar (standard target)}{91}{\code {shar} \r {(standard target)}}
|
||||
\entry {dist (standard target)}{91}{\code {dist} \r {(standard target)}}
|
||||
\entry {TAGS (standard target)}{91}{\code {TAGS} \r {(standard target)}}
|
||||
\entry {check (standard target)}{91}{\code {check} \r {(standard target)}}
|
||||
\entry {test (standard target)}{91}{\code {test} \r {(standard target)}}
|
||||
\entry {execution, instead of}{91}{execution, instead of}
|
||||
\entry {commands, instead of executing}{91}{commands, instead of executing}
|
||||
\entry {--just-print}{91}{\code {--just-print}}
|
||||
\entry {--dry-run}{91}{\code {--dry-run}}
|
||||
\entry {--recon}{91}{\code {--recon}}
|
||||
\entry {-n}{91}{\code {-n}}
|
||||
\entry {--touch}{92}{\code {--touch}}
|
||||
\entry {touching files}{92}{touching files}
|
||||
\entry {target, touching}{92}{target, touching}
|
||||
\entry {-t}{92}{\code {-t}}
|
||||
\entry {--question}{92}{\code {--question}}
|
||||
\entry {-q}{92}{\code {-q}}
|
||||
\entry {question mode}{92}{question mode}
|
||||
\entry {--what-if}{92}{\code {--what-if}}
|
||||
\entry {-W}{92}{\code {-W}}
|
||||
\entry {--assume-new}{92}{\code {--assume-new}}
|
||||
\entry {--new-file}{92}{\code {--new-file}}
|
||||
\entry {what if}{92}{what if}
|
||||
\entry {files, assuming new}{92}{files, assuming new}
|
||||
\entry {-o}{93}{\code {-o}}
|
||||
\entry {--old-file}{93}{\code {--old-file}}
|
||||
\entry {--assume-old}{93}{\code {--assume-old}}
|
||||
\entry {files, assuming old}{93}{files, assuming old}
|
||||
\entry {files, avoiding recompilation of}{93}{files, avoiding recompilation of}
|
||||
\entry {recompilation, avoiding}{93}{recompilation, avoiding}
|
||||
\entry {overriding variables with arguments}{94}{overriding variables with arguments}
|
||||
\entry {variables, overriding with arguments}{94}{variables, overriding with arguments}
|
||||
\entry {command line variables}{94}{command line variables}
|
||||
\entry {variables, command line}{94}{variables, command line}
|
||||
\entry {testing compilation}{95}{testing compilation}
|
||||
\entry {compilation, testing}{95}{compilation, testing}
|
||||
\entry {-k}{95}{\code {-k}}
|
||||
\entry {--keep-going}{95}{\code {--keep-going}}
|
||||
\entry {options}{95}{options}
|
||||
\entry {flags}{95}{flags}
|
||||
\entry {switches}{95}{switches}
|
||||
\entry {-b}{95}{\code {-b}}
|
||||
\entry {-m}{95}{\code {-m}}
|
||||
\entry {-C}{95}{\code {-C}}
|
||||
\entry {--directory}{95}{\code {--directory}}
|
||||
\entry {-d}{96}{\code {-d}}
|
||||
\entry {--debug}{96}{\code {--debug}}
|
||||
\entry {-e}{96}{\code {-e}}
|
||||
\entry {--environment-overrides}{96}{\code {--environment-overrides}}
|
||||
\entry {-f}{96}{\code {-f}}
|
||||
\entry {--file}{96}{\code {--file}}
|
||||
\entry {--makefile}{96}{\code {--makefile}}
|
||||
\entry {-h}{96}{\code {-h}}
|
||||
\entry {--help}{96}{\code {--help}}
|
||||
\entry {-i}{96}{\code {-i}}
|
||||
\entry {--ignore-errors}{96}{\code {--ignore-errors}}
|
||||
\entry {-I}{96}{\code {-I}}
|
||||
\entry {--include-dir}{96}{\code {--include-dir}}
|
||||
\entry {-j}{96}{\code {-j}}
|
||||
\entry {--jobs}{96}{\code {--jobs}}
|
||||
\entry {-k}{96}{\code {-k}}
|
||||
\entry {--keep-going}{96}{\code {--keep-going}}
|
||||
\entry {-l}{97}{\code {-l}}
|
||||
\entry {--load-average}{97}{\code {--load-average}}
|
||||
\entry {--max-load}{97}{\code {--max-load}}
|
||||
\entry {-n}{97}{\code {-n}}
|
||||
\entry {--just-print}{97}{\code {--just-print}}
|
||||
\entry {--dry-run}{97}{\code {--dry-run}}
|
||||
\entry {--recon}{97}{\code {--recon}}
|
||||
\entry {-o}{97}{\code {-o}}
|
||||
\entry {--old-file}{97}{\code {--old-file}}
|
||||
\entry {--assume-old}{97}{\code {--assume-old}}
|
||||
\entry {-p}{97}{\code {-p}}
|
||||
\entry {--print-data-base}{97}{\code {--print-data-base}}
|
||||
\entry {-q}{97}{\code {-q}}
|
||||
\entry {--question}{97}{\code {--question}}
|
||||
\entry {-r}{97}{\code {-r}}
|
||||
\entry {--no-builtin-rules}{97}{\code {--no-builtin-rules}}
|
||||
\entry {-s}{97}{\code {-s}}
|
||||
\entry {--silent}{98}{\code {--silent}}
|
||||
\entry {--quiet}{98}{\code {--quiet}}
|
||||
\entry {-S}{98}{\code {-S}}
|
||||
\entry {--no-keep-going}{98}{\code {--no-keep-going}}
|
||||
\entry {--stop}{98}{\code {--stop}}
|
||||
\entry {-t}{98}{\code {-t}}
|
||||
\entry {--touch}{98}{\code {--touch}}
|
||||
\entry {-v}{98}{\code {-v}}
|
||||
\entry {--version}{98}{\code {--version}}
|
||||
\entry {-w}{98}{\code {-w}}
|
||||
\entry {--print-directory}{98}{\code {--print-directory}}
|
||||
\entry {--no-print-directory}{98}{\code {--no-print-directory}}
|
||||
\entry {-W}{98}{\code {-W}}
|
||||
\entry {--what-if}{98}{\code {--what-if}}
|
||||
\entry {--new-file}{98}{\code {--new-file}}
|
||||
\entry {--assume-new}{98}{\code {--assume-new}}
|
||||
\entry {--warn-undefined-variables}{99}{\code {--warn-undefined-variables}}
|
||||
\entry {variables, warning for undefined}{99}{variables, warning for undefined}
|
||||
\entry {undefined variables, warning message}{99}{undefined variables, warning message}
|
||||
\entry {implicit rule}{101}{implicit rule}
|
||||
\entry {rule, implicit}{101}{rule, implicit}
|
||||
\entry {implicit rule, how to use}{101}{implicit rule, how to use}
|
||||
\entry {rule, implicit, how to use}{101}{rule, implicit, how to use}
|
||||
\entry {implicit rule, predefined}{103}{implicit rule, predefined}
|
||||
\entry {rule, implicit, predefined}{103}{rule, implicit, predefined}
|
||||
\entry {C, rule to compile}{103}{C, rule to compile}
|
||||
\entry {cc}{103}{\code {cc}}
|
||||
\entry {gcc}{103}{\code {gcc}}
|
||||
\entry {.o}{103}{\code {.o}}
|
||||
\entry {.c}{103}{\code {.c}}
|
||||
\entry {C{\tt\char43}{\tt\char43}, rule to compile}{103}{C{\tt\char43}{\tt\char43}, rule to compile}
|
||||
\entry {g{\tt\char43}{\tt\char43}}{103}{\code {g{\tt\char43}{\tt\char43}}}
|
||||
\entry {.C}{103}{\code {.C}}
|
||||
\entry {.cc}{103}{\code {.cc}}
|
||||
\entry {Pascal, rule to compile}{103}{Pascal, rule to compile}
|
||||
\entry {pc}{103}{\code {pc}}
|
||||
\entry {.p}{103}{\code {.p}}
|
||||
\entry {Fortran, rule to compile}{103}{Fortran, rule to compile}
|
||||
\entry {Ratfor, rule to compile}{103}{Ratfor, rule to compile}
|
||||
\entry {f77}{103}{\code {f77}}
|
||||
\entry {.f}{103}{\code {.f}}
|
||||
\entry {.r}{103}{\code {.r}}
|
||||
\entry {.F}{103}{\code {.F}}
|
||||
\entry {Modula-2, rule to compile}{104}{Modula-2, rule to compile}
|
||||
\entry {m2c}{104}{\code {m2c}}
|
||||
\entry {.sym}{104}{\code {.sym}}
|
||||
\entry {.def}{104}{\code {.def}}
|
||||
\entry {.mod}{104}{\code {.mod}}
|
||||
\entry {assembly, rule to compile}{104}{assembly, rule to compile}
|
||||
\entry {as}{104}{\code {as}}
|
||||
\entry {.s}{104}{\code {.s}}
|
||||
\entry {.S}{104}{\code {.S}}
|
||||
\entry {linking, predefined rule for}{104}{linking, predefined rule for}
|
||||
\entry {ld}{104}{\code {ld}}
|
||||
\entry {.o}{104}{\code {.o}}
|
||||
\entry {yacc}{105}{\code {yacc}}
|
||||
\entry {Yacc, rule to run}{105}{Yacc, rule to run}
|
||||
\entry {.y}{105}{\code {.y}}
|
||||
\entry {lex}{105}{\code {lex}}
|
||||
\entry {Lex, rule to run}{105}{Lex, rule to run}
|
||||
\entry {.l}{105}{\code {.l}}
|
||||
\entry {lint}{105}{\code {lint}}
|
||||
\entry {lint, rule to run}{105}{\code {lint}, rule to run}
|
||||
\entry {.ln}{105}{\code {.ln}}
|
||||
\entry {TeX{}, rule to run}{105}{\TeX{}, rule to run}
|
||||
\entry {Web, rule to run}{105}{Web, rule to run}
|
||||
\entry {tex}{105}{\code {tex}}
|
||||
\entry {cweave}{105}{\code {cweave}}
|
||||
\entry {weave}{105}{\code {weave}}
|
||||
\entry {tangle}{105}{\code {tangle}}
|
||||
\entry {ctangle}{105}{\code {ctangle}}
|
||||
\entry {.dvi}{105}{\code {.dvi}}
|
||||
\entry {.tex}{105}{\code {.tex}}
|
||||
\entry {.web}{105}{\code {.web}}
|
||||
\entry {.w}{105}{\code {.w}}
|
||||
\entry {.ch}{105}{\code {.ch}}
|
||||
\entry {Texinfo, rule to format}{105}{Texinfo, rule to format}
|
||||
\entry {Info, rule to format}{105}{Info, rule to format}
|
||||
\entry {texi2dvi}{105}{\code {texi2dvi}}
|
||||
\entry {makeinfo}{105}{\code {makeinfo}}
|
||||
\entry {.texinfo}{105}{\code {.texinfo}}
|
||||
\entry {.info}{105}{\code {.info}}
|
||||
\entry {.texi}{105}{\code {.texi}}
|
||||
\entry {.txinfo}{105}{\code {.txinfo}}
|
||||
\entry {RCS, rule to extract from}{105}{RCS, rule to extract from}
|
||||
\entry {co}{105}{\code {co}}
|
||||
\entry {,v (RCS file extension)}{105}{\code {,v \r {(RCS file extension)}}}
|
||||
\entry {SCCS, rule to extract from}{105}{SCCS, rule to extract from}
|
||||
\entry {get}{105}{\code {get}}
|
||||
\entry {s. (SCCS file prefix)}{105}{\code {s. \r {(SCCS file prefix)}}}
|
||||
\entry {.sh}{105}{\code {.sh}}
|
||||
\entry {flags for compilers}{106}{flags for compilers}
|
||||
\entry {ar}{107}{\code {ar}}
|
||||
\entry {as}{107}{\code {as}}
|
||||
\entry {cc}{107}{\code {cc}}
|
||||
\entry {g{\tt\char43}{\tt\char43}}{107}{\code {g{\tt\char43}{\tt\char43}}}
|
||||
\entry {co}{107}{\code {co}}
|
||||
\entry {f77}{107}{\code {f77}}
|
||||
\entry {get}{107}{\code {get}}
|
||||
\entry {lex}{107}{\code {lex}}
|
||||
\entry {pc}{107}{\code {pc}}
|
||||
\entry {yacc}{107}{\code {yacc}}
|
||||
\entry {makeinfo}{107}{\code {makeinfo}}
|
||||
\entry {tex}{107}{\code {tex}}
|
||||
\entry {texi2dvi}{107}{\code {texi2dvi}}
|
||||
\entry {weave}{107}{\code {weave}}
|
||||
\entry {cweave}{107}{\code {cweave}}
|
||||
\entry {tangle}{107}{\code {tangle}}
|
||||
\entry {ctangle}{107}{\code {ctangle}}
|
||||
\entry {rm}{107}{\code {rm}}
|
||||
\entry {chains of rules}{108}{chains of rules}
|
||||
\entry {rule, implicit, chains of}{108}{rule, implicit, chains of}
|
||||
\entry {intermediate files}{108}{intermediate files}
|
||||
\entry {files, intermediate}{108}{files, intermediate}
|
||||
\entry {intermediate files, preserving}{109}{intermediate files, preserving}
|
||||
\entry {preserving intermediate files}{109}{preserving intermediate files}
|
||||
\entry {preserving with .PRECIOUS}{109}{preserving with \code {.PRECIOUS}}
|
||||
\entry {.PRECIOUS intermediate files}{109}{\code {.PRECIOUS} intermediate files}
|
||||
\entry {pattern rule}{110}{pattern rule}
|
||||
\entry {rule, pattern}{110}{rule, pattern}
|
||||
\entry {target pattern, implicit}{110}{target pattern, implicit}
|
||||
\entry {%, in pattern rules}{110}{\code {%}, in pattern rules}
|
||||
\entry {dependency pattern, implicit}{110}{dependency pattern, implicit}
|
||||
\entry {multiple targets, in pattern rule}{110}{multiple targets, in pattern rule}
|
||||
\entry {target, multiple in pattern rule}{110}{target, multiple in pattern rule}
|
||||
\entry {pattern rules, order of}{111}{pattern rules, order of}
|
||||
\entry {order of pattern rules}{111}{order of pattern rules}
|
||||
\entry {automatic variables}{112}{automatic variables}
|
||||
\entry {variables, automatic}{112}{variables, automatic}
|
||||
\entry {variables, and implicit rule}{112}{variables, and implicit rule}
|
||||
\entry {dependencies, list of changed}{112}{dependencies, list of changed}
|
||||
\entry {list of changed dependencies}{112}{list of changed dependencies}
|
||||
\entry {dependencies, list of all}{112}{dependencies, list of all}
|
||||
\entry {list of all dependencies}{112}{list of all dependencies}
|
||||
\entry {stem, variable for}{113}{stem, variable for}
|
||||
\entry {stem}{114}{stem}
|
||||
\entry {match-anything rule}{115}{match-anything rule}
|
||||
\entry {terminal rule}{115}{terminal rule}
|
||||
\entry {last-resort default rules}{116}{last-resort default rules}
|
||||
\entry {default rules, last-resort}{116}{default rules, last-resort}
|
||||
\entry {old-fashioned suffix rules}{117}{old-fashioned suffix rules}
|
||||
\entry {suffix rule}{117}{suffix rule}
|
||||
\entry {implicit rule, search algorithm}{119}{implicit rule, search algorithm}
|
||||
\entry {search algorithm, implicit rule}{119}{search algorithm, implicit rule}
|
||||
\entry {archive}{121}{archive}
|
||||
\entry {archive member targets}{121}{archive member targets}
|
||||
\entry {wildcard, in archive member}{121}{wildcard, in archive member}
|
||||
\entry {{\_}{\_}.SYMDEF}{123}{\code {{\_}{\_}.SYMDEF}}
|
||||
\entry {updating archive symbol directories}{123}{updating archive symbol directories}
|
||||
\entry {archive symbol directory updating}{123}{archive symbol directory updating}
|
||||
\entry {symbol directories, updating archive}{123}{symbol directories, updating archive}
|
||||
\entry {directories, updating archive symbol}{123}{directories, updating archive symbol}
|
||||
\entry {archive, and parallel execution}{123}{archive, and parallel execution}
|
||||
\entry {parallel execution, and archive update}{123}{parallel execution, and archive update}
|
||||
\entry {archive, and -j}{123}{archive, and \code {-j}}
|
||||
\entry {-j, and archive update}{123}{\code {-j}, and archive update}
|
||||
\entry {suffix rule, for archive}{124}{suffix rule, for archive}
|
||||
\entry {archive, suffix rule for}{124}{archive, suffix rule for}
|
||||
\entry {library archive, suffix rule for}{124}{library archive, suffix rule for}
|
||||
\entry {.a (archives)}{124}{\code {.a} (archives)}
|
||||
\entry {features of GNU make}{125}{features of GNU \code {make}}
|
||||
\entry {portability}{125}{portability}
|
||||
\entry {compatibility}{125}{compatibility}
|
||||
\entry {incompatibilities}{129}{incompatibilities}
|
||||
\entry {missing features}{129}{missing features}
|
||||
\entry {features, missing}{129}{features, missing}
|
||||
\entry {makefile, conventions for}{131}{makefile, conventions for}
|
||||
\entry {conventions for makefiles}{131}{conventions for makefiles}
|
||||
\entry {standards for makefiles}{131}{standards for makefiles}
|
||||
@ -1,652 +0,0 @@
|
||||
\initial {#}
|
||||
\entry {\code {#} (comments), in commands}{41}
|
||||
\entry {\code {#} (comments), in makefile}{13}
|
||||
\entry {\code {#include}}{38}
|
||||
\initial {$}
|
||||
\entry {\code {$}, in function call}{77}
|
||||
\entry {\code {$}, in rules}{20}
|
||||
\entry {\code {$}, in variable name}{60}
|
||||
\entry {\code {$}, in variable reference}{55}
|
||||
\initial {%}
|
||||
\entry {\code {%}, in pattern rules}{110}
|
||||
\entry {\code {%}, quoting in \code {patsubst}}{78}
|
||||
\entry {\code {%}, quoting in static pattern}{35}
|
||||
\entry {\code {%}, quoting in \code {vpath}}{25}
|
||||
\entry {\code {%}, quoting with \code {{\tt\indexbackslash }} (backslash)}{25, 35, 78}
|
||||
\initial {*}
|
||||
\entry {\code {*} (wildcard character)}{20}
|
||||
\initial {,}
|
||||
\entry {\code {,v \r {(RCS file extension)}}}{105}
|
||||
\initial {-}
|
||||
\entry {\code {-} (in commands)}{44}
|
||||
\entry {-, and \code {define}}{53}
|
||||
\entry {\code {--assume-new}}{92, 98}
|
||||
\entry {\code {--assume-new}, and recursion}{50}
|
||||
\entry {\code {--assume-old}}{93, 97}
|
||||
\entry {\code {--assume-old}, and recursion}{50}
|
||||
\entry {\code {--debug}}{96}
|
||||
\entry {\code {--directory}}{46, 95}
|
||||
\entry {\code {--directory}, and \code {--print-directory}}{52}
|
||||
\entry {\code {--directory}, and recursion}{50}
|
||||
\entry {\code {--dry-run}}{41, 91, 97}
|
||||
\entry {\code {--environment-overrides}}{96}
|
||||
\entry {\code {--file}}{14, 89, 96}
|
||||
\entry {\code {--file}, and recursion}{50}
|
||||
\entry {\code {--help}}{96}
|
||||
\entry {\code {--ignore-errors}}{44, 96}
|
||||
\entry {\code {--include-dir}}{15, 96}
|
||||
\entry {\code {--jobs}}{42, 96}
|
||||
\entry {\code {--jobs}, and recursion}{50}
|
||||
\entry {\code {--just-print}}{41, 91, 97}
|
||||
\entry {\code {--keep-going}}{45, 95, 96}
|
||||
\entry {\code {--load-average}}{43, 97}
|
||||
\entry {\code {--makefile}}{14, 89, 96}
|
||||
\entry {\code {--max-load}}{43, 97}
|
||||
\entry {\code {--new-file}}{92, 98}
|
||||
\entry {\code {--new-file}, and recursion}{50}
|
||||
\entry {\code {--no-builtin-rules}}{97}
|
||||
\entry {\code {--no-keep-going}}{98}
|
||||
\entry {\code {--no-print-directory}}{52, 98}
|
||||
\entry {\code {--old-file}}{93, 97}
|
||||
\entry {\code {--old-file}, and recursion}{50}
|
||||
\entry {\code {--print-data-base}}{97}
|
||||
\entry {\code {--print-directory}}{98}
|
||||
\entry {\code {--print-directory}, and \code {--directory}}{52}
|
||||
\entry {\code {--print-directory}, and recursion}{52}
|
||||
\entry {\code {--print-directory}, disabling}{52}
|
||||
\entry {\code {--question}}{92, 97}
|
||||
\entry {\code {--quiet}}{41, 98}
|
||||
\entry {\code {--recon}}{41, 91, 97}
|
||||
\entry {\code {--silent}}{41, 98}
|
||||
\entry {\code {--stop}}{98}
|
||||
\entry {\code {--touch}}{92, 98}
|
||||
\entry {\code {--touch}, and recursion}{47}
|
||||
\entry {\code {--version}}{98}
|
||||
\entry {\code {--warn-undefined-variables}}{99}
|
||||
\entry {\code {--what-if}}{92, 98}
|
||||
\entry {\code {-b}}{95}
|
||||
\entry {\code {-C}}{46, 95}
|
||||
\entry {\code {-C}, and \code {-w}}{52}
|
||||
\entry {\code {-C}, and recursion}{50}
|
||||
\entry {\code {-d}}{96}
|
||||
\entry {\code {-e}}{96}
|
||||
\entry {\code {-e} (shell flag)}{39}
|
||||
\entry {\code {-f}}{14, 89, 96}
|
||||
\entry {\code {-f}, and recursion}{50}
|
||||
\entry {\code {-h}}{96}
|
||||
\entry {\code {-i}}{44, 96}
|
||||
\entry {\code {-I}}{15, 96}
|
||||
\entry {\code {-j}}{42, 96}
|
||||
\entry {\code {-j}, and archive update}{123}
|
||||
\entry {\code {-j}, and recursion}{50}
|
||||
\entry {\code {-k}}{45, 95, 96}
|
||||
\entry {\code {-l}}{97}
|
||||
\entry {\code {-l} (library search)}{27}
|
||||
\entry {\code {-l} (load average)}{43}
|
||||
\entry {\code {-m}}{95}
|
||||
\entry {\code {-M} (to compiler)}{38}
|
||||
\entry {\code {-MM} (to GNU compiler)}{39}
|
||||
\entry {\code {-n}}{41, 91, 97}
|
||||
\entry {\code {-o}}{93, 97}
|
||||
\entry {\code {-o}, and recursion}{50}
|
||||
\entry {\code {-p}}{97}
|
||||
\entry {\code {-q}}{92, 97}
|
||||
\entry {\code {-r}}{97}
|
||||
\entry {\code {-s}}{41, 97}
|
||||
\entry {\code {-S}}{98}
|
||||
\entry {\code {-t}}{92, 98}
|
||||
\entry {\code {-t}, and recursion}{47}
|
||||
\entry {\code {-v}}{98}
|
||||
\entry {\code {-w}}{98}
|
||||
\entry {\code {-W}}{92, 98}
|
||||
\entry {\code {-w}, and \code {-C}}{52}
|
||||
\entry {\code {-w}, and recursion}{52}
|
||||
\entry {\code {-W}, and recursion}{50}
|
||||
\entry {\code {-w}, disabling}{52}
|
||||
\initial {.}
|
||||
\entry {\code {.a} (archives)}{124}
|
||||
\entry {\code {.c}}{103}
|
||||
\entry {\code {.C}}{103}
|
||||
\entry {\code {.cc}}{103}
|
||||
\entry {\code {.ch}}{105}
|
||||
\entry {\code {.d}}{39}
|
||||
\entry {\code {.def}}{104}
|
||||
\entry {\code {.dvi}}{105}
|
||||
\entry {\code {.f}}{103}
|
||||
\entry {\code {.F}}{103}
|
||||
\entry {\code {.info}}{105}
|
||||
\entry {\code {.l}}{105}
|
||||
\entry {\code {.ln}}{105}
|
||||
\entry {\code {.mod}}{104}
|
||||
\entry {\code {.o}}{103, 104}
|
||||
\entry {\code {.p}}{103}
|
||||
\entry {\code {.PRECIOUS} intermediate files}{109}
|
||||
\entry {\code {.r}}{103}
|
||||
\entry {\code {.s}}{104}
|
||||
\entry {\code {.S}}{104}
|
||||
\entry {\code {.sh}}{105}
|
||||
\entry {\code {.sym}}{104}
|
||||
\entry {\code {.tex}}{105}
|
||||
\entry {\code {.texi}}{105}
|
||||
\entry {\code {.texinfo}}{105}
|
||||
\entry {\code {.txinfo}}{105}
|
||||
\entry {\code {.w}}{105}
|
||||
\entry {\code {.web}}{105}
|
||||
\entry {\code {.y}}{105}
|
||||
\initial {:}
|
||||
\entry {\code {::} rules (double-colon)}{37}
|
||||
\entry {:=}{57, 63}
|
||||
\initial {=}
|
||||
\entry {=}{56, 63}
|
||||
\initial {?}
|
||||
\entry {\code {?} (wildcard character)}{20}
|
||||
\initial {[}
|
||||
\entry {\code {[\dots {}]} (wildcard characters)}{20}
|
||||
\initial {{\_}}
|
||||
\entry {\code {{\_}{\_}.SYMDEF}}{123}
|
||||
\initial {{\tt\char'100}}
|
||||
\entry {\code {{\tt\char'100}} (in commands)}{41}
|
||||
\entry {{\tt\char'100}, and \code {define}}{53}
|
||||
\initial {{\tt\char'176}}
|
||||
\entry {\code {{\tt\char'176}} (tilde)}{20}
|
||||
\initial {{\tt\char43}}
|
||||
\entry {{\tt\char43}, and \code {define}}{53}
|
||||
\entry {{\tt\char43}=}{64}
|
||||
\initial {{\tt\indexbackslash }}
|
||||
\entry {\code {{\tt\indexbackslash }} (backslash), for continuation lines}{7}
|
||||
\entry {\code {{\tt\indexbackslash }} (backslash), in commands}{42}
|
||||
\entry {\code {{\tt\indexbackslash }} (backslash), to quote \code {%}}{25, 35, 78}
|
||||
\initial {A}
|
||||
\entry {\code {all} \r {(standard target)}}{91}
|
||||
\entry {appending to variables}{64}
|
||||
\entry {\code {ar}}{107}
|
||||
\entry {archive}{121}
|
||||
\entry {archive member targets}{121}
|
||||
\entry {archive symbol directory updating}{123}
|
||||
\entry {archive, and \code {-j}}{123}
|
||||
\entry {archive, and parallel execution}{123}
|
||||
\entry {archive, suffix rule for}{124}
|
||||
\entry {Arg list too long}{51}
|
||||
\entry {arguments of functions}{77}
|
||||
\entry {\code {as}}{104, 107}
|
||||
\entry {assembly, rule to compile}{104}
|
||||
\entry {automatic generation of dependencies}{15, 37}
|
||||
\entry {automatic variables}{112}
|
||||
\initial {B}
|
||||
\entry {backquotes}{87}
|
||||
\entry {backslash (\code {{\tt\indexbackslash }}), for continuation lines}{7}
|
||||
\entry {backslash (\code {{\tt\indexbackslash }}), in commands}{42}
|
||||
\entry {backslash (\code {{\tt\indexbackslash }}), to quote \code {%}}{25, 35, 78}
|
||||
\entry {basename}{82}
|
||||
\entry {broken pipe}{43}
|
||||
\entry {bugs, reporting}{2}
|
||||
\entry {built-in special targets}{31}
|
||||
\initial {C}
|
||||
\entry {C, rule to compile}{103}
|
||||
\entry {C{\tt\char43}{\tt\char43}, rule to compile}{103}
|
||||
\entry {\code {cc}}{103, 107}
|
||||
\entry {\code {cd} (shell command)}{42, 47}
|
||||
\entry {chains of rules}{108}
|
||||
\entry {\code {check} \r {(standard target)}}{91}
|
||||
\entry {\code {clean} \r {(standard target)}}{91}
|
||||
\entry {\code {clean} target}{8, 12}
|
||||
\entry {cleaning up}{12}
|
||||
\entry {\code {clobber} \r {(standard target)}}{91}
|
||||
\entry {\code {co}}{105, 107}
|
||||
\entry {combining rules by dependency}{11}
|
||||
\entry {command line variable definitions, and recursion}{50}
|
||||
\entry {command line variables}{94}
|
||||
\entry {commands}{19}
|
||||
\entry {commands, backslash (\code {{\tt\indexbackslash }}) in}{42}
|
||||
\entry {commands, comments in}{41}
|
||||
\entry {commands, echoing}{41}
|
||||
\entry {commands, empty}{54}
|
||||
\entry {commands, errors in}{44}
|
||||
\entry {commands, execution}{42}
|
||||
\entry {commands, execution in parallel}{42}
|
||||
\entry {commands, expansion}{87}
|
||||
\entry {commands, how to write}{41}
|
||||
\entry {commands, instead of executing}{91}
|
||||
\entry {commands, introduction to}{5}
|
||||
\entry {commands, quoting newlines in}{42}
|
||||
\entry {commands, sequences of}{52}
|
||||
\entry {comments, in commands}{41}
|
||||
\entry {comments, in makefile}{13}
|
||||
\entry {compatibility}{125}
|
||||
\entry {compatibility in exporting}{49}
|
||||
\entry {compilation, testing}{95}
|
||||
\entry {computed variable name}{60}
|
||||
\entry {conditionals}{71}
|
||||
\entry {continuation lines}{7}
|
||||
\entry {conventions for makefiles}{131}
|
||||
\entry {\code {ctangle}}{105, 107}
|
||||
\entry {\code {cweave}}{105, 107}
|
||||
\initial {D}
|
||||
\entry {deducing commands (implicit rules)}{10}
|
||||
\entry {default goal}{8, 19}
|
||||
\entry {default makefile name}{14}
|
||||
\entry {default rules, last-resort}{116}
|
||||
\entry {defining variables verbatim}{67}
|
||||
\entry {deletion of target files}{45}
|
||||
\entry {dependencies}{20}
|
||||
\entry {dependencies, automatic generation}{15, 37}
|
||||
\entry {dependencies, introduction to}{5}
|
||||
\entry {dependencies, list of all}{112}
|
||||
\entry {dependencies, list of changed}{112}
|
||||
\entry {dependencies, varying (static pattern)}{34}
|
||||
\entry {dependency}{19}
|
||||
\entry {dependency pattern, implicit}{110}
|
||||
\entry {dependency pattern, static (not implicit)}{35}
|
||||
\entry {directive}{13}
|
||||
\entry {directories, printing them}{52}
|
||||
\entry {directories, updating archive symbol}{123}
|
||||
\entry {directory part}{81}
|
||||
\entry {directory search (\code {VPATH})}{23}
|
||||
\entry {directory search (\code {VPATH}), and implicit rules}{27}
|
||||
\entry {directory search (\code {VPATH}), and link libraries}{27}
|
||||
\entry {directory search (\code {VPATH}), and shell commands}{26}
|
||||
\entry {\code {dist} \r {(standard target)}}{91}
|
||||
\entry {\code {distclean} \r {(standard target)}}{91}
|
||||
\entry {dollar sign (\code {$}), in function call}{77}
|
||||
\entry {dollar sign (\code {$}), in rules}{20}
|
||||
\entry {dollar sign (\code {$}), in variable name}{60}
|
||||
\entry {dollar sign (\code {$}), in variable reference}{55}
|
||||
\entry {double-colon rules}{37}
|
||||
\entry {duplicate words, removing}{80}
|
||||
\initial {E}
|
||||
\entry {E2BIG}{51}
|
||||
\entry {echoing of commands}{41}
|
||||
\entry {editor}{5}
|
||||
\entry {Emacs (\code {M-x compile})}{45}
|
||||
\entry {empty commands}{54}
|
||||
\entry {empty targets}{30}
|
||||
\entry {environment}{68}
|
||||
\entry {environment, and recursion}{47}
|
||||
\entry {environment, \code {SHELL} in}{42}
|
||||
\entry {errors (in commands)}{44}
|
||||
\entry {errors with wildcards}{22}
|
||||
\entry {execution, in parallel}{42}
|
||||
\entry {execution, instead of}{91}
|
||||
\entry {execution, of commands}{42}
|
||||
\entry {exit status (errors)}{44}
|
||||
\entry {explicit rule, definition of}{13}
|
||||
\entry {exporting variables}{47}
|
||||
\initial {F}
|
||||
\entry {\code {f77}}{103, 107}
|
||||
\entry {features of GNU \code {make}}{125}
|
||||
\entry {features, missing}{129}
|
||||
\entry {file name functions}{81}
|
||||
\entry {file name of makefile}{14}
|
||||
\entry {file name of makefile, how to specify}{14}
|
||||
\entry {file name prefix, adding}{82}
|
||||
\entry {file name suffix}{82}
|
||||
\entry {file name suffix, adding}{82}
|
||||
\entry {file name with wildcards}{20}
|
||||
\entry {file name, basename of}{82}
|
||||
\entry {file name, directory part}{81}
|
||||
\entry {file name, nondirectory part}{81}
|
||||
\entry {files, assuming new}{92}
|
||||
\entry {files, assuming old}{93}
|
||||
\entry {files, avoiding recompilation of}{93}
|
||||
\entry {files, intermediate}{108}
|
||||
\entry {filtering out words}{80}
|
||||
\entry {filtering words}{80}
|
||||
\entry {finding strings}{79}
|
||||
\entry {flags}{95}
|
||||
\entry {flags for compilers}{106}
|
||||
\entry {flavors of variables}{56}
|
||||
\entry {\code {FORCE}}{30}
|
||||
\entry {force targets}{30}
|
||||
\entry {Fortran, rule to compile}{103}
|
||||
\entry {functions}{77}
|
||||
\entry {functions, for file names}{81}
|
||||
\entry {functions, for text}{78}
|
||||
\entry {functions, syntax of}{77}
|
||||
\initial {G}
|
||||
\entry {\code {g{\tt\char43}{\tt\char43}}}{103, 107}
|
||||
\entry {\code {gcc}}{103}
|
||||
\entry {generating dependencies automatically}{15, 37}
|
||||
\entry {\code {get}}{105, 107}
|
||||
\entry {globbing (wildcards)}{20}
|
||||
\entry {goal}{8}
|
||||
\entry {goal, default}{8, 19}
|
||||
\entry {goal, how to specify}{90}
|
||||
\initial {H}
|
||||
\entry {home directory}{20}
|
||||
\initial {I}
|
||||
\entry {IEEE Standard 1003.2}{1}
|
||||
\entry {implicit rule}{101}
|
||||
\entry {implicit rule, and directory search}{27}
|
||||
\entry {implicit rule, and \code {VPATH}}{27}
|
||||
\entry {implicit rule, definition of}{13}
|
||||
\entry {implicit rule, how to use}{101}
|
||||
\entry {implicit rule, introduction to}{10}
|
||||
\entry {implicit rule, predefined}{103}
|
||||
\entry {implicit rule, search algorithm}{119}
|
||||
\entry {including (\code {MAKEFILES} variable)}{16}
|
||||
\entry {including other makefiles}{14}
|
||||
\entry {incompatibilities}{129}
|
||||
\entry {Info, rule to format}{105}
|
||||
\entry {\code {install} \r {(standard target)}}{91}
|
||||
\entry {intermediate files}{108}
|
||||
\entry {intermediate files, preserving}{109}
|
||||
\entry {interrupt}{45}
|
||||
\initial {J}
|
||||
\entry {job slots}{42}
|
||||
\entry {job slots, and recursion}{50}
|
||||
\entry {jobs, limiting based on load}{43}
|
||||
\entry {joining lists of words}{82}
|
||||
\initial {K}
|
||||
\entry {killing (interruption)}{45}
|
||||
\initial {L}
|
||||
\entry {last-resort default rules}{116}
|
||||
\entry {\code {ld}}{104}
|
||||
\entry {\code {lex}}{105, 107}
|
||||
\entry {Lex, rule to run}{105}
|
||||
\entry {libraries for linking, directory search}{27}
|
||||
\entry {library archive, suffix rule for}{124}
|
||||
\entry {limiting jobs based on load}{43}
|
||||
\entry {link libraries, and directory search}{27}
|
||||
\entry {linking, predefined rule for}{104}
|
||||
\entry {\code {lint}}{105}
|
||||
\entry {\code {lint}, rule to run}{105}
|
||||
\entry {list of all dependencies}{112}
|
||||
\entry {list of changed dependencies}{112}
|
||||
\entry {load average}{43}
|
||||
\entry {loops in variable expansion}{57}
|
||||
\entry {\code {lpr} (shell command)}{21, 30}
|
||||
\initial {M}
|
||||
\entry {\code {m2c}}{104}
|
||||
\entry {macro}{55}
|
||||
\entry {\code {make depend}}{38}
|
||||
\entry {makefile}{5}
|
||||
\entry {makefile name}{14}
|
||||
\entry {makefile name, how to specify}{14}
|
||||
\entry {makefile rule parts}{5}
|
||||
\entry {makefile, and \code {MAKEFILES} variable}{16}
|
||||
\entry {makefile, conventions for}{131}
|
||||
\entry {makefile, how \code {make} processes}{8}
|
||||
\entry {makefile, how to write}{13}
|
||||
\entry {makefile, including}{14}
|
||||
\entry {makefile, overriding}{18}
|
||||
\entry {makefile, remaking of}{16}
|
||||
\entry {makefile, simple}{6}
|
||||
\entry {\code {makeinfo}}{105, 107}
|
||||
\entry {match-anything rule}{115}
|
||||
\entry {match-anything rule, used to override}{18}
|
||||
\entry {missing features}{129}
|
||||
\entry {mistakes with wildcards}{22}
|
||||
\entry {modified variable reference}{59}
|
||||
\entry {Modula-2, rule to compile}{104}
|
||||
\entry {\code {mostlyclean} \r {(standard target)}}{91}
|
||||
\entry {multiple rules for one target}{33}
|
||||
\entry {multiple rules for one target (\code {::})}{37}
|
||||
\entry {multiple targets}{32}
|
||||
\entry {multiple targets, in pattern rule}{110}
|
||||
\initial {N}
|
||||
\entry {name of makefile}{14}
|
||||
\entry {name of makefile, how to specify}{14}
|
||||
\entry {nested variable reference}{60}
|
||||
\entry {newline, quoting, in commands}{42}
|
||||
\entry {newline, quoting, in makefile}{7}
|
||||
\entry {nondirectory part}{81}
|
||||
\initial {O}
|
||||
\entry {\code {obj}}{9}
|
||||
\entry {\code {OBJ}}{9}
|
||||
\entry {\code {objects}}{9}
|
||||
\entry {\code {OBJECTS}}{9}
|
||||
\entry {\code {objs}}{9}
|
||||
\entry {\code {OBJS}}{9}
|
||||
\entry {old-fashioned suffix rules}{117}
|
||||
\entry {options}{95}
|
||||
\entry {options, and recursion}{50}
|
||||
\entry {options, setting from environment}{51}
|
||||
\entry {options, setting in makefiles}{51}
|
||||
\entry {order of pattern rules}{111}
|
||||
\entry {origin of variable}{85}
|
||||
\entry {overriding makefiles}{18}
|
||||
\entry {overriding variables with arguments}{94}
|
||||
\entry {overriding with \code {override}}{66}
|
||||
\initial {P}
|
||||
\entry {parallel execution}{42}
|
||||
\entry {parallel execution, and archive update}{123}
|
||||
\entry {parts of makefile rule}{5}
|
||||
\entry {Pascal, rule to compile}{103}
|
||||
\entry {pattern rule}{110}
|
||||
\entry {pattern rules, order of}{111}
|
||||
\entry {pattern rules, static (not implicit)}{34}
|
||||
\entry {pattern rules, static, syntax of}{34}
|
||||
\entry {\code {pc}}{103, 107}
|
||||
\entry {phony targets}{28}
|
||||
\entry {pitfalls of wildcards}{22}
|
||||
\entry {portability}{125}
|
||||
\entry {POSIX}{1}
|
||||
\entry {POSIX.2}{51}
|
||||
\entry {precious targets}{31}
|
||||
\entry {prefix, adding}{82}
|
||||
\entry {preserving intermediate files}{109}
|
||||
\entry {preserving with \code {.PRECIOUS}}{31, 109}
|
||||
\entry {\code {print} \r {(standard target)}}{91}
|
||||
\entry {\code {print} target}{21, 30}
|
||||
\entry {printing directories}{52}
|
||||
\entry {printing of commands}{41}
|
||||
\entry {problems and bugs, reporting}{2}
|
||||
\entry {problems with wildcards}{22}
|
||||
\entry {processing a makefile}{8}
|
||||
\initial {Q}
|
||||
\entry {question mode}{92}
|
||||
\entry {quoting \code {%}, in \code {patsubst}}{78}
|
||||
\entry {quoting \code {%}, in static pattern}{35}
|
||||
\entry {quoting \code {%}, in \code {vpath}}{25}
|
||||
\entry {quoting newline, in commands}{42}
|
||||
\entry {quoting newline, in makefile}{7}
|
||||
\initial {R}
|
||||
\entry {Ratfor, rule to compile}{103}
|
||||
\entry {RCS, rule to extract from}{105}
|
||||
\entry {\code {README}}{14}
|
||||
\entry {\code {realclean} \r {(standard target)}}{91}
|
||||
\entry {recompilation}{5}
|
||||
\entry {recompilation, avoiding}{93}
|
||||
\entry {recording events with empty targets}{30}
|
||||
\entry {recursion}{46}
|
||||
\entry {recursion, and \code {-C}}{50}
|
||||
\entry {recursion, and \code {-f}}{50}
|
||||
\entry {recursion, and \code {-j}}{50}
|
||||
\entry {recursion, and \code {-o}}{50}
|
||||
\entry {recursion, and \code {-t}}{47}
|
||||
\entry {recursion, and \code {-w}}{52}
|
||||
\entry {recursion, and \code {-W}}{50}
|
||||
\entry {recursion, and command line variable definitions}{50}
|
||||
\entry {recursion, and environment}{47}
|
||||
\entry {recursion, and \code {MAKE} variable}{46}
|
||||
\entry {recursion, and \code {MAKEFILES} variable}{16}
|
||||
\entry {recursion, and options}{50}
|
||||
\entry {recursion, and printing directories}{52}
|
||||
\entry {recursion, and variables}{47}
|
||||
\entry {recursion, level of}{49}
|
||||
\entry {recursive variable expansion}{55, 56}
|
||||
\entry {recursively expanded variables}{56}
|
||||
\entry {reference to variables}{55, 59}
|
||||
\entry {relinking}{9}
|
||||
\entry {remaking makefiles}{16}
|
||||
\entry {removal of target files}{45}
|
||||
\entry {removing duplicate words}{80}
|
||||
\entry {removing, to clean up}{12}
|
||||
\entry {reporting bugs}{2}
|
||||
\entry {\code {rm}}{107}
|
||||
\entry {\code {rm} (shell command)}{8, 21, 28, 44}
|
||||
\entry {rule commands}{41}
|
||||
\entry {rule dependencies}{20}
|
||||
\entry {rule syntax}{19}
|
||||
\entry {rule targets}{19}
|
||||
\entry {rule, and \code {$}}{20}
|
||||
\entry {rule, double-colon (\code {::})}{37}
|
||||
\entry {rule, explicit, definition of}{13}
|
||||
\entry {rule, how to write}{19}
|
||||
\entry {rule, implicit}{101}
|
||||
\entry {rule, implicit, and directory search}{27}
|
||||
\entry {rule, implicit, and \code {VPATH}}{27}
|
||||
\entry {rule, implicit, chains of}{108}
|
||||
\entry {rule, implicit, definition of}{13}
|
||||
\entry {rule, implicit, how to use}{101}
|
||||
\entry {rule, implicit, introduction to}{10}
|
||||
\entry {rule, implicit, predefined}{103}
|
||||
\entry {rule, introduction to}{5}
|
||||
\entry {rule, multiple for one target}{33}
|
||||
\entry {rule, no commands or dependencies}{30}
|
||||
\entry {rule, pattern}{110}
|
||||
\entry {rule, static pattern}{34}
|
||||
\entry {rule, static pattern versus implicit}{36}
|
||||
\entry {rule, with multiple targets}{32}
|
||||
\initial {S}
|
||||
\entry {\code {s. \r {(SCCS file prefix)}}}{105}
|
||||
\entry {SCCS, rule to extract from}{105}
|
||||
\entry {search algorithm, implicit rule}{119}
|
||||
\entry {search path for dependencies (\code {VPATH})}{23}
|
||||
\entry {search path for dependencies (\code {VPATH}), and implicit rules}{27}
|
||||
\entry {search path for dependencies (\code {VPATH}), and link libraries}{27}
|
||||
\entry {searching for strings}{79}
|
||||
\entry {\code {sed} (shell command)}{39}
|
||||
\entry {selecting words}{83}
|
||||
\entry {sequences of commands}{52}
|
||||
\entry {setting options from environment}{51}
|
||||
\entry {setting options in makefiles}{51}
|
||||
\entry {setting variables}{63}
|
||||
\entry {several rules for one target}{33}
|
||||
\entry {several targets in a rule}{32}
|
||||
\entry {\code {shar} \r {(standard target)}}{91}
|
||||
\entry {shell command}{8}
|
||||
\entry {shell command, and directory search}{26}
|
||||
\entry {shell command, execution}{42}
|
||||
\entry {shell command, function for}{87}
|
||||
\entry {shell file name pattern (in \code {include})}{14}
|
||||
\entry {shell wildcards (in \code {include})}{14}
|
||||
\entry {signal}{45}
|
||||
\entry {silent operation}{41}
|
||||
\entry {simple makefile}{6}
|
||||
\entry {simple variable expansion}{55}
|
||||
\entry {simplifying with variables}{9}
|
||||
\entry {simply expanded variables}{57}
|
||||
\entry {sorting words}{80}
|
||||
\entry {spaces, in variable values}{58}
|
||||
\entry {spaces, stripping}{79}
|
||||
\entry {special targets}{31}
|
||||
\entry {specifying makefile name}{14}
|
||||
\entry {standard input}{43}
|
||||
\entry {standards conformance}{1}
|
||||
\entry {standards for makefiles}{131}
|
||||
\entry {static pattern rule}{34}
|
||||
\entry {static pattern rule, syntax of}{34}
|
||||
\entry {static pattern rule, versus implicit}{36}
|
||||
\entry {stem}{35, 114}
|
||||
\entry {stem, variable for}{113}
|
||||
\entry {strings, searching for}{79}
|
||||
\entry {stripping whitespace}{79}
|
||||
\entry {sub-\code {make}}{47}
|
||||
\entry {subdirectories, recursion for}{46}
|
||||
\entry {substitution variable reference}{59}
|
||||
\entry {suffix rule}{117}
|
||||
\entry {suffix rule, for archive}{124}
|
||||
\entry {suffix, adding}{82}
|
||||
\entry {suffix, function to find}{82}
|
||||
\entry {suffix, substituting in variables}{59}
|
||||
\entry {switches}{95}
|
||||
\entry {symbol directories, updating archive}{123}
|
||||
\entry {syntax of rules}{19}
|
||||
\initial {T}
|
||||
\entry {tab character (in commands)}{19}
|
||||
\entry {tabs in rules}{5}
|
||||
\entry {\code {TAGS} \r {(standard target)}}{91}
|
||||
\entry {\code {tangle}}{105, 107}
|
||||
\entry {\code {tar} \r {(standard target)}}{91}
|
||||
\entry {target}{19}
|
||||
\entry {target pattern, implicit}{110}
|
||||
\entry {target pattern, static (not implicit)}{35}
|
||||
\entry {target, deleting on error}{45}
|
||||
\entry {target, deleting on interrupt}{45}
|
||||
\entry {target, multiple in pattern rule}{110}
|
||||
\entry {target, multiple rules for one}{33}
|
||||
\entry {target, touching}{92}
|
||||
\entry {targets}{19}
|
||||
\entry {targets without a file}{28}
|
||||
\entry {targets, built-in special}{31}
|
||||
\entry {targets, empty}{30}
|
||||
\entry {targets, force}{30}
|
||||
\entry {targets, introduction to}{5}
|
||||
\entry {targets, multiple}{32}
|
||||
\entry {targets, phony}{28}
|
||||
\entry {terminal rule}{115}
|
||||
\entry {\code {test} \r {(standard target)}}{91}
|
||||
\entry {testing compilation}{95}
|
||||
\entry {\code {tex}}{105, 107}
|
||||
\entry {\TeX{}, rule to run}{105}
|
||||
\entry {\code {texi2dvi}}{105, 107}
|
||||
\entry {Texinfo, rule to format}{105}
|
||||
\entry {tilde (\code {{\tt\char'176}})}{20}
|
||||
\entry {\code {touch} (shell command)}{21, 30}
|
||||
\entry {touching files}{92}
|
||||
\initial {U}
|
||||
\entry {undefined variables, warning message}{99}
|
||||
\entry {updating archive symbol directories}{123}
|
||||
\entry {updating makefiles}{16}
|
||||
\initial {V}
|
||||
\entry {value}{55}
|
||||
\entry {value, how a variable gets it}{63}
|
||||
\entry {variable}{55}
|
||||
\entry {variable definition}{13}
|
||||
\entry {variables}{9}
|
||||
\entry {variables, \samp {$} in name}{60}
|
||||
\entry {variables, and implicit rule}{112}
|
||||
\entry {variables, appending to}{64}
|
||||
\entry {variables, automatic}{112}
|
||||
\entry {variables, command line}{94}
|
||||
\entry {variables, command line, and recursion}{50}
|
||||
\entry {variables, computed names}{60}
|
||||
\entry {variables, defining verbatim}{67}
|
||||
\entry {variables, environment}{47, 68}
|
||||
\entry {variables, exporting}{47}
|
||||
\entry {variables, flavors}{56}
|
||||
\entry {variables, how they get their values}{63}
|
||||
\entry {variables, how to reference}{55}
|
||||
\entry {variables, loops in expansion}{57}
|
||||
\entry {variables, modified reference}{59}
|
||||
\entry {variables, nested references}{60}
|
||||
\entry {variables, origin of}{85}
|
||||
\entry {variables, overriding}{66}
|
||||
\entry {variables, overriding with arguments}{94}
|
||||
\entry {variables, recursively expanded}{56}
|
||||
\entry {variables, setting}{63}
|
||||
\entry {variables, simply expanded}{57}
|
||||
\entry {variables, spaces in values}{58}
|
||||
\entry {variables, substituting suffix in}{59}
|
||||
\entry {variables, substitution reference}{59}
|
||||
\entry {variables, warning for undefined}{99}
|
||||
\entry {varying dependencies}{34}
|
||||
\entry {verbatim variable definition}{67}
|
||||
\entry {vpath}{23}
|
||||
\entry {\code {VPATH}, and implicit rules}{27}
|
||||
\entry {\code {VPATH}, and link libraries}{27}
|
||||
\initial {W}
|
||||
\entry {\code {weave}}{105, 107}
|
||||
\entry {Web, rule to run}{105}
|
||||
\entry {what if}{92}
|
||||
\entry {whitespace, in variable values}{58}
|
||||
\entry {whitespace, stripping}{79}
|
||||
\entry {wildcard}{20}
|
||||
\entry {wildcard pitfalls}{22}
|
||||
\entry {wildcard, function}{83}
|
||||
\entry {wildcard, in archive member}{121}
|
||||
\entry {wildcard, in \code {include}}{14}
|
||||
\entry {words, extracting first}{83}
|
||||
\entry {words, filtering}{80}
|
||||
\entry {words, filtering out}{80}
|
||||
\entry {words, finding number}{83}
|
||||
\entry {words, iterating over}{83}
|
||||
\entry {words, joining lists}{82}
|
||||
\entry {words, removing duplicates}{80}
|
||||
\entry {words, selecting}{83}
|
||||
\entry {writing rule commands}{41}
|
||||
\entry {writing rules}{19}
|
||||
\initial {Y}
|
||||
\entry {\code {yacc}}{53, 105, 107}
|
||||
\entry {Yacc, rule to run}{105}
|
||||
@ -1,149 +0,0 @@
|
||||
\entry {Makefile}{14}{\code {Makefile}}
|
||||
\entry {GNUmakefile}{14}{\code {GNUmakefile}}
|
||||
\entry {makefile}{14}{\code {makefile}}
|
||||
\entry {include}{14}{\code {include}}
|
||||
\entry {/usr/gnu/include}{15}{\code {/usr/gnu/include}}
|
||||
\entry {/usr/local/include}{15}{\code {/usr/local/include}}
|
||||
\entry {/usr/include}{15}{\code {/usr/include}}
|
||||
\entry {MAKEFILES}{16}{\code {MAKEFILES}}
|
||||
\entry {wildcard}{22}{\code {wildcard}}
|
||||
\entry {VPATH}{23}{\code {VPATH}}
|
||||
\entry {vpath}{23}{\code {vpath}}
|
||||
\entry {VPATH}{23}{\code {VPATH}}
|
||||
\entry {vpath}{24}{\code {vpath}}
|
||||
\entry {.PHONY}{28}{\code {.PHONY}}
|
||||
\entry {.PHONY}{31}{\code {.PHONY}}
|
||||
\entry {.SUFFIXES}{31}{\code {.SUFFIXES}}
|
||||
\entry {.DEFAULT}{31}{\code {.DEFAULT}}
|
||||
\entry {.PRECIOUS}{31}{\code {.PRECIOUS}}
|
||||
\entry {.IGNORE}{31}{\code {.IGNORE}}
|
||||
\entry {.SILENT}{32}{\code {.SILENT}}
|
||||
\entry {.EXPORT{\_}ALL{\_}VARIABLES}{32}{\code {.EXPORT{\_}ALL{\_}VARIABLES}}
|
||||
\entry {subst}{33}{\code {subst}}
|
||||
\entry {$*, and static pattern}{36}{\code {$*\r {, and static pattern}}}
|
||||
\entry {.SILENT}{41}{\code {.SILENT}}
|
||||
\entry {SHELL (command execution)}{42}{\code {SHELL \r {(command execution)}}}
|
||||
\entry {SHELL}{42}{\code {SHELL}}
|
||||
\entry {.IGNORE}{44}{\code {.IGNORE}}
|
||||
\entry {.DELETE{\_}ON{\_}ERROR}{45}{\code {.DELETE{\_}ON{\_}ERROR}}
|
||||
\entry {.PRECIOUS}{46}{\code {.PRECIOUS}}
|
||||
\entry {MAKE}{46}{\code {MAKE}}
|
||||
\entry {export}{48}{\code {export}}
|
||||
\entry {unexport}{48}{\code {unexport}}
|
||||
\entry {.EXPORT{\_}ALL{\_}VARIABLES}{49}{\code {.EXPORT{\_}ALL{\_}VARIABLES}}
|
||||
\entry {MAKELEVEL}{49}{\code {MAKELEVEL}}
|
||||
\entry {MAKEFILES}{50}{\code {MAKEFILES}}
|
||||
\entry {MAKEFLAGS}{50}{\code {MAKEFLAGS}}
|
||||
\entry {MAKEOVERRIDES}{51}{\code {MAKEOVERRIDES}}
|
||||
\entry {.POSIX}{51}{\code {.POSIX}}
|
||||
\entry {MFLAGS}{51}{\code {MFLAGS}}
|
||||
\entry {.DEFAULT, and empty commands}{54}{\code {.DEFAULT\r {, and empty commands}}}
|
||||
\entry {MAKELEVEL}{58}{\code {MAKELEVEL}}
|
||||
\entry {MAKE}{58}{\code {MAKE}}
|
||||
\entry {patsubst}{59}{\code {patsubst}}
|
||||
\entry {override}{66}{\code {override}}
|
||||
\entry {define}{67}{\code {define}}
|
||||
\entry {endef}{67}{\code {endef}}
|
||||
\entry {ifdef}{72}{\code {ifdef}}
|
||||
\entry {ifeq}{72}{\code {ifeq}}
|
||||
\entry {ifndef}{72}{\code {ifndef}}
|
||||
\entry {ifneq}{72}{\code {ifneq}}
|
||||
\entry {else}{72}{\code {else}}
|
||||
\entry {endif}{72}{\code {endif}}
|
||||
\entry {subst}{78}{\code {subst}}
|
||||
\entry {patsubst}{78}{\code {patsubst}}
|
||||
\entry {strip}{79}{\code {strip}}
|
||||
\entry {findstring}{79}{\code {findstring}}
|
||||
\entry {filter}{80}{\code {filter}}
|
||||
\entry {filter-out}{80}{\code {filter-out}}
|
||||
\entry {sort}{80}{\code {sort}}
|
||||
\entry {dir}{81}{\code {dir}}
|
||||
\entry {notdir}{81}{\code {notdir}}
|
||||
\entry {suffix}{82}{\code {suffix}}
|
||||
\entry {basename}{82}{\code {basename}}
|
||||
\entry {addsuffix}{82}{\code {addsuffix}}
|
||||
\entry {addprefix}{82}{\code {addprefix}}
|
||||
\entry {join}{82}{\code {join}}
|
||||
\entry {word}{83}{\code {word}}
|
||||
\entry {words}{83}{\code {words}}
|
||||
\entry {firstword}{83}{\code {firstword}}
|
||||
\entry {wildcard}{83}{\code {wildcard}}
|
||||
\entry {foreach}{83}{\code {foreach}}
|
||||
\entry {origin}{85}{\code {origin}}
|
||||
\entry {shell}{87}{\code {shell}}
|
||||
\entry {OUTPUT{\_}OPTION}{106}{\code {OUTPUT{\_}OPTION}}
|
||||
\entry {AR}{107}{\code {AR}}
|
||||
\entry {AS}{107}{\code {AS}}
|
||||
\entry {CC}{107}{\code {CC}}
|
||||
\entry {CXX}{107}{\code {CXX}}
|
||||
\entry {CO}{107}{\code {CO}}
|
||||
\entry {CPP}{107}{\code {CPP}}
|
||||
\entry {FC}{107}{\code {FC}}
|
||||
\entry {GET}{107}{\code {GET}}
|
||||
\entry {LEX}{107}{\code {LEX}}
|
||||
\entry {PC}{107}{\code {PC}}
|
||||
\entry {YACC}{107}{\code {YACC}}
|
||||
\entry {YACCR}{107}{\code {YACCR}}
|
||||
\entry {MAKEINFO}{107}{\code {MAKEINFO}}
|
||||
\entry {TEX}{107}{\code {TEX}}
|
||||
\entry {TEXI2DVI}{107}{\code {TEXI2DVI}}
|
||||
\entry {WEAVE}{107}{\code {WEAVE}}
|
||||
\entry {CWEAVE}{107}{\code {CWEAVE}}
|
||||
\entry {TANGLE}{107}{\code {TANGLE}}
|
||||
\entry {CTANGLE}{107}{\code {CTANGLE}}
|
||||
\entry {RM}{107}{\code {RM}}
|
||||
\entry {ARFLAGS}{108}{\code {ARFLAGS}}
|
||||
\entry {ASFLAGS}{108}{\code {ASFLAGS}}
|
||||
\entry {CFLAGS}{108}{\code {CFLAGS}}
|
||||
\entry {CXXFLAGS}{108}{\code {CXXFLAGS}}
|
||||
\entry {COFLAGS}{108}{\code {COFLAGS}}
|
||||
\entry {CPPFLAGS}{108}{\code {CPPFLAGS}}
|
||||
\entry {FFLAGS}{108}{\code {FFLAGS}}
|
||||
\entry {GFLAGS}{108}{\code {GFLAGS}}
|
||||
\entry {LDFLAGS}{108}{\code {LDFLAGS}}
|
||||
\entry {LFLAGS}{108}{\code {LFLAGS}}
|
||||
\entry {PFLAGS}{108}{\code {PFLAGS}}
|
||||
\entry {RFLAGS}{108}{\code {RFLAGS}}
|
||||
\entry {YFLAGS}{108}{\code {YFLAGS}}
|
||||
\entry {${\tt\char'100}}{112}{\code {${\tt\char'100}}}
|
||||
\entry {{\tt\char'100} (automatic variable)}{112}{\code {{\tt\char'100} \r {(automatic variable)}}}
|
||||
\entry {$%}{112}{\code {$%}}
|
||||
\entry {% (automatic variable)}{112}{\code {% \r {(automatic variable)}}}
|
||||
\entry {${\tt\less}}{112}{\code {${\tt\less}}}
|
||||
\entry {{\tt\less} (automatic variable)}{112}{\code {{\tt\less} \r {(automatic variable)}}}
|
||||
\entry {$?}{112}{\code {$?}}
|
||||
\entry {? (automatic variable)}{112}{\code {? \r {(automatic variable)}}}
|
||||
\entry {${\tt\hat}}{112}{\code {${\tt\hat}}}
|
||||
\entry {{\tt\hat} (automatic variable)}{112}{\code {{\tt\hat} \r {(automatic variable)}}}
|
||||
\entry {${\tt\char43}}{112}{\code {${\tt\char43}}}
|
||||
\entry {{\tt\char43} (automatic variable)}{112}{\code {{\tt\char43} \r {(automatic variable)}}}
|
||||
\entry {$*}{112}{\code {$*}}
|
||||
\entry {* (automatic variable)}{112}{\code {* \r {(automatic variable)}}}
|
||||
\entry {$({\tt\char'100}D)}{113}{\code {$({\tt\char'100}D)}}
|
||||
\entry {{\tt\char'100}D (automatic variable)}{113}{\code {{\tt\char'100}D \r {(automatic variable)}}}
|
||||
\entry {$({\tt\char'100}F)}{113}{\code {$({\tt\char'100}F)}}
|
||||
\entry {{\tt\char'100}F (automatic variable)}{113}{\code {{\tt\char'100}F \r {(automatic variable)}}}
|
||||
\entry {$(*D)}{113}{\code {$(*D)}}
|
||||
\entry {*D (automatic variable)}{113}{\code {*D \r {(automatic variable)}}}
|
||||
\entry {$(*F)}{113}{\code {$(*F)}}
|
||||
\entry {*F (automatic variable)}{113}{\code {*F \r {(automatic variable)}}}
|
||||
\entry {$(%D)}{113}{\code {$(%D)}}
|
||||
\entry {%D (automatic variable)}{113}{\code {%D \r {(automatic variable)}}}
|
||||
\entry {$(%F)}{113}{\code {$(%F)}}
|
||||
\entry {%F (automatic variable)}{113}{\code {%F \r {(automatic variable)}}}
|
||||
\entry {$({\tt\less}D)}{114}{\code {$({\tt\less}D)}}
|
||||
\entry {{\tt\less}D (automatic variable)}{114}{\code {{\tt\less}D \r {(automatic variable)}}}
|
||||
\entry {$({\tt\less}F)}{114}{\code {$({\tt\less}F)}}
|
||||
\entry {{\tt\less}F (automatic variable)}{114}{\code {{\tt\less}F \r {(automatic variable)}}}
|
||||
\entry {$({\tt\hat}D)}{114}{\code {$({\tt\hat}D)}}
|
||||
\entry {{\tt\hat}D (automatic variable)}{114}{\code {{\tt\hat}D \r {(automatic variable)}}}
|
||||
\entry {$({\tt\hat}F)}{114}{\code {$({\tt\hat}F)}}
|
||||
\entry {{\tt\hat}F (automatic variable)}{114}{\code {{\tt\hat}F \r {(automatic variable)}}}
|
||||
\entry {$(?D)}{114}{\code {$(?D)}}
|
||||
\entry {?D (automatic variable)}{114}{\code {?D \r {(automatic variable)}}}
|
||||
\entry {$(?F)}{114}{\code {$(?F)}}
|
||||
\entry {?F (automatic variable)}{114}{\code {?F \r {(automatic variable)}}}
|
||||
\entry {.DEFAULT}{117}{\code {.DEFAULT}}
|
||||
\entry {.SUFFIXES}{118}{\code {.SUFFIXES}}
|
||||
\entry {SUFFIXES}{119}{\code {SUFFIXES}}
|
||||
\entry {* (automatic variable), unsupported bizarre usage}{129}{\code {* \r {(automatic variable), unsupported bizarre usage}}}
|
||||
@ -1,165 +0,0 @@
|
||||
\initial {$}
|
||||
\entry {\code {$%}}{112}
|
||||
\entry {\code {$(%D)}}{113}
|
||||
\entry {\code {$(%F)}}{113}
|
||||
\entry {\code {$(*D)}}{113}
|
||||
\entry {\code {$(*F)}}{113}
|
||||
\entry {\code {$(?D)}}{114}
|
||||
\entry {\code {$(?F)}}{114}
|
||||
\entry {\code {$({\tt\char'100}D)}}{113}
|
||||
\entry {\code {$({\tt\char'100}F)}}{113}
|
||||
\entry {\code {$({\tt\hat}D)}}{114}
|
||||
\entry {\code {$({\tt\hat}F)}}{114}
|
||||
\entry {\code {$({\tt\less}D)}}{114}
|
||||
\entry {\code {$({\tt\less}F)}}{114}
|
||||
\entry {\code {$*}}{112}
|
||||
\entry {\code {$*\r {, and static pattern}}}{36}
|
||||
\entry {\code {$?}}{112}
|
||||
\entry {\code {${\tt\char'100}}}{112}
|
||||
\entry {\code {${\tt\char43}}}{112}
|
||||
\entry {\code {${\tt\hat}}}{112}
|
||||
\entry {\code {${\tt\less}}}{112}
|
||||
\initial {%}
|
||||
\entry {\code {% \r {(automatic variable)}}}{112}
|
||||
\entry {\code {%D \r {(automatic variable)}}}{113}
|
||||
\entry {\code {%F \r {(automatic variable)}}}{113}
|
||||
\initial {*}
|
||||
\entry {\code {* \r {(automatic variable)}}}{112}
|
||||
\entry {\code {* \r {(automatic variable), unsupported bizarre usage}}}{129}
|
||||
\entry {\code {*D \r {(automatic variable)}}}{113}
|
||||
\entry {\code {*F \r {(automatic variable)}}}{113}
|
||||
\initial {.}
|
||||
\entry {\code {.DEFAULT}}{31, 117}
|
||||
\entry {\code {.DEFAULT\r {, and empty commands}}}{54}
|
||||
\entry {\code {.DELETE{\_}ON{\_}ERROR}}{45}
|
||||
\entry {\code {.EXPORT{\_}ALL{\_}VARIABLES}}{32, 49}
|
||||
\entry {\code {.IGNORE}}{31, 44}
|
||||
\entry {\code {.PHONY}}{28, 31}
|
||||
\entry {\code {.POSIX}}{51}
|
||||
\entry {\code {.PRECIOUS}}{31, 46}
|
||||
\entry {\code {.SILENT}}{32, 41}
|
||||
\entry {\code {.SUFFIXES}}{31, 118}
|
||||
\initial {/}
|
||||
\entry {\code {/usr/gnu/include}}{15}
|
||||
\entry {\code {/usr/include}}{15}
|
||||
\entry {\code {/usr/local/include}}{15}
|
||||
\initial {?}
|
||||
\entry {\code {? \r {(automatic variable)}}}{112}
|
||||
\entry {\code {?D \r {(automatic variable)}}}{114}
|
||||
\entry {\code {?F \r {(automatic variable)}}}{114}
|
||||
\initial {{\tt\char'100}}
|
||||
\entry {\code {{\tt\char'100} \r {(automatic variable)}}}{112}
|
||||
\entry {\code {{\tt\char'100}D \r {(automatic variable)}}}{113}
|
||||
\entry {\code {{\tt\char'100}F \r {(automatic variable)}}}{113}
|
||||
\initial {{\tt\char43}}
|
||||
\entry {\code {{\tt\char43} \r {(automatic variable)}}}{112}
|
||||
\initial {{\tt\hat}}
|
||||
\entry {\code {{\tt\hat} \r {(automatic variable)}}}{112}
|
||||
\entry {\code {{\tt\hat}D \r {(automatic variable)}}}{114}
|
||||
\entry {\code {{\tt\hat}F \r {(automatic variable)}}}{114}
|
||||
\initial {{\tt\less}}
|
||||
\entry {\code {{\tt\less} \r {(automatic variable)}}}{112}
|
||||
\entry {\code {{\tt\less}D \r {(automatic variable)}}}{114}
|
||||
\entry {\code {{\tt\less}F \r {(automatic variable)}}}{114}
|
||||
\initial {A}
|
||||
\entry {\code {addprefix}}{82}
|
||||
\entry {\code {addsuffix}}{82}
|
||||
\entry {\code {AR}}{107}
|
||||
\entry {\code {ARFLAGS}}{108}
|
||||
\entry {\code {AS}}{107}
|
||||
\entry {\code {ASFLAGS}}{108}
|
||||
\initial {B}
|
||||
\entry {\code {basename}}{82}
|
||||
\initial {C}
|
||||
\entry {\code {CC}}{107}
|
||||
\entry {\code {CFLAGS}}{108}
|
||||
\entry {\code {CO}}{107}
|
||||
\entry {\code {COFLAGS}}{108}
|
||||
\entry {\code {CPP}}{107}
|
||||
\entry {\code {CPPFLAGS}}{108}
|
||||
\entry {\code {CTANGLE}}{107}
|
||||
\entry {\code {CWEAVE}}{107}
|
||||
\entry {\code {CXX}}{107}
|
||||
\entry {\code {CXXFLAGS}}{108}
|
||||
\initial {D}
|
||||
\entry {\code {define}}{67}
|
||||
\entry {\code {dir}}{81}
|
||||
\initial {E}
|
||||
\entry {\code {else}}{72}
|
||||
\entry {\code {endef}}{67}
|
||||
\entry {\code {endif}}{72}
|
||||
\entry {\code {export}}{48}
|
||||
\initial {F}
|
||||
\entry {\code {FC}}{107}
|
||||
\entry {\code {FFLAGS}}{108}
|
||||
\entry {\code {filter}}{80}
|
||||
\entry {\code {filter-out}}{80}
|
||||
\entry {\code {findstring}}{79}
|
||||
\entry {\code {firstword}}{83}
|
||||
\entry {\code {foreach}}{83}
|
||||
\initial {G}
|
||||
\entry {\code {GET}}{107}
|
||||
\entry {\code {GFLAGS}}{108}
|
||||
\entry {\code {GNUmakefile}}{14}
|
||||
\initial {I}
|
||||
\entry {\code {ifdef}}{72}
|
||||
\entry {\code {ifeq}}{72}
|
||||
\entry {\code {ifndef}}{72}
|
||||
\entry {\code {ifneq}}{72}
|
||||
\entry {\code {include}}{14}
|
||||
\initial {J}
|
||||
\entry {\code {join}}{82}
|
||||
\initial {L}
|
||||
\entry {\code {LDFLAGS}}{108}
|
||||
\entry {\code {LEX}}{107}
|
||||
\entry {\code {LFLAGS}}{108}
|
||||
\initial {M}
|
||||
\entry {\code {MAKE}}{46, 58}
|
||||
\entry {\code {makefile}}{14}
|
||||
\entry {\code {Makefile}}{14}
|
||||
\entry {\code {MAKEFILES}}{16, 50}
|
||||
\entry {\code {MAKEFLAGS}}{50}
|
||||
\entry {\code {MAKEINFO}}{107}
|
||||
\entry {\code {MAKELEVEL}}{49, 58}
|
||||
\entry {\code {MAKEOVERRIDES}}{51}
|
||||
\entry {\code {MFLAGS}}{51}
|
||||
\initial {N}
|
||||
\entry {\code {notdir}}{81}
|
||||
\initial {O}
|
||||
\entry {\code {origin}}{85}
|
||||
\entry {\code {OUTPUT{\_}OPTION}}{106}
|
||||
\entry {\code {override}}{66}
|
||||
\initial {P}
|
||||
\entry {\code {patsubst}}{59, 78}
|
||||
\entry {\code {PC}}{107}
|
||||
\entry {\code {PFLAGS}}{108}
|
||||
\initial {R}
|
||||
\entry {\code {RFLAGS}}{108}
|
||||
\entry {\code {RM}}{107}
|
||||
\initial {S}
|
||||
\entry {\code {shell}}{87}
|
||||
\entry {\code {SHELL}}{42}
|
||||
\entry {\code {SHELL \r {(command execution)}}}{42}
|
||||
\entry {\code {sort}}{80}
|
||||
\entry {\code {strip}}{79}
|
||||
\entry {\code {subst}}{33, 78}
|
||||
\entry {\code {suffix}}{82}
|
||||
\entry {\code {SUFFIXES}}{119}
|
||||
\initial {T}
|
||||
\entry {\code {TANGLE}}{107}
|
||||
\entry {\code {TEX}}{107}
|
||||
\entry {\code {TEXI2DVI}}{107}
|
||||
\initial {U}
|
||||
\entry {\code {unexport}}{48}
|
||||
\initial {V}
|
||||
\entry {\code {vpath}}{23, 24}
|
||||
\entry {\code {VPATH}}{23}
|
||||
\initial {W}
|
||||
\entry {\code {WEAVE}}{107}
|
||||
\entry {\code {wildcard}}{22, 83}
|
||||
\entry {\code {word}}{83}
|
||||
\entry {\code {words}}{83}
|
||||
\initial {Y}
|
||||
\entry {\code {YACC}}{107}
|
||||
\entry {\code {YACCR}}{107}
|
||||
\entry {\code {YFLAGS}}{108}
|
||||
@ -1,355 +0,0 @@
|
||||
/* Miscellaneous global declarations and portability cruft for GNU Make.
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 95 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#if defined (_AIX) && !defined (__GNUC__)
|
||||
#pragma alloca
|
||||
#endif
|
||||
|
||||
/* We use <config.h> instead of "config.h" so that a compilation
|
||||
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
|
||||
(which it would do because make.h was found in $srcdir). */
|
||||
#include <config.h>
|
||||
#undef HAVE_CONFIG_H
|
||||
#define HAVE_CONFIG_H
|
||||
|
||||
#ifdef CRAY
|
||||
/* This must happen before #include <signal.h> so
|
||||
that the declaration therein is changed. */
|
||||
#define signal bsdsignal
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_SYS_TIMEB_H
|
||||
/* SCO 3.2 "devsys 4.2" has a prototype for `ftime' in <time.h> that bombs
|
||||
unless <sys/timeb.h> has been included first. Does every system have a
|
||||
<sys/timeb.h>? If any does not, configure should check for it. */
|
||||
#include <sys/timeb.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifndef isblank
|
||||
#define isblank(c) ((c) == ' ' || (c) == '\t')
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
/* Ultrix's unistd.h always defines _POSIX_VERSION, but you only get
|
||||
POSIX.1 behavior with `cc -YPOSIX', which predefines POSIX itself! */
|
||||
#if defined (_POSIX_VERSION) && !defined (ultrix)
|
||||
#define POSIX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Some systems define _POSIX_VERSION but are not really POSIX.1. */
|
||||
#if (defined (butterfly) || defined (__arm) || \
|
||||
(defined (__mips) && defined (_SYSTYPE_SVR3)) || \
|
||||
(defined (sequent) && defined (i386)))
|
||||
#undef POSIX
|
||||
#endif
|
||||
|
||||
#if !defined (POSIX) && defined (_AIX) && defined (_POSIX_SOURCE)
|
||||
#define POSIX
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_SYS_SIGLIST) && defined (HAVE__SYS_SIGLIST)
|
||||
#define sys_siglist _sys_siglist
|
||||
#define HAVE_SYS_SIGLIST /* Now we have it. */
|
||||
|
||||
/* It was declared in <signal.h>, with who knows what type.
|
||||
Don't declare it again and risk conflicting. */
|
||||
#define SYS_SIGLIST_DECLARED
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SIGLIST
|
||||
#ifndef SYS_SIGLIST_DECLARED
|
||||
extern char *sys_siglist[];
|
||||
#endif
|
||||
#else
|
||||
#include "signame.h"
|
||||
#endif
|
||||
|
||||
/* Some systems do not define NSIG in <signal.h>. */
|
||||
#ifndef NSIG
|
||||
#ifdef _NSIG
|
||||
#define NSIG _NSIG
|
||||
#else
|
||||
#define NSIG 32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RETSIGTYPE
|
||||
#define RETSIGTYPE void
|
||||
#endif
|
||||
|
||||
#ifndef sigmask
|
||||
#define sigmask(sig) (1 << ((sig) - 1))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#ifndef POSIX
|
||||
#define PATH_MAX MAXPATHLEN
|
||||
#endif /* Not POSIX. */
|
||||
#endif /* No PATH_MAX. */
|
||||
#ifndef MAXPATHLEN
|
||||
#define MAXPATHLEN 1024
|
||||
#endif /* No MAXPATHLEN. */
|
||||
|
||||
#ifdef PATH_MAX
|
||||
#define GET_PATH_MAX PATH_MAX
|
||||
#define PATH_VAR(var) char var[PATH_MAX]
|
||||
#else
|
||||
#define NEED_GET_PATH_MAX
|
||||
extern unsigned int get_path_max ();
|
||||
#define GET_PATH_MAX (get_path_max ())
|
||||
#define PATH_VAR(var) char *var = (char *) alloca (GET_PATH_MAX)
|
||||
#endif
|
||||
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
#ifdef S_ISREG
|
||||
#undef S_ISREG
|
||||
#endif
|
||||
#ifdef S_ISDIR
|
||||
#undef S_ISDIR
|
||||
#endif
|
||||
#endif /* STAT_MACROS_BROKEN. */
|
||||
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
|
||||
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__))
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define ANSI_STRING
|
||||
#else /* No standard headers. */
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#define ANSI_STRING
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#ifdef HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
|
||||
extern char *malloc (), *realloc ();
|
||||
extern void free ();
|
||||
|
||||
extern void abort (), exit ();
|
||||
|
||||
#endif /* Standard headers. */
|
||||
|
||||
#ifdef ANSI_STRING
|
||||
|
||||
#ifndef index
|
||||
#define index(s, c) strchr((s), (c))
|
||||
#endif
|
||||
#ifndef rindex
|
||||
#define rindex(s, c) strrchr((s), (c))
|
||||
#endif
|
||||
|
||||
#ifndef bcmp
|
||||
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
|
||||
#endif
|
||||
#ifndef bzero
|
||||
#define bzero(s, n) memset ((s), 0, (n))
|
||||
#endif
|
||||
#ifndef bcopy
|
||||
#define bcopy(s, d, n) memcpy ((d), (s), (n))
|
||||
#endif
|
||||
|
||||
#else /* Not ANSI_STRING. */
|
||||
|
||||
#ifndef bcmp
|
||||
extern int bcmp ();
|
||||
#endif
|
||||
#ifndef bzero
|
||||
extern void bzero ();
|
||||
#endif
|
||||
#ifndef bcopy
|
||||
extern void bcopy ();
|
||||
#endif
|
||||
|
||||
#endif /* ANSI_STRING. */
|
||||
#undef ANSI_STRING
|
||||
|
||||
/* SCO Xenix has a buggy macro definition in <string.h>. */
|
||||
#undef strerror
|
||||
|
||||
#ifndef ANSI_STRING
|
||||
extern char *strerror ();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
#undef alloca
|
||||
#define alloca(n) __builtin_alloca (n)
|
||||
#else /* Not GCC. */
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#elif defined(NETSCAPE)
|
||||
#include <malloc.h>
|
||||
#else /* Not HAVE_ALLOCA_H. */
|
||||
#ifndef _AIX
|
||||
extern char *alloca ();
|
||||
#endif /* Not AIX. */
|
||||
#endif /* HAVE_ALLOCA_H. */
|
||||
#endif /* GCC. */
|
||||
|
||||
#ifndef iAPX286
|
||||
#define streq(a, b) \
|
||||
((a) == (b) || \
|
||||
(*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1))))
|
||||
#else
|
||||
/* Buggy compiler can't handle this. */
|
||||
#define streq(a, b) (strcmp ((a), (b)) == 0)
|
||||
#endif
|
||||
|
||||
/* Add to VAR the hashing value of C, one character in a name. */
|
||||
#define HASH(var, c) \
|
||||
((var += (c)), (var = ((var) << 7) + ((var) >> 20)))
|
||||
|
||||
#if defined(__GNUC__) || defined(ENUM_BITFIELDS)
|
||||
#define ENUM_BITFIELD(bits) :bits
|
||||
#else
|
||||
#define ENUM_BITFIELD(bits)
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) || defined(NETSCAPE)
|
||||
#define PATH_SEPARATOR_CHAR ';'
|
||||
#else
|
||||
#define PATH_SEPARATOR_CHAR ':'
|
||||
#endif
|
||||
|
||||
extern void die ();
|
||||
extern void message (), fatal (), error ();
|
||||
extern void makefile_error (), makefile_fatal ();
|
||||
extern void pfatal_with_name (), perror_with_name ();
|
||||
extern char *savestring (), *concat ();
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
extern char *find_next_token (), *next_token (), *end_of_token ();
|
||||
extern void collapse_continuations (), remove_comments ();
|
||||
extern char *sindex (), *lindex ();
|
||||
extern int alpha_compare (const void *elem1, const void *elem2);
|
||||
extern void print_spaces ();
|
||||
extern struct dep *copy_dep_chain ();
|
||||
extern char *find_char_unquote (), *find_percent ();
|
||||
|
||||
extern int safe_stat (char * name, struct stat * buf);
|
||||
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
extern int ar_name ();
|
||||
extern void ar_parse_name ();
|
||||
extern int ar_touch ();
|
||||
extern time_t ar_member_date ();
|
||||
#endif
|
||||
|
||||
extern void dir_load ();
|
||||
extern int dir_file_exists_p (), file_exists_p (), file_impossible_p ();
|
||||
extern void file_impossible ();
|
||||
extern char *dir_name ();
|
||||
|
||||
extern void define_default_variables ();
|
||||
extern void set_default_suffixes (), install_default_suffix_rules ();
|
||||
extern void install_default_implicit_rules (), count_implicit_rule_limits ();
|
||||
extern void convert_to_pattern (), create_pattern_rule ();
|
||||
|
||||
extern void build_vpath_lists (), construct_vpath_list ();
|
||||
extern int vpath_search ();
|
||||
|
||||
extern void construct_include_path ();
|
||||
extern void uniquize_deps ();
|
||||
|
||||
extern int update_goal_chain ();
|
||||
extern void notice_finished_file ();
|
||||
|
||||
extern void user_access (), make_access (), child_access ();
|
||||
|
||||
|
||||
#ifdef HAVE_VFORK_H
|
||||
#include <vfork.h>
|
||||
#endif
|
||||
|
||||
/* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
|
||||
because such systems often declare the in header files anyway. */
|
||||
|
||||
#if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION)
|
||||
|
||||
extern long int atol ();
|
||||
extern long int lseek ();
|
||||
|
||||
#endif /* Not GNU C library or POSIX. */
|
||||
|
||||
#ifdef HAVE_GETCWD
|
||||
extern char *getcwd ();
|
||||
#else
|
||||
extern char *getwd ();
|
||||
#define getcwd(buf, len) getwd (buf)
|
||||
#endif
|
||||
|
||||
extern char **environ;
|
||||
|
||||
extern char *reading_filename;
|
||||
extern unsigned int *reading_lineno_ptr;
|
||||
|
||||
extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
|
||||
extern int debug_flag, print_data_base_flag, question_flag, touch_flag;
|
||||
extern int env_overrides, no_builtin_rules_flag, print_version_flag;
|
||||
extern int print_directory_flag, warn_undefined_variables_flag;
|
||||
extern int posix_pedantic;
|
||||
|
||||
extern unsigned int job_slots;
|
||||
extern double max_load_average;
|
||||
|
||||
extern char *program;
|
||||
extern char *starting_directory;
|
||||
extern unsigned int makelevel;
|
||||
extern char *version_string, *remote_description;
|
||||
|
||||
extern unsigned int commands_started;
|
||||
|
||||
extern int handling_fatal_signal;
|
||||
|
||||
|
||||
#define DEBUGPR(msg) \
|
||||
do if (debug_flag) { print_spaces (depth); printf (msg, file->name); \
|
||||
fflush (stdout); } while (0)
|
||||
@ -1,163 +0,0 @@
|
||||
This is Info file make.info, produced by Makeinfo-1.55 from the input
|
||||
file ./make.texinfo.
|
||||
|
||||
This file documents the GNU Make utility, which determines
|
||||
automatically which pieces of a large program need to be recompiled,
|
||||
and issues the commands to recompile them.
|
||||
|
||||
This is Edition 0.48, last updated 4 April 1995, of `The GNU Make
|
||||
Manual', for `make', Version 3.73 Beta.
|
||||
|
||||
Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this
|
||||
manual provided the copyright notice and this permission notice are
|
||||
preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided that
|
||||
the entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that this permission notice may be stated in a
|
||||
translation approved by the Free Software Foundation.
|
||||
|
||||
|
||||
Indirect:
|
||||
make.info-1: 1141
|
||||
make.info-2: 50405
|
||||
make.info-3: 97832
|
||||
make.info-4: 147393
|
||||
make.info-5: 196701
|
||||
make.info-6: 243137
|
||||
make.info-7: 292772
|
||||
make.info-8: 318335
|
||||
|
||||
Tag Table:
|
||||
(Indirect)
|
||||
Node: Top1141
|
||||
Node: Overview12012
|
||||
Node: Preparing12949
|
||||
Node: Reading13904
|
||||
Node: Bugs14826
|
||||
Node: Introduction16694
|
||||
Node: Rule Introduction18281
|
||||
Node: Simple Makefile19990
|
||||
Node: How Make Works23603
|
||||
Node: Variables Simplify26101
|
||||
Node: make Deduces28307
|
||||
Node: Combine By Dependency30054
|
||||
Node: Cleanup31082
|
||||
Node: Makefiles32492
|
||||
Node: Makefile Contents33189
|
||||
Node: Makefile Names35449
|
||||
Node: Include37051
|
||||
Node: MAKEFILES Variable40462
|
||||
Node: Remaking Makefiles41964
|
||||
Node: Overriding Makefiles45782
|
||||
Node: Rules47805
|
||||
Node: Rule Example50405
|
||||
Node: Rule Syntax51240
|
||||
Node: Wildcards53449
|
||||
Node: Wildcard Examples54959
|
||||
Node: Wildcard Pitfall56194
|
||||
Node: Wildcard Function57444
|
||||
Node: Directory Search59225
|
||||
Node: General Search60285
|
||||
Node: Selective Search61803
|
||||
Node: Commands/Search64723
|
||||
Node: Implicit/Search66063
|
||||
Node: Libraries/Search66998
|
||||
Node: Phony Targets68067
|
||||
Node: Force Targets71412
|
||||
Node: Empty Targets72449
|
||||
Node: Special Targets73709
|
||||
Node: Multiple Targets77631
|
||||
Node: Multiple Rules79498
|
||||
Node: Static Pattern81581
|
||||
Node: Static Usage82221
|
||||
Node: Static versus Implicit85875
|
||||
Node: Double-Colon87606
|
||||
Node: Automatic Dependencies89136
|
||||
Node: Commands93214
|
||||
Node: Echoing94906
|
||||
Node: Execution96164
|
||||
Node: Parallel97832
|
||||
Node: Errors101147
|
||||
Node: Interrupts104783
|
||||
Node: Recursion106364
|
||||
Node: MAKE Variable107650
|
||||
Node: Variables/Recursion109608
|
||||
Node: Options/Recursion114571
|
||||
Node: -w Option119257
|
||||
Node: Sequences120243
|
||||
Node: Empty Commands123238
|
||||
Node: Using Variables124406
|
||||
Node: Reference127390
|
||||
Node: Flavors128935
|
||||
Node: Advanced134252
|
||||
Node: Substitution Refs134752
|
||||
Node: Computed Names136279
|
||||
Node: Values140849
|
||||
Node: Setting141766
|
||||
Node: Appending143475
|
||||
Node: Override Directive147393
|
||||
Node: Defining148772
|
||||
Node: Environment150770
|
||||
Node: Conditionals152898
|
||||
Node: Conditional Example153607
|
||||
Node: Conditional Syntax156173
|
||||
Node: Testing Flags160919
|
||||
Node: Functions162016
|
||||
Node: Syntax of Functions163014
|
||||
Node: Text Functions165151
|
||||
Node: Filename Functions171905
|
||||
Node: Foreach Function177026
|
||||
Node: Origin Function180232
|
||||
Node: Shell Function183457
|
||||
Node: Running184834
|
||||
Node: Makefile Arguments186822
|
||||
Node: Goals187517
|
||||
Node: Instead of Execution191519
|
||||
Node: Avoiding Compilation194800
|
||||
Node: Overriding196701
|
||||
Node: Testing198989
|
||||
Node: Options Summary200866
|
||||
Node: Implicit Rules207676
|
||||
Node: Using Implicit209822
|
||||
Node: Catalogue of Rules213309
|
||||
Node: Implicit Variables222290
|
||||
Node: Chained Rules226416
|
||||
Node: Pattern Rules229114
|
||||
Node: Pattern Intro230642
|
||||
Node: Pattern Examples233453
|
||||
Node: Automatic235246
|
||||
Node: Pattern Match241533
|
||||
Node: Match-Anything Rules243137
|
||||
Node: Canceling Rules246996
|
||||
Node: Last Resort247699
|
||||
Node: Suffix Rules249536
|
||||
Node: Search Algorithm253243
|
||||
Node: Archives256739
|
||||
Node: Archive Members257434
|
||||
Node: Archive Update259013
|
||||
Node: Archive Symbols260929
|
||||
Node: Archive Pitfalls262128
|
||||
Node: Archive Suffix Rules262844
|
||||
Node: Features264384
|
||||
Node: Missing272736
|
||||
Node: Makefile Conventions277065
|
||||
Node: Makefile Basics277413
|
||||
Node: Utilities in Makefiles279752
|
||||
Node: Standard Targets281444
|
||||
Node: Command Variables289947
|
||||
Node: Directory Variables292772
|
||||
Node: Quick Reference302070
|
||||
Node: Complex Makefile309668
|
||||
Node: Concept Index318335
|
||||
Node: Name Index357722
|
||||
|
||||
End Tag Table
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,727 +0,0 @@
|
||||
This is Info file make.info, produced by Makeinfo-1.55 from the input
|
||||
file ./make.texinfo.
|
||||
|
||||
This file documents the GNU Make utility, which determines
|
||||
automatically which pieces of a large program need to be recompiled,
|
||||
and issues the commands to recompile them.
|
||||
|
||||
This is Edition 0.48, last updated 4 April 1995, of `The GNU Make
|
||||
Manual', for `make', Version 3.73 Beta.
|
||||
|
||||
Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this
|
||||
manual provided the copyright notice and this permission notice are
|
||||
preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided that
|
||||
the entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that this permission notice may be stated in a
|
||||
translation approved by the Free Software Foundation.
|
||||
|
||||
|
||||
File: make.info, Node: Directory Variables, Prev: Command Variables, Up: Makefile Conventions
|
||||
|
||||
Variables for Installation Directories
|
||||
======================================
|
||||
|
||||
Installation directories should always be named by variables, so it
|
||||
is easy to install in a nonstandard place. The standard names for these
|
||||
variables are described below. They are based on a standard filesystem
|
||||
layout; variants of it are used in SVR4, 4.4BSD, Linux, Ultrix v4, and
|
||||
other modern operating systems.
|
||||
|
||||
These two variables set the root for the installation. All the other
|
||||
installation directories should be subdirectories of one of these two,
|
||||
and nothing should be directly installed into these two directories.
|
||||
|
||||
`prefix'
|
||||
A prefix used in constructing the default values of the variables
|
||||
listed below. The default value of `prefix' should be `/usr/local'
|
||||
When building the complete GNU system, the prefix will be empty and
|
||||
`/usr' will be a symbolic link to `/'.
|
||||
|
||||
`exec_prefix'
|
||||
A prefix used in constructing the default values of some of the
|
||||
variables listed below. The default value of `exec_prefix' should
|
||||
be `$(prefix)'.
|
||||
|
||||
Generally, `$(exec_prefix)' is used for directories that contain
|
||||
machine-specific files (such as executables and subroutine
|
||||
libraries), while `$(prefix)' is used directly for other
|
||||
directories.
|
||||
|
||||
Executable programs are installed in one of the following
|
||||
directories.
|
||||
|
||||
`bindir'
|
||||
The directory for installing executable programs that users can
|
||||
run. This should normally be `/usr/local/bin', but write it as
|
||||
`$(exec_prefix)/bin'.
|
||||
|
||||
`sbindir'
|
||||
The directory for installing executable programs that can be run
|
||||
from the shell, but are only generally useful to system
|
||||
administrators. This should normally be `/usr/local/sbin', but
|
||||
write it as `$(exec_prefix)/sbin'.
|
||||
|
||||
`libexecdir'
|
||||
The directory for installing executable programs to be run by other
|
||||
programs rather than by users. This directory should normally be
|
||||
`/usr/local/libexec', but write it as `$(exec_prefix)/libexec'.
|
||||
|
||||
Data files used by the program during its execution are divided into
|
||||
categories in two ways.
|
||||
|
||||
* Some files are normally modified by programs; others are never
|
||||
normally modified (though users may edit some of these).
|
||||
|
||||
* Some files are architecture-independent and can be shared by all
|
||||
machines at a site; some are architecture-dependent and can be
|
||||
shared only by machines of the same kind and operating system;
|
||||
others may never be shared between two machines.
|
||||
|
||||
This makes for six different possibilities. However, we want to
|
||||
discourage the use of architecture-dependent files, aside from of object
|
||||
files and libraries. It is much cleaner to make other data files
|
||||
architecture-independent, and it is generally not hard.
|
||||
|
||||
Therefore, here are the variables makefiles should use to specify
|
||||
directories:
|
||||
|
||||
`datadir'
|
||||
The directory for installing read-only architecture independent
|
||||
data files. This should normally be `/usr/local/share', but write
|
||||
it as `$(prefix)/share'. As a special exception, see `$(infodir)'
|
||||
and `$(includedir)' below.
|
||||
|
||||
`sysconfdir'
|
||||
The directory for installing read-only data files that pertain to a
|
||||
single machine-that is to say, files for configuring a host.
|
||||
Mailer and network configuration files, `/etc/passwd', and so
|
||||
forth belong here. All the files in this directory should be
|
||||
ordinary ASCII text files. This directory should normally be
|
||||
`/usr/local/etc', but write it as `$(prefix)/etc'.
|
||||
|
||||
Do not install executables in this directory (they probably belong
|
||||
in `$(libexecdir)' or `$(sbindir))'. Also do not install files
|
||||
that are modified in the normal course of their use (programs
|
||||
whose purpose is to change the configuration of the system
|
||||
excluded). Those probably belong in `$(localstatedir)'.
|
||||
|
||||
`sharedstatedir'
|
||||
The directory for installing architecture-independent data files
|
||||
which the programs modify while they run. This should normally be
|
||||
`/usr/local/com', but write it as `$(prefix)/com'.
|
||||
|
||||
`localstatedir'
|
||||
The directory for installing data files which the programs modify
|
||||
while they run, and that pertain to one specific machine. Users
|
||||
should never need to modify files in this directory to configure
|
||||
the package's operation; put such configuration information in
|
||||
separate files that go in `datadir' or `$(sysconfdir)'.
|
||||
`$(localstatedir)' should normally be `/usr/local/var', but write
|
||||
it as `$(prefix)/var'.
|
||||
|
||||
`libdir'
|
||||
The directory for object files and libraries of object code. Do
|
||||
not install executables here, they probably belong in
|
||||
`$(libexecdir)' instead. The value of `libdir' should normally be
|
||||
`/usr/local/lib', but write it as `$(exec_prefix)/lib'.
|
||||
|
||||
`infodir'
|
||||
The directory for installing the Info files for this package. By
|
||||
default, it should be `/usr/local/info', but it should be written
|
||||
as `$(prefix)/info'.
|
||||
|
||||
`includedir'
|
||||
The directory for installing header files to be included by user
|
||||
programs with the C `#include' preprocessor directive. This
|
||||
should normally be `/usr/local/include', but write it as
|
||||
`$(prefix)/include'.
|
||||
|
||||
Most compilers other than GCC do not look for header files in
|
||||
`/usr/local/include'. So installing the header files this way is
|
||||
only useful with GCC. Sometimes this is not a problem because some
|
||||
libraries are only really intended to work with GCC. But some
|
||||
libraries are intended to work with other compilers. They should
|
||||
install their header files in two places, one specified by
|
||||
`includedir' and one specified by `oldincludedir'.
|
||||
|
||||
`oldincludedir'
|
||||
The directory for installing `#include' header files for use with
|
||||
compilers other than GCC. This should normally be `/usr/include'.
|
||||
|
||||
The Makefile commands should check whether the value of
|
||||
`oldincludedir' is empty. If it is, they should not try to use
|
||||
it; they should cancel the second installation of the header files.
|
||||
|
||||
A package should not replace an existing header in this directory
|
||||
unless the header came from the same package. Thus, if your Foo
|
||||
package provides a header file `foo.h', then it should install the
|
||||
header file in the `oldincludedir' directory if either (1) there
|
||||
is no `foo.h' there or (2) the `foo.h' that exists came from the
|
||||
Foo package.
|
||||
|
||||
To tell whether `foo.h' came from the Foo package, put a magic
|
||||
string in the file--part of a comment--and grep for that string.
|
||||
|
||||
Unix-style man pages are installed in one of the following:
|
||||
|
||||
`mandir'
|
||||
The directory for installing the man pages (if any) for this
|
||||
package. It should include the suffix for the proper section of
|
||||
the manual--usually `1' for a utility. It will normally be
|
||||
`/usr/local/man/man1', but you should write it as
|
||||
`$(prefix)/man/man1'.
|
||||
|
||||
`man1dir'
|
||||
The directory for installing section 1 man pages.
|
||||
|
||||
`man2dir'
|
||||
The directory for installing section 2 man pages.
|
||||
|
||||
`...'
|
||||
Use these names instead of `mandir' if the package needs to
|
||||
install man pages in more than one section of the manual.
|
||||
|
||||
*Don't make the primary documentation for any GNU software be a
|
||||
man page. Write a manual in Texinfo instead. Man pages are just
|
||||
for the sake of people running GNU software on Unix, which is a
|
||||
secondary application only.*
|
||||
|
||||
`manext'
|
||||
The file name extension for the installed man page. This should
|
||||
contain a period followed by the appropriate digit; it should
|
||||
normally be `.1'.
|
||||
|
||||
`man1ext'
|
||||
The file name extension for installed section 1 man pages.
|
||||
|
||||
`man2ext'
|
||||
The file name extension for installed section 2 man pages.
|
||||
|
||||
`...'
|
||||
Use these names instead of `manext' if the package needs to
|
||||
install man pages in more than one section of the manual.
|
||||
|
||||
And finally, you should set the following variable:
|
||||
|
||||
`srcdir'
|
||||
The directory for the sources being compiled. The value of this
|
||||
variable is normally inserted by the `configure' shell script.
|
||||
|
||||
For example:
|
||||
|
||||
# Common prefix for installation directories.
|
||||
# NOTE: This directory must exist when you start the install.
|
||||
prefix = /usr/local
|
||||
exec_prefix = $(prefix)
|
||||
# Where to put the executable for the command `gcc'.
|
||||
bindir = $(exec_prefix)/bin
|
||||
# Where to put the directories used by the compiler.
|
||||
libexecdir = $(exec_prefix)/libexec
|
||||
# Where to put the Info files.
|
||||
infodir = $(prefix)/info
|
||||
|
||||
If your program installs a large number of files into one of the
|
||||
standard user-specified directories, it might be useful to group them
|
||||
into a subdirectory particular to that program. If you do this, you
|
||||
should write the `install' rule to create these subdirectories.
|
||||
|
||||
Do not expect the user to include the subdirectory name in the value
|
||||
of any of the variables listed above. The idea of having a uniform set
|
||||
of variable names for installation directories is to enable the user to
|
||||
specify the exact same values for several different GNU packages. In
|
||||
order for this to be useful, all the packages must be designed so that
|
||||
they will work sensibly when the user does so.
|
||||
|
||||
|
||||
File: make.info, Node: Quick Reference, Next: Complex Makefile, Prev: Makefile Conventions, Up: Top
|
||||
|
||||
Quick Reference
|
||||
***************
|
||||
|
||||
This appendix summarizes the directives, text manipulation functions,
|
||||
and special variables which GNU `make' understands. *Note Special
|
||||
Targets::, *Note Catalogue of Implicit Rules: Catalogue of Rules, and
|
||||
*Note Summary of Options: Options Summary, for other summaries.
|
||||
|
||||
Here is a summary of the directives GNU `make' recognizes:
|
||||
|
||||
`define VARIABLE'
|
||||
`endef'
|
||||
Define a multi-line, recursively-expanded variable.
|
||||
*Note Sequences::.
|
||||
|
||||
`ifdef VARIABLE'
|
||||
`ifndef VARIABLE'
|
||||
`ifeq (A,B)'
|
||||
`ifeq "A" "B"'
|
||||
`ifeq 'A' 'B''
|
||||
`ifneq (A,B)'
|
||||
`ifneq "A" "B"'
|
||||
`ifneq 'A' 'B''
|
||||
`else'
|
||||
`endif'
|
||||
Conditionally evaluate part of the makefile.
|
||||
*Note Conditionals::.
|
||||
|
||||
`include FILE'
|
||||
Include another makefile.
|
||||
*Note Including Other Makefiles: Include.
|
||||
|
||||
`override VARIABLE = VALUE'
|
||||
`override VARIABLE := VALUE'
|
||||
`override VARIABLE += VALUE'
|
||||
`override define VARIABLE'
|
||||
`endef'
|
||||
Define a variable, overriding any previous definition, even one
|
||||
from the command line.
|
||||
*Note The `override' Directive: Override Directive.
|
||||
|
||||
`export'
|
||||
Tell `make' to export all variables to child processes by default.
|
||||
*Note Communicating Variables to a Sub-`make': Variables/Recursion.
|
||||
|
||||
`export VARIABLE'
|
||||
`export VARIABLE = VALUE'
|
||||
`export VARIABLE := VALUE'
|
||||
`export VARIABLE += VALUE'
|
||||
`unexport VARIABLE'
|
||||
Tell `make' whether or not to export a particular variable to child
|
||||
processes.
|
||||
*Note Communicating Variables to a Sub-`make': Variables/Recursion.
|
||||
|
||||
`vpath PATTERN PATH'
|
||||
Specify a search path for files matching a `%' pattern.
|
||||
*Note The `vpath' Directive: Selective Search.
|
||||
|
||||
`vpath PATTERN'
|
||||
Remove all search paths previously specified for PATTERN.
|
||||
|
||||
`vpath'
|
||||
Remove all search paths previously specified in any `vpath'
|
||||
directive.
|
||||
|
||||
Here is a summary of the text manipulation functions (*note
|
||||
Functions::.):
|
||||
|
||||
`$(subst FROM,TO,TEXT)'
|
||||
Replace FROM with TO in TEXT.
|
||||
*Note Functions for String Substitution and Analysis: Text
|
||||
Functions.
|
||||
|
||||
`$(patsubst PATTERN,REPLACEMENT,TEXT)'
|
||||
Replace words matching PATTERN with REPLACEMENT in TEXT.
|
||||
*Note Functions for String Substitution and Analysis: Text
|
||||
Functions.
|
||||
|
||||
`$(strip STRING)'
|
||||
Remove excess whitespace characters from STRING.
|
||||
*Note Functions for String Substitution and Analysis: Text
|
||||
Functions.
|
||||
|
||||
`$(findstring FIND,TEXT)'
|
||||
Locate FIND in TEXT.
|
||||
*Note Functions for String Substitution and Analysis: Text
|
||||
Functions.
|
||||
|
||||
`$(filter PATTERN...,TEXT)'
|
||||
Select words in TEXT that match one of the PATTERN words.
|
||||
*Note Functions for String Substitution and Analysis: Text
|
||||
Functions.
|
||||
|
||||
`$(filter-out PATTERN...,TEXT)'
|
||||
Select words in TEXT that *do not* match any of the PATTERN words.
|
||||
*Note Functions for String Substitution and Analysis: Text
|
||||
Functions.
|
||||
|
||||
`$(sort LIST)'
|
||||
Sort the words in LIST lexicographically, removing duplicates.
|
||||
*Note Functions for String Substitution and Analysis: Text
|
||||
Functions.
|
||||
|
||||
`$(dir NAMES...)'
|
||||
Extract the directory part of each file name.
|
||||
*Note Functions for File Names: Filename Functions.
|
||||
|
||||
`$(notdir NAMES...)'
|
||||
Extract the non-directory part of each file name.
|
||||
*Note Functions for File Names: Filename Functions.
|
||||
|
||||
`$(suffix NAMES...)'
|
||||
Extract the suffix (the last `.' and following characters) of each
|
||||
file name.
|
||||
*Note Functions for File Names: Filename Functions.
|
||||
|
||||
`$(basename NAMES...)'
|
||||
Extract the base name (name without suffix) of each file name.
|
||||
*Note Functions for File Names: Filename Functions.
|
||||
|
||||
`$(addsuffix SUFFIX,NAMES...)'
|
||||
Append SUFFIX to each word in NAMES.
|
||||
*Note Functions for File Names: Filename Functions.
|
||||
|
||||
`$(addprefix PREFIX,NAMES...)'
|
||||
Prepend PREFIX to each word in NAMES.
|
||||
*Note Functions for File Names: Filename Functions.
|
||||
|
||||
`$(join LIST1,LIST2)'
|
||||
Join two parallel lists of words.
|
||||
*Note Functions for File Names: Filename Functions.
|
||||
|
||||
`$(word N,TEXT)'
|
||||
Extract the Nth word (one-origin) of TEXT.
|
||||
*Note Functions for File Names: Filename Functions.
|
||||
|
||||
`$(words TEXT)'
|
||||
Count the number of words in TEXT.
|
||||
*Note Functions for File Names: Filename Functions.
|
||||
|
||||
`$(firstword NAMES...)'
|
||||
Extract the first word of NAMES.
|
||||
*Note Functions for File Names: Filename Functions.
|
||||
|
||||
`$(wildcard PATTERN...)'
|
||||
Find file names matching a shell file name pattern (*not* a `%'
|
||||
pattern).
|
||||
*Note The Function `wildcard': Wildcard Function.
|
||||
|
||||
`$(shell COMMAND)'
|
||||
Execute a shell command and return its output.
|
||||
*Note The `shell' Function: Shell Function.
|
||||
|
||||
`$(origin VARIABLE)'
|
||||
Return a string describing how the `make' variable VARIABLE was
|
||||
defined.
|
||||
*Note The `origin' Function: Origin Function.
|
||||
|
||||
`$(foreach VAR,WORDS,TEXT)'
|
||||
Evaluate TEXT with VAR bound to each word in WORDS, and
|
||||
concatenate the results.
|
||||
*Note The `foreach' Function: Foreach Function.
|
||||
|
||||
Here is a summary of the automatic variables. *Note Automatic
|
||||
Variables: Automatic, for full information.
|
||||
|
||||
`$@'
|
||||
The file name of the target.
|
||||
|
||||
`$%'
|
||||
The target member name, when the target is an archive member.
|
||||
|
||||
`$<'
|
||||
The name of the first dependency.
|
||||
|
||||
`$?'
|
||||
The names of all the dependencies that are newer than the target,
|
||||
with spaces between them. For dependencies which are archive
|
||||
members, only the member named is used (*note Archives::.).
|
||||
|
||||
`$^'
|
||||
`$+'
|
||||
The names of all the dependencies, with spaces between them. For
|
||||
dependencies which are archive members, only the member named is
|
||||
used (*note Archives::.). The value of `$^' omits duplicate
|
||||
dependencies, while `$+' retains them and preserves their order.
|
||||
|
||||
`$*'
|
||||
The stem with which an implicit rule matches (*note How Patterns
|
||||
Match: Pattern Match.).
|
||||
|
||||
`$(@D)'
|
||||
`$(@F)'
|
||||
The directory part and the file-within-directory part of `$@'.
|
||||
|
||||
`$(*D)'
|
||||
`$(*F)'
|
||||
The directory part and the file-within-directory part of `$*'.
|
||||
|
||||
`$(%D)'
|
||||
`$(%F)'
|
||||
The directory part and the file-within-directory part of `$%'.
|
||||
|
||||
`$(<D)'
|
||||
`$(<F)'
|
||||
The directory part and the file-within-directory part of `$<'.
|
||||
|
||||
`$(^D)'
|
||||
`$(^F)'
|
||||
The directory part and the file-within-directory part of `$^'.
|
||||
|
||||
`$(+D)'
|
||||
`$(+F)'
|
||||
The directory part and the file-within-directory part of `$+'.
|
||||
|
||||
`$(?D)'
|
||||
`$(?F)'
|
||||
The directory part and the file-within-directory part of `$?'.
|
||||
|
||||
These variables are used specially by GNU `make':
|
||||
|
||||
`MAKEFILES'
|
||||
Makefiles to be read on every invocation of `make'.
|
||||
*Note The Variable `MAKEFILES': MAKEFILES Variable.
|
||||
|
||||
`VPATH'
|
||||
Directory search path for files not found in the current directory.
|
||||
*Note `VPATH' Search Path for All Dependencies: General Search.
|
||||
|
||||
`SHELL'
|
||||
The name of the system default command interpreter, usually
|
||||
`/bin/sh'. You can set `SHELL' in the makefile to change the
|
||||
shell used to run commands. *Note Command Execution: Execution.
|
||||
|
||||
`MAKE'
|
||||
The name with which `make' was invoked. Using this variable in
|
||||
commands has special meaning. *Note How the `MAKE' Variable
|
||||
Works: MAKE Variable.
|
||||
|
||||
`MAKELEVEL'
|
||||
The number of levels of recursion (sub-`make's).
|
||||
*Note Variables/Recursion::.
|
||||
|
||||
`MAKEFLAGS'
|
||||
The flags given to `make'. You can set this in the environment or
|
||||
a makefile to set flags.
|
||||
*Note Communicating Options to a Sub-`make': Options/Recursion.
|
||||
|
||||
`SUFFIXES'
|
||||
The default list of suffixes before `make' reads any makefiles.
|
||||
|
||||
|
||||
File: make.info, Node: Complex Makefile, Next: Concept Index, Prev: Quick Reference, Up: Top
|
||||
|
||||
Complex Makefile Example
|
||||
************************
|
||||
|
||||
Here is the makefile for the GNU `tar' program. This is a
|
||||
moderately complex makefile.
|
||||
|
||||
Because it is the first target, the default goal is `all'. An
|
||||
interesting feature of this makefile is that `testpad.h' is a source
|
||||
file automatically created by the `testpad' program, itself compiled
|
||||
from `testpad.c'.
|
||||
|
||||
If you type `make' or `make all', then `make' creates the `tar'
|
||||
executable, the `rmt' daemon that provides remote tape access, and the
|
||||
`tar.info' Info file.
|
||||
|
||||
If you type `make install', then `make' not only creates `tar',
|
||||
`rmt', and `tar.info', but also installs them.
|
||||
|
||||
If you type `make clean', then `make' removes the `.o' files, and
|
||||
the `tar', `rmt', `testpad', `testpad.h', and `core' files.
|
||||
|
||||
If you type `make distclean', then `make' not only removes the same
|
||||
files as does `make clean' but also the `TAGS', `Makefile', and
|
||||
`config.status' files. (Although it is not evident, this makefile (and
|
||||
`config.status') is generated by the user with the `configure' program,
|
||||
which is provided in the `tar' distribution, but is not shown here.)
|
||||
|
||||
If you type `make realclean', then `make' removes the same files as
|
||||
does `make distclean' and also removes the Info files generated from
|
||||
`tar.texinfo'.
|
||||
|
||||
In addition, there are targets `shar' and `dist' that create
|
||||
distribution kits.
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
# Un*x Makefile for GNU tar program.
|
||||
# Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute
|
||||
# it and/or modify it under the terms of the GNU
|
||||
# General Public License ...
|
||||
...
|
||||
...
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = .
|
||||
|
||||
# If you use gcc, you should either run the
|
||||
# fixincludes script that comes with it or else use
|
||||
# gcc with the -traditional option. Otherwise ioctl
|
||||
# calls will be compiled incorrectly on some systems.
|
||||
CC = gcc -O
|
||||
YACC = bison -y
|
||||
INSTALL = /usr/local/bin/install -c
|
||||
INSTALLDATA = /usr/local/bin/install -c -m 644
|
||||
|
||||
# Things you might add to DEFS:
|
||||
# -DSTDC_HEADERS If you have ANSI C headers and
|
||||
# libraries.
|
||||
# -DPOSIX If you have POSIX.1 headers and
|
||||
# libraries.
|
||||
# -DBSD42 If you have sys/dir.h (unless
|
||||
# you use -DPOSIX), sys/file.h,
|
||||
# and st_blocks in `struct stat'.
|
||||
# -DUSG If you have System V/ANSI C
|
||||
# string and memory functions
|
||||
# and headers, sys/sysmacros.h,
|
||||
# fcntl.h, getcwd, no valloc,
|
||||
# and ndir.h (unless
|
||||
# you use -DDIRENT).
|
||||
# -DNO_MEMORY_H If USG or STDC_HEADERS but do not
|
||||
# include memory.h.
|
||||
# -DDIRENT If USG and you have dirent.h
|
||||
# instead of ndir.h.
|
||||
# -DSIGTYPE=int If your signal handlers
|
||||
# return int, not void.
|
||||
# -DNO_MTIO If you lack sys/mtio.h
|
||||
# (magtape ioctls).
|
||||
# -DNO_REMOTE If you do not have a remote shell
|
||||
# or rexec.
|
||||
# -DUSE_REXEC To use rexec for remote tape
|
||||
# operations instead of
|
||||
# forking rsh or remsh.
|
||||
# -DVPRINTF_MISSING If you lack vprintf function
|
||||
# (but have _doprnt).
|
||||
# -DDOPRNT_MISSING If you lack _doprnt function.
|
||||
# Also need to define
|
||||
# -DVPRINTF_MISSING.
|
||||
# -DFTIME_MISSING If you lack ftime system call.
|
||||
# -DSTRSTR_MISSING If you lack strstr function.
|
||||
# -DVALLOC_MISSING If you lack valloc function.
|
||||
# -DMKDIR_MISSING If you lack mkdir and
|
||||
# rmdir system calls.
|
||||
# -DRENAME_MISSING If you lack rename system call.
|
||||
# -DFTRUNCATE_MISSING If you lack ftruncate
|
||||
# system call.
|
||||
# -DV7 On Version 7 Unix (not
|
||||
# tested in a long time).
|
||||
# -DEMUL_OPEN3 If you lack a 3-argument version
|
||||
# of open, and want to emulate it
|
||||
# with system calls you do have.
|
||||
# -DNO_OPEN3 If you lack the 3-argument open
|
||||
# and want to disable the tar -k
|
||||
# option instead of emulating open.
|
||||
# -DXENIX If you have sys/inode.h
|
||||
# and need it 94 to be included.
|
||||
|
||||
DEFS = -DSIGTYPE=int -DDIRENT -DSTRSTR_MISSING \
|
||||
-DVPRINTF_MISSING -DBSD42
|
||||
# Set this to rtapelib.o unless you defined NO_REMOTE,
|
||||
# in which case make it empty.
|
||||
RTAPELIB = rtapelib.o
|
||||
LIBS =
|
||||
DEF_AR_FILE = /dev/rmt8
|
||||
DEFBLOCKING = 20
|
||||
|
||||
CDEBUG = -g
|
||||
CFLAGS = $(CDEBUG) -I. -I$(srcdir) $(DEFS) \
|
||||
-DDEF_AR_FILE=\"$(DEF_AR_FILE)\" \
|
||||
-DDEFBLOCKING=$(DEFBLOCKING)
|
||||
LDFLAGS = -g
|
||||
|
||||
prefix = /usr/local
|
||||
# Prefix for each installed program,
|
||||
# normally empty or `g'.
|
||||
binprefix =
|
||||
|
||||
# The directory to install tar in.
|
||||
bindir = $(prefix)/bin
|
||||
|
||||
# The directory to install the info files in.
|
||||
infodir = $(prefix)/info
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
SRC1 = tar.c create.c extract.c buffer.c \
|
||||
getoldopt.c update.c gnu.c mangle.c
|
||||
SRC2 = version.c list.c names.c diffarch.c \
|
||||
port.c wildmat.c getopt.c
|
||||
SRC3 = getopt1.c regex.c getdate.y
|
||||
SRCS = $(SRC1) $(SRC2) $(SRC3)
|
||||
OBJ1 = tar.o create.o extract.o buffer.o \
|
||||
getoldopt.o update.o gnu.o mangle.o
|
||||
OBJ2 = version.o list.o names.o diffarch.o \
|
||||
port.o wildmat.o getopt.o
|
||||
OBJ3 = getopt1.o regex.o getdate.o $(RTAPELIB)
|
||||
OBJS = $(OBJ1) $(OBJ2) $(OBJ3)
|
||||
AUX = README COPYING ChangeLog Makefile.in \
|
||||
makefile.pc configure configure.in \
|
||||
tar.texinfo tar.info* texinfo.tex \
|
||||
tar.h port.h open3.h getopt.h regex.h \
|
||||
rmt.h rmt.c rtapelib.c alloca.c \
|
||||
msd_dir.h msd_dir.c tcexparg.c \
|
||||
level-0 level-1 backup-specs testpad.c
|
||||
|
||||
all: tar rmt tar.info
|
||||
|
||||
tar: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
|
||||
rmt: rmt.c
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ rmt.c
|
||||
|
||||
tar.info: tar.texinfo
|
||||
makeinfo tar.texinfo
|
||||
|
||||
install: all
|
||||
$(INSTALL) tar $(bindir)/$(binprefix)tar
|
||||
-test ! -f rmt || $(INSTALL) rmt /etc/rmt
|
||||
$(INSTALLDATA) $(srcdir)/tar.info* $(infodir)
|
||||
|
||||
$(OBJS): tar.h port.h testpad.h
|
||||
regex.o buffer.o tar.o: regex.h
|
||||
# getdate.y has 8 shift/reduce conflicts.
|
||||
|
||||
testpad.h: testpad
|
||||
./testpad
|
||||
|
||||
testpad: testpad.o
|
||||
$(CC) -o $@ testpad.o
|
||||
|
||||
TAGS: $(SRCS)
|
||||
etags $(SRCS)
|
||||
|
||||
clean:
|
||||
rm -f *.o tar rmt testpad testpad.h core
|
||||
|
||||
distclean: clean
|
||||
rm -f TAGS Makefile config.status
|
||||
|
||||
realclean: distclean
|
||||
rm -f tar.info*
|
||||
|
||||
shar: $(SRCS) $(AUX)
|
||||
shar $(SRCS) $(AUX) | compress \
|
||||
> tar-`sed -e '/version_string/!d' \
|
||||
-e 's/[^0-9.]*\([0-9.]*\).*/\1/' \
|
||||
-e q
|
||||
version.c`.shar.Z
|
||||
|
||||
dist: $(SRCS) $(AUX)
|
||||
echo tar-`sed \
|
||||
-e '/version_string/!d' \
|
||||
-e 's/[^0-9.]*\([0-9.]*\).*/\1/' \
|
||||
-e q
|
||||
version.c` > .fname
|
||||
-rm -rf `cat .fname`
|
||||
mkdir `cat .fname`
|
||||
ln $(SRCS) $(AUX) `cat .fname`
|
||||
-rm -rf `cat .fname` .fname
|
||||
tar chZf `cat .fname`.tar.Z `cat .fname`
|
||||
|
||||
tar.zoo: $(SRCS) $(AUX)
|
||||
-rm -rf tmp.dir
|
||||
-mkdir tmp.dir
|
||||
-rm tar.zoo
|
||||
for X in $(SRCS) $(AUX) ; do \
|
||||
echo $$X ; \
|
||||
sed 's/$$/^M/' $$X \
|
||||
> tmp.dir/$$X ; done
|
||||
cd tmp.dir ; zoo aM ../tar.zoo *
|
||||
-rm -rf tmp.dir
|
||||
|
||||
@ -1,896 +0,0 @@
|
||||
This is Info file make.info, produced by Makeinfo-1.55 from the input
|
||||
file ./make.texinfo.
|
||||
|
||||
This file documents the GNU Make utility, which determines
|
||||
automatically which pieces of a large program need to be recompiled,
|
||||
and issues the commands to recompile them.
|
||||
|
||||
This is Edition 0.48, last updated 4 April 1995, of `The GNU Make
|
||||
Manual', for `make', Version 3.73 Beta.
|
||||
|
||||
Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this
|
||||
manual provided the copyright notice and this permission notice are
|
||||
preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided that
|
||||
the entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that this permission notice may be stated in a
|
||||
translation approved by the Free Software Foundation.
|
||||
|
||||
|
||||
File: make.info, Node: Concept Index, Next: Name Index, Prev: Complex Makefile, Up: Top
|
||||
|
||||
Index of Concepts
|
||||
*****************
|
||||
|
||||
* Menu:
|
||||
|
||||
* +, and define: Sequences.
|
||||
* +=: Appending.
|
||||
* ,v (RCS file extension): Catalogue of Rules.
|
||||
* -, and define: Sequences.
|
||||
* .C: Catalogue of Rules.
|
||||
* .c: Catalogue of Rules.
|
||||
* .cc: Catalogue of Rules.
|
||||
* .ch: Catalogue of Rules.
|
||||
* .def: Catalogue of Rules.
|
||||
* .dvi: Catalogue of Rules.
|
||||
* .F: Catalogue of Rules.
|
||||
* .f: Catalogue of Rules.
|
||||
* .info: Catalogue of Rules.
|
||||
* .l: Catalogue of Rules.
|
||||
* .ln: Catalogue of Rules.
|
||||
* .mod: Catalogue of Rules.
|
||||
* .o: Catalogue of Rules.
|
||||
* .o: Catalogue of Rules.
|
||||
* .p: Catalogue of Rules.
|
||||
* .r: Catalogue of Rules.
|
||||
* .S: Catalogue of Rules.
|
||||
* .s: Catalogue of Rules.
|
||||
* .sh: Catalogue of Rules.
|
||||
* .sym: Catalogue of Rules.
|
||||
* .tex: Catalogue of Rules.
|
||||
* .texi: Catalogue of Rules.
|
||||
* .texinfo: Catalogue of Rules.
|
||||
* .txinfo: Catalogue of Rules.
|
||||
* .w: Catalogue of Rules.
|
||||
* .web: Catalogue of Rules.
|
||||
* .y: Catalogue of Rules.
|
||||
* :=: Setting.
|
||||
* :=: Flavors.
|
||||
* =: Flavors.
|
||||
* =: Setting.
|
||||
* @, and define: Sequences.
|
||||
* #include: Automatic Dependencies.
|
||||
* # (comments), in commands: Commands.
|
||||
* # (comments), in makefile: Makefile Contents.
|
||||
* $, in function call: Syntax of Functions.
|
||||
* $, in rules: Rule Syntax.
|
||||
* $, in variable name: Computed Names.
|
||||
* $, in variable reference: Reference.
|
||||
* %, in pattern rules: Pattern Intro.
|
||||
* %, quoting in patsubst: Text Functions.
|
||||
* %, quoting in vpath: Selective Search.
|
||||
* %, quoting in static pattern: Static Usage.
|
||||
* %, quoting with \ (backslash): Selective Search.
|
||||
* %, quoting with \ (backslash): Static Usage.
|
||||
* %, quoting with \ (backslash): Text Functions.
|
||||
* * (wildcard character): Wildcards.
|
||||
* -assume-new: Options Summary.
|
||||
* -assume-new: Instead of Execution.
|
||||
* -assume-new, and recursion: Options/Recursion.
|
||||
* -assume-old: Avoiding Compilation.
|
||||
* -assume-old: Options Summary.
|
||||
* -assume-old, and recursion: Options/Recursion.
|
||||
* -debug: Options Summary.
|
||||
* -directory: Options Summary.
|
||||
* -directory: Recursion.
|
||||
* -directory, and -print-directory: -w Option.
|
||||
* -directory, and recursion: Options/Recursion.
|
||||
* -dry-run: Echoing.
|
||||
* -dry-run: Instead of Execution.
|
||||
* -dry-run: Options Summary.
|
||||
* -environment-overrides: Options Summary.
|
||||
* -file: Options Summary.
|
||||
* -file: Makefile Arguments.
|
||||
* -file: Makefile Names.
|
||||
* -file, and recursion: Options/Recursion.
|
||||
* -help: Options Summary.
|
||||
* -ignore-errors: Errors.
|
||||
* -ignore-errors: Options Summary.
|
||||
* -include-dir: Options Summary.
|
||||
* -include-dir: Include.
|
||||
* -jobs: Parallel.
|
||||
* -jobs: Options Summary.
|
||||
* -jobs, and recursion: Options/Recursion.
|
||||
* -just-print: Options Summary.
|
||||
* -just-print: Instead of Execution.
|
||||
* -just-print: Echoing.
|
||||
* -keep-going: Options Summary.
|
||||
* -keep-going: Errors.
|
||||
* -keep-going: Testing.
|
||||
* -load-average: Options Summary.
|
||||
* -load-average: Parallel.
|
||||
* -makefile: Options Summary.
|
||||
* -makefile: Makefile Arguments.
|
||||
* -makefile: Makefile Names.
|
||||
* -max-load: Options Summary.
|
||||
* -max-load: Parallel.
|
||||
* -new-file: Instead of Execution.
|
||||
* -new-file: Options Summary.
|
||||
* -new-file, and recursion: Options/Recursion.
|
||||
* -no-builtin-rules: Options Summary.
|
||||
* -no-keep-going: Options Summary.
|
||||
* -no-print-directory: -w Option.
|
||||
* -no-print-directory: Options Summary.
|
||||
* -old-file: Avoiding Compilation.
|
||||
* -old-file: Options Summary.
|
||||
* -old-file, and recursion: Options/Recursion.
|
||||
* -print-data-base: Options Summary.
|
||||
* -print-directory: Options Summary.
|
||||
* -print-directory, and -directory: -w Option.
|
||||
* -print-directory, and recursion: -w Option.
|
||||
* -print-directory, disabling: -w Option.
|
||||
* -question: Instead of Execution.
|
||||
* -question: Options Summary.
|
||||
* -quiet: Echoing.
|
||||
* -quiet: Options Summary.
|
||||
* -recon: Options Summary.
|
||||
* -recon: Echoing.
|
||||
* -recon: Instead of Execution.
|
||||
* -silent: Options Summary.
|
||||
* -silent: Echoing.
|
||||
* -stop: Options Summary.
|
||||
* -touch: Instead of Execution.
|
||||
* -touch: Options Summary.
|
||||
* -touch, and recursion: MAKE Variable.
|
||||
* -version: Options Summary.
|
||||
* -warn-undefined-variables: Options Summary.
|
||||
* -what-if: Instead of Execution.
|
||||
* -what-if: Options Summary.
|
||||
* -b: Options Summary.
|
||||
* -C: Options Summary.
|
||||
* -C: Recursion.
|
||||
* -C, and -w: -w Option.
|
||||
* -C, and recursion: Options/Recursion.
|
||||
* -d: Options Summary.
|
||||
* -e: Options Summary.
|
||||
* -e (shell flag): Automatic Dependencies.
|
||||
* -f: Makefile Arguments.
|
||||
* -f: Makefile Names.
|
||||
* -f: Options Summary.
|
||||
* -f, and recursion: Options/Recursion.
|
||||
* -h: Options Summary.
|
||||
* -I: Options Summary.
|
||||
* -i: Options Summary.
|
||||
* -i: Errors.
|
||||
* -I: Include.
|
||||
* -j: Options Summary.
|
||||
* -j: Parallel.
|
||||
* -j, and archive update: Archive Pitfalls.
|
||||
* -j, and recursion: Options/Recursion.
|
||||
* -k: Errors.
|
||||
* -k: Testing.
|
||||
* -k: Options Summary.
|
||||
* -l: Options Summary.
|
||||
* -l (library search): Libraries/Search.
|
||||
* -l (load average): Parallel.
|
||||
* -MM (to GNU compiler): Automatic Dependencies.
|
||||
* -m: Options Summary.
|
||||
* -M (to compiler): Automatic Dependencies.
|
||||
* -n: Echoing.
|
||||
* -n: Instead of Execution.
|
||||
* -n: Options Summary.
|
||||
* -o: Avoiding Compilation.
|
||||
* -o: Options Summary.
|
||||
* -o, and recursion: Options/Recursion.
|
||||
* -p: Options Summary.
|
||||
* -q: Options Summary.
|
||||
* -q: Instead of Execution.
|
||||
* -r: Options Summary.
|
||||
* -s: Echoing.
|
||||
* -s: Options Summary.
|
||||
* -S: Options Summary.
|
||||
* -t: Options Summary.
|
||||
* -t: Instead of Execution.
|
||||
* -t, and recursion: MAKE Variable.
|
||||
* -v: Options Summary.
|
||||
* -w: Options Summary.
|
||||
* -W: Options Summary.
|
||||
* -W: Instead of Execution.
|
||||
* -w, and -C: -w Option.
|
||||
* -W, and recursion: Options/Recursion.
|
||||
* -w, and recursion: -w Option.
|
||||
* -w, disabling: -w Option.
|
||||
* - (in commands): Errors.
|
||||
* .a (archives): Archive Suffix Rules.
|
||||
* .d: Automatic Dependencies.
|
||||
* .PRECIOUS intermediate files: Chained Rules.
|
||||
* :: rules (double-colon): Double-Colon.
|
||||
* ? (wildcard character): Wildcards.
|
||||
* @ (in commands): Echoing.
|
||||
* all (standard target): Goals.
|
||||
* cd (shell command): Execution.
|
||||
* cd (shell command): MAKE Variable.
|
||||
* check (standard target): Goals.
|
||||
* clean (standard target): Goals.
|
||||
* clean target: Cleanup.
|
||||
* clean target: Simple Makefile.
|
||||
* clobber (standard target): Goals.
|
||||
* distclean (standard target): Goals.
|
||||
* dist (standard target): Goals.
|
||||
* FORCE: Force Targets.
|
||||
* install (standard target): Goals.
|
||||
* lint, rule to run: Catalogue of Rules.
|
||||
* lpr (shell command): Wildcard Examples.
|
||||
* lpr (shell command): Empty Targets.
|
||||
* make depend: Automatic Dependencies.
|
||||
* mostlyclean (standard target): Goals.
|
||||
* OBJECTS: Variables Simplify.
|
||||
* objects: Variables Simplify.
|
||||
* objs: Variables Simplify.
|
||||
* OBJS: Variables Simplify.
|
||||
* obj: Variables Simplify.
|
||||
* OBJ: Variables Simplify.
|
||||
* print (standard target): Goals.
|
||||
* print target: Empty Targets.
|
||||
* print target: Wildcard Examples.
|
||||
* README: Makefile Names.
|
||||
* realclean (standard target): Goals.
|
||||
* rm (shell command): Phony Targets.
|
||||
* rm (shell command): Errors.
|
||||
* rm (shell command): Simple Makefile.
|
||||
* rm (shell command): Wildcard Examples.
|
||||
* sed (shell command): Automatic Dependencies.
|
||||
* shar (standard target): Goals.
|
||||
* TAGS (standard target): Goals.
|
||||
* tar (standard target): Goals.
|
||||
* test (standard target): Goals.
|
||||
* touch (shell command): Empty Targets.
|
||||
* touch (shell command): Wildcard Examples.
|
||||
* VPATH, and implicit rules: Implicit/Search.
|
||||
* VPATH, and link libraries: Libraries/Search.
|
||||
* yacc: Sequences.
|
||||
* [...] (wildcard characters): Wildcards.
|
||||
* \ (backslash), for continuation lines: Simple Makefile.
|
||||
* \ (backslash), in commands: Execution.
|
||||
* \ (backslash), to quote %: Text Functions.
|
||||
* \ (backslash), to quote %: Static Usage.
|
||||
* \ (backslash), to quote %: Selective Search.
|
||||
* __.SYMDEF: Archive Symbols.
|
||||
* ~ (tilde): Wildcards.
|
||||
* TeX, rule to run: Catalogue of Rules.
|
||||
* appending to variables: Appending.
|
||||
* ar: Implicit Variables.
|
||||
* archive: Archives.
|
||||
* archive member targets: Archive Members.
|
||||
* archive symbol directory updating: Archive Symbols.
|
||||
* archive, and -j: Archive Pitfalls.
|
||||
* archive, and parallel execution: Archive Pitfalls.
|
||||
* archive, suffix rule for: Archive Suffix Rules.
|
||||
* Arg list too long: Options/Recursion.
|
||||
* arguments of functions: Syntax of Functions.
|
||||
* as: Implicit Variables.
|
||||
* as: Catalogue of Rules.
|
||||
* assembly, rule to compile: Catalogue of Rules.
|
||||
* automatic generation of dependencies: Include.
|
||||
* automatic generation of dependencies: Automatic Dependencies.
|
||||
* automatic variables: Automatic.
|
||||
* backquotes: Shell Function.
|
||||
* backslash (\), for continuation lines: Simple Makefile.
|
||||
* backslash (\), in commands: Execution.
|
||||
* backslash (\), to quote %: Text Functions.
|
||||
* backslash (\), to quote %: Selective Search.
|
||||
* backslash (\), to quote %: Static Usage.
|
||||
* basename: Filename Functions.
|
||||
* broken pipe: Parallel.
|
||||
* bugs, reporting: Bugs.
|
||||
* built-in special targets: Special Targets.
|
||||
* C++, rule to compile: Catalogue of Rules.
|
||||
* C, rule to compile: Catalogue of Rules.
|
||||
* cc: Implicit Variables.
|
||||
* cc: Catalogue of Rules.
|
||||
* chains of rules: Chained Rules.
|
||||
* cleaning up: Cleanup.
|
||||
* co: Implicit Variables.
|
||||
* co: Catalogue of Rules.
|
||||
* combining rules by dependency: Combine By Dependency.
|
||||
* command line variable definitions, and recursion: Options/Recursion.
|
||||
* command line variables: Overriding.
|
||||
* commands: Rule Syntax.
|
||||
* commands, backslash (\) in: Execution.
|
||||
* commands, comments in: Commands.
|
||||
* commands, echoing: Echoing.
|
||||
* commands, empty: Empty Commands.
|
||||
* commands, errors in: Errors.
|
||||
* commands, execution: Execution.
|
||||
* commands, execution in parallel: Parallel.
|
||||
* commands, expansion: Shell Function.
|
||||
* commands, how to write: Commands.
|
||||
* commands, instead of executing: Instead of Execution.
|
||||
* commands, introduction to: Rule Introduction.
|
||||
* commands, quoting newlines in: Execution.
|
||||
* commands, sequences of: Sequences.
|
||||
* comments, in commands: Commands.
|
||||
* comments, in makefile: Makefile Contents.
|
||||
* compatibility: Features.
|
||||
* compatibility in exporting: Variables/Recursion.
|
||||
* compilation, testing: Testing.
|
||||
* computed variable name: Computed Names.
|
||||
* conditionals: Conditionals.
|
||||
* continuation lines: Simple Makefile.
|
||||
* conventions for makefiles: Makefile Conventions.
|
||||
* ctangle: Implicit Variables.
|
||||
* ctangle: Catalogue of Rules.
|
||||
* cweave: Catalogue of Rules.
|
||||
* cweave: Implicit Variables.
|
||||
* deducing commands (implicit rules): make Deduces.
|
||||
* default goal: Rules.
|
||||
* default goal: How Make Works.
|
||||
* default makefile name: Makefile Names.
|
||||
* default rules, last-resort: Last Resort.
|
||||
* defining variables verbatim: Defining.
|
||||
* deletion of target files: Interrupts.
|
||||
* deletion of target files: Errors.
|
||||
* dependencies: Rule Syntax.
|
||||
* dependencies, automatic generation: Automatic Dependencies.
|
||||
* dependencies, automatic generation: Include.
|
||||
* dependencies, introduction to: Rule Introduction.
|
||||
* dependencies, list of all: Automatic.
|
||||
* dependencies, list of changed: Automatic.
|
||||
* dependencies, varying (static pattern): Static Pattern.
|
||||
* dependency: Rules.
|
||||
* dependency pattern, implicit: Pattern Intro.
|
||||
* dependency pattern, static (not implicit): Static Usage.
|
||||
* directive: Makefile Contents.
|
||||
* directories, printing them: -w Option.
|
||||
* directories, updating archive symbol: Archive Symbols.
|
||||
* directory part: Filename Functions.
|
||||
* directory search (VPATH): Directory Search.
|
||||
* directory search (VPATH), and implicit rules: Implicit/Search.
|
||||
* directory search (VPATH), and link libraries: Libraries/Search.
|
||||
* directory search (VPATH), and shell commands: Commands/Search.
|
||||
* dollar sign ($), in function call: Syntax of Functions.
|
||||
* dollar sign ($), in rules: Rule Syntax.
|
||||
* dollar sign ($), in variable name: Computed Names.
|
||||
* dollar sign ($), in variable reference: Reference.
|
||||
* double-colon rules: Double-Colon.
|
||||
* duplicate words, removing: Text Functions.
|
||||
* E2BIG: Options/Recursion.
|
||||
* echoing of commands: Echoing.
|
||||
* editor: Introduction.
|
||||
* Emacs (M-x compile): Errors.
|
||||
* empty commands: Empty Commands.
|
||||
* empty targets: Empty Targets.
|
||||
* environment: Environment.
|
||||
* environment, SHELL in: Execution.
|
||||
* environment, and recursion: Variables/Recursion.
|
||||
* errors (in commands): Errors.
|
||||
* errors with wildcards: Wildcard Pitfall.
|
||||
* execution, in parallel: Parallel.
|
||||
* execution, instead of: Instead of Execution.
|
||||
* execution, of commands: Execution.
|
||||
* exit status (errors): Errors.
|
||||
* explicit rule, definition of: Makefile Contents.
|
||||
* exporting variables: Variables/Recursion.
|
||||
* f77: Catalogue of Rules.
|
||||
* f77: Implicit Variables.
|
||||
* features of GNU make: Features.
|
||||
* features, missing: Missing.
|
||||
* file name functions: Filename Functions.
|
||||
* file name of makefile: Makefile Names.
|
||||
* file name of makefile, how to specify: Makefile Names.
|
||||
* file name prefix, adding: Filename Functions.
|
||||
* file name suffix: Filename Functions.
|
||||
* file name suffix, adding: Filename Functions.
|
||||
* file name with wildcards: Wildcards.
|
||||
* file name, basename of: Filename Functions.
|
||||
* file name, directory part: Filename Functions.
|
||||
* file name, nondirectory part: Filename Functions.
|
||||
* files, assuming new: Instead of Execution.
|
||||
* files, assuming old: Avoiding Compilation.
|
||||
* files, avoiding recompilation of: Avoiding Compilation.
|
||||
* files, intermediate: Chained Rules.
|
||||
* filtering out words: Text Functions.
|
||||
* filtering words: Text Functions.
|
||||
* finding strings: Text Functions.
|
||||
* flags: Options Summary.
|
||||
* flags for compilers: Implicit Variables.
|
||||
* flavors of variables: Flavors.
|
||||
* force targets: Force Targets.
|
||||
* Fortran, rule to compile: Catalogue of Rules.
|
||||
* functions: Functions.
|
||||
* functions, for file names: Filename Functions.
|
||||
* functions, for text: Text Functions.
|
||||
* functions, syntax of: Syntax of Functions.
|
||||
* g++: Implicit Variables.
|
||||
* g++: Catalogue of Rules.
|
||||
* gcc: Catalogue of Rules.
|
||||
* generating dependencies automatically: Include.
|
||||
* generating dependencies automatically: Automatic Dependencies.
|
||||
* get: Catalogue of Rules.
|
||||
* get: Implicit Variables.
|
||||
* globbing (wildcards): Wildcards.
|
||||
* goal: How Make Works.
|
||||
* goal, default: Rules.
|
||||
* goal, default: How Make Works.
|
||||
* goal, how to specify: Goals.
|
||||
* home directory: Wildcards.
|
||||
* IEEE Standard 1003.2: Overview.
|
||||
* implicit rule: Implicit Rules.
|
||||
* implicit rule, and VPATH: Implicit/Search.
|
||||
* implicit rule, and directory search: Implicit/Search.
|
||||
* implicit rule, definition of: Makefile Contents.
|
||||
* implicit rule, how to use: Using Implicit.
|
||||
* implicit rule, introduction to: make Deduces.
|
||||
* implicit rule, predefined: Catalogue of Rules.
|
||||
* implicit rule, search algorithm: Search Algorithm.
|
||||
* including (MAKEFILES variable): MAKEFILES Variable.
|
||||
* including other makefiles: Include.
|
||||
* incompatibilities: Missing.
|
||||
* Info, rule to format: Catalogue of Rules.
|
||||
* intermediate files: Chained Rules.
|
||||
* intermediate files, preserving: Chained Rules.
|
||||
* interrupt: Interrupts.
|
||||
* job slots: Parallel.
|
||||
* job slots, and recursion: Options/Recursion.
|
||||
* jobs, limiting based on load: Parallel.
|
||||
* joining lists of words: Filename Functions.
|
||||
* killing (interruption): Interrupts.
|
||||
* last-resort default rules: Last Resort.
|
||||
* ld: Catalogue of Rules.
|
||||
* lex: Implicit Variables.
|
||||
* lex: Catalogue of Rules.
|
||||
* Lex, rule to run: Catalogue of Rules.
|
||||
* libraries for linking, directory search: Libraries/Search.
|
||||
* library archive, suffix rule for: Archive Suffix Rules.
|
||||
* limiting jobs based on load: Parallel.
|
||||
* link libraries, and directory search: Libraries/Search.
|
||||
* linking, predefined rule for: Catalogue of Rules.
|
||||
* lint: Catalogue of Rules.
|
||||
* list of all dependencies: Automatic.
|
||||
* list of changed dependencies: Automatic.
|
||||
* load average: Parallel.
|
||||
* loops in variable expansion: Flavors.
|
||||
* m2c: Catalogue of Rules.
|
||||
* macro: Using Variables.
|
||||
* makefile: Introduction.
|
||||
* makefile name: Makefile Names.
|
||||
* makefile name, how to specify: Makefile Names.
|
||||
* makefile rule parts: Rule Introduction.
|
||||
* makefile, and MAKEFILES variable: MAKEFILES Variable.
|
||||
* makefile, conventions for: Makefile Conventions.
|
||||
* makefile, how make processes: How Make Works.
|
||||
* makefile, how to write: Makefiles.
|
||||
* makefile, including: Include.
|
||||
* makefile, overriding: Overriding Makefiles.
|
||||
* makefile, remaking of: Remaking Makefiles.
|
||||
* makefile, simple: Simple Makefile.
|
||||
* makeinfo: Catalogue of Rules.
|
||||
* makeinfo: Implicit Variables.
|
||||
* match-anything rule: Match-Anything Rules.
|
||||
* match-anything rule, used to override: Overriding Makefiles.
|
||||
* missing features: Missing.
|
||||
* mistakes with wildcards: Wildcard Pitfall.
|
||||
* modified variable reference: Substitution Refs.
|
||||
* Modula-2, rule to compile: Catalogue of Rules.
|
||||
* multiple rules for one target: Multiple Rules.
|
||||
* multiple rules for one target (::): Double-Colon.
|
||||
* multiple targets: Multiple Targets.
|
||||
* multiple targets, in pattern rule: Pattern Intro.
|
||||
* name of makefile: Makefile Names.
|
||||
* name of makefile, how to specify: Makefile Names.
|
||||
* nested variable reference: Computed Names.
|
||||
* newline, quoting, in commands: Execution.
|
||||
* newline, quoting, in makefile: Simple Makefile.
|
||||
* nondirectory part: Filename Functions.
|
||||
* old-fashioned suffix rules: Suffix Rules.
|
||||
* options: Options Summary.
|
||||
* options, and recursion: Options/Recursion.
|
||||
* options, setting from environment: Options/Recursion.
|
||||
* options, setting in makefiles: Options/Recursion.
|
||||
* order of pattern rules: Pattern Intro.
|
||||
* origin of variable: Origin Function.
|
||||
* overriding makefiles: Overriding Makefiles.
|
||||
* overriding variables with arguments: Overriding.
|
||||
* overriding with override: Override Directive.
|
||||
* parallel execution: Parallel.
|
||||
* parallel execution, and archive update: Archive Pitfalls.
|
||||
* parts of makefile rule: Rule Introduction.
|
||||
* Pascal, rule to compile: Catalogue of Rules.
|
||||
* pattern rule: Pattern Intro.
|
||||
* pattern rules, order of: Pattern Intro.
|
||||
* pattern rules, static (not implicit): Static Pattern.
|
||||
* pattern rules, static, syntax of: Static Usage.
|
||||
* pc: Implicit Variables.
|
||||
* pc: Catalogue of Rules.
|
||||
* phony targets: Phony Targets.
|
||||
* pitfalls of wildcards: Wildcard Pitfall.
|
||||
* portability: Features.
|
||||
* POSIX: Overview.
|
||||
* POSIX.2: Options/Recursion.
|
||||
* precious targets: Special Targets.
|
||||
* prefix, adding: Filename Functions.
|
||||
* preserving intermediate files: Chained Rules.
|
||||
* preserving with .PRECIOUS: Chained Rules.
|
||||
* preserving with .PRECIOUS: Special Targets.
|
||||
* printing directories: -w Option.
|
||||
* printing of commands: Echoing.
|
||||
* problems and bugs, reporting: Bugs.
|
||||
* problems with wildcards: Wildcard Pitfall.
|
||||
* processing a makefile: How Make Works.
|
||||
* question mode: Instead of Execution.
|
||||
* quoting %, in patsubst: Text Functions.
|
||||
* quoting %, in vpath: Selective Search.
|
||||
* quoting %, in static pattern: Static Usage.
|
||||
* quoting newline, in commands: Execution.
|
||||
* quoting newline, in makefile: Simple Makefile.
|
||||
* Ratfor, rule to compile: Catalogue of Rules.
|
||||
* RCS, rule to extract from: Catalogue of Rules.
|
||||
* recompilation: Introduction.
|
||||
* recompilation, avoiding: Avoiding Compilation.
|
||||
* recording events with empty targets: Empty Targets.
|
||||
* recursion: Recursion.
|
||||
* recursion, and -C: Options/Recursion.
|
||||
* recursion, and -f: Options/Recursion.
|
||||
* recursion, and -j: Options/Recursion.
|
||||
* recursion, and -o: Options/Recursion.
|
||||
* recursion, and -t: MAKE Variable.
|
||||
* recursion, and -W: Options/Recursion.
|
||||
* recursion, and -w: -w Option.
|
||||
* recursion, and MAKEFILES variable: MAKEFILES Variable.
|
||||
* recursion, and MAKE variable: MAKE Variable.
|
||||
* recursion, and command line variable definitions: Options/Recursion.
|
||||
* recursion, and environment: Variables/Recursion.
|
||||
* recursion, and options: Options/Recursion.
|
||||
* recursion, and printing directories: -w Option.
|
||||
* recursion, and variables: Variables/Recursion.
|
||||
* recursion, level of: Variables/Recursion.
|
||||
* recursive variable expansion: Using Variables.
|
||||
* recursive variable expansion: Flavors.
|
||||
* recursively expanded variables: Flavors.
|
||||
* reference to variables: Reference.
|
||||
* reference to variables: Advanced.
|
||||
* relinking: How Make Works.
|
||||
* remaking makefiles: Remaking Makefiles.
|
||||
* removal of target files: Errors.
|
||||
* removal of target files: Interrupts.
|
||||
* removing duplicate words: Text Functions.
|
||||
* removing, to clean up: Cleanup.
|
||||
* reporting bugs: Bugs.
|
||||
* rm: Implicit Variables.
|
||||
* rule commands: Commands.
|
||||
* rule dependencies: Rule Syntax.
|
||||
* rule syntax: Rule Syntax.
|
||||
* rule targets: Rule Syntax.
|
||||
* rule, and $: Rule Syntax.
|
||||
* rule, double-colon (::): Double-Colon.
|
||||
* rule, explicit, definition of: Makefile Contents.
|
||||
* rule, how to write: Rules.
|
||||
* rule, implicit: Implicit Rules.
|
||||
* rule, implicit, and VPATH: Implicit/Search.
|
||||
* rule, implicit, and directory search: Implicit/Search.
|
||||
* rule, implicit, chains of: Chained Rules.
|
||||
* rule, implicit, definition of: Makefile Contents.
|
||||
* rule, implicit, how to use: Using Implicit.
|
||||
* rule, implicit, introduction to: make Deduces.
|
||||
* rule, implicit, predefined: Catalogue of Rules.
|
||||
* rule, introduction to: Rule Introduction.
|
||||
* rule, multiple for one target: Multiple Rules.
|
||||
* rule, no commands or dependencies: Force Targets.
|
||||
* rule, pattern: Pattern Intro.
|
||||
* rule, static pattern: Static Pattern.
|
||||
* rule, static pattern versus implicit: Static versus Implicit.
|
||||
* rule, with multiple targets: Multiple Targets.
|
||||
* s. (SCCS file prefix): Catalogue of Rules.
|
||||
* SCCS, rule to extract from: Catalogue of Rules.
|
||||
* search algorithm, implicit rule: Search Algorithm.
|
||||
* search path for dependencies (VPATH): Directory Search.
|
||||
* search path for dependencies (VPATH), and implicit rules: Implicit/Search.
|
||||
* search path for dependencies (VPATH), and link libraries: Libraries/Search.
|
||||
* searching for strings: Text Functions.
|
||||
* selecting words: Filename Functions.
|
||||
* sequences of commands: Sequences.
|
||||
* setting options from environment: Options/Recursion.
|
||||
* setting options in makefiles: Options/Recursion.
|
||||
* setting variables: Setting.
|
||||
* several rules for one target: Multiple Rules.
|
||||
* several targets in a rule: Multiple Targets.
|
||||
* shell command: Simple Makefile.
|
||||
* shell command, and directory search: Commands/Search.
|
||||
* shell command, execution: Execution.
|
||||
* shell command, function for: Shell Function.
|
||||
* shell file name pattern (in include): Include.
|
||||
* shell wildcards (in include): Include.
|
||||
* signal: Interrupts.
|
||||
* silent operation: Echoing.
|
||||
* simple makefile: Simple Makefile.
|
||||
* simple variable expansion: Using Variables.
|
||||
* simplifying with variables: Variables Simplify.
|
||||
* simply expanded variables: Flavors.
|
||||
* sorting words: Text Functions.
|
||||
* spaces, in variable values: Flavors.
|
||||
* spaces, stripping: Text Functions.
|
||||
* special targets: Special Targets.
|
||||
* specifying makefile name: Makefile Names.
|
||||
* standard input: Parallel.
|
||||
* standards conformance: Overview.
|
||||
* standards for makefiles: Makefile Conventions.
|
||||
* static pattern rule: Static Pattern.
|
||||
* static pattern rule, syntax of: Static Usage.
|
||||
* static pattern rule, versus implicit: Static versus Implicit.
|
||||
* stem: Pattern Match.
|
||||
* stem: Static Usage.
|
||||
* stem, variable for: Automatic.
|
||||
* strings, searching for: Text Functions.
|
||||
* stripping whitespace: Text Functions.
|
||||
* sub-make: Variables/Recursion.
|
||||
* subdirectories, recursion for: Recursion.
|
||||
* substitution variable reference: Substitution Refs.
|
||||
* suffix rule: Suffix Rules.
|
||||
* suffix rule, for archive: Archive Suffix Rules.
|
||||
* suffix, adding: Filename Functions.
|
||||
* suffix, function to find: Filename Functions.
|
||||
* suffix, substituting in variables: Substitution Refs.
|
||||
* switches: Options Summary.
|
||||
* symbol directories, updating archive: Archive Symbols.
|
||||
* syntax of rules: Rule Syntax.
|
||||
* tab character (in commands): Rule Syntax.
|
||||
* tabs in rules: Rule Introduction.
|
||||
* tangle: Implicit Variables.
|
||||
* tangle: Catalogue of Rules.
|
||||
* target: Rules.
|
||||
* target pattern, implicit: Pattern Intro.
|
||||
* target pattern, static (not implicit): Static Usage.
|
||||
* target, deleting on error: Errors.
|
||||
* target, deleting on interrupt: Interrupts.
|
||||
* target, multiple in pattern rule: Pattern Intro.
|
||||
* target, multiple rules for one: Multiple Rules.
|
||||
* target, touching: Instead of Execution.
|
||||
* targets: Rule Syntax.
|
||||
* targets without a file: Phony Targets.
|
||||
* targets, built-in special: Special Targets.
|
||||
* targets, empty: Empty Targets.
|
||||
* targets, force: Force Targets.
|
||||
* targets, introduction to: Rule Introduction.
|
||||
* targets, multiple: Multiple Targets.
|
||||
* targets, phony: Phony Targets.
|
||||
* terminal rule: Match-Anything Rules.
|
||||
* testing compilation: Testing.
|
||||
* tex: Catalogue of Rules.
|
||||
* tex: Implicit Variables.
|
||||
* texi2dvi: Catalogue of Rules.
|
||||
* texi2dvi: Implicit Variables.
|
||||
* Texinfo, rule to format: Catalogue of Rules.
|
||||
* tilde (~): Wildcards.
|
||||
* touching files: Instead of Execution.
|
||||
* undefined variables, warning message: Options Summary.
|
||||
* updating archive symbol directories: Archive Symbols.
|
||||
* updating makefiles: Remaking Makefiles.
|
||||
* value: Using Variables.
|
||||
* value, how a variable gets it: Values.
|
||||
* variable: Using Variables.
|
||||
* variable definition: Makefile Contents.
|
||||
* variables: Variables Simplify.
|
||||
* variables, $ in name: Computed Names.
|
||||
* variables, and implicit rule: Automatic.
|
||||
* variables, appending to: Appending.
|
||||
* variables, automatic: Automatic.
|
||||
* variables, command line: Overriding.
|
||||
* variables, command line, and recursion: Options/Recursion.
|
||||
* variables, computed names: Computed Names.
|
||||
* variables, defining verbatim: Defining.
|
||||
* variables, environment: Variables/Recursion.
|
||||
* variables, environment: Environment.
|
||||
* variables, exporting: Variables/Recursion.
|
||||
* variables, flavors: Flavors.
|
||||
* variables, how they get their values: Values.
|
||||
* variables, how to reference: Reference.
|
||||
* variables, loops in expansion: Flavors.
|
||||
* variables, modified reference: Substitution Refs.
|
||||
* variables, nested references: Computed Names.
|
||||
* variables, origin of: Origin Function.
|
||||
* variables, overriding: Override Directive.
|
||||
* variables, overriding with arguments: Overriding.
|
||||
* variables, recursively expanded: Flavors.
|
||||
* variables, setting: Setting.
|
||||
* variables, simply expanded: Flavors.
|
||||
* variables, spaces in values: Flavors.
|
||||
* variables, substituting suffix in: Substitution Refs.
|
||||
* variables, substitution reference: Substitution Refs.
|
||||
* variables, warning for undefined: Options Summary.
|
||||
* varying dependencies: Static Pattern.
|
||||
* verbatim variable definition: Defining.
|
||||
* vpath: Directory Search.
|
||||
* weave: Catalogue of Rules.
|
||||
* weave: Implicit Variables.
|
||||
* Web, rule to run: Catalogue of Rules.
|
||||
* what if: Instead of Execution.
|
||||
* whitespace, in variable values: Flavors.
|
||||
* whitespace, stripping: Text Functions.
|
||||
* wildcard: Wildcards.
|
||||
* wildcard pitfalls: Wildcard Pitfall.
|
||||
* wildcard, function: Filename Functions.
|
||||
* wildcard, in include: Include.
|
||||
* wildcard, in archive member: Archive Members.
|
||||
* words, extracting first: Filename Functions.
|
||||
* words, filtering: Text Functions.
|
||||
* words, filtering out: Text Functions.
|
||||
* words, finding number: Filename Functions.
|
||||
* words, iterating over: Foreach Function.
|
||||
* words, joining lists: Filename Functions.
|
||||
* words, removing duplicates: Text Functions.
|
||||
* words, selecting: Filename Functions.
|
||||
* writing rule commands: Commands.
|
||||
* writing rules: Rules.
|
||||
* yacc: Implicit Variables.
|
||||
* yacc: Catalogue of Rules.
|
||||
* Yacc, rule to run: Catalogue of Rules.
|
||||
|
||||
|
||||
File: make.info, Node: Name Index, Prev: Concept Index, Up: Top
|
||||
|
||||
Index of Functions, Variables, & Directives
|
||||
*******************************************
|
||||
|
||||
* Menu:
|
||||
|
||||
* $%: Automatic.
|
||||
* $(%D): Automatic.
|
||||
* $(%F): Automatic.
|
||||
* $(*D): Automatic.
|
||||
* $(*F): Automatic.
|
||||
* $(<D): Automatic.
|
||||
* $(<F): Automatic.
|
||||
* $(?D): Automatic.
|
||||
* $(?F): Automatic.
|
||||
* $(@D): Automatic.
|
||||
* $(@F): Automatic.
|
||||
* $(^D): Automatic.
|
||||
* $(^F): Automatic.
|
||||
* $*: Automatic.
|
||||
* $*, and static pattern: Static Usage.
|
||||
* $+: Automatic.
|
||||
* $<: Automatic.
|
||||
* $?: Automatic.
|
||||
* $@: Automatic.
|
||||
* $^: Automatic.
|
||||
* % (automatic variable): Automatic.
|
||||
* %D (automatic variable): Automatic.
|
||||
* %F (automatic variable): Automatic.
|
||||
* * (automatic variable), unsupported bizarre usage: Missing.
|
||||
* * (automatic variable): Automatic.
|
||||
* *D (automatic variable): Automatic.
|
||||
* *F (automatic variable): Automatic.
|
||||
* + (automatic variable): Automatic.
|
||||
* .DEFAULT: Last Resort.
|
||||
* .DEFAULT: Special Targets.
|
||||
* .DEFAULT, and empty commands: Empty Commands.
|
||||
* .DELETE_ON_ERROR: Errors.
|
||||
* .EXPORT_ALL_VARIABLES: Variables/Recursion.
|
||||
* .EXPORT_ALL_VARIABLES: Special Targets.
|
||||
* .IGNORE: Errors.
|
||||
* .IGNORE: Special Targets.
|
||||
* .PHONY: Special Targets.
|
||||
* .PHONY: Phony Targets.
|
||||
* .POSIX: Options/Recursion.
|
||||
* .PRECIOUS: Interrupts.
|
||||
* .PRECIOUS: Special Targets.
|
||||
* .SILENT: Special Targets.
|
||||
* .SILENT: Echoing.
|
||||
* .SUFFIXES: Special Targets.
|
||||
* .SUFFIXES: Suffix Rules.
|
||||
* /usr/gnu/include: Include.
|
||||
* /usr/include: Include.
|
||||
* /usr/local/include: Include.
|
||||
* < (automatic variable): Automatic.
|
||||
* <D (automatic variable): Automatic.
|
||||
* <F (automatic variable): Automatic.
|
||||
* ? (automatic variable): Automatic.
|
||||
* ?D (automatic variable): Automatic.
|
||||
* ?F (automatic variable): Automatic.
|
||||
* @ (automatic variable): Automatic.
|
||||
* @D (automatic variable): Automatic.
|
||||
* @F (automatic variable): Automatic.
|
||||
* addprefix: Filename Functions.
|
||||
* addsuffix: Filename Functions.
|
||||
* AR: Implicit Variables.
|
||||
* ARFLAGS: Implicit Variables.
|
||||
* AS: Implicit Variables.
|
||||
* ASFLAGS: Implicit Variables.
|
||||
* basename: Filename Functions.
|
||||
* CC: Implicit Variables.
|
||||
* CFLAGS: Implicit Variables.
|
||||
* CO: Implicit Variables.
|
||||
* COFLAGS: Implicit Variables.
|
||||
* CPP: Implicit Variables.
|
||||
* CPPFLAGS: Implicit Variables.
|
||||
* CTANGLE: Implicit Variables.
|
||||
* CWEAVE: Implicit Variables.
|
||||
* CXX: Implicit Variables.
|
||||
* CXXFLAGS: Implicit Variables.
|
||||
* define: Defining.
|
||||
* dir: Filename Functions.
|
||||
* else: Conditional Syntax.
|
||||
* endef: Defining.
|
||||
* endif: Conditional Syntax.
|
||||
* export: Variables/Recursion.
|
||||
* FC: Implicit Variables.
|
||||
* FFLAGS: Implicit Variables.
|
||||
* filter: Text Functions.
|
||||
* filter-out: Text Functions.
|
||||
* findstring: Text Functions.
|
||||
* firstword: Filename Functions.
|
||||
* foreach: Foreach Function.
|
||||
* GET: Implicit Variables.
|
||||
* GFLAGS: Implicit Variables.
|
||||
* GNUmakefile: Makefile Names.
|
||||
* ifdef: Conditional Syntax.
|
||||
* ifeq: Conditional Syntax.
|
||||
* ifndef: Conditional Syntax.
|
||||
* ifneq: Conditional Syntax.
|
||||
* include: Include.
|
||||
* join: Filename Functions.
|
||||
* LDFLAGS: Implicit Variables.
|
||||
* LEX: Implicit Variables.
|
||||
* LFLAGS: Implicit Variables.
|
||||
* MAKE: MAKE Variable.
|
||||
* MAKE: Flavors.
|
||||
* Makefile: Makefile Names.
|
||||
* makefile: Makefile Names.
|
||||
* MAKEFILES: Variables/Recursion.
|
||||
* MAKEFILES: MAKEFILES Variable.
|
||||
* MAKEFLAGS: Options/Recursion.
|
||||
* MAKEINFO: Implicit Variables.
|
||||
* MAKELEVEL: Variables/Recursion.
|
||||
* MAKELEVEL: Flavors.
|
||||
* MAKEOVERRIDES: Options/Recursion.
|
||||
* MFLAGS: Options/Recursion.
|
||||
* notdir: Filename Functions.
|
||||
* origin: Origin Function.
|
||||
* OUTPUT_OPTION: Catalogue of Rules.
|
||||
* override: Override Directive.
|
||||
* patsubst: Text Functions.
|
||||
* patsubst: Substitution Refs.
|
||||
* PC: Implicit Variables.
|
||||
* PFLAGS: Implicit Variables.
|
||||
* RFLAGS: Implicit Variables.
|
||||
* RM: Implicit Variables.
|
||||
* SHELL: Execution.
|
||||
* shell: Shell Function.
|
||||
* SHELL (command execution): Execution.
|
||||
* sort: Text Functions.
|
||||
* strip: Text Functions.
|
||||
* subst: Text Functions.
|
||||
* subst: Multiple Targets.
|
||||
* suffix: Filename Functions.
|
||||
* SUFFIXES: Suffix Rules.
|
||||
* TANGLE: Implicit Variables.
|
||||
* TEX: Implicit Variables.
|
||||
* TEXI2DVI: Implicit Variables.
|
||||
* unexport: Variables/Recursion.
|
||||
* vpath: Directory Search.
|
||||
* VPATH: General Search.
|
||||
* vpath: Selective Search.
|
||||
* VPATH: Directory Search.
|
||||
* WEAVE: Implicit Variables.
|
||||
* wildcard: Filename Functions.
|
||||
* wildcard: Wildcard Function.
|
||||
* word: Filename Functions.
|
||||
* words: Filename Functions.
|
||||
* YACC: Implicit Variables.
|
||||
* YACCR: Implicit Variables.
|
||||
* YFLAGS: Implicit Variables.
|
||||
* ^ (automatic variable): Automatic.
|
||||
* ^D (automatic variable): Automatic.
|
||||
* ^F (automatic variable): Automatic.
|
||||
|
||||
|
||||
@ -1,302 +0,0 @@
|
||||
.TH MAKE 1L "22 August 1989" "GNU" "LOCAL USER COMMANDS"
|
||||
.SH NAME
|
||||
make \- GNU make utility to maintain groups of programs
|
||||
.SH SYNOPSIS
|
||||
.B "make "
|
||||
[
|
||||
.B \-f
|
||||
makefile ] [ option ] ...
|
||||
target ...
|
||||
.SH WARNING
|
||||
This man paage is an extract of the documentation of
|
||||
.I GNU make .
|
||||
It is updated only occasionally, because the GNU project does not use nroff.
|
||||
For complete, current documentation, refer to the Info file
|
||||
.B make
|
||||
or the DVI file
|
||||
.B make.dvi
|
||||
which are made from the Texinfo source file
|
||||
.BR make.texinfo .
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
The purpose of the
|
||||
.I make
|
||||
utility is to determine automatically which
|
||||
pieces of a large program need to be recompiled, and issue the commands to
|
||||
recompile them.
|
||||
This manual describes the GNU implementation of
|
||||
.IR make ,
|
||||
which was written by Richard Stallman and Roland McGrath.
|
||||
Our examples show C programs, since they are most common, but you can use
|
||||
.I make
|
||||
with any programming language whose compiler can be run with a
|
||||
shell command.
|
||||
In fact,
|
||||
.I make
|
||||
is not limited to programs.
|
||||
You can use it to describe any task where some files must be
|
||||
updated automatically from others whenever the others change.
|
||||
.LP
|
||||
To prepare to use
|
||||
.IR make ,
|
||||
you must write a file called the
|
||||
.I makefile
|
||||
that describes the relationships among files in your program, and the
|
||||
states the commands for updating each file.
|
||||
In a program, typically the executable file is updated from object
|
||||
files, which are in turn made by compiling source files.
|
||||
.LP
|
||||
Once a suitable makefile exists, each time you change some source files,
|
||||
this simple shell command:
|
||||
.sp 1
|
||||
.RS
|
||||
.B make
|
||||
.RE
|
||||
.sp 1
|
||||
suffices to perform all necessary recompilations.
|
||||
The
|
||||
.I make
|
||||
program uses the makefile data base and the last-modification times
|
||||
of the files to decide which of the files need to be updated.
|
||||
For each of those files, it issues the commands recorded in the data base.
|
||||
.LP
|
||||
.I make
|
||||
executes commands in the
|
||||
.I makefile
|
||||
to update
|
||||
one or more target
|
||||
.IR names ,
|
||||
where
|
||||
.I name
|
||||
is typically a program.
|
||||
If no
|
||||
.B \-f
|
||||
option is present,
|
||||
.I make
|
||||
will look for the makefiles
|
||||
.IR GNUmakefile ,
|
||||
.IR makefile ,
|
||||
and
|
||||
.IR Makefile ,
|
||||
in that order.
|
||||
.LP
|
||||
Normally you should call your makefile either
|
||||
.I makefile
|
||||
or
|
||||
.IR Makefile .
|
||||
(We recommend
|
||||
.I Makefile
|
||||
because it appears prominently near the beginning of a directory
|
||||
listing, right near other important files such as
|
||||
.IR README .)
|
||||
The first name checked,
|
||||
.IR GNUmakefile ,
|
||||
is not recommended for most makefiles.
|
||||
You should use this name if you have a makefile that is specific to GNU
|
||||
.IR make ,
|
||||
and will not be understood by other versions of
|
||||
.IR make .
|
||||
If
|
||||
.I makefile
|
||||
is `\-', the standard input is read.
|
||||
.LP
|
||||
.I make
|
||||
updates a target if it depends on prerequisite files
|
||||
that have been modified since the target was last modified,
|
||||
or if the target does not exist.
|
||||
.SH OPTIONS
|
||||
.sp 1
|
||||
.TP 0.5i
|
||||
.B \-b
|
||||
.TP 0.5i
|
||||
.B \-m
|
||||
These options are ignored for compatibility with other versions of
|
||||
.IR make .
|
||||
.TP 0.5i
|
||||
.BI "\-C " dir
|
||||
Change to directory
|
||||
.I dir
|
||||
before reading the makefiles or doing anything else.
|
||||
If multiple
|
||||
.B \-C
|
||||
options are specified, each is interpreted relative to the
|
||||
previous one:
|
||||
.BR "\-C " /
|
||||
.BR "\-C " etc
|
||||
is equivalent to
|
||||
.BR "\-C " /etc.
|
||||
This is typically used with recursive invocations of
|
||||
.IR make .
|
||||
.TP 0.5i
|
||||
.B \-d
|
||||
Print debugging information in addition to normal processing.
|
||||
The debugging information says which files are being considered for
|
||||
remaking, which file-times are being compared and with what results,
|
||||
which files actually need to be remade, which implicit rules are
|
||||
considered and which are applied---everything interesting about how
|
||||
.I make
|
||||
decides what to do.
|
||||
.TP 0.5i
|
||||
.B \-e
|
||||
Give variables taken from the environment precedence
|
||||
over variables from makefiles.
|
||||
.TP 0.5i
|
||||
.BI "\-f " file
|
||||
Use
|
||||
.I file
|
||||
as a makefile.
|
||||
.TP 0.5i
|
||||
.B \-i
|
||||
Ignore all errors in commands executed to remake files.
|
||||
.TP 0.5i
|
||||
.BI "\-I " dir
|
||||
Specifies a directory
|
||||
.I dir
|
||||
to search for included makefiles.
|
||||
If several
|
||||
.B \-I
|
||||
options are used to specify several directories, the directories are
|
||||
searched in the order specified.
|
||||
Unlike the arguments to other flags of
|
||||
.IR make ,
|
||||
directories given with
|
||||
.B \-I
|
||||
flags may come directly after the flag:
|
||||
.BI \-I dir
|
||||
is allowed, as well as
|
||||
.BI "\-I " dir.
|
||||
This syntax is allowed for compatibility with the C
|
||||
preprocessor's
|
||||
.B \-I
|
||||
flag.
|
||||
.TP 0.5i
|
||||
.BI "\-j " jobs
|
||||
Specifies the number of jobs (commands) to run simultaneously.
|
||||
If there is more than one
|
||||
.B \-j
|
||||
option, the last one is effective.
|
||||
If the
|
||||
.B \-j
|
||||
option is given without an argument,
|
||||
.IR make
|
||||
will not limit the number of jobs that can run simultaneously.
|
||||
.TP 0.5i
|
||||
.B \-k
|
||||
Continue as much as possible after an error.
|
||||
While the target that failed, and those that depend on it, cannot
|
||||
be remade, the other dependencies of these targets can be processed
|
||||
all the same.
|
||||
.TP 0.5i
|
||||
.B \-l
|
||||
.TP 0.5i
|
||||
.BI "\-l " load
|
||||
Specifies that no new jobs (commands) should be started if there are
|
||||
others jobs running and the load average is at least
|
||||
.I load
|
||||
(a floating-point number).
|
||||
With no argument, removes a previous load limit.
|
||||
.TP 0.5i
|
||||
.B \-n
|
||||
Print the commands that would be executed, but do not execute them.
|
||||
.TP 0.5i
|
||||
.BI "\-o " file
|
||||
Do not remake the file
|
||||
.I file
|
||||
even if it is older than its dependencies, and do not remake anything
|
||||
on account of changes in
|
||||
.IR file .
|
||||
Essentially the file is treated as very old and its rules are ignored.
|
||||
.TP 0.5i
|
||||
.B \-p
|
||||
Print the data base (rules and variable values) that results from
|
||||
reading the makefiles; then execute as usual or as otherwise
|
||||
specified.
|
||||
This also prints the version information given by the
|
||||
.B \-v
|
||||
switch (see below).
|
||||
To print the data base without trying to remake any files, use
|
||||
.B make
|
||||
.B \-p
|
||||
.BI \-f /dev/null.
|
||||
.TP 0.5i
|
||||
.B \-q
|
||||
``Question mode''.
|
||||
Do not run any commands, or print anything; just return an exit status
|
||||
that is zero if the specified targets are already up to date, nonzero
|
||||
otherwise.
|
||||
.TP 0.5i
|
||||
.B \-r
|
||||
Eliminate use of the built-in implicit rules.
|
||||
Also clear out the default list of suffixes for suffix rules.
|
||||
.TP 0.5i
|
||||
.B \-s
|
||||
Silent operation; do not print the commands as they are executed.
|
||||
.TP 0.5i
|
||||
.B \-S
|
||||
Cancel the effect of the
|
||||
.B \-k
|
||||
option.
|
||||
This is never necessary except in a recursive
|
||||
.I make
|
||||
where
|
||||
.B \-k
|
||||
might be inherited from the top-level
|
||||
.I make
|
||||
via MAKEFLAGS or if you set
|
||||
.B \-k
|
||||
in MAKEFLAGS in your environment.
|
||||
.TP 0.5i
|
||||
.B \-t
|
||||
Touch files (mark them up to date without really changing them)
|
||||
instead of running their commands.
|
||||
This is used to pretend that the commands were done, in order to fool
|
||||
future invocations of
|
||||
.IR make .
|
||||
.TP 0.5i
|
||||
.B \-v
|
||||
Print the version of the
|
||||
.I make
|
||||
program plus a copyright, a list of authors and a notice that there
|
||||
is no warranty.
|
||||
After this information is printed, processing continues normally.
|
||||
To get this information without doing anything else, use
|
||||
.B make
|
||||
.B \-v
|
||||
.BI \-f /dev/null.
|
||||
.TP 0.5i
|
||||
.B \-w
|
||||
Print a message containing the working directory
|
||||
before and after other processing.
|
||||
This may be useful for tracking down errors from complicated nests of
|
||||
recursive
|
||||
.I make
|
||||
commands.
|
||||
.TP 0.5i
|
||||
.BI "\-W " file
|
||||
Pretend that the target
|
||||
.I file
|
||||
has just been modified.
|
||||
When used with the
|
||||
.B \-n
|
||||
flag, this shows you what would happen if you were to modify that file.
|
||||
Without
|
||||
.BR \-n ,
|
||||
it is almost the same as running a
|
||||
.I touch
|
||||
command on the given file before running
|
||||
.IR make ,
|
||||
except that the modification time is changed only in the imagination of
|
||||
.IR make .
|
||||
.SH "SEE ALSO"
|
||||
.PD 0
|
||||
.TP 2.0i
|
||||
/usr/local/doc/gnumake.dvi
|
||||
.I
|
||||
The GNU Make Manual
|
||||
.PD
|
||||
.SH BUGS
|
||||
See the chapter `Problems and Bugs' in
|
||||
.I "The GNU Make Manual" .
|
||||
.SH AUTHOR
|
||||
This manual page contributed by Dennis Morse of Stanford University.
|
||||
It has been reworked by Roland McGrath.
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,118 +0,0 @@
|
||||
\chapentry {Overview of \code {make}}{1}{1}
|
||||
\secentry {How to Read This Manual}{1}{1}{1}
|
||||
\secentry {Problems and Bugs}{1}{2}{2}
|
||||
\chapentry {An Introduction to Makefiles}{2}{5}
|
||||
\secentry {What a Rule Looks Like}{2}{1}{5}
|
||||
\secentry {A Simple Makefile}{2}{2}{6}
|
||||
\secentry {How \code {make} Processes a Makefile}{2}{3}{8}
|
||||
\secentry {Variables Make Makefiles Simpler}{2}{4}{9}
|
||||
\secentry {Letting \code {make} Deduce the Commands}{2}{5}{10}
|
||||
\secentry {Another Style of Makefile}{2}{6}{11}
|
||||
\secentry {Rules for Cleaning the Directory}{2}{7}{12}
|
||||
\chapentry {Writing Makefiles}{3}{13}
|
||||
\secentry {What Makefiles Contain}{3}{1}{13}
|
||||
\secentry {What Name to Give Your Makefile}{3}{2}{14}
|
||||
\secentry {Including Other Makefiles}{3}{3}{14}
|
||||
\secentry {The Variable \code {MAKEFILES}}{3}{4}{16}
|
||||
\secentry {How Makefiles Are Remade}{3}{5}{16}
|
||||
\secentry {Overriding Part of Another Makefile}{3}{6}{18}
|
||||
\chapentry {Writing Rules}{4}{19}
|
||||
\secentry {Rule Syntax}{4}{1}{19}
|
||||
\secentry {Using Wildcard Characters in File Names}{4}{2}{20}
|
||||
\subsecentry {Wildcard Examples}{4}{2}{1}{21}
|
||||
\subsecentry {Pitfalls of Using Wildcards}{4}{2}{2}{22}
|
||||
\subsecentry {The Function \code {wildcard}}{4}{2}{3}{22}
|
||||
\secentry {Searching Directories for Dependencies}{4}{3}{23}
|
||||
\subsecentry {\code {VPATH}: Search Path for All Dependencies}{4}{3}{1}{23}
|
||||
\subsecentry {The \code {vpath} Directive}{4}{3}{2}{24}
|
||||
\subsecentry {Writing Shell Commands with Directory Search}{4}{3}{3}{26}
|
||||
\subsecentry {Directory Search and Implicit Rules}{4}{3}{4}{27}
|
||||
\subsecentry {Directory Search for Link Libraries}{4}{3}{5}{27}
|
||||
\secentry {Phony Targets}{4}{4}{28}
|
||||
\secentry {Rules without Commands or Dependencies}{4}{5}{30}
|
||||
\secentry {Empty Target Files to Record Events}{4}{6}{30}
|
||||
\secentry {Special Built-in Target Names}{4}{7}{31}
|
||||
\secentry {Multiple Targets in a Rule}{4}{8}{32}
|
||||
\secentry {Multiple Rules for One Target}{4}{9}{33}
|
||||
\secentry {Static Pattern Rules}{4}{10}{34}
|
||||
\subsecentry {Syntax of Static Pattern Rules}{4}{10}{1}{34}
|
||||
\subsecentry {Static Pattern Rules versus Implicit Rules}{4}{10}{2}{36}
|
||||
\secentry {Double-Colon Rules}{4}{11}{37}
|
||||
\secentry {Generating Dependencies Automatically}{4}{12}{37}
|
||||
\chapentry {Writing the Commands in Rules}{5}{41}
|
||||
\secentry {Command Echoing}{5}{1}{41}
|
||||
\secentry {Command Execution}{5}{2}{42}
|
||||
\secentry {Parallel Execution}{5}{3}{42}
|
||||
\secentry {Errors in Commands}{5}{4}{44}
|
||||
\secentry {Interrupting or Killing \code {make}}{5}{5}{45}
|
||||
\secentry {Recursive Use of \code {make}}{5}{6}{46}
|
||||
\subsecentry {How the \code {MAKE} Variable Works}{5}{6}{1}{46}
|
||||
\subsecentry {Communicating Variables to a Sub-\code {make}}{5}{6}{2}{47}
|
||||
\subsecentry {Communicating Options to a Sub-\code {make}}{5}{6}{3}{50}
|
||||
\subsecentry {The \samp {--print-directory} Option}{5}{6}{4}{52}
|
||||
\secentry {Defining Canned Command Sequences}{5}{7}{52}
|
||||
\secentry {Using Empty Commands}{5}{8}{54}
|
||||
\chapentry {How to Use Variables}{6}{55}
|
||||
\secentry {Basics of Variable References}{6}{1}{55}
|
||||
\secentry {The Two Flavors of Variables}{6}{2}{56}
|
||||
\secentry {Advanced Features for Reference to Variables}{6}{3}{59}
|
||||
\subsecentry {Substitution References}{6}{3}{1}{59}
|
||||
\subsecentry {Computed Variable Names}{6}{3}{2}{60}
|
||||
\secentry {How Variables Get Their Values}{6}{4}{63}
|
||||
\secentry {Setting Variables}{6}{5}{63}
|
||||
\secentry {Appending More Text to Variables}{6}{6}{64}
|
||||
\secentry {The \code {override} Directive}{6}{7}{66}
|
||||
\secentry {Defining Variables Verbatim}{6}{8}{67}
|
||||
\secentry {Variables from the Environment}{6}{9}{68}
|
||||
\chapentry {Conditional Parts of Makefiles}{7}{71}
|
||||
\secentry {Example of a Conditional}{7}{1}{71}
|
||||
\secentry {Syntax of Conditionals}{7}{2}{72}
|
||||
\secentry {Conditionals that Test Flags}{7}{3}{75}
|
||||
\chapentry {Functions for Transforming Text}{8}{77}
|
||||
\secentry {Function Call Syntax}{8}{1}{77}
|
||||
\secentry {Functions for String Substitution and Analysis}{8}{2}{78}
|
||||
\secentry {Functions for File Names}{8}{3}{81}
|
||||
\secentry {The \code {foreach} Function}{8}{4}{83}
|
||||
\secentry {The \code {origin} Function}{8}{5}{85}
|
||||
\secentry {The \code {shell} Function}{8}{6}{87}
|
||||
\chapentry {How to Run \code {make}}{9}{89}
|
||||
\secentry {Arguments to Specify the Makefile}{9}{1}{89}
|
||||
\secentry {Arguments to Specify the Goals}{9}{2}{90}
|
||||
\secentry {Instead of Executing the Commands}{9}{3}{91}
|
||||
\secentry {Avoiding Recompilation of Some Files}{9}{4}{93}
|
||||
\secentry {Overriding Variables}{9}{5}{94}
|
||||
\secentry {Testing the Compilation of a Program}{9}{6}{95}
|
||||
\secentry {Summary of Options}{9}{7}{95}
|
||||
\chapentry {Using Implicit Rules}{10}{101}
|
||||
\secentry {Using Implicit Rules}{10}{1}{101}
|
||||
\secentry {Catalogue of Implicit Rules}{10}{2}{103}
|
||||
\secentry {Variables Used by Implicit Rules}{10}{3}{106}
|
||||
\secentry {Chains of Implicit Rules}{10}{4}{108}
|
||||
\secentry {Defining and Redefining Pattern Rules}{10}{5}{109}
|
||||
\subsecentry {Introduction to Pattern Rules}{10}{5}{1}{110}
|
||||
\subsecentry {Pattern Rule Examples}{10}{5}{2}{111}
|
||||
\subsecentry {Automatic Variables}{10}{5}{3}{112}
|
||||
\subsecentry {How Patterns Match}{10}{5}{4}{114}
|
||||
\subsecentry {Match-Anything Pattern Rules}{10}{5}{5}{115}
|
||||
\subsecentry {Canceling Implicit Rules}{10}{5}{6}{116}
|
||||
\secentry {Defining Last-Resort Default Rules}{10}{6}{116}
|
||||
\secentry {Old-Fashioned Suffix Rules}{10}{7}{117}
|
||||
\secentry {Implicit Rule Search Algorithm}{10}{8}{119}
|
||||
\chapentry {Using \code {make} to Update Archive Files}{11}{121}
|
||||
\secentry {Archive Members as Targets}{11}{1}{121}
|
||||
\secentry {Implicit Rule for Archive Member Targets}{11}{2}{122}
|
||||
\subsecentry {Updating Archive Symbol Directories}{11}{2}{1}{123}
|
||||
\secentry {Dangers When Using Archives}{11}{3}{123}
|
||||
\secentry {Suffix Rules for Archive Files}{11}{4}{124}
|
||||
\chapentry {Features of GNU \code {make}}{12}{125}
|
||||
\chapentry {Incompatibilities and Missing Features}{13}{129}
|
||||
\chapentry {Makefile Conventions}{14}{131}
|
||||
\secentry {General Conventions for Makefiles}{14}{1}{131}
|
||||
\secentry {Utilities in Makefiles}{14}{2}{132}
|
||||
\secentry {Standard Targets for Users}{14}{3}{133}
|
||||
\secentry {Variables for Specifying Commands}{14}{4}{136}
|
||||
\secentry {Variables for Installation Directories}{14}{5}{138}
|
||||
\chapentry {Quick Reference}{Appendix{} \char65}{143}
|
||||
\chapentry {Complex Makefile Example}{Appendix{} \char66}{149}
|
||||
\unnumbchapentry {Index of Concepts}{155}
|
||||
\unnumbchapentry {Index of Functions, Variables, & Directives}{165}
|
||||
@ -1,739 +0,0 @@
|
||||
/* Miscellaneous generic support functions for GNU Make.
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "dep.h"
|
||||
|
||||
|
||||
/* Compare strings *S1 and *S2.
|
||||
Return negative if the first is less, positive if it is greater,
|
||||
zero if they are equal. */
|
||||
|
||||
int
|
||||
alpha_compare (const void *elem1, const void *elem2)
|
||||
{
|
||||
char **s1 = (char **)elem1;
|
||||
char **s2 = (char **)elem2;
|
||||
if (**s1 != **s2)
|
||||
return **s1 - **s2;
|
||||
return strcmp (*s1, *s2);
|
||||
}
|
||||
|
||||
/* Discard each backslash-newline combination from LINE.
|
||||
Backslash-backslash-newline combinations become backslash-newlines.
|
||||
This is done by copying the text at LINE into itself. */
|
||||
|
||||
void
|
||||
collapse_continuations (line)
|
||||
char *line;
|
||||
{
|
||||
register char *in, *out, *p;
|
||||
register int backslash;
|
||||
register unsigned int bs_write;
|
||||
|
||||
in = index (line, '\n');
|
||||
if (in == 0)
|
||||
return;
|
||||
|
||||
out = in;
|
||||
if (out > line)
|
||||
while (out[-1] == '\\')
|
||||
--out;
|
||||
|
||||
while (*in != '\0')
|
||||
{
|
||||
/* BS_WRITE gets the number of quoted backslashes at
|
||||
the end just before IN, and BACKSLASH gets nonzero
|
||||
if the next character is quoted. */
|
||||
backslash = 0;
|
||||
bs_write = 0;
|
||||
for (p = in - 1; p >= line && *p == '\\'; --p)
|
||||
{
|
||||
if (backslash)
|
||||
++bs_write;
|
||||
backslash = !backslash;
|
||||
|
||||
/* It should be impossible to go back this far without exiting,
|
||||
but if we do, we can't get the right answer. */
|
||||
if (in == out - 1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Output the appropriate number of backslashes. */
|
||||
while (bs_write-- > 0)
|
||||
*out++ = '\\';
|
||||
|
||||
/* Skip the newline. */
|
||||
++in;
|
||||
|
||||
/* If the newline is quoted, discard following whitespace
|
||||
and any preceding whitespace; leave just one space. */
|
||||
if (backslash)
|
||||
{
|
||||
in = next_token (in);
|
||||
while (out > line && isblank (out[-1]))
|
||||
--out;
|
||||
*out++ = ' ';
|
||||
}
|
||||
else
|
||||
/* If the newline isn't quoted, put it in the output. */
|
||||
*out++ = '\n';
|
||||
|
||||
/* Now copy the following line to the output.
|
||||
Stop when we find backslashes followed by a newline. */
|
||||
while (*in != '\0')
|
||||
if (*in == '\\')
|
||||
{
|
||||
p = in + 1;
|
||||
while (*p == '\\')
|
||||
++p;
|
||||
if (*p == '\n')
|
||||
{
|
||||
in = p;
|
||||
break;
|
||||
}
|
||||
while (in < p)
|
||||
*out++ = *in++;
|
||||
}
|
||||
else
|
||||
*out++ = *in++;
|
||||
}
|
||||
|
||||
*out = '\0';
|
||||
}
|
||||
|
||||
|
||||
/* Remove comments from LINE.
|
||||
This is done by copying the text at LINE onto itself. */
|
||||
|
||||
void
|
||||
remove_comments (line)
|
||||
char *line;
|
||||
{
|
||||
char *comment;
|
||||
|
||||
comment = find_char_unquote (line, "#", 0);
|
||||
|
||||
if (comment != 0)
|
||||
/* Cut off the line at the #. */
|
||||
*comment = '\0';
|
||||
}
|
||||
|
||||
/* Print N spaces (used by DEBUGPR for target-depth). */
|
||||
|
||||
void
|
||||
print_spaces (n)
|
||||
register unsigned int n;
|
||||
{
|
||||
while (n-- > 0)
|
||||
putchar (' ');
|
||||
}
|
||||
|
||||
|
||||
/* Return a newly-allocated string whose contents
|
||||
concatenate those of s1, s2, s3. */
|
||||
|
||||
char *
|
||||
concat (s1, s2, s3)
|
||||
register char *s1, *s2, *s3;
|
||||
{
|
||||
register unsigned int len1, len2, len3;
|
||||
register char *result;
|
||||
|
||||
len1 = *s1 != '\0' ? strlen (s1) : 0;
|
||||
len2 = *s2 != '\0' ? strlen (s2) : 0;
|
||||
len3 = *s3 != '\0' ? strlen (s3) : 0;
|
||||
|
||||
result = (char *) xmalloc (len1 + len2 + len3 + 1);
|
||||
|
||||
if (*s1 != '\0')
|
||||
bcopy (s1, result, len1);
|
||||
if (*s2 != '\0')
|
||||
bcopy (s2, result + len1, len2);
|
||||
if (*s3 != '\0')
|
||||
bcopy (s3, result + len1 + len2, len3);
|
||||
*(result + len1 + len2 + len3) = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Print a message on stdout. */
|
||||
|
||||
void
|
||||
message (s1, s2, s3, s4, s5, s6)
|
||||
char *s1, *s2, *s3, *s4, *s5, *s6;
|
||||
{
|
||||
if (makelevel == 0)
|
||||
printf ("%s: ", program);
|
||||
else
|
||||
printf ("%s[%u]: ", program, makelevel);
|
||||
printf (s1, s2, s3, s4, s5, s6);
|
||||
putchar ('\n');
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
/* Print an error message and exit. */
|
||||
|
||||
/* VARARGS1 */
|
||||
void
|
||||
fatal (s1, s2, s3, s4, s5, s6)
|
||||
char *s1, *s2, *s3, *s4, *s5, *s6;
|
||||
{
|
||||
if (makelevel == 0)
|
||||
fprintf (stderr, "%s: *** ", program);
|
||||
else
|
||||
fprintf (stderr, "%s[%u]: *** ", program, makelevel);
|
||||
fprintf (stderr, s1, s2, s3, s4, s5, s6);
|
||||
fputs (". Stop.\n", stderr);
|
||||
|
||||
die (2);
|
||||
}
|
||||
|
||||
/* Print error message. `s1' is printf control string, `s2' is arg for it. */
|
||||
|
||||
/* VARARGS1 */
|
||||
|
||||
void
|
||||
error (s1, s2, s3, s4, s5, s6)
|
||||
char *s1, *s2, *s3, *s4, *s5, *s6;
|
||||
{
|
||||
if (makelevel == 0)
|
||||
fprintf (stderr, "%s: ", program);
|
||||
else
|
||||
fprintf (stderr, "%s[%u]: ", program, makelevel);
|
||||
fprintf (stderr, s1, s2, s3, s4, s5, s6);
|
||||
putc ('\n', stderr);
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
void
|
||||
makefile_error (file, lineno, s1, s2, s3, s4, s5, s6)
|
||||
char *file;
|
||||
unsigned int lineno;
|
||||
char *s1, *s2, *s3, *s4, *s5, *s6;
|
||||
{
|
||||
fprintf (stderr, "%s:%u: ", file, lineno);
|
||||
fprintf (stderr, s1, s2, s3, s4, s5, s6);
|
||||
putc ('\n', stderr);
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
void
|
||||
makefile_fatal (file, lineno, s1, s2, s3, s4, s5, s6)
|
||||
char *file;
|
||||
unsigned int lineno;
|
||||
char *s1, *s2, *s3, *s4, *s5, *s6;
|
||||
{
|
||||
fprintf (stderr, "%s:%u: *** ", file, lineno);
|
||||
fprintf (stderr, s1, s2, s3, s4, s5, s6);
|
||||
fputs (". Stop.\n", stderr);
|
||||
|
||||
die (2);
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
|
||||
#undef strerror
|
||||
|
||||
char *
|
||||
strerror (errnum)
|
||||
int errnum;
|
||||
{
|
||||
extern int errno, sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
static char buf[] = "Unknown error 12345678901234567890";
|
||||
|
||||
if (errno < sys_nerr)
|
||||
return sys_errlist[errnum];
|
||||
|
||||
sprintf (buf, "Unknown error %d", errnum);
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Print an error message from errno. */
|
||||
|
||||
void
|
||||
perror_with_name (str, name)
|
||||
char *str, *name;
|
||||
{
|
||||
error ("%s%s: %s", str, name, strerror (errno));
|
||||
}
|
||||
|
||||
/* Print an error message from errno and exit. */
|
||||
|
||||
void
|
||||
pfatal_with_name (name)
|
||||
char *name;
|
||||
{
|
||||
fatal ("%s: %s", name, strerror (errno));
|
||||
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* Like malloc but get fatal error if memory is exhausted. */
|
||||
|
||||
#undef xmalloc
|
||||
#undef xrealloc
|
||||
|
||||
char *
|
||||
xmalloc (size)
|
||||
unsigned int size;
|
||||
{
|
||||
char *result = (char *) malloc (size);
|
||||
if (result == 0)
|
||||
fatal ("virtual memory exhausted");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
xrealloc (ptr, size)
|
||||
char *ptr;
|
||||
unsigned int size;
|
||||
{
|
||||
char *result = (char *) realloc (ptr, size);
|
||||
if (result == 0)
|
||||
fatal ("virtual memory exhausted");
|
||||
return result;
|
||||
}
|
||||
|
||||
char *
|
||||
savestring (str, length)
|
||||
char *str;
|
||||
unsigned int length;
|
||||
{
|
||||
register char *out = (char *) xmalloc (length + 1);
|
||||
if (length > 0)
|
||||
bcopy (str, out, length);
|
||||
out[length] = '\0';
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Search string BIG (length BLEN) for an occurrence of
|
||||
string SMALL (length SLEN). Return a pointer to the
|
||||
beginning of the first occurrence, or return nil if none found. */
|
||||
|
||||
char *
|
||||
sindex (big, blen, small, slen)
|
||||
char *big;
|
||||
unsigned int blen;
|
||||
char *small;
|
||||
unsigned int slen;
|
||||
{
|
||||
register unsigned int b;
|
||||
|
||||
if (blen < 1)
|
||||
blen = strlen (big);
|
||||
if (slen < 1)
|
||||
slen = strlen (small);
|
||||
|
||||
for (b = 0; b < blen; ++b)
|
||||
if (big[b] == *small && !strncmp (&big[b + 1], small + 1, slen - 1))
|
||||
return (&big[b]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Limited INDEX:
|
||||
Search through the string STRING, which ends at LIMIT, for the character C.
|
||||
Returns a pointer to the first occurrence, or nil if none is found.
|
||||
Like INDEX except that the string searched ends where specified
|
||||
instead of at the first null. */
|
||||
|
||||
char *
|
||||
lindex (s, limit, c)
|
||||
register char *s, *limit;
|
||||
int c;
|
||||
{
|
||||
while (s < limit)
|
||||
if (*s++ == c)
|
||||
return s - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the address of the first whitespace or null in the string S. */
|
||||
|
||||
char *
|
||||
end_of_token (s)
|
||||
char *s;
|
||||
{
|
||||
while (*s != '\0' && !isblank (*s))
|
||||
++s;
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return the address of the first nonwhitespace or null in the string S. */
|
||||
|
||||
char *
|
||||
next_token (s)
|
||||
char *s;
|
||||
{
|
||||
register char *p = s;
|
||||
|
||||
while (isblank (*p))
|
||||
++p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Find the next token in PTR; return the address of it, and store the
|
||||
length of the token into *LENGTHPTR if LENGTHPTR is not nil. */
|
||||
|
||||
char *
|
||||
find_next_token (ptr, lengthptr)
|
||||
char **ptr;
|
||||
unsigned int *lengthptr;
|
||||
{
|
||||
char *p = next_token (*ptr);
|
||||
char *end;
|
||||
|
||||
if (*p == '\0')
|
||||
return 0;
|
||||
|
||||
*ptr = end = end_of_token (p);
|
||||
if (lengthptr != 0)
|
||||
*lengthptr = end - p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Copy a chain of `struct dep', making a new chain
|
||||
with the same contents as the old one. */
|
||||
|
||||
struct dep *
|
||||
copy_dep_chain (d)
|
||||
register struct dep *d;
|
||||
{
|
||||
register struct dep *c;
|
||||
struct dep *firstnew = 0;
|
||||
struct dep *lastnew;
|
||||
|
||||
while (d != 0)
|
||||
{
|
||||
c = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
bcopy ((char *) d, (char *) c, sizeof (struct dep));
|
||||
if (c->name != 0)
|
||||
c->name = savestring (c->name, strlen (c->name));
|
||||
c->next = 0;
|
||||
if (firstnew == 0)
|
||||
firstnew = lastnew = c;
|
||||
else
|
||||
lastnew = lastnew->next = c;
|
||||
|
||||
d = d->next;
|
||||
}
|
||||
|
||||
return firstnew;
|
||||
}
|
||||
|
||||
#ifdef iAPX286
|
||||
/* The losing compiler on this machine can't handle this macro. */
|
||||
|
||||
char *
|
||||
dep_name (dep)
|
||||
struct dep *dep;
|
||||
{
|
||||
return dep->name == 0 ? dep->file->name : dep->name;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
|
||||
#ifdef POSIX
|
||||
|
||||
/* Hopefully if a system says it's POSIX.1 and has the setuid and setgid
|
||||
functions, they work as POSIX.1 says. Some systems (Alpha OSF/1 1.2,
|
||||
for example) which claim to be POSIX.1 also have the BSD setreuid and
|
||||
setregid functions, but they don't work as in BSD and only the POSIX.1
|
||||
way works. */
|
||||
|
||||
#undef HAVE_SETREUID
|
||||
#undef HAVE_SETREGID
|
||||
|
||||
#else /* Not POSIX. */
|
||||
|
||||
/* Some POSIX.1 systems have the seteuid and setegid functions. In a
|
||||
POSIX-like system, they are the best thing to use. However, some
|
||||
non-POSIX systems have them too but they do not work in the POSIX style
|
||||
and we must use setreuid and setregid instead. */
|
||||
|
||||
#undef HAVE_SETEUID
|
||||
#undef HAVE_SETEGID
|
||||
|
||||
#endif /* POSIX. */
|
||||
|
||||
#ifndef HAVE_UNISTD_H
|
||||
extern int getuid (), getgid (), geteuid (), getegid ();
|
||||
extern int setuid (), setgid ();
|
||||
#ifdef HAVE_SETEUID
|
||||
extern int seteuid ();
|
||||
#else
|
||||
#ifdef HAVE_SETREUID
|
||||
extern int setreuid ();
|
||||
#endif /* Have setreuid. */
|
||||
#endif /* Have seteuid. */
|
||||
#ifdef HAVE_SETEGID
|
||||
extern int setegid ();
|
||||
#else
|
||||
#ifdef HAVE_SETREGID
|
||||
extern int setregid ();
|
||||
#endif /* Have setregid. */
|
||||
#endif /* Have setegid. */
|
||||
#endif /* No <unistd.h>. */
|
||||
|
||||
/* Keep track of the user and group IDs for user- and make- access. */
|
||||
static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1;
|
||||
#define access_inited (user_uid != -1)
|
||||
static enum { make, user } current_access;
|
||||
|
||||
|
||||
/* Under -d, write a message describing the current IDs. */
|
||||
|
||||
static void
|
||||
log_access (flavor)
|
||||
char *flavor;
|
||||
{
|
||||
if (! debug_flag)
|
||||
return;
|
||||
|
||||
/* All the other debugging messages go to stdout,
|
||||
but we write this one to stderr because it might be
|
||||
run in a child fork whose stdout is piped. */
|
||||
|
||||
fprintf (stderr, "%s access: user %d (real %d), group %d (real %d)\n",
|
||||
flavor, geteuid (), getuid (), getegid (), getgid ());
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_access ()
|
||||
{
|
||||
user_uid = getuid ();
|
||||
user_gid = getgid ();
|
||||
|
||||
make_uid = geteuid ();
|
||||
make_gid = getegid ();
|
||||
|
||||
/* Do these ever fail? */
|
||||
if (user_uid == -1 || user_gid == -1 || make_uid == -1 || make_gid == -1)
|
||||
pfatal_with_name ("get{e}[gu]id");
|
||||
|
||||
log_access ("Initialized");
|
||||
|
||||
current_access = make;
|
||||
}
|
||||
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
|
||||
/* Give the process appropriate permissions for access to
|
||||
user data (i.e., to stat files, or to spawn a child process). */
|
||||
void
|
||||
user_access ()
|
||||
{
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
|
||||
if (!access_inited)
|
||||
init_access ();
|
||||
|
||||
if (current_access == user)
|
||||
return;
|
||||
|
||||
/* We are in "make access" mode. This means that the effective user and
|
||||
group IDs are those of make (if it was installed setuid or setgid).
|
||||
We now want to set the effective user and group IDs to the real IDs,
|
||||
which are the IDs of the process that exec'd make. */
|
||||
|
||||
#ifdef HAVE_SETEUID
|
||||
|
||||
/* Modern systems have the seteuid/setegid calls which set only the
|
||||
effective IDs, which is ideal. */
|
||||
|
||||
if (seteuid (user_uid) < 0)
|
||||
pfatal_with_name ("user_access: seteuid");
|
||||
|
||||
#else /* Not HAVE_SETEUID. */
|
||||
|
||||
#ifndef HAVE_SETREUID
|
||||
|
||||
/* System V has only the setuid/setgid calls to set user/group IDs.
|
||||
There is an effective ID, which can be set by setuid/setgid.
|
||||
It can be set (unless you are root) only to either what it already is
|
||||
(returned by geteuid/getegid, now in make_uid/make_gid),
|
||||
the real ID (return by getuid/getgid, now in user_uid/user_gid),
|
||||
or the saved set ID (what the effective ID was before this set-ID
|
||||
executable (make) was exec'd). */
|
||||
|
||||
if (setuid (user_uid) < 0)
|
||||
pfatal_with_name ("user_access: setuid");
|
||||
|
||||
#else /* HAVE_SETREUID. */
|
||||
|
||||
/* In 4BSD, the setreuid/setregid calls set both the real and effective IDs.
|
||||
They may be set to themselves or each other. So you have two alternatives
|
||||
at any one time. If you use setuid/setgid, the effective will be set to
|
||||
the real, leaving only one alternative. Using setreuid/setregid, however,
|
||||
you can toggle between your two alternatives by swapping the values in a
|
||||
single setreuid or setregid call. */
|
||||
|
||||
if (setreuid (make_uid, user_uid) < 0)
|
||||
pfatal_with_name ("user_access: setreuid");
|
||||
|
||||
#endif /* Not HAVE_SETREUID. */
|
||||
#endif /* HAVE_SETEUID. */
|
||||
|
||||
#ifdef HAVE_SETEGID
|
||||
if (setegid (user_gid) < 0)
|
||||
pfatal_with_name ("user_access: setegid");
|
||||
#else
|
||||
#ifndef HAVE_SETREGID
|
||||
if (setgid (user_gid) < 0)
|
||||
pfatal_with_name ("user_access: setgid");
|
||||
#else
|
||||
if (setregid (make_gid, user_gid) < 0)
|
||||
pfatal_with_name ("user_access: setregid");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
current_access = user;
|
||||
|
||||
log_access ("User");
|
||||
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
}
|
||||
|
||||
/* Give the process appropriate permissions for access to
|
||||
make data (i.e., the load average). */
|
||||
void
|
||||
make_access ()
|
||||
{
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
|
||||
if (!access_inited)
|
||||
init_access ();
|
||||
|
||||
if (current_access == make)
|
||||
return;
|
||||
|
||||
/* See comments in user_access, above. */
|
||||
|
||||
#ifdef HAVE_SETEUID
|
||||
if (seteuid (make_uid) < 0)
|
||||
pfatal_with_name ("make_access: seteuid");
|
||||
#else
|
||||
#ifndef HAVE_SETREUID
|
||||
if (setuid (make_uid) < 0)
|
||||
pfatal_with_name ("make_access: setuid");
|
||||
#else
|
||||
if (setreuid (user_uid, make_uid) < 0)
|
||||
pfatal_with_name ("make_access: setreuid");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETEGID
|
||||
if (setegid (make_gid) < 0)
|
||||
pfatal_with_name ("make_access: setegid");
|
||||
#else
|
||||
#ifndef HAVE_SETREGID
|
||||
if (setgid (make_gid) < 0)
|
||||
pfatal_with_name ("make_access: setgid");
|
||||
#else
|
||||
if (setregid (user_gid, make_gid) < 0)
|
||||
pfatal_with_name ("make_access: setregid");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
current_access = make;
|
||||
|
||||
log_access ("Make");
|
||||
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
}
|
||||
|
||||
/* Give the process appropriate permissions for a child process.
|
||||
This is like user_access, but you can't get back to make_access. */
|
||||
void
|
||||
child_access ()
|
||||
{
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
|
||||
if (!access_inited)
|
||||
abort ();
|
||||
|
||||
/* Set both the real and effective UID and GID to the user's.
|
||||
They cannot be changed back to make's. */
|
||||
|
||||
#ifndef HAVE_SETREUID
|
||||
if (setuid (user_uid) < 0)
|
||||
pfatal_with_name ("child_access: setuid");
|
||||
#else
|
||||
if (setreuid (user_uid, user_uid) < 0)
|
||||
pfatal_with_name ("child_access: setreuid");
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SETREGID
|
||||
if (setgid (user_gid) < 0)
|
||||
pfatal_with_name ("child_access: setgid");
|
||||
#else
|
||||
if (setregid (user_gid, user_gid) < 0)
|
||||
pfatal_with_name ("child_access: setregid");
|
||||
#endif
|
||||
|
||||
log_access ("Child");
|
||||
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
}
|
||||
|
||||
#ifdef NEED_GET_PATH_MAX
|
||||
unsigned int
|
||||
get_path_max ()
|
||||
{
|
||||
static unsigned int value;
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
long int x = pathconf ("/", _PC_PATH_MAX);
|
||||
if (x > 0)
|
||||
value = x;
|
||||
else
|
||||
return MAXPATHLEN;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* On some systems, stat can return EINTR. */
|
||||
|
||||
int
|
||||
safe_stat (name, buf)
|
||||
char *name;
|
||||
struct stat *buf;
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef EINTR
|
||||
do
|
||||
#endif
|
||||
ret = stat (name, buf);
|
||||
#ifdef EINTR
|
||||
while (ret < 0 && errno == EINTR);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
#! /bin/sh
|
||||
# mkinstalldirs --- make directory hierarchy
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-05-16
|
||||
# Last modified: 1994-03-25
|
||||
# Public domain
|
||||
|
||||
errstatus=0
|
||||
|
||||
for file in ${1+"$@"} ; do
|
||||
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
|
||||
shift
|
||||
|
||||
pathcomp=
|
||||
for d in ${1+"$@"} ; do
|
||||
pathcomp="$pathcomp$d"
|
||||
case "$pathcomp" in
|
||||
-* ) pathcomp=./$pathcomp ;;
|
||||
esac
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
echo "mkdir $pathcomp" 1>&2
|
||||
mkdir "$pathcomp" || errstatus=$?
|
||||
fi
|
||||
|
||||
pathcomp="$pathcomp/"
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# mkinstalldirs ends here
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,270 +0,0 @@
|
||||
/* GNU Make remote job exportation interface to the Customs daemon.
|
||||
THIS CODE IS NOT SUPPORTED BY THE GNU PROJECT.
|
||||
Please do not send bug reports or questions about it to
|
||||
the Make maintainers.
|
||||
|
||||
Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "commands.h"
|
||||
#include "job.h"
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#define __STRICT_BSD__ /* Don't make conflicting declarations. */
|
||||
#include "customs.h"
|
||||
|
||||
|
||||
char *remote_description = "Customs";
|
||||
|
||||
/* File name of the Customs `export' client command.
|
||||
A full path name can be used to avoid some path-searching overhead. */
|
||||
#define EXPORT_COMMAND "/usr/local/bin/export"
|
||||
|
||||
/* ExportPermit gotten by start_remote_job_p, and used by start_remote_job. */
|
||||
static ExportPermit permit;
|
||||
|
||||
/* Normalized path name of the current directory. */
|
||||
static char *normalized_cwd;
|
||||
|
||||
/* Return nonzero if the next job should be done remotely. */
|
||||
|
||||
int
|
||||
start_remote_job_p ()
|
||||
{
|
||||
static int inited = 0;
|
||||
int status;
|
||||
|
||||
/* Allow the user to turn off job exportation
|
||||
(useful while he is debugging Customs, for example). */
|
||||
if (getenv ("GNU_MAKE_NO_CUSTOMS") != 0)
|
||||
return 0;
|
||||
|
||||
if (!inited)
|
||||
{
|
||||
/* For secure Customs, make is installed setuid root and
|
||||
Customs requires a privileged source port be used. */
|
||||
make_access ();
|
||||
|
||||
/* Ping the daemon once to see if it is there. */
|
||||
inited = Customs_Ping () == RPC_SUCCESS ? 1 : -1;
|
||||
|
||||
/* Return to normal user access. */
|
||||
user_access ();
|
||||
|
||||
if (starting_directory == 0)
|
||||
/* main couldn't figure it out. */
|
||||
inited = -1;
|
||||
else
|
||||
{
|
||||
/* Normalize the current directory path name to something
|
||||
that should work on all machines exported to. */
|
||||
|
||||
normalized_cwd = (char *) xmalloc (GET_PATH_MAX);
|
||||
strcpy (normalized_cwd, starting_directory);
|
||||
if (Customs_NormPath (normalized_cwd, GET_PATH_MAX) < 0)
|
||||
/* Path normalization failure means using Customs
|
||||
won't work, but it's not really an error. */
|
||||
inited = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (inited < 0)
|
||||
return 0;
|
||||
|
||||
status = Customs_Host (EXPORT_SAME, &permit);
|
||||
if (status != RPC_SUCCESS)
|
||||
{
|
||||
if (debug_flag)
|
||||
printf ("Customs won't export: %s\n", Rpc_ErrorMessage (status));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return !CUSTOMS_FAIL (&permit.addr);
|
||||
}
|
||||
|
||||
/* Start a remote job running the command in ARGV, with environment from
|
||||
ENVP. It gets standard input from STDIN_FD. On failure, return
|
||||
nonzero. On success, return zero, and set *USED_STDIN to nonzero if it
|
||||
will actually use STDIN_FD, zero if not, set *ID_PTR to a unique
|
||||
identification, and set *IS_REMOTE to nonzero if the job is remote, zero
|
||||
if it is local (meaning *ID_PTR is a process ID). */
|
||||
|
||||
int
|
||||
start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin)
|
||||
char **argv, **envp;
|
||||
int stdin_fd;
|
||||
int *is_remote;
|
||||
int *id_ptr;
|
||||
int *used_stdin;
|
||||
{
|
||||
extern int vfork (), execve ();
|
||||
char waybill[MAX_DATA_SIZE], msg[128];
|
||||
struct timeval timeout;
|
||||
struct sockaddr_in sin;
|
||||
int len;
|
||||
int retsock, retport, sock;
|
||||
Rpc_Stat status;
|
||||
int pid;
|
||||
|
||||
/* Create the return socket. */
|
||||
retsock = Rpc_UdpCreate (True, 0);
|
||||
if (retsock < 0)
|
||||
{
|
||||
error ("exporting: Couldn't create return socket.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get the return socket's port number. */
|
||||
len = sizeof (sin);
|
||||
if (getsockname (retsock, (struct sockaddr *) &sin, &len) < 0)
|
||||
{
|
||||
(void) close (retsock);
|
||||
perror_with_name ("exporting: ", "getsockname");
|
||||
return 1;
|
||||
}
|
||||
retport = sin.sin_port;
|
||||
|
||||
/* Create the TCP socket for talking to the remote child. */
|
||||
sock = Rpc_TcpCreate (False, 0);
|
||||
|
||||
/* Create a WayBill to give to the server. */
|
||||
len = Customs_MakeWayBill (&permit, normalized_cwd, argv[0], argv,
|
||||
envp, retport, waybill);
|
||||
|
||||
/* Modify the waybill as if the remote child had done `child_access ()'. */
|
||||
{
|
||||
WayBill *wb = (WayBill *) waybill;
|
||||
wb->euid = wb->ruid;
|
||||
wb->rgid = wb->rgid;
|
||||
}
|
||||
|
||||
/* Send the request to the server, timing out in 20 seconds. */
|
||||
timeout.tv_usec = 0;
|
||||
timeout.tv_sec = 20;
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons (Customs_Port ());
|
||||
sin.sin_addr = permit.addr;
|
||||
status = Rpc_Call (sock, &sin, (Rpc_Proc) CUSTOMS_IMPORT,
|
||||
len, (Rpc_Opaque) waybill,
|
||||
sizeof(msg), (Rpc_Opaque) msg,
|
||||
1, &timeout);
|
||||
if (status != RPC_SUCCESS)
|
||||
{
|
||||
(void) close (retsock);
|
||||
(void) close (sock);
|
||||
error ("exporting: %s", Rpc_ErrorMessage (status));
|
||||
return 1;
|
||||
}
|
||||
else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
|
||||
{
|
||||
(void) close (retsock);
|
||||
(void) close (sock);
|
||||
error ("CUSTOMS_IMPORT: %s", msg);
|
||||
return 1;
|
||||
}
|
||||
else if (debug_flag)
|
||||
{
|
||||
struct hostent *host = gethostbyaddr (&permit.addr, sizeof (permit.addr),
|
||||
AF_INET);
|
||||
printf ("Job exported to %s ID %u\n",
|
||||
host == 0 ? inet_ntoa (permit.addr) : host->h_name,
|
||||
permit.id);
|
||||
}
|
||||
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
|
||||
pid = vfork ();
|
||||
if (pid < 0)
|
||||
{
|
||||
/* The fork failed! */
|
||||
perror_with_name ("vfork", "");
|
||||
return 1;
|
||||
}
|
||||
else if (pid == 0)
|
||||
{
|
||||
/* Child side. Run `export' to handle the connection. */
|
||||
static char sock_buf[20], retsock_buf[20], id_buf[20];
|
||||
static char *new_argv[6] =
|
||||
{ EXPORT_COMMAND, "-id", sock_buf, retsock_buf, id_buf, 0 };
|
||||
|
||||
/* Set up the arguments. */
|
||||
(void) sprintf (sock_buf, "%d", sock);
|
||||
(void) sprintf (retsock_buf, "%d", retsock);
|
||||
(void) sprintf (id_buf, "%x", permit.id);
|
||||
|
||||
/* Get the right stdin. */
|
||||
if (stdin_fd != 0)
|
||||
(void) dup2 (stdin_fd, 0);
|
||||
|
||||
/* Unblock signals in the child. */
|
||||
unblock_sigs ();
|
||||
|
||||
/* Run the command. */
|
||||
exec_command (new_argv, envp);
|
||||
}
|
||||
|
||||
/* Parent side. Return the `export' process's ID. */
|
||||
(void) close (retsock);
|
||||
(void) close (sock);
|
||||
*is_remote = 0;
|
||||
*id_ptr = pid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the status of a dead remote child. Block waiting for one to die
|
||||
if BLOCK is nonzero. Set *EXIT_CODE_PTR to the exit status, *SIGNAL_PTR
|
||||
to the termination signal or zero if it exited normally, and *COREDUMP_PTR
|
||||
nonzero if it dumped core. Return the ID of the child that died,
|
||||
0 if we would have to block and !BLOCK, or < 0 if there were none. */
|
||||
|
||||
int
|
||||
remote_status (exit_code_ptr, signal_ptr, coredump_ptr, block)
|
||||
int *exit_code_ptr, *signal_ptr, *coredump_ptr;
|
||||
int block;
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Block asynchronous notification of remote child death.
|
||||
If this notification is done by raising the child termination
|
||||
signal, do not block that signal. */
|
||||
void
|
||||
block_remote_children ()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Restore asynchronous notification of remote child death.
|
||||
If this is done by raising the child termination signal,
|
||||
do not unblock that signal. */
|
||||
void
|
||||
unblock_remote_children ()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send signal SIG to child ID. Return 0 if successful, -1 if not. */
|
||||
int
|
||||
remote_kill (id, sig)
|
||||
int id;
|
||||
int sig;
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -1,92 +0,0 @@
|
||||
/* Template for the remote job exportation interface to GNU Make.
|
||||
Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "commands.h"
|
||||
|
||||
|
||||
char *remote_description = 0;
|
||||
|
||||
|
||||
/* Return nonzero if the next job should be done remotely. */
|
||||
|
||||
int
|
||||
start_remote_job_p ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Start a remote job running the command in ARGV,
|
||||
with environment from ENVP. It gets standard input from STDIN_FD. On
|
||||
failure, return nonzero. On success, return zero, and set *USED_STDIN
|
||||
to nonzero if it will actually use STDIN_FD, zero if not, set *ID_PTR to
|
||||
a unique identification, and set *IS_REMOTE to zero if the job is local,
|
||||
nonzero if it is remote (meaning *ID_PTR is a process ID). */
|
||||
|
||||
int
|
||||
start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin)
|
||||
char **argv, **envp;
|
||||
int stdin_fd;
|
||||
int *is_remote;
|
||||
int *id_ptr;
|
||||
int *used_stdin;
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the status of a dead remote child. Block waiting for one to die
|
||||
if BLOCK is nonzero. Set *EXIT_CODE_PTR to the exit status, *SIGNAL_PTR
|
||||
to the termination signal or zero if it exited normally, and *COREDUMP_PTR
|
||||
nonzero if it dumped core. Return the ID of the child that died,
|
||||
0 if we would have to block and !BLOCK, or < 0 if there were none. */
|
||||
|
||||
int
|
||||
remote_status (exit_code_ptr, signal_ptr, coredump_ptr, block)
|
||||
int *exit_code_ptr, *signal_ptr, *coredump_ptr;
|
||||
int block;
|
||||
{
|
||||
errno = ECHILD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Block asynchronous notification of remote child death.
|
||||
If this notification is done by raising the child termination
|
||||
signal, do not block that signal. */
|
||||
void
|
||||
block_remote_children ()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Restore asynchronous notification of remote child death.
|
||||
If this is done by raising the child termination signal,
|
||||
do not unblock that signal. */
|
||||
void
|
||||
unblock_remote_children ()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send signal SIG to child ID. Return 0 if successful, -1 if not. */
|
||||
int
|
||||
remote_kill (id, sig)
|
||||
int id;
|
||||
int sig;
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -1,571 +0,0 @@
|
||||
/* Pattern and suffix rule internals for GNU Make.
|
||||
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "commands.h"
|
||||
#include "dep.h"
|
||||
#include "file.h"
|
||||
#include "variable.h"
|
||||
#include "rule.h"
|
||||
|
||||
static void freerule ();
|
||||
|
||||
/* Chain of all pattern rules. */
|
||||
|
||||
struct rule *pattern_rules;
|
||||
|
||||
/* Pointer to last rule in the chain, so we can add onto the end. */
|
||||
|
||||
struct rule *last_pattern_rule;
|
||||
|
||||
/* Number of rules in the chain. */
|
||||
|
||||
unsigned int num_pattern_rules;
|
||||
|
||||
/* Maximum number of target patterns of any pattern rule. */
|
||||
|
||||
unsigned int max_pattern_targets;
|
||||
|
||||
/* Maximum number of dependencies of any pattern rule. */
|
||||
|
||||
unsigned int max_pattern_deps;
|
||||
|
||||
/* Maximum length of the name of a dependencies of any pattern rule. */
|
||||
|
||||
unsigned int max_pattern_dep_length;
|
||||
|
||||
/* Pointer to structure for the file .SUFFIXES
|
||||
whose dependencies are the suffixes to be searched. */
|
||||
|
||||
struct file *suffix_file;
|
||||
|
||||
/* Maximum length of a suffix. */
|
||||
|
||||
unsigned int maxsuffix;
|
||||
|
||||
/* Compute the maximum dependency length and maximum number of
|
||||
dependencies of all implicit rules. Also sets the subdir
|
||||
flag for a rule when appropriate, possibly removing the rule
|
||||
completely when appropriate. */
|
||||
|
||||
void
|
||||
count_implicit_rule_limits ()
|
||||
{
|
||||
char *name;
|
||||
unsigned int namelen;
|
||||
register struct rule *rule, *lastrule;
|
||||
|
||||
num_pattern_rules = max_pattern_targets = max_pattern_deps = 0;
|
||||
max_pattern_dep_length = 0;
|
||||
|
||||
name = 0;
|
||||
namelen = 0;
|
||||
rule = pattern_rules;
|
||||
lastrule = 0;
|
||||
while (rule != 0)
|
||||
{
|
||||
unsigned int ndeps = 0;
|
||||
register struct dep *dep;
|
||||
struct rule *next = rule->next;
|
||||
unsigned int ntargets;
|
||||
|
||||
++num_pattern_rules;
|
||||
|
||||
ntargets = 0;
|
||||
while (rule->targets[ntargets] != 0)
|
||||
++ntargets;
|
||||
|
||||
if (ntargets > max_pattern_targets)
|
||||
max_pattern_targets = ntargets;
|
||||
|
||||
for (dep = rule->deps; dep != 0; dep = dep->next)
|
||||
{
|
||||
unsigned int len = strlen (dep->name);
|
||||
char *p = rindex (dep->name, '/');
|
||||
char *p2 = p != 0 ? index (dep->name, '%') : 0;
|
||||
|
||||
ndeps++;
|
||||
|
||||
if (len > max_pattern_dep_length)
|
||||
max_pattern_dep_length = len;
|
||||
|
||||
if (p != 0 && p2 > p)
|
||||
{
|
||||
/* There is a slash before the % in the dep name.
|
||||
Extract the directory name. */
|
||||
if (p == dep->name)
|
||||
++p;
|
||||
if ((unsigned int)(p - dep->name) > namelen)
|
||||
{
|
||||
if (name != 0)
|
||||
free (name);
|
||||
namelen = p - dep->name;
|
||||
name = (char *) xmalloc (namelen + 1);
|
||||
}
|
||||
bcopy (dep->name, name, p - dep->name);
|
||||
name[p - dep->name] = '\0';
|
||||
|
||||
/* In the deps of an implicit rule the `changed' flag
|
||||
actually indicates that the dependency is in a
|
||||
nonexistent subdirectory. */
|
||||
|
||||
dep->changed = !dir_file_exists_p (name, "");
|
||||
if (dep->changed && *name == '/')
|
||||
{
|
||||
/* The name is absolute and the directory does not exist.
|
||||
This rule can never possibly match, since this dependency
|
||||
can never possibly exist. So just remove the rule from
|
||||
the list. */
|
||||
freerule (rule, lastrule);
|
||||
--num_pattern_rules;
|
||||
goto end_main_loop;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* This dependency does not reside in a subdirectory. */
|
||||
dep->changed = 0;
|
||||
}
|
||||
|
||||
if (ndeps > max_pattern_deps)
|
||||
max_pattern_deps = ndeps;
|
||||
|
||||
lastrule = rule;
|
||||
end_main_loop:
|
||||
rule = next;
|
||||
}
|
||||
|
||||
if (name != 0)
|
||||
free (name);
|
||||
}
|
||||
|
||||
/* Create a pattern rule from a suffix rule.
|
||||
TARGET is the target suffix; SOURCE is the source suffix.
|
||||
CMDS are the commands.
|
||||
If TARGET is nil, it means the target pattern should be `(%.o)'.
|
||||
If SOURCE is nil, it means there should be no deps. */
|
||||
|
||||
static void
|
||||
convert_suffix_rule (target, source, cmds)
|
||||
char *target, *source;
|
||||
struct commands *cmds;
|
||||
{
|
||||
char *targname, *targpercent, *depname;
|
||||
char **names, **percents;
|
||||
struct dep *deps;
|
||||
unsigned int len;
|
||||
|
||||
if (target == 0)
|
||||
/* Special case: TARGET being nil means we are defining a
|
||||
`.X.a' suffix rule; the target pattern is always `(%.o)'. */
|
||||
{
|
||||
targname = savestring ("(%.o)", 5);
|
||||
targpercent = targname + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Construct the target name. */
|
||||
len = strlen (target);
|
||||
targname = xmalloc (1 + len + 1);
|
||||
targname[0] = '%';
|
||||
bcopy (target, targname + 1, len + 1);
|
||||
targpercent = targname;
|
||||
}
|
||||
|
||||
names = (char **) xmalloc (2 * sizeof (char *));
|
||||
percents = (char **) alloca (2 * sizeof (char *));
|
||||
names[0] = targname;
|
||||
percents[0] = targpercent;
|
||||
names[1] = percents[1] = 0;
|
||||
|
||||
if (source == 0)
|
||||
deps = 0;
|
||||
else
|
||||
{
|
||||
/* Construct the dependency name. */
|
||||
len = strlen (source);
|
||||
depname = xmalloc (1 + len + 1);
|
||||
depname[0] = '%';
|
||||
bcopy (source, depname + 1, len + 1);
|
||||
deps = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
deps->next = 0;
|
||||
deps->name = depname;
|
||||
}
|
||||
|
||||
create_pattern_rule (names, percents, 0, deps, cmds, 0);
|
||||
}
|
||||
|
||||
/* Convert old-style suffix rules to pattern rules.
|
||||
All rules for the suffixes on the .SUFFIXES list
|
||||
are converted and added to the chain of pattern rules. */
|
||||
|
||||
void
|
||||
convert_to_pattern ()
|
||||
{
|
||||
register struct dep *d, *d2;
|
||||
register struct file *f;
|
||||
register char *rulename;
|
||||
register unsigned int slen, s2len;
|
||||
|
||||
/* Compute maximum length of all the suffixes. */
|
||||
|
||||
maxsuffix = 0;
|
||||
for (d = suffix_file->deps; d != 0; d = d->next)
|
||||
{
|
||||
register unsigned int namelen = strlen (dep_name (d));
|
||||
if (namelen > maxsuffix)
|
||||
maxsuffix = namelen;
|
||||
}
|
||||
|
||||
rulename = (char *) alloca ((maxsuffix * 2) + 1);
|
||||
|
||||
for (d = suffix_file->deps; d != 0; d = d->next)
|
||||
{
|
||||
/* Make a rule that is just the suffix, with no deps or commands.
|
||||
This rule exists solely to disqualify match-anything rules. */
|
||||
convert_suffix_rule (dep_name (d), (char *) 0, (struct commands *) 0);
|
||||
|
||||
f = d->file;
|
||||
if (f->cmds != 0)
|
||||
/* Record a pattern for this suffix's null-suffix rule. */
|
||||
convert_suffix_rule ("", dep_name (d), f->cmds);
|
||||
|
||||
/* Record a pattern for each of this suffix's two-suffix rules. */
|
||||
slen = strlen (dep_name (d));
|
||||
bcopy (dep_name (d), rulename, slen);
|
||||
for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next)
|
||||
{
|
||||
s2len = strlen (dep_name (d2));
|
||||
|
||||
if (slen == s2len && streq (dep_name (d), dep_name (d2)))
|
||||
continue;
|
||||
|
||||
bcopy (dep_name (d2), rulename + slen, s2len + 1);
|
||||
f = lookup_file (rulename);
|
||||
if (f == 0 || f->cmds == 0)
|
||||
continue;
|
||||
|
||||
if (s2len == 2 && rulename[slen] == '.' && rulename[slen + 1] == 'a')
|
||||
/* A suffix rule `.X.a:' generates the pattern rule `(%.o): %.X'.
|
||||
It also generates a normal `%.a: %.X' rule below. */
|
||||
convert_suffix_rule ((char *) 0, /* Indicates `(%.o)'. */
|
||||
dep_name (d),
|
||||
f->cmds);
|
||||
|
||||
/* The suffix rule `.X.Y:' is converted
|
||||
to the pattern rule `%.Y: %.X'. */
|
||||
convert_suffix_rule (dep_name (d2), dep_name (d), f->cmds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Install the pattern rule RULE (whose fields have been filled in)
|
||||
at the end of the list (so that any rules previously defined
|
||||
will take precedence). If this rule duplicates a previous one
|
||||
(identical target and dependencies), the old one is replaced
|
||||
if OVERRIDE is nonzero, otherwise this new one is thrown out.
|
||||
When an old rule is replaced, the new one is put at the end of the
|
||||
list. Return nonzero if RULE is used; zero if not. */
|
||||
|
||||
int
|
||||
new_pattern_rule (rule, override)
|
||||
register struct rule *rule;
|
||||
int override;
|
||||
{
|
||||
register struct rule *r, *lastrule;
|
||||
register unsigned int i, j;
|
||||
|
||||
rule->in_use = 0;
|
||||
rule->terminal = 0;
|
||||
|
||||
rule->next = 0;
|
||||
|
||||
/* Search for an identical rule. */
|
||||
lastrule = 0;
|
||||
for (r = pattern_rules; r != 0; lastrule = r, r = r->next)
|
||||
for (i = 0; rule->targets[i] != 0; ++i)
|
||||
{
|
||||
for (j = 0; r->targets[j] != 0; ++j)
|
||||
if (!streq (rule->targets[i], r->targets[j]))
|
||||
break;
|
||||
if (r->targets[j] == 0)
|
||||
/* All the targets matched. */
|
||||
{
|
||||
register struct dep *d, *d2;
|
||||
for (d = rule->deps, d2 = r->deps;
|
||||
d != 0 && d2 != 0; d = d->next, d2 = d2->next)
|
||||
if (!streq (dep_name (d), dep_name (d2)))
|
||||
break;
|
||||
if (d == 0 && d2 == 0)
|
||||
/* All the dependencies matched. */
|
||||
if (override)
|
||||
{
|
||||
/* Remove the old rule. */
|
||||
freerule (r, lastrule);
|
||||
/* Install the new one. */
|
||||
if (pattern_rules == 0)
|
||||
pattern_rules = rule;
|
||||
else
|
||||
last_pattern_rule->next = rule;
|
||||
last_pattern_rule = rule;
|
||||
|
||||
/* We got one. Stop looking. */
|
||||
goto matched;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The old rule stays intact. Destroy the new one. */
|
||||
freerule (rule, (struct rule *) 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matched:;
|
||||
|
||||
if (r == 0)
|
||||
{
|
||||
/* There was no rule to replace. */
|
||||
if (pattern_rules == 0)
|
||||
pattern_rules = rule;
|
||||
else
|
||||
last_pattern_rule->next = rule;
|
||||
last_pattern_rule = rule;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Install an implicit pattern rule based on the three text strings
|
||||
in the structure P points to. These strings come from one of
|
||||
the arrays of default implicit pattern rules.
|
||||
TERMINAL specifies what the `terminal' field of the rule should be. */
|
||||
|
||||
void
|
||||
install_pattern_rule (p, terminal)
|
||||
struct pspec *p;
|
||||
int terminal;
|
||||
{
|
||||
register struct rule *r;
|
||||
char *ptr;
|
||||
|
||||
r = (struct rule *) xmalloc (sizeof (struct rule));
|
||||
|
||||
r->targets = (char **) xmalloc (2 * sizeof (char *));
|
||||
r->suffixes = (char **) xmalloc (2 * sizeof (char *));
|
||||
r->lens = (unsigned int *) xmalloc (2 * sizeof (unsigned int));
|
||||
|
||||
r->targets[1] = 0;
|
||||
r->suffixes[1] = 0;
|
||||
r->lens[1] = 0;
|
||||
|
||||
r->lens[0] = strlen (p->target);
|
||||
/* These will all be string literals, but we malloc space for
|
||||
them anyway because somebody might want to free them later on. */
|
||||
r->targets[0] = savestring (p->target, r->lens[0]);
|
||||
r->suffixes[0] = find_percent (r->targets[0]);
|
||||
if (r->suffixes[0] == 0)
|
||||
/* Programmer-out-to-lunch error. */
|
||||
abort ();
|
||||
else
|
||||
++r->suffixes[0];
|
||||
|
||||
ptr = p->dep;
|
||||
r->deps = (struct dep *) multi_glob (parse_file_seq (&ptr, '\0',
|
||||
sizeof (struct dep), 1),
|
||||
sizeof (struct dep));
|
||||
|
||||
if (new_pattern_rule (r, 0))
|
||||
{
|
||||
r->terminal = terminal;
|
||||
r->cmds = (struct commands *) xmalloc (sizeof (struct commands));
|
||||
r->cmds->filename = 0;
|
||||
r->cmds->lineno = 0;
|
||||
/* These will all be string literals, but we malloc space for them
|
||||
anyway because somebody might want to free them later. */
|
||||
r->cmds->commands = savestring (p->commands, strlen (p->commands));
|
||||
r->cmds->command_lines = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Free all the storage used in RULE and take it out of the
|
||||
pattern_rules chain. LASTRULE is the rule whose next pointer
|
||||
points to RULE. */
|
||||
|
||||
static void
|
||||
freerule (rule, lastrule)
|
||||
register struct rule *rule, *lastrule;
|
||||
{
|
||||
struct rule *next = rule->next;
|
||||
register unsigned int i;
|
||||
|
||||
for (i = 0; rule->targets[i] != 0; ++i)
|
||||
free (rule->targets[i]);
|
||||
|
||||
free ((char *) rule->targets);
|
||||
free ((char *) rule->suffixes);
|
||||
free ((char *) rule->lens);
|
||||
|
||||
/* We can't free the storage for the commands because there
|
||||
are ways that they could be in more than one place:
|
||||
* If the commands came from a suffix rule, they could also be in
|
||||
the `struct file's for other suffix rules or plain targets given
|
||||
on the same makefile line.
|
||||
* If two suffixes that together make a two-suffix rule were each
|
||||
given twice in the .SUFFIXES list, and in the proper order, two
|
||||
identical pattern rules would be created and the second one would
|
||||
be discarded here, but both would contain the same `struct commands'
|
||||
pointer from the `struct file' for the suffix rule. */
|
||||
|
||||
free ((char *) rule);
|
||||
|
||||
if (pattern_rules == rule)
|
||||
if (lastrule != 0)
|
||||
abort ();
|
||||
else
|
||||
pattern_rules = next;
|
||||
else if (lastrule != 0)
|
||||
lastrule->next = next;
|
||||
if (last_pattern_rule == rule)
|
||||
last_pattern_rule = lastrule;
|
||||
}
|
||||
|
||||
/* Create a new pattern rule with the targets in the nil-terminated
|
||||
array TARGETS. If TARGET_PERCENTS is not nil, it is an array of
|
||||
pointers into the elements of TARGETS, where the `%'s are.
|
||||
The new rule has dependencies DEPS and commands from COMMANDS.
|
||||
It is a terminal rule if TERMINAL is nonzero. This rule overrides
|
||||
identical rules with different commands if OVERRIDE is nonzero.
|
||||
|
||||
The storage for TARGETS and its elements is used and must not be freed
|
||||
until the rule is destroyed. The storage for TARGET_PERCENTS is not used;
|
||||
it may be freed. */
|
||||
|
||||
void
|
||||
create_pattern_rule (targets, target_percents,
|
||||
terminal, deps, commands, override)
|
||||
char **targets, **target_percents;
|
||||
int terminal;
|
||||
struct dep *deps;
|
||||
struct commands *commands;
|
||||
int override;
|
||||
{
|
||||
register struct rule *r = (struct rule *) xmalloc (sizeof (struct rule));
|
||||
register unsigned int max_targets, i;
|
||||
|
||||
r->cmds = commands;
|
||||
r->deps = deps;
|
||||
r->targets = targets;
|
||||
|
||||
max_targets = 2;
|
||||
r->lens = (unsigned int *) xmalloc (2 * sizeof (unsigned int));
|
||||
r->suffixes = (char **) xmalloc (2 * sizeof (char *));
|
||||
for (i = 0; targets[i] != 0; ++i)
|
||||
{
|
||||
if (i == max_targets - 1)
|
||||
{
|
||||
max_targets += 5;
|
||||
r->lens = (unsigned int *)
|
||||
xrealloc ((char *) r->lens, max_targets * sizeof (unsigned int));
|
||||
r->suffixes = (char **)
|
||||
xrealloc ((char *) r->suffixes, max_targets * sizeof (char *));
|
||||
}
|
||||
r->lens[i] = strlen (targets[i]);
|
||||
r->suffixes[i] = (target_percents == 0 ? find_percent (targets[i])
|
||||
: target_percents[i]) + 1;
|
||||
if (r->suffixes[i] == 0)
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (i < max_targets - 1)
|
||||
{
|
||||
r->lens = (unsigned int *) xrealloc ((char *) r->lens,
|
||||
(i + 1) * sizeof (unsigned int));
|
||||
r->suffixes = (char **) xrealloc ((char *) r->suffixes,
|
||||
(i + 1) * sizeof (char *));
|
||||
}
|
||||
|
||||
if (new_pattern_rule (r, override))
|
||||
r->terminal = terminal;
|
||||
}
|
||||
|
||||
/* Print the data base of rules. */
|
||||
|
||||
static void /* Useful to call from gdb. */
|
||||
print_rule (r)
|
||||
struct rule *r;
|
||||
{
|
||||
register unsigned int i;
|
||||
register struct dep *d;
|
||||
|
||||
for (i = 0; r->targets[i] != 0; ++i)
|
||||
{
|
||||
fputs (r->targets[i], stdout);
|
||||
if (r->targets[i + 1] != 0)
|
||||
putchar (' ');
|
||||
else
|
||||
putchar (':');
|
||||
}
|
||||
if (r->terminal)
|
||||
putchar (':');
|
||||
|
||||
for (d = r->deps; d != 0; d = d->next)
|
||||
printf (" %s", dep_name (d));
|
||||
putchar ('\n');
|
||||
|
||||
if (r->cmds != 0)
|
||||
print_commands (r->cmds);
|
||||
}
|
||||
|
||||
void
|
||||
print_rule_data_base ()
|
||||
{
|
||||
register unsigned int rules, terminal;
|
||||
register struct rule *r;
|
||||
|
||||
puts ("\n# Implicit Rules");
|
||||
|
||||
rules = terminal = 0;
|
||||
for (r = pattern_rules; r != 0; r = r->next)
|
||||
{
|
||||
++rules;
|
||||
|
||||
putchar ('\n');
|
||||
print_rule (r);
|
||||
|
||||
if (r->terminal)
|
||||
++terminal;
|
||||
}
|
||||
|
||||
if (rules == 0)
|
||||
puts ("\n# No implicit rules.");
|
||||
else
|
||||
{
|
||||
printf ("\n# %u implicit rules, %u", rules, terminal);
|
||||
#ifndef NO_FLOAT
|
||||
printf (" (%.1f%%)", (double) terminal / (double) rules * 100.0);
|
||||
#endif
|
||||
puts (" terminal.");
|
||||
}
|
||||
|
||||
if (num_pattern_rules != rules)
|
||||
fatal ("BUG: num_pattern_rules wrong! %u != %u",
|
||||
num_pattern_rules, rules);
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
/* Definitions for using pattern rules in GNU Make.
|
||||
Copyright (C) 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Structure used for pattern rules. */
|
||||
|
||||
struct rule
|
||||
{
|
||||
struct rule *next;
|
||||
char **targets; /* Targets of the rule. */
|
||||
unsigned int *lens; /* Lengths of each target. */
|
||||
char **suffixes; /* Suffixes (after `%') of each target. */
|
||||
struct dep *deps; /* Dependencies of the rule. */
|
||||
struct commands *cmds; /* Commands to execute. */
|
||||
char terminal; /* If terminal (double-colon). */
|
||||
char in_use; /* If in use by a parent pattern_search. */
|
||||
};
|
||||
|
||||
/* For calling install_pattern_rule. */
|
||||
struct pspec
|
||||
{
|
||||
char *target, *dep, *commands;
|
||||
};
|
||||
|
||||
|
||||
extern struct rule *pattern_rules;
|
||||
extern struct rule *last_pattern_rule;
|
||||
extern unsigned int num_pattern_rules;
|
||||
|
||||
extern unsigned int max_pattern_deps;
|
||||
extern unsigned int max_pattern_targets;
|
||||
extern unsigned int max_pattern_dep_length;
|
||||
|
||||
extern struct file *suffix_file;
|
||||
extern unsigned int maxsuffix;
|
||||
|
||||
|
||||
extern void install_pattern_rule ();
|
||||
int new_pattern_rule ();
|
||||
@ -1,304 +0,0 @@
|
||||
/* Convert between signal names and numbers.
|
||||
Copyright (C) 1990, 1992, 1993, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h> /* Some systems need this for <signal.h>. */
|
||||
#include <signal.h>
|
||||
|
||||
/* Some systems declare `sys_siglist in <unistd.h>; if
|
||||
configure defined SYS_SIGLIST_DECLARED, it may expect
|
||||
to find the declaration there. */
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Some systems do not define NSIG in <signal.h>. */
|
||||
#ifndef NSIG
|
||||
#ifdef _NSIG
|
||||
#define NSIG _NSIG
|
||||
#else
|
||||
#define NSIG 32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !__STDC__
|
||||
#define const
|
||||
#endif
|
||||
|
||||
#include "signame.h"
|
||||
|
||||
#ifndef HAVE_SYS_SIGLIST
|
||||
/* There is too much variation in Sys V signal numbers and names, so
|
||||
we must initialize them at runtime. */
|
||||
|
||||
static const char undoc[] = "unknown signal";
|
||||
|
||||
const char *sys_siglist[NSIG];
|
||||
|
||||
#else /* HAVE_SYS_SIGLIST. */
|
||||
|
||||
#ifndef SYS_SIGLIST_DECLARED
|
||||
extern char *sys_siglist[];
|
||||
#endif /* Not SYS_SIGLIST_DECLARED. */
|
||||
|
||||
#endif /* Not HAVE_SYS_SIGLIST. */
|
||||
|
||||
/* Table of abbreviations for signals. Note: A given number can
|
||||
appear more than once with different abbreviations. */
|
||||
typedef struct
|
||||
{
|
||||
int number;
|
||||
const char *abbrev;
|
||||
} num_abbrev;
|
||||
static num_abbrev sig_table[NSIG*2];
|
||||
/* Number of elements of sig_table used. */
|
||||
static int sig_table_nelts = 0;
|
||||
|
||||
/* Enter signal number NUMBER into the tables with ABBREV and NAME. */
|
||||
|
||||
static void
|
||||
init_sig (number, abbrev, name)
|
||||
int number;
|
||||
const char *abbrev;
|
||||
const char *name;
|
||||
{
|
||||
#ifndef HAVE_SYS_SIGLIST
|
||||
sys_siglist[number] = name;
|
||||
#endif
|
||||
sig_table[sig_table_nelts].number = number;
|
||||
sig_table[sig_table_nelts++].abbrev = abbrev;
|
||||
}
|
||||
|
||||
void
|
||||
signame_init ()
|
||||
{
|
||||
#ifndef HAVE_SYS_SIGLIST
|
||||
int i;
|
||||
/* Initialize signal names. */
|
||||
for (i = 0; i < NSIG; i++)
|
||||
sys_siglist[i] = undoc;
|
||||
#endif /* !HAVE_SYS_SIGLIST */
|
||||
|
||||
/* Initialize signal names. */
|
||||
#if defined (SIGHUP)
|
||||
init_sig (SIGHUP, "HUP", "Hangup");
|
||||
#endif
|
||||
#if defined (SIGINT)
|
||||
init_sig (SIGINT, "INT", "Interrupt");
|
||||
#endif
|
||||
#if defined (SIGQUIT)
|
||||
init_sig (SIGQUIT, "QUIT", "Quit");
|
||||
#endif
|
||||
#if defined (SIGILL)
|
||||
init_sig (SIGILL, "ILL", "Illegal Instruction");
|
||||
#endif
|
||||
#if defined (SIGTRAP)
|
||||
init_sig (SIGTRAP, "TRAP", "Trace/breakpoint trap");
|
||||
#endif
|
||||
/* If SIGIOT == SIGABRT, we want to print it as SIGABRT because
|
||||
SIGABRT is in ANSI and POSIX.1 and SIGIOT isn't. */
|
||||
#if defined (SIGABRT)
|
||||
init_sig (SIGABRT, "ABRT", "Aborted");
|
||||
#endif
|
||||
#if defined (SIGIOT)
|
||||
init_sig (SIGIOT, "IOT", "IOT trap");
|
||||
#endif
|
||||
#if defined (SIGEMT)
|
||||
init_sig (SIGEMT, "EMT", "EMT trap");
|
||||
#endif
|
||||
#if defined (SIGFPE)
|
||||
init_sig (SIGFPE, "FPE", "Floating point exception");
|
||||
#endif
|
||||
#if defined (SIGKILL)
|
||||
init_sig (SIGKILL, "KILL", "Killed");
|
||||
#endif
|
||||
#if defined (SIGBUS)
|
||||
init_sig (SIGBUS, "BUS", "Bus error");
|
||||
#endif
|
||||
#if defined (SIGSEGV)
|
||||
init_sig (SIGSEGV, "SEGV", "Segmentation fault");
|
||||
#endif
|
||||
#if defined (SIGSYS)
|
||||
init_sig (SIGSYS, "SYS", "Bad system call");
|
||||
#endif
|
||||
#if defined (SIGPIPE)
|
||||
init_sig (SIGPIPE, "PIPE", "Broken pipe");
|
||||
#endif
|
||||
#if defined (SIGALRM)
|
||||
init_sig (SIGALRM, "ALRM", "Alarm clock");
|
||||
#endif
|
||||
#if defined (SIGTERM)
|
||||
init_sig (SIGTERM, "TERM", "Terminated");
|
||||
#endif
|
||||
#if defined (SIGUSR1)
|
||||
init_sig (SIGUSR1, "USR1", "User defined signal 1");
|
||||
#endif
|
||||
#if defined (SIGUSR2)
|
||||
init_sig (SIGUSR2, "USR2", "User defined signal 2");
|
||||
#endif
|
||||
/* If SIGCLD == SIGCHLD, we want to print it as SIGCHLD because that
|
||||
is what is in POSIX.1. */
|
||||
#if defined (SIGCHLD)
|
||||
init_sig (SIGCHLD, "CHLD", "Child exited");
|
||||
#endif
|
||||
#if defined (SIGCLD)
|
||||
init_sig (SIGCLD, "CLD", "Child exited");
|
||||
#endif
|
||||
#if defined (SIGPWR)
|
||||
init_sig (SIGPWR, "PWR", "Power failure");
|
||||
#endif
|
||||
#if defined (SIGTSTP)
|
||||
init_sig (SIGTSTP, "TSTP", "Stopped");
|
||||
#endif
|
||||
#if defined (SIGTTIN)
|
||||
init_sig (SIGTTIN, "TTIN", "Stopped (tty input)");
|
||||
#endif
|
||||
#if defined (SIGTTOU)
|
||||
init_sig (SIGTTOU, "TTOU", "Stopped (tty output)");
|
||||
#endif
|
||||
#if defined (SIGSTOP)
|
||||
init_sig (SIGSTOP, "STOP", "Stopped (signal)");
|
||||
#endif
|
||||
#if defined (SIGXCPU)
|
||||
init_sig (SIGXCPU, "XCPU", "CPU time limit exceeded");
|
||||
#endif
|
||||
#if defined (SIGXFSZ)
|
||||
init_sig (SIGXFSZ, "XFSZ", "File size limit exceeded");
|
||||
#endif
|
||||
#if defined (SIGVTALRM)
|
||||
init_sig (SIGVTALRM, "VTALRM", "Virtual timer expired");
|
||||
#endif
|
||||
#if defined (SIGPROF)
|
||||
init_sig (SIGPROF, "PROF", "Profiling timer expired");
|
||||
#endif
|
||||
#if defined (SIGWINCH)
|
||||
/* "Window size changed" might be more accurate, but even if that
|
||||
is all that it means now, perhaps in the future it will be
|
||||
extended to cover other kinds of window changes. */
|
||||
init_sig (SIGWINCH, "WINCH", "Window changed");
|
||||
#endif
|
||||
#if defined (SIGCONT)
|
||||
init_sig (SIGCONT, "CONT", "Continued");
|
||||
#endif
|
||||
#if defined (SIGURG)
|
||||
init_sig (SIGURG, "URG", "Urgent I/O condition");
|
||||
#endif
|
||||
#if defined (SIGIO)
|
||||
/* "I/O pending" has also been suggested. A disadvantage is
|
||||
that signal only happens when the process has
|
||||
asked for it, not everytime I/O is pending. Another disadvantage
|
||||
is the confusion from giving it a different name than under Unix. */
|
||||
init_sig (SIGIO, "IO", "I/O possible");
|
||||
#endif
|
||||
#if defined (SIGWIND)
|
||||
init_sig (SIGWIND, "WIND", "SIGWIND");
|
||||
#endif
|
||||
#if defined (SIGPHONE)
|
||||
init_sig (SIGPHONE, "PHONE", "SIGPHONE");
|
||||
#endif
|
||||
#if defined (SIGPOLL)
|
||||
init_sig (SIGPOLL, "POLL", "I/O possible");
|
||||
#endif
|
||||
#if defined (SIGLOST)
|
||||
init_sig (SIGLOST, "LOST", "Resource lost");
|
||||
#endif
|
||||
#if defined (SIGDANGER)
|
||||
init_sig (SIGDANGER, "DANGER", "Danger signal");
|
||||
#endif
|
||||
#if defined (SIGINFO)
|
||||
init_sig (SIGINFO, "INFO", "Information request");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the abbreviation for signal NUMBER. */
|
||||
|
||||
char *
|
||||
sig_abbrev (number)
|
||||
int number;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (sig_table_nelts == 0)
|
||||
signame_init ();
|
||||
|
||||
for (i = 0; i < sig_table_nelts; i++)
|
||||
if (sig_table[i].number == number)
|
||||
return (char *)sig_table[i].abbrev;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the signal number for an ABBREV, or -1 if there is no
|
||||
signal by that name. */
|
||||
|
||||
int
|
||||
sig_number (abbrev)
|
||||
const char *abbrev;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (sig_table_nelts == 0)
|
||||
signame_init ();
|
||||
|
||||
/* Skip over "SIG" if present. */
|
||||
if (abbrev[0] == 'S' && abbrev[1] == 'I' && abbrev[2] == 'G')
|
||||
abbrev += 3;
|
||||
|
||||
for (i = 0; i < sig_table_nelts; i++)
|
||||
if (abbrev[0] == sig_table[i].abbrev[0]
|
||||
&& strcmp (abbrev, sig_table[i].abbrev) == 0)
|
||||
return sig_table[i].number;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef HAVE_PSIGNAL
|
||||
/* Print to standard error the name of SIGNAL, preceded by MESSAGE and
|
||||
a colon, and followed by a newline. */
|
||||
|
||||
void
|
||||
psignal (signal, message)
|
||||
int signal;
|
||||
const char *message;
|
||||
{
|
||||
if (signal <= 0 || signal >= NSIG)
|
||||
fprintf (stderr, "%s: unknown signal", message);
|
||||
else
|
||||
fprintf (stderr, "%s: %s\n", message, sys_siglist[signal]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRSIGNAL
|
||||
/* Return the string associated with the signal number. */
|
||||
|
||||
char *
|
||||
strsignal (signal)
|
||||
int signal;
|
||||
{
|
||||
static char buf[] = "Signal 12345678901234567890";
|
||||
|
||||
if (signal > 0 || signal < NSIG)
|
||||
return (char *) sys_siglist[signal];
|
||||
|
||||
sprintf (buf, "Signal %d", signal);
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
@ -1,65 +0,0 @@
|
||||
/* Convert between signal names and numbers.
|
||||
Copyright (C) 1990, 1992, 1993, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if defined (__STDC__) && __STDC__
|
||||
|
||||
/* Initialize `sys_siglist'. */
|
||||
void signame_init (void);
|
||||
|
||||
/* Return the abbreviation (e.g. ABRT, FPE, etc.) for signal NUMBER.
|
||||
Do not return this as a const char *. The caller might want to
|
||||
assign it to a char *. */
|
||||
char *sig_abbrev (int number);
|
||||
|
||||
/* Return the signal number for an ABBREV, or -1 if there is no
|
||||
signal by that name. */
|
||||
int sig_number (const char *abbrev);
|
||||
|
||||
/* Avoid conflicts with a system header file that might define these three. */
|
||||
|
||||
#ifndef HAVE_PSIGNAL
|
||||
/* Print to standard error the name of SIGNAL, preceded by MESSAGE and
|
||||
a colon, and followed by a newline. */
|
||||
void psignal (int signal, const char *message);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRSIGNAL
|
||||
/* Return the name of SIGNAL. */
|
||||
char *strsignal (int signal);
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_SYS_SIGLIST)
|
||||
/* Names for signals from 0 to NSIG-1. */
|
||||
extern const char *sys_siglist[];
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
void signame_init ();
|
||||
char *sig_abbrev ();
|
||||
int sig_number ();
|
||||
#if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_PSIGNAL)
|
||||
void psignal ();
|
||||
#endif
|
||||
#ifndef HAVE_STRSIGNAL
|
||||
char *strsignal ();
|
||||
#endif
|
||||
#if !defined (HAVE_SYS_SIGLIST)
|
||||
extern char *sys_siglist[];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,822 +0,0 @@
|
||||
/* Internals of variables for GNU Make.
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "commands.h"
|
||||
#include "variable.h"
|
||||
#include "dep.h"
|
||||
#include "file.h"
|
||||
|
||||
/* Hash table of all global variable definitions. */
|
||||
|
||||
#ifndef VARIABLE_BUCKETS
|
||||
#define VARIABLE_BUCKETS 523
|
||||
#endif
|
||||
#ifndef PERFILE_VARIABLE_BUCKETS
|
||||
#define PERFILE_VARIABLE_BUCKETS 23
|
||||
#endif
|
||||
#ifndef SMALL_SCOPE_VARIABLE_BUCKETS
|
||||
#define SMALL_SCOPE_VARIABLE_BUCKETS 13
|
||||
#endif
|
||||
static struct variable *variable_table[VARIABLE_BUCKETS];
|
||||
static struct variable_set global_variable_set
|
||||
= { variable_table, VARIABLE_BUCKETS };
|
||||
static struct variable_set_list global_setlist
|
||||
= { 0, &global_variable_set };
|
||||
struct variable_set_list *current_variable_set_list = &global_setlist;
|
||||
|
||||
/* Implement variables. */
|
||||
|
||||
/* Define variable named NAME with value VALUE in SET. VALUE is copied.
|
||||
LENGTH is the length of NAME, which does not need to be null-terminated.
|
||||
ORIGIN specifies the origin of the variable (makefile, command line
|
||||
or environment).
|
||||
If RECURSIVE is nonzero a flag is set in the variable saying
|
||||
that it should be recursively re-expanded. */
|
||||
|
||||
static struct variable *
|
||||
define_variable_in_set (name, length, value, origin, recursive, set)
|
||||
char *name;
|
||||
unsigned int length;
|
||||
char *value;
|
||||
enum variable_origin origin;
|
||||
int recursive;
|
||||
struct variable_set *set;
|
||||
{
|
||||
register unsigned int i;
|
||||
register unsigned int hashval;
|
||||
register struct variable *v;
|
||||
|
||||
hashval = 0;
|
||||
for (i = 0; i < length; ++i)
|
||||
HASH (hashval, name[i]);
|
||||
hashval %= set->buckets;
|
||||
|
||||
for (v = set->table[hashval]; v != 0; v = v->next)
|
||||
if (*v->name == *name
|
||||
&& !strncmp (v->name + 1, name + 1, length - 1)
|
||||
&& v->name[length] == '\0')
|
||||
break;
|
||||
|
||||
if (env_overrides && origin == o_env)
|
||||
origin = o_env_override;
|
||||
|
||||
if (v != 0)
|
||||
{
|
||||
if (env_overrides && v->origin == o_env)
|
||||
/* V came from in the environment. Since it was defined
|
||||
before the switches were parsed, it wasn't affected by -e. */
|
||||
v->origin = o_env_override;
|
||||
|
||||
/* A variable of this name is already defined.
|
||||
If the old definition is from a stronger source
|
||||
than this one, don't redefine it. */
|
||||
if ((int) origin >= (int) v->origin)
|
||||
{
|
||||
if (v->value != 0)
|
||||
free (v->value);
|
||||
v->value = savestring (value, strlen (value));
|
||||
v->origin = origin;
|
||||
v->recursive = recursive;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Create a new variable definition and add it to the hash table. */
|
||||
|
||||
v = (struct variable *) xmalloc (sizeof (struct variable));
|
||||
v->name = savestring (name, length);
|
||||
v->value = savestring (value, strlen (value));
|
||||
v->origin = origin;
|
||||
v->recursive = recursive;
|
||||
v->expanding = 0;
|
||||
v->export = v_default;
|
||||
v->next = set->table[hashval];
|
||||
set->table[hashval] = v;
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Define a variable in the current variable set. */
|
||||
|
||||
struct variable *
|
||||
define_variable (name, length, value, origin, recursive)
|
||||
char *name;
|
||||
unsigned int length;
|
||||
char *value;
|
||||
enum variable_origin origin;
|
||||
int recursive;
|
||||
{
|
||||
return define_variable_in_set (name, length, value, origin, recursive,
|
||||
current_variable_set_list->set);
|
||||
}
|
||||
|
||||
/* Define a variable in FILE's variable set. */
|
||||
|
||||
struct variable *
|
||||
define_variable_for_file (name, length, value, origin, recursive, file)
|
||||
char *name;
|
||||
unsigned int length;
|
||||
char *value;
|
||||
enum variable_origin origin;
|
||||
int recursive;
|
||||
struct file *file;
|
||||
{
|
||||
return define_variable_in_set (name, length, value, origin, recursive,
|
||||
file->variables->set);
|
||||
}
|
||||
|
||||
/* Lookup a variable whose name is a string starting at NAME
|
||||
and with LENGTH chars. NAME need not be null-terminated.
|
||||
Returns address of the `struct variable' containing all info
|
||||
on the variable, or nil if no such variable is defined. */
|
||||
|
||||
struct variable *
|
||||
lookup_variable (name, length)
|
||||
char *name;
|
||||
unsigned int length;
|
||||
{
|
||||
register struct variable_set_list *setlist;
|
||||
|
||||
register unsigned int i;
|
||||
register unsigned int rawhash = 0;
|
||||
|
||||
for (i = 0; i < length; ++i)
|
||||
HASH (rawhash, name[i]);
|
||||
|
||||
for (setlist = current_variable_set_list;
|
||||
setlist != 0; setlist = setlist->next)
|
||||
{
|
||||
register struct variable_set *set = setlist->set;
|
||||
register unsigned int hashval = rawhash % set->buckets;
|
||||
register struct variable *v;
|
||||
|
||||
for (v = set->table[hashval]; v != 0; v = v->next)
|
||||
if (*v->name == *name
|
||||
&& !strncmp (v->name + 1, name + 1, length - 1)
|
||||
&& v->name[length] == 0)
|
||||
return v;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize FILE's variable set list. If FILE already has a variable set
|
||||
list, the topmost variable set is left intact, but the the rest of the
|
||||
chain is replaced with FILE->parent's setlist. */
|
||||
|
||||
void
|
||||
initialize_file_variables (file)
|
||||
struct file *file;
|
||||
{
|
||||
register struct variable_set_list *l = file->variables;
|
||||
if (l == 0)
|
||||
{
|
||||
l = (struct variable_set_list *)
|
||||
xmalloc (sizeof (struct variable_set_list));
|
||||
l->set = (struct variable_set *) xmalloc (sizeof (struct variable_set));
|
||||
l->set->buckets = PERFILE_VARIABLE_BUCKETS;
|
||||
l->set->table = (struct variable **)
|
||||
xmalloc (l->set->buckets * sizeof (struct variable *));
|
||||
bzero ((char *) l->set->table,
|
||||
l->set->buckets * sizeof (struct variable *));
|
||||
file->variables = l;
|
||||
}
|
||||
|
||||
if (file->parent == 0)
|
||||
l->next = &global_setlist;
|
||||
else
|
||||
{
|
||||
if (file->parent->variables == 0)
|
||||
initialize_file_variables (file->parent);
|
||||
l->next = file->parent->variables;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pop the top set off the current variable set list,
|
||||
and free all its storage. */
|
||||
|
||||
void
|
||||
pop_variable_scope ()
|
||||
{
|
||||
register struct variable_set_list *setlist = current_variable_set_list;
|
||||
register struct variable_set *set = setlist->set;
|
||||
register unsigned int i;
|
||||
|
||||
current_variable_set_list = setlist->next;
|
||||
free ((char *) setlist);
|
||||
|
||||
for (i = 0; i < set->buckets; ++i)
|
||||
{
|
||||
register struct variable *next = set->table[i];
|
||||
while (next != 0)
|
||||
{
|
||||
register struct variable *v = next;
|
||||
next = v->next;
|
||||
|
||||
free (v->name);
|
||||
free ((char *) v);
|
||||
}
|
||||
}
|
||||
free ((char *) set->table);
|
||||
free ((char *) set);
|
||||
}
|
||||
|
||||
/* Create a new variable set and push it on the current setlist. */
|
||||
|
||||
void
|
||||
push_new_variable_scope ()
|
||||
{
|
||||
register struct variable_set_list *setlist;
|
||||
register struct variable_set *set;
|
||||
|
||||
set = (struct variable_set *) xmalloc (sizeof (struct variable_set));
|
||||
set->buckets = SMALL_SCOPE_VARIABLE_BUCKETS;
|
||||
set->table = (struct variable **)
|
||||
xmalloc (set->buckets * sizeof (struct variable *));
|
||||
bzero ((char *) set->table, set->buckets * sizeof (struct variable *));
|
||||
|
||||
setlist = (struct variable_set_list *)
|
||||
xmalloc (sizeof (struct variable_set_list));
|
||||
setlist->set = set;
|
||||
setlist->next = current_variable_set_list;
|
||||
current_variable_set_list = setlist;
|
||||
}
|
||||
|
||||
/* Merge SET1 into SET0, freeing unused storage in SET1. */
|
||||
|
||||
static void
|
||||
merge_variable_sets (set0, set1)
|
||||
struct variable_set *set0, *set1;
|
||||
{
|
||||
register unsigned int bucket1;
|
||||
|
||||
for (bucket1 = 0; bucket1 < set1->buckets; ++bucket1)
|
||||
{
|
||||
register struct variable *v1 = set1->table[bucket1];
|
||||
while (v1 != 0)
|
||||
{
|
||||
struct variable *next = v1->next;
|
||||
unsigned int bucket0;
|
||||
register struct variable *v0;
|
||||
|
||||
if (set1->buckets >= set0->buckets)
|
||||
bucket0 = bucket1;
|
||||
else
|
||||
{
|
||||
register char *n;
|
||||
bucket0 = 0;
|
||||
for (n = v1->name; *n != '\0'; ++n)
|
||||
HASH (bucket0, *n);
|
||||
}
|
||||
bucket0 %= set0->buckets;
|
||||
|
||||
for (v0 = set0->table[bucket0]; v0 != 0; v0 = v0->next)
|
||||
if (streq (v0->name, v1->name))
|
||||
break;
|
||||
|
||||
if (v0 == 0)
|
||||
{
|
||||
/* There is no variable in SET0 with the same name. */
|
||||
v1->next = set0->table[bucket0];
|
||||
set0->table[bucket0] = v1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The same variable exists in both sets.
|
||||
SET0 takes precedence. */
|
||||
free (v1->value);
|
||||
free ((char *) v1);
|
||||
}
|
||||
|
||||
v1 = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Merge SETLIST1 into SETLIST0, freeing unused storage in SETLIST1. */
|
||||
|
||||
void
|
||||
merge_variable_set_lists (setlist0, setlist1)
|
||||
struct variable_set_list **setlist0, *setlist1;
|
||||
{
|
||||
register struct variable_set_list *list0 = *setlist0;
|
||||
struct variable_set_list *last0 = 0;
|
||||
|
||||
while (setlist1 != 0 && list0 != 0)
|
||||
{
|
||||
struct variable_set_list *next = setlist1;
|
||||
setlist1 = setlist1->next;
|
||||
|
||||
merge_variable_sets (list0->set, next->set);
|
||||
|
||||
free ((char *) next);
|
||||
|
||||
last0 = list0;
|
||||
list0 = list0->next;
|
||||
}
|
||||
|
||||
if (setlist1 != 0)
|
||||
{
|
||||
if (last0 == 0)
|
||||
*setlist0 = setlist1;
|
||||
else
|
||||
last0->next = setlist1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Define the automatic variables, and record the addresses
|
||||
of their structures so we can change their values quickly. */
|
||||
|
||||
void
|
||||
define_automatic_variables ()
|
||||
{
|
||||
extern char default_shell[];
|
||||
register struct variable *v;
|
||||
char buf[200];
|
||||
|
||||
sprintf (buf, "%u", makelevel);
|
||||
(void) define_variable ("MAKELEVEL", 9, buf, o_env, 0);
|
||||
|
||||
sprintf (buf, "%s%s%s",
|
||||
version_string,
|
||||
(remote_description == 0 || remote_description[0] == '\0')
|
||||
? "" : "-",
|
||||
(remote_description == 0 || remote_description[0] == '\0')
|
||||
? "" : remote_description);
|
||||
(void) define_variable ("MAKE_VERSION", 12, buf, o_default, 0);
|
||||
|
||||
|
||||
/* This won't override any definition, but it
|
||||
will provide one if there isn't one there. */
|
||||
v = define_variable ("SHELL", 5, default_shell, o_default, 0);
|
||||
v->export = v_export; /* Always export SHELL. */
|
||||
|
||||
/* Don't let SHELL come from the environment. */
|
||||
if (*v->value == '\0' || v->origin == o_env || v->origin == o_env_override)
|
||||
{
|
||||
free (v->value);
|
||||
v->origin = o_file;
|
||||
v->value = savestring (default_shell, strlen (default_shell));
|
||||
}
|
||||
|
||||
/* Make sure MAKEFILES gets exported if it is set. */
|
||||
v = define_variable ("MAKEFILES", 9, "", o_default, 0);
|
||||
v->export = v_ifset;
|
||||
|
||||
/* Define the magic D and F variables in terms of
|
||||
the automatic variables they are variations of. */
|
||||
|
||||
define_variable ("@D", 2, "$(patsubst %/,%,$(dir $@))", o_automatic, 1);
|
||||
define_variable ("%D", 2, "$(patsubst %/,%,$(dir $%))", o_automatic, 1);
|
||||
define_variable ("*D", 2, "$(patsubst %/,%,$(dir $*))", o_automatic, 1);
|
||||
define_variable ("<D", 2, "$(patsubst %/,%,$(dir $<))", o_automatic, 1);
|
||||
define_variable ("?D", 2, "$(patsubst %/,%,$(dir $?))", o_automatic, 1);
|
||||
define_variable ("^D", 2, "$(patsubst %/,%,$(dir $^))", o_automatic, 1);
|
||||
define_variable ("+D", 2, "$(patsubst %/,%,$(dir $+))", o_automatic, 1);
|
||||
define_variable ("@F", 2, "$(notdir $@)", o_automatic, 1);
|
||||
define_variable ("%F", 2, "$(notdir $%)", o_automatic, 1);
|
||||
define_variable ("*F", 2, "$(notdir $*)", o_automatic, 1);
|
||||
define_variable ("<F", 2, "$(notdir $<)", o_automatic, 1);
|
||||
define_variable ("?F", 2, "$(notdir $?)", o_automatic, 1);
|
||||
define_variable ("^F", 2, "$(notdir $^)", o_automatic, 1);
|
||||
define_variable ("+F", 2, "$(notdir $+)", o_automatic, 1);
|
||||
}
|
||||
|
||||
int export_all_variables;
|
||||
|
||||
/* Create a new environment for FILE's commands.
|
||||
If FILE is nil, this is for the `shell' function.
|
||||
The child's MAKELEVEL variable is incremented. */
|
||||
|
||||
char **
|
||||
target_environment (file)
|
||||
struct file *file;
|
||||
{
|
||||
struct variable_set_list *set_list;
|
||||
register struct variable_set_list *s;
|
||||
struct variable_bucket
|
||||
{
|
||||
struct variable_bucket *next;
|
||||
struct variable *variable;
|
||||
};
|
||||
struct variable_bucket **table;
|
||||
unsigned int buckets;
|
||||
register unsigned int i;
|
||||
register unsigned nvariables;
|
||||
char **result;
|
||||
unsigned int mklev_hash;
|
||||
|
||||
if (file == 0)
|
||||
set_list = current_variable_set_list;
|
||||
else
|
||||
set_list = file->variables;
|
||||
|
||||
/* Find the lowest number of buckets in any set in the list. */
|
||||
s = set_list;
|
||||
buckets = s->set->buckets;
|
||||
for (s = s->next; s != 0; s = s->next)
|
||||
if (s->set->buckets < buckets)
|
||||
buckets = s->set->buckets;
|
||||
|
||||
/* Find the hash value of the bucket `MAKELEVEL' will fall into. */
|
||||
{
|
||||
char *p = "MAKELEVEL";
|
||||
mklev_hash = 0;
|
||||
while (*p != '\0')
|
||||
HASH (mklev_hash, *p++);
|
||||
}
|
||||
|
||||
/* Temporarily allocate a table with that many buckets. */
|
||||
table = (struct variable_bucket **)
|
||||
alloca (buckets * sizeof (struct variable_bucket *));
|
||||
bzero ((char *) table, buckets * sizeof (struct variable_bucket *));
|
||||
|
||||
/* Run through all the variable sets in the list,
|
||||
accumulating variables in TABLE. */
|
||||
nvariables = 0;
|
||||
for (s = set_list; s != 0; s = s->next)
|
||||
{
|
||||
register struct variable_set *set = s->set;
|
||||
for (i = 0; i < set->buckets; ++i)
|
||||
{
|
||||
register struct variable *v;
|
||||
for (v = set->table[i]; v != 0; v = v->next)
|
||||
{
|
||||
unsigned int j = i % buckets;
|
||||
register struct variable_bucket *ov;
|
||||
register char *p = v->name;
|
||||
|
||||
if (i == mklev_hash % set->buckets
|
||||
&& streq (v->name, "MAKELEVEL"))
|
||||
/* Don't include MAKELEVEL because it will be
|
||||
added specially at the end. */
|
||||
continue;
|
||||
|
||||
switch (v->export)
|
||||
{
|
||||
case v_default:
|
||||
if (v->origin == o_default || v->origin == o_automatic)
|
||||
/* Only export default variables by explicit request. */
|
||||
continue;
|
||||
|
||||
if (! export_all_variables
|
||||
&& v->origin != o_command
|
||||
&& v->origin != o_env && v->origin != o_env_override)
|
||||
continue;
|
||||
|
||||
if (*p != '_' && (*p < 'A' || *p > 'Z')
|
||||
&& (*p < 'a' || *p > 'z'))
|
||||
continue;
|
||||
for (++p; *p != '\0'; ++p)
|
||||
if (*p != '_' && (*p < 'a' || *p > 'z')
|
||||
&& (*p < 'A' || *p > 'Z') && (*p < '0' || *p > '9'))
|
||||
break;
|
||||
if (*p != '\0')
|
||||
continue;
|
||||
|
||||
case v_export:
|
||||
break;
|
||||
|
||||
case v_noexport:
|
||||
continue;
|
||||
|
||||
case v_ifset:
|
||||
if (v->origin == o_default)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
for (ov = table[j]; ov != 0; ov = ov->next)
|
||||
if (streq (v->name, ov->variable->name))
|
||||
break;
|
||||
if (ov == 0)
|
||||
{
|
||||
register struct variable_bucket *entry;
|
||||
entry = (struct variable_bucket *)
|
||||
alloca (sizeof (struct variable_bucket));
|
||||
entry->next = table[j];
|
||||
entry->variable = v;
|
||||
table[j] = entry;
|
||||
++nvariables;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = (char **) xmalloc ((nvariables + 2) * sizeof (char *));
|
||||
nvariables = 0;
|
||||
for (i = 0; i < buckets; ++i)
|
||||
{
|
||||
register struct variable_bucket *b;
|
||||
for (b = table[i]; b != 0; b = b->next)
|
||||
{
|
||||
register struct variable *v = b->variable;
|
||||
/* If V is recursively expanded and didn't come from the environment,
|
||||
expand its value. If it came from the environment, it should
|
||||
go back into the environment unchanged. */
|
||||
if (v->recursive
|
||||
&& v->origin != o_env && v->origin != o_env_override)
|
||||
{
|
||||
char *value = recursively_expand (v);
|
||||
result[nvariables++] = concat (v->name, "=", value);
|
||||
free (value);
|
||||
}
|
||||
else
|
||||
result[nvariables++] = concat (v->name, "=", v->value);
|
||||
}
|
||||
}
|
||||
result[nvariables] = (char *) xmalloc (100);
|
||||
(void) sprintf (result[nvariables], "MAKELEVEL=%u", makelevel + 1);
|
||||
result[++nvariables] = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Try to interpret LINE (a null-terminated string) as a variable definition.
|
||||
|
||||
ORIGIN may be o_file, o_override, o_env, o_env_override,
|
||||
or o_command specifying that the variable definition comes
|
||||
from a makefile, an override directive, the environment with
|
||||
or without the -e switch, or the command line.
|
||||
|
||||
A variable definition has the form "name = value" or "name := value".
|
||||
Any whitespace around the "=" or ":=" is removed. The first form
|
||||
defines a variable that is recursively re-evaluated. The second form
|
||||
defines a variable whose value is variable-expanded at the time of
|
||||
definition and then is evaluated only once at the time of expansion.
|
||||
|
||||
If a variable was defined, a pointer to its `struct variable' is returned.
|
||||
If not, NULL is returned. */
|
||||
|
||||
struct variable *
|
||||
try_variable_definition (filename, lineno, line, origin)
|
||||
char *filename;
|
||||
unsigned int lineno;
|
||||
char *line;
|
||||
enum variable_origin origin;
|
||||
{
|
||||
register int c;
|
||||
register char *p = line;
|
||||
register char *beg;
|
||||
register char *end;
|
||||
enum { bogus, simple, recursive, append } flavor = bogus;
|
||||
char *name, *expanded_name, *value;
|
||||
struct variable *v;
|
||||
|
||||
while (1)
|
||||
{
|
||||
c = *p++;
|
||||
if (c == '\0' || c == '#')
|
||||
return 0;
|
||||
if (c == '=')
|
||||
{
|
||||
end = p - 1;
|
||||
flavor = recursive;
|
||||
break;
|
||||
}
|
||||
else if (c == ':')
|
||||
if (*p == '=')
|
||||
{
|
||||
end = p++ - 1;
|
||||
flavor = simple;
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* A colon other than := is a rule line, not a variable defn. */
|
||||
return 0;
|
||||
else if (c == '+' && *p == '=')
|
||||
{
|
||||
end = p++ - 1;
|
||||
flavor = append;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
beg = next_token (line);
|
||||
while (end > beg && isblank (end[-1]))
|
||||
--end;
|
||||
p = next_token (p);
|
||||
|
||||
/* Expand the name, so "$(foo)bar = baz" works. */
|
||||
name = (char *) alloca (end - beg + 1);
|
||||
bcopy (beg, name, end - beg);
|
||||
name[end - beg] = '\0';
|
||||
expanded_name = allocated_variable_expand (name);
|
||||
|
||||
if (expanded_name[0] == '\0')
|
||||
{
|
||||
if (filename == 0)
|
||||
fatal ("empty variable name");
|
||||
else
|
||||
makefile_fatal (filename, lineno, "empty variable name");
|
||||
}
|
||||
|
||||
/* Calculate the variable's new value in VALUE. */
|
||||
|
||||
switch (flavor)
|
||||
{
|
||||
case bogus:
|
||||
/* Should not be possible. */
|
||||
abort ();
|
||||
return 0;
|
||||
case simple:
|
||||
/* A simple variable definition "var := value". Expand the value. */
|
||||
value = variable_expand (p);
|
||||
break;
|
||||
case recursive:
|
||||
/* A recursive variable definition "var = value".
|
||||
The value is used verbatim. */
|
||||
value = p;
|
||||
break;
|
||||
case append:
|
||||
/* An appending variable definition "var += value".
|
||||
Extract the old value and append the new one. */
|
||||
v = lookup_variable (expanded_name, strlen (expanded_name));
|
||||
if (v == 0)
|
||||
{
|
||||
/* There was no old value.
|
||||
This becomes a normal recursive definition. */
|
||||
value = p;
|
||||
flavor = recursive;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Paste the old and new values together in VALUE. */
|
||||
|
||||
unsigned int oldlen, newlen;
|
||||
|
||||
if (v->recursive)
|
||||
/* The previous definition of the variable was recursive.
|
||||
The new value comes from the unexpanded old and new values. */
|
||||
flavor = recursive;
|
||||
else
|
||||
/* The previous definition of the variable was simple.
|
||||
The new value comes from the old value, which was expanded
|
||||
when it was set; and from the expanded new value. */
|
||||
p = variable_expand (p);
|
||||
|
||||
oldlen = strlen (v->value);
|
||||
newlen = strlen (p);
|
||||
value = (char *) alloca (oldlen + 1 + newlen + 1);
|
||||
bcopy (v->value, value, oldlen);
|
||||
value[oldlen] = ' ';
|
||||
bcopy (p, &value[oldlen + 1], newlen + 1);
|
||||
}
|
||||
}
|
||||
|
||||
v = define_variable (expanded_name, strlen (expanded_name),
|
||||
value, origin, flavor == recursive);
|
||||
|
||||
free (expanded_name);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Print information for variable V, prefixing it with PREFIX. */
|
||||
|
||||
static void
|
||||
print_variable (v, prefix)
|
||||
register struct variable *v;
|
||||
char *prefix;
|
||||
{
|
||||
char *origin;
|
||||
|
||||
switch (v->origin)
|
||||
{
|
||||
case o_default:
|
||||
origin = "default";
|
||||
break;
|
||||
case o_env:
|
||||
origin = "environment";
|
||||
break;
|
||||
case o_file:
|
||||
origin = "makefile";
|
||||
break;
|
||||
case o_env_override:
|
||||
origin = "environment under -e";
|
||||
break;
|
||||
case o_command:
|
||||
origin = "command line";
|
||||
break;
|
||||
case o_override:
|
||||
origin = "`override' directive";
|
||||
break;
|
||||
case o_automatic:
|
||||
origin = "automatic";
|
||||
break;
|
||||
case o_invalid:
|
||||
default:
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
printf ("# %s\n", origin);
|
||||
|
||||
fputs (prefix, stdout);
|
||||
|
||||
/* Is this a `define'? */
|
||||
if (v->recursive && index (v->value, '\n') != 0)
|
||||
printf ("define %s\n%s\nendef\n", v->name, v->value);
|
||||
else
|
||||
{
|
||||
register char *p;
|
||||
|
||||
printf ("%s %s= ", v->name, v->recursive ? "" : ":");
|
||||
|
||||
/* Check if the value is just whitespace. */
|
||||
p = next_token (v->value);
|
||||
if (p != v->value && *p == '\0')
|
||||
/* All whitespace. */
|
||||
printf ("$(subst ,,%s)", v->value);
|
||||
else if (v->recursive)
|
||||
fputs (v->value, stdout);
|
||||
else
|
||||
/* Double up dollar signs. */
|
||||
for (p = v->value; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == '$')
|
||||
putchar ('$');
|
||||
putchar (*p);
|
||||
}
|
||||
putchar ('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Print all the variables in SET. PREFIX is printed before
|
||||
the actual variable definitions (everything else is comments). */
|
||||
|
||||
static void
|
||||
print_variable_set (set, prefix)
|
||||
register struct variable_set *set;
|
||||
char *prefix;
|
||||
{
|
||||
register unsigned int i, nvariables, per_bucket;
|
||||
register struct variable *v;
|
||||
|
||||
per_bucket = nvariables = 0;
|
||||
for (i = 0; i < set->buckets; ++i)
|
||||
{
|
||||
register unsigned int this_bucket = 0;
|
||||
|
||||
for (v = set->table[i]; v != 0; v = v->next)
|
||||
{
|
||||
++this_bucket;
|
||||
print_variable (v, prefix);
|
||||
}
|
||||
|
||||
nvariables += this_bucket;
|
||||
if (this_bucket > per_bucket)
|
||||
per_bucket = this_bucket;
|
||||
}
|
||||
|
||||
if (nvariables == 0)
|
||||
puts ("# No variables.");
|
||||
else
|
||||
{
|
||||
printf ("# %u variables in %u hash buckets.\n",
|
||||
nvariables, set->buckets);
|
||||
#ifndef NO_FLOAT
|
||||
printf ("# average of %.1f variables per bucket, \
|
||||
max %u in one bucket.\n",
|
||||
(double) nvariables / (double) set->buckets,
|
||||
per_bucket);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Print the data base of variables. */
|
||||
|
||||
void
|
||||
print_variable_data_base ()
|
||||
{
|
||||
puts ("\n# Variables\n");
|
||||
|
||||
print_variable_set (&global_variable_set, "");
|
||||
}
|
||||
|
||||
|
||||
/* Print all the local variables of FILE. */
|
||||
|
||||
void
|
||||
print_file_variables (file)
|
||||
struct file *file;
|
||||
{
|
||||
if (file->variables != 0)
|
||||
print_variable_set (file->variables->set, "# ");
|
||||
}
|
||||
@ -1,100 +0,0 @@
|
||||
/* Definitions for using variables in GNU Make.
|
||||
Copyright (C) 1988, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Codes in a variable definition saying where the definition came from.
|
||||
Increasing numeric values signify less-overridable definitions. */
|
||||
enum variable_origin
|
||||
{
|
||||
o_default, /* Variable from the default set. */
|
||||
o_env, /* Variable from environment. */
|
||||
o_file, /* Variable given in a makefile. */
|
||||
o_env_override, /* Variable from environment, if -e. */
|
||||
o_command, /* Variable given by user. */
|
||||
o_override, /* Variable from an `override' directive. */
|
||||
o_automatic, /* Automatic variable -- cannot be set. */
|
||||
o_invalid /* Core dump time. */
|
||||
};
|
||||
|
||||
/* Structure that represents one variable definition.
|
||||
Each bucket of the hash table is a chain of these,
|
||||
chained through `next'. */
|
||||
|
||||
struct variable
|
||||
{
|
||||
struct variable *next; /* Link in the chain. */
|
||||
char *name; /* Variable name. */
|
||||
char *value; /* Variable value. */
|
||||
enum variable_origin
|
||||
origin ENUM_BITFIELD (3); /* Variable origin. */
|
||||
unsigned int recursive:1; /* Gets recursively re-evaluated. */
|
||||
unsigned int expanding:1; /* Nonzero if currently being expanded. */
|
||||
enum
|
||||
{
|
||||
v_export, /* Export this variable. */
|
||||
v_noexport, /* Don't export this variable. */
|
||||
v_ifset, /* Export it if it has a non-default value. */
|
||||
v_default /* Decide in target_environment. */
|
||||
} export ENUM_BITFIELD (2);
|
||||
};
|
||||
|
||||
/* Structure that represents a variable set. */
|
||||
|
||||
struct variable_set
|
||||
{
|
||||
struct variable **table; /* Hash table of variables. */
|
||||
unsigned int buckets; /* Number of hash buckets in `table'. */
|
||||
};
|
||||
|
||||
/* Structure that represents a list of variable sets. */
|
||||
|
||||
struct variable_set_list
|
||||
{
|
||||
struct variable_set_list *next; /* Link in the chain. */
|
||||
struct variable_set *set; /* Variable set. */
|
||||
};
|
||||
|
||||
extern struct variable_set_list *current_variable_set_list;
|
||||
|
||||
|
||||
extern void push_new_variable_scope (), pop_variable_scope ();
|
||||
|
||||
extern int handle_function ();
|
||||
|
||||
extern char *variable_buffer_output ();
|
||||
extern char *variable_expand (), *variable_expand_for_file ();
|
||||
extern char *allocated_variable_expand_for_file ();
|
||||
#define allocated_variable_expand(line) \
|
||||
allocated_variable_expand_for_file (line, (struct file *) 0)
|
||||
extern char *expand_argument ();
|
||||
|
||||
extern void define_automatic_variables ();
|
||||
extern void initialize_file_variables ();
|
||||
extern void print_file_variables ();
|
||||
|
||||
extern void merge_variable_set_lists ();
|
||||
|
||||
extern struct variable *try_variable_definition ();
|
||||
|
||||
extern struct variable *lookup_variable (), *define_variable ();
|
||||
extern struct variable *define_variable_for_file ();
|
||||
|
||||
extern int pattern_matches ();
|
||||
extern char *subst_expand (), *patsubst_expand (), *recursively_expand ();
|
||||
|
||||
extern char **target_environment ();
|
||||
extern int export_all_variables;
|
||||
@ -1,7 +0,0 @@
|
||||
char *version_string = "3.74";
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
version-control: never
|
||||
End:
|
||||
*/
|
||||
@ -1,487 +0,0 @@
|
||||
/* Implementation of pattern-matching file search paths for GNU Make.
|
||||
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Make is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Make; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "file.h"
|
||||
#include "variable.h"
|
||||
|
||||
|
||||
/* Structure used to represent a selective VPATH searchpath. */
|
||||
|
||||
struct vpath
|
||||
{
|
||||
struct vpath *next; /* Pointer to next struct in the linked list. */
|
||||
char *pattern; /* The pattern to match. */
|
||||
char *percent; /* Pointer into `pattern' where the `%' is. */
|
||||
unsigned int patlen;/* Length of the pattern. */
|
||||
char **searchpath; /* Null-terminated list of directories. */
|
||||
unsigned int maxlen;/* Maximum length of any entry in the list. */
|
||||
};
|
||||
|
||||
/* Linked-list of all selective VPATHs. */
|
||||
|
||||
static struct vpath *vpaths;
|
||||
|
||||
/* Structure for the general VPATH given in the variable. */
|
||||
|
||||
static struct vpath *general_vpath;
|
||||
|
||||
static int selective_vpath_search ();
|
||||
|
||||
/* Reverse the chain of selective VPATH lists so they
|
||||
will be searched in the order given in the makefiles
|
||||
and construct the list from the VPATH variable. */
|
||||
|
||||
void
|
||||
build_vpath_lists ()
|
||||
{
|
||||
register struct vpath *new = 0;
|
||||
register struct vpath *old, *nexto;
|
||||
register char *p;
|
||||
|
||||
/* Reverse the chain. */
|
||||
for (old = vpaths; old != 0; old = nexto)
|
||||
{
|
||||
nexto = old->next;
|
||||
old->next = new;
|
||||
new = old;
|
||||
}
|
||||
|
||||
vpaths = new;
|
||||
|
||||
/* If there is a VPATH variable with a nonnull value, construct the
|
||||
general VPATH list from it. We use variable_expand rather than just
|
||||
calling lookup_variable so that it will be recursively expanded. */
|
||||
|
||||
{
|
||||
/* Turn off --warn-undefined-variables while we expand SHELL and IFS. */
|
||||
int save = warn_undefined_variables_flag;
|
||||
warn_undefined_variables_flag = 0;
|
||||
|
||||
p = variable_expand ("$(strip $(VPATH))");
|
||||
|
||||
warn_undefined_variables_flag = save;
|
||||
}
|
||||
|
||||
if (*p != '\0')
|
||||
{
|
||||
/* Save the list of vpaths. */
|
||||
struct vpath *save_vpaths = vpaths;
|
||||
|
||||
/* Empty `vpaths' so the new one will have no next, and `vpaths'
|
||||
will still be nil if P contains no existing directories. */
|
||||
vpaths = 0;
|
||||
|
||||
/* Parse P. */
|
||||
construct_vpath_list ("%", p);
|
||||
|
||||
/* Store the created path as the general path,
|
||||
and restore the old list of vpaths. */
|
||||
general_vpath = vpaths;
|
||||
vpaths = save_vpaths;
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct the VPATH listing for the pattern and searchpath given.
|
||||
|
||||
This function is called to generate selective VPATH lists and also for
|
||||
the general VPATH list (which is in fact just a selective VPATH that
|
||||
is applied to everything). The returned pointer is either put in the
|
||||
linked list of all selective VPATH lists or in the GENERAL_VPATH
|
||||
variable.
|
||||
|
||||
If SEARCHPATH is nil, remove all previous listings with the same
|
||||
pattern. If PATTERN is nil, remove all VPATH listings.
|
||||
Existing and readable directories that are not "." given in the
|
||||
searchpath separated by colons are loaded into the directory hash
|
||||
table if they are not there already and put in the VPATH searchpath
|
||||
for the given pattern with trailing slashes stripped off if present
|
||||
(and if the directory is not the root, "/").
|
||||
The length of the longest entry in the list is put in the structure as well.
|
||||
The new entry will be at the head of the VPATHS chain. */
|
||||
|
||||
void
|
||||
construct_vpath_list (pattern, dirpath)
|
||||
char *pattern, *dirpath;
|
||||
{
|
||||
register unsigned int elem;
|
||||
register char *p;
|
||||
register char **vpath;
|
||||
register unsigned int maxvpath;
|
||||
unsigned int maxelem;
|
||||
char *percent;
|
||||
|
||||
if (pattern != 0)
|
||||
{
|
||||
pattern = savestring (pattern, strlen (pattern));
|
||||
percent = find_percent (pattern);
|
||||
}
|
||||
|
||||
if (dirpath == 0)
|
||||
{
|
||||
/* Remove matching listings. */
|
||||
register struct vpath *path, *lastpath;
|
||||
|
||||
lastpath = 0;
|
||||
path = vpaths;
|
||||
while (path != 0)
|
||||
{
|
||||
struct vpath *next = path->next;
|
||||
|
||||
if (pattern == 0
|
||||
|| (((percent == 0 && path->percent == 0)
|
||||
|| (percent - pattern == path->percent - path->pattern))
|
||||
&& streq (pattern, path->pattern)))
|
||||
{
|
||||
/* Remove it from the linked list. */
|
||||
if (lastpath == 0)
|
||||
vpaths = path->next;
|
||||
else
|
||||
lastpath->next = next;
|
||||
|
||||
/* Free its unused storage. */
|
||||
free (path->pattern);
|
||||
free ((char *) path->searchpath);
|
||||
free ((char *) path);
|
||||
}
|
||||
else
|
||||
lastpath = path;
|
||||
|
||||
path = next;
|
||||
}
|
||||
|
||||
if (pattern != 0)
|
||||
free (pattern);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Figure out the maximum number of VPATH entries and
|
||||
put it in MAXELEM. We start with 2, one before the
|
||||
first colon and one nil, the list terminator and
|
||||
increment our estimated number for each colon or blank we find. */
|
||||
maxelem = 2;
|
||||
p = dirpath;
|
||||
while (*p != '\0')
|
||||
if (*p++ == PATH_SEPARATOR_CHAR || isblank (*p))
|
||||
++maxelem;
|
||||
|
||||
vpath = (char **) xmalloc (maxelem * sizeof (char *));
|
||||
maxvpath = 0;
|
||||
|
||||
/* Skip over any initial colons and blanks. */
|
||||
p = dirpath;
|
||||
while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
|
||||
++p;
|
||||
|
||||
elem = 0;
|
||||
while (*p != '\0')
|
||||
{
|
||||
char *v;
|
||||
unsigned int len;
|
||||
|
||||
/* Find the end of this entry. */
|
||||
v = p;
|
||||
while (*p != '\0' && *p != PATH_SEPARATOR_CHAR && !isblank (*p))
|
||||
++p;
|
||||
|
||||
len = p - v;
|
||||
/* Make sure there's no trailing slash,
|
||||
but still allow "/" as a directory. */
|
||||
if (len > 1 && p[-1] == '/')
|
||||
--len;
|
||||
|
||||
if (len > 1 || *v != '.')
|
||||
{
|
||||
v = savestring (v, len);
|
||||
|
||||
/* Verify that the directory actually exists. */
|
||||
|
||||
if (dir_file_exists_p (v, ""))
|
||||
{
|
||||
/* It does. Put it in the list. */
|
||||
vpath[elem++] = dir_name (v);
|
||||
free (v);
|
||||
if (len > maxvpath)
|
||||
maxvpath = len;
|
||||
}
|
||||
else
|
||||
/* The directory does not exist. Omit from the list. */
|
||||
free (v);
|
||||
}
|
||||
|
||||
/* Skip over colons and blanks between entries. */
|
||||
while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
|
||||
++p;
|
||||
}
|
||||
|
||||
if (elem > 0)
|
||||
{
|
||||
struct vpath *path;
|
||||
/* ELEM is now incremented one element past the last
|
||||
entry, to where the nil-pointer terminator goes.
|
||||
Usually this is maxelem - 1. If not, shrink down. */
|
||||
if (elem < (maxelem - 1))
|
||||
vpath = (char **) xrealloc ((char *) vpath,
|
||||
(elem + 1) * sizeof (char *));
|
||||
|
||||
/* Put the nil-pointer terminator on the end of the VPATH list. */
|
||||
vpath[elem] = 0;
|
||||
|
||||
/* Construct the vpath structure and put it into the linked list. */
|
||||
path = (struct vpath *) xmalloc (sizeof (struct vpath));
|
||||
path->searchpath = vpath;
|
||||
path->maxlen = maxvpath;
|
||||
path->next = vpaths;
|
||||
vpaths = path;
|
||||
|
||||
/* Set up the members. */
|
||||
path->pattern = pattern;
|
||||
path->percent = percent;
|
||||
path->patlen = strlen (pattern);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There were no entries, so free whatever space we allocated. */
|
||||
free ((char *) vpath);
|
||||
if (pattern != 0)
|
||||
free (pattern);
|
||||
}
|
||||
}
|
||||
|
||||
/* Search the VPATH list whose pattern matches *FILE for a directory
|
||||
where the name pointed to by FILE exists. If it is found, we set *FILE to
|
||||
the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is
|
||||
not NULL) to its modtime (or zero if no stat call was done), and return 1.
|
||||
Otherwise we return 0. */
|
||||
|
||||
int
|
||||
vpath_search (file, mtime_ptr)
|
||||
char **file;
|
||||
time_t *mtime_ptr;
|
||||
{
|
||||
register struct vpath *v;
|
||||
|
||||
/* If there are no VPATH entries or FILENAME starts at the root,
|
||||
there is nothing we can do. */
|
||||
|
||||
if (**file == '/' || (vpaths == 0 && general_vpath == 0))
|
||||
return 0;
|
||||
|
||||
for (v = vpaths; v != 0; v = v->next)
|
||||
if (pattern_matches (v->pattern, v->percent, *file))
|
||||
if (selective_vpath_search (v, file, mtime_ptr))
|
||||
return 1;
|
||||
|
||||
if (general_vpath != 0
|
||||
&& selective_vpath_search (general_vpath, file, mtime_ptr))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Search the given VPATH list for a directory where the name pointed
|
||||
to by FILE exists. If it is found, we set *FILE to the newly malloc'd
|
||||
name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to
|
||||
its modtime (or zero if no stat call was done), and we return 1.
|
||||
Otherwise we return 0. */
|
||||
|
||||
static int
|
||||
selective_vpath_search (path, file, mtime_ptr)
|
||||
struct vpath *path;
|
||||
char **file;
|
||||
time_t *mtime_ptr;
|
||||
{
|
||||
int not_target;
|
||||
char *name, *n;
|
||||
char *filename;
|
||||
register char **vpath = path->searchpath;
|
||||
unsigned int maxvpath = path->maxlen;
|
||||
register unsigned int i;
|
||||
unsigned int flen, vlen, name_dplen;
|
||||
int exists = 0;
|
||||
|
||||
/* Find out if *FILE is a target.
|
||||
If and only if it is NOT a target, we will accept prospective
|
||||
files that don't exist but are mentioned in a makefile. */
|
||||
{
|
||||
struct file *f = lookup_file (*file);
|
||||
not_target = f == 0 || !f->is_target;
|
||||
}
|
||||
|
||||
flen = strlen (*file);
|
||||
|
||||
/* Split *FILE into a directory prefix and a name-within-directory.
|
||||
NAME_DPLEN gets the length of the prefix; FILENAME gets the
|
||||
pointer to the name-within-directory and FLEN is its length. */
|
||||
|
||||
n = rindex (*file, '/');
|
||||
name_dplen = n != 0 ? n - *file : 0;
|
||||
filename = name_dplen > 0 ? n + 1 : *file;
|
||||
if (name_dplen > 0)
|
||||
flen -= name_dplen + 1;
|
||||
|
||||
/* Allocate enough space for the biggest VPATH entry,
|
||||
a slash, the directory prefix that came with *FILE,
|
||||
another slash (although this one may not always be
|
||||
necessary), the filename, and a null terminator. */
|
||||
name = (char *) alloca (maxvpath + 1 + name_dplen + 1 + flen + 1);
|
||||
|
||||
/* Try each VPATH entry. */
|
||||
for (i = 0; vpath[i] != 0; ++i)
|
||||
{
|
||||
int exists_in_cache = 0;
|
||||
|
||||
n = name;
|
||||
|
||||
/* Put the next VPATH entry into NAME at N and increment N past it. */
|
||||
vlen = strlen (vpath[i]);
|
||||
bcopy (vpath[i], n, vlen);
|
||||
n += vlen;
|
||||
|
||||
/* Add the directory prefix already in *FILE. */
|
||||
if (name_dplen > 0)
|
||||
{
|
||||
*n++ = '/';
|
||||
bcopy (*file, n, name_dplen);
|
||||
n += name_dplen;
|
||||
}
|
||||
|
||||
/* Now add the name-within-directory at the end of NAME. */
|
||||
if (n != name && n[-1] != '/')
|
||||
{
|
||||
*n = '/';
|
||||
bcopy (filename, n + 1, flen + 1);
|
||||
}
|
||||
else
|
||||
bcopy (filename, n, flen + 1);
|
||||
|
||||
/* Check if the file is mentioned in a makefile. If *FILE is not
|
||||
a target, that is enough for us to decide this file exists.
|
||||
If *FILE is a target, then the file must be mentioned in the
|
||||
makefile also as a target to be chosen.
|
||||
|
||||
The restriction that *FILE must not be a target for a
|
||||
makefile-mentioned file to be chosen was added by an
|
||||
inadequately commented change in July 1990; I am not sure off
|
||||
hand what problem it fixes.
|
||||
|
||||
In December 1993 I loosened of this restriction to allow a file
|
||||
to be chosen if it is mentioned as a target in a makefile. This
|
||||
seem logical. */
|
||||
{
|
||||
struct file *f = lookup_file (name);
|
||||
if (f != 0)
|
||||
exists = not_target || f->is_target;
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
/* That file wasn't mentioned in the makefile.
|
||||
See if it actually exists. */
|
||||
|
||||
/* Clobber a null into the name at the last slash.
|
||||
Now NAME is the name of the directory to look in. */
|
||||
*n = '\0';
|
||||
|
||||
/* We know the directory is in the hash table now because either
|
||||
construct_vpath_list or the code just above put it there.
|
||||
Does the file we seek exist in it? */
|
||||
exists_in_cache = exists = dir_file_exists_p (name, filename);
|
||||
}
|
||||
|
||||
if (exists)
|
||||
{
|
||||
/* The file is in the directory cache.
|
||||
Now check that it actually exists in the filesystem.
|
||||
The cache may be out of date. When vpath thinks a file
|
||||
exists, but stat fails for it, confusion results in the
|
||||
higher levels. */
|
||||
|
||||
struct stat st;
|
||||
|
||||
/* Put the slash back in NAME. */
|
||||
*n = '/';
|
||||
|
||||
if (!exists_in_cache /* Makefile-mentioned file need not exist. */
|
||||
|| safe_stat (name, &st) == 0) /* Does it really exist? */
|
||||
{
|
||||
/* We have found a file.
|
||||
Store the name we found into *FILE for the caller. */
|
||||
|
||||
*file = savestring (name, (n + 1 - name) + flen);
|
||||
|
||||
if (mtime_ptr != 0)
|
||||
/* Store the modtime into *MTIME_PTR for the caller.
|
||||
If we have had no need to stat the file here,
|
||||
we record a zero modtime to indicate this. */
|
||||
*mtime_ptr = exists_in_cache ? st.st_mtime : (time_t) 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
exists = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print the data base of VPATH search paths. */
|
||||
|
||||
void
|
||||
print_vpath_data_base ()
|
||||
{
|
||||
register unsigned int nvpaths;
|
||||
register struct vpath *v;
|
||||
|
||||
puts ("\n# VPATH Search Paths\n");
|
||||
|
||||
nvpaths = 0;
|
||||
for (v = vpaths; v != 0; v = v->next)
|
||||
{
|
||||
register unsigned int i;
|
||||
|
||||
++nvpaths;
|
||||
|
||||
printf ("vpath %s ", v->pattern);
|
||||
|
||||
for (i = 0; v->searchpath[i] != 0; ++i)
|
||||
printf ("%s%c", v->searchpath[i],
|
||||
v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
|
||||
}
|
||||
|
||||
if (vpaths == 0)
|
||||
puts ("# No `vpath' search paths.");
|
||||
else
|
||||
printf ("\n# %u `vpath' search paths.\n", nvpaths);
|
||||
|
||||
if (general_vpath == 0)
|
||||
puts ("\n# No general (`VPATH' variable) search path.");
|
||||
else
|
||||
{
|
||||
register char **path = general_vpath->searchpath;
|
||||
register unsigned int i;
|
||||
|
||||
fputs ("\n# General (`VPATH' variable) search path:\n# ", stdout);
|
||||
|
||||
for (i = 0; path[i] != 0; ++i)
|
||||
printf ("%s%c", path[i],
|
||||
path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
#ifndef WINDIR_H
|
||||
#define WINDIR_H
|
||||
|
||||
#include <wtypes.h>
|
||||
#include <winbase.h>
|
||||
|
||||
struct dirent {
|
||||
char *d_name;
|
||||
};
|
||||
typedef struct {
|
||||
HANDLE dp;
|
||||
WIN32_FIND_DATA fdata;
|
||||
struct dirent de;
|
||||
} dir_s;
|
||||
typedef dir_s DIR;
|
||||
|
||||
DIR *opendir(char *);
|
||||
struct dirent *readdir(DIR *);
|
||||
void closedir(DIR *);
|
||||
|
||||
#endif
|
||||
@ -1,27 +0,0 @@
|
||||
This directory contains the source files for shmsdos.exe and
|
||||
nsinstall.exe, which are used in conjunction with gmake.exe
|
||||
to build some components of the Mozilla client on Win32.
|
||||
|
||||
The tool shmsdos.exe is a very lightweight shell. It is
|
||||
the default shell for our gmake.exe. shmsdos.exe implements
|
||||
several common Unix utilities as built-in commands, such as
|
||||
mv, cp, rm, echo, mkdir, etc. It only implements very
|
||||
limited shell features. It can do if-then-else and for loops,
|
||||
but it can't do variables, pipes, standard I/O redicrection, etc.
|
||||
|
||||
It is possible to use a real Bourne shell with our gmake.exe
|
||||
by defining the SHELL variable in your makefiles. Our gmake.exe
|
||||
works with the Korn shell (sh.exe) of MKS Toolkit. If you go
|
||||
this route, you will also need nsinstall.exe. (nsinstall is
|
||||
a built-in command for shmsdos.exe.)
|
||||
|
||||
To build shmsdos.exe, you need Microsoft Visual C++ and nmake.
|
||||
Just issue the command:
|
||||
nmake /f shmsdos.mak
|
||||
The output is Release\shmsdos.exe. Copy it to a directory on
|
||||
your Path.
|
||||
|
||||
To build nsinstall.exe, issue the command:
|
||||
nmake /f nsinstall.mak
|
||||
The output is Release\nsinstall.exe. Copy it to a directory
|
||||
on your Path.
|
||||
@ -1,697 +0,0 @@
|
||||
/*
|
||||
* The nsinstall command for Win32
|
||||
*
|
||||
* Our gmake makefiles use the nsinstall command to create the
|
||||
* object directories or installing headers and libs to ns/dist.
|
||||
* The shmsdos shell has nsinstall as a built-in command. However,
|
||||
* if we use another shell like MKS toolkit's sh, we need to have
|
||||
* the nsinstall command separately.
|
||||
*
|
||||
* This file was generated by just taking the part of shmsdos.c
|
||||
* needed by nsinstall and deleting the recursive directory copy code.
|
||||
*
|
||||
* To build, say
|
||||
* nmake /f nsinstall.mak
|
||||
*/
|
||||
|
||||
#include <direct.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#pragma hdrstop
|
||||
|
||||
/*
|
||||
* sh_FileFcn --
|
||||
*
|
||||
* A function that operates on a file. The pathname is either
|
||||
* absolute or relative to the current directory, and contains
|
||||
* no wildcard characters such as * and ?. Additional arguments
|
||||
* can be passed to the function via the arg pointer.
|
||||
*/
|
||||
|
||||
typedef BOOL (*sh_FileFcn)(
|
||||
char *pathName,
|
||||
WIN32_FIND_DATA *fileData,
|
||||
void *arg);
|
||||
|
||||
static int shellCp (char **pArgv);
|
||||
static int shellNsinstall (char **pArgv);
|
||||
static int shellMkdir (char **pArgv);
|
||||
static BOOL sh_EnumerateFiles(const char *pattern, const char *where,
|
||||
sh_FileFcn fileFcn, void *arg, int *nFiles);
|
||||
static const char *sh_GetLastErrorMessage(void);
|
||||
static BOOL sh_DoCopy(char *srcFileName, DWORD srcFileAttributes,
|
||||
char *dstFileName, DWORD dstFileAttributes,
|
||||
int force, int recursive);
|
||||
|
||||
/* changes all forward slashes in token to back slashes */
|
||||
void changeForwardSlashesTpBackSlashes ( char *arg )
|
||||
{
|
||||
if ( arg == NULL )
|
||||
return;
|
||||
|
||||
while ( *arg ) {
|
||||
if ( *arg == '/' )
|
||||
*arg = '\\';
|
||||
arg++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[ ])
|
||||
{
|
||||
return shellNsinstall ( argv + 1 );
|
||||
}
|
||||
|
||||
static int
|
||||
shellNsinstall (char **pArgv)
|
||||
{
|
||||
int retVal = 0; /* exit status */
|
||||
int dirOnly = 0; /* 1 if and only if -D is specified */
|
||||
char **pSrc;
|
||||
char **pDst;
|
||||
|
||||
/*
|
||||
* Process the command-line options. We ignore the
|
||||
* options except for -D. Some options, such as -m,
|
||||
* are followed by an argument. We need to skip the
|
||||
* argument too.
|
||||
*/
|
||||
while ( *pArgv && **pArgv == '-' ) {
|
||||
char c = (*pArgv)[1]; /* The char after '-' */
|
||||
|
||||
if ( c == 'D' ) {
|
||||
dirOnly = 1;
|
||||
} else if ( c == 'm' ) {
|
||||
pArgv++; /* skip the next argument */
|
||||
}
|
||||
pArgv++;
|
||||
}
|
||||
|
||||
if ( !dirOnly ) {
|
||||
/* There are files to install. Get source files */
|
||||
if ( *pArgv ) {
|
||||
pSrc = pArgv++;
|
||||
} else {
|
||||
fprintf( stderr, "nsinstall: not enough arguments\n");
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get to last token to find destination directory */
|
||||
if ( *pArgv ) {
|
||||
pDst = pArgv++;
|
||||
if ( dirOnly && *pArgv ) {
|
||||
fprintf( stderr, "nsinstall: too many arguments with -D\n");
|
||||
return 3;
|
||||
}
|
||||
} else {
|
||||
fprintf( stderr, "nsinstall: not enough arguments\n");
|
||||
return 3;
|
||||
}
|
||||
while ( *pArgv )
|
||||
pDst = pArgv++;
|
||||
|
||||
retVal = shellMkdir ( pDst );
|
||||
if ( retVal )
|
||||
return retVal;
|
||||
if ( !dirOnly )
|
||||
retVal = shellCp ( pSrc );
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static int
|
||||
shellMkdir (char **pArgv)
|
||||
{
|
||||
int retVal = 0; /* assume valid return */
|
||||
char *arg;
|
||||
char *pArg;
|
||||
char path[_MAX_PATH];
|
||||
char tmpPath[_MAX_PATH];
|
||||
char *pTmpPath = tmpPath;
|
||||
|
||||
/* All the options are simply ignored in this implementation */
|
||||
while ( *pArgv && **pArgv == '-' ) {
|
||||
if ( (*pArgv)[1] == 'm' ) {
|
||||
pArgv++; /* skip the next argument (mode) */
|
||||
}
|
||||
pArgv++;
|
||||
}
|
||||
|
||||
while ( *pArgv ) {
|
||||
arg = *pArgv;
|
||||
changeForwardSlashesTpBackSlashes ( arg );
|
||||
pArg = arg;
|
||||
pTmpPath = tmpPath;
|
||||
while ( 1 ) {
|
||||
/* create part of path */
|
||||
while ( *pArg ) {
|
||||
*pTmpPath++ = *pArg++;
|
||||
if ( *pArg == '\\' )
|
||||
break;
|
||||
}
|
||||
*pTmpPath = '\0';
|
||||
|
||||
/* check if directory alreay exists */
|
||||
_getcwd ( path, sizeof (path) );
|
||||
if ( _chdir ( tmpPath ) != -1 ) {
|
||||
_chdir ( path );
|
||||
} else {
|
||||
if ( _mkdir ( tmpPath ) == -1 ) {
|
||||
// while ( waitForDebug );
|
||||
printf ( "%s: ", tmpPath );
|
||||
perror ( "Could not create the directory" );
|
||||
retVal = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( *pArg == '\0' ) /* complete path? */
|
||||
break;
|
||||
/* loop for next directory */
|
||||
}
|
||||
|
||||
pArgv++;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static const char *
|
||||
sh_GetLastErrorMessage()
|
||||
{
|
||||
static char buf[128];
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* default language */
|
||||
buf,
|
||||
sizeof(buf),
|
||||
NULL
|
||||
);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* struct sh_FileData --
|
||||
*
|
||||
* A pointer to the sh_FileData structure is passed into sh_RecordFileData,
|
||||
* which will fill in the fields.
|
||||
*/
|
||||
|
||||
struct sh_FileData {
|
||||
char pathName[_MAX_PATH];
|
||||
DWORD dwFileAttributes;
|
||||
};
|
||||
|
||||
/*
|
||||
* sh_RecordFileData --
|
||||
*
|
||||
* Record the pathname and attributes of the file in
|
||||
* the sh_FileData structure pointed to by arg.
|
||||
*
|
||||
* Always return TRUE (successful completion).
|
||||
*
|
||||
* This function is intended to be passed into sh_EnumerateFiles
|
||||
* to see if a certain pattern expands to exactly one file/directory,
|
||||
* and if so, record its pathname and attributes.
|
||||
*/
|
||||
|
||||
static BOOL
|
||||
sh_RecordFileData(char *pathName, WIN32_FIND_DATA *findData, void *arg)
|
||||
{
|
||||
struct sh_FileData *fData = (struct sh_FileData *) arg;
|
||||
|
||||
strcpy(fData->pathName, pathName);
|
||||
fData->dwFileAttributes = findData->dwFileAttributes;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
sh_DoCopy(char *srcFileName,
|
||||
DWORD srcFileAttributes,
|
||||
char *dstFileName,
|
||||
DWORD dstFileAttributes,
|
||||
int force,
|
||||
int recursive
|
||||
)
|
||||
{
|
||||
if (dstFileAttributes != 0xFFFFFFFF) {
|
||||
if ((dstFileAttributes & FILE_ATTRIBUTE_READONLY) && force) {
|
||||
dstFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
|
||||
SetFileAttributes(dstFileName, dstFileAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
if (srcFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
fprintf(stderr, "nsinstall: %s is a directory\n",
|
||||
srcFileName);
|
||||
return FALSE;
|
||||
} else {
|
||||
if (!CopyFile(srcFileName, dstFileName, FALSE)) {
|
||||
fprintf(stderr, "nsinstall: cannot copy %s to %s: %s\n",
|
||||
srcFileName, dstFileName, sh_GetLastErrorMessage());
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* struct sh_CpCmdArg --
|
||||
*
|
||||
* A pointer to the sh_CpCmdArg structure is passed into sh_CpFileCmd.
|
||||
* The sh_CpCmdArg contains information about the cp command, and
|
||||
* provide a buffer for constructing the destination file name.
|
||||
*/
|
||||
|
||||
struct sh_CpCmdArg {
|
||||
int force; /* -f option, ok to overwrite an existing
|
||||
* read-only destination file */
|
||||
int recursive; /* -r or -R option, recursively copy
|
||||
* directories. Note: this field is not used
|
||||
* by nsinstall and should always be 0. */
|
||||
char *dstFileName; /* a buffer for constructing the destination
|
||||
* file name */
|
||||
char *dstFileNameMarker; /* points to where in the dstFileName buffer
|
||||
* we should write the file component of the
|
||||
* destination file */
|
||||
};
|
||||
|
||||
/*
|
||||
* sh_CpFileCmd --
|
||||
*
|
||||
* Copy a file to the destination directory
|
||||
*
|
||||
* This function is intended to be passed into sh_EnumerateFiles to
|
||||
* copy all the files specified by the pattern to the destination
|
||||
* directory.
|
||||
*
|
||||
* Return TRUE if the file is successfully copied, and FALSE otherwise.
|
||||
*/
|
||||
|
||||
static BOOL
|
||||
sh_CpFileCmd(char *pathName, WIN32_FIND_DATA *findData, void *cpArg)
|
||||
{
|
||||
BOOL retVal = TRUE;
|
||||
struct sh_CpCmdArg *arg = (struct sh_CpCmdArg *) cpArg;
|
||||
|
||||
strcpy(arg->dstFileNameMarker, findData->cFileName);
|
||||
return sh_DoCopy(pathName, findData->dwFileAttributes,
|
||||
arg->dstFileName, GetFileAttributes(arg->dstFileName),
|
||||
arg->force, arg->recursive);
|
||||
}
|
||||
|
||||
static int
|
||||
shellCp (char **pArgv)
|
||||
{
|
||||
int retVal = 0;
|
||||
char **pSrc;
|
||||
char **pDst;
|
||||
struct sh_CpCmdArg arg;
|
||||
struct sh_FileData dstData;
|
||||
int dstIsDir = 0;
|
||||
int n;
|
||||
|
||||
arg.force = 0;
|
||||
arg.recursive = 0;
|
||||
arg.dstFileName = dstData.pathName;
|
||||
arg.dstFileNameMarker = 0;
|
||||
|
||||
while (*pArgv && **pArgv == '-') {
|
||||
char *p = *pArgv;
|
||||
|
||||
while (*(++p)) {
|
||||
if (*p == 'f') {
|
||||
arg.force = 1;
|
||||
}
|
||||
}
|
||||
pArgv++;
|
||||
}
|
||||
|
||||
/* the first source file */
|
||||
if (*pArgv) {
|
||||
pSrc = pArgv++;
|
||||
} else {
|
||||
fprintf(stderr, "nsinstall: not enough arguments\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* get to the last token to find destination */
|
||||
if (*pArgv) {
|
||||
pDst = pArgv++;
|
||||
} else {
|
||||
fprintf(stderr, "nsinstall: not enough arguments\n");
|
||||
return 3;
|
||||
}
|
||||
while (*pArgv) {
|
||||
pDst = pArgv++;
|
||||
}
|
||||
|
||||
/*
|
||||
* The destination pattern must unambiguously expand to exactly
|
||||
* one file or directory.
|
||||
*/
|
||||
|
||||
changeForwardSlashesTpBackSlashes(*pDst);
|
||||
sh_EnumerateFiles(*pDst, *pDst, sh_RecordFileData, &dstData, &n);
|
||||
assert(n >= 0);
|
||||
if (n == 1) {
|
||||
/*
|
||||
* Is the destination a file or directory?
|
||||
*/
|
||||
|
||||
if (dstData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
dstIsDir = 1;
|
||||
}
|
||||
} else if (n > 1) {
|
||||
fprintf(stderr, "nsinstall: %s: ambiguous destination file "
|
||||
"or directory\n", *pDst);
|
||||
return 3;
|
||||
} else {
|
||||
/*
|
||||
* n == 0, meaning that destination file or directory does
|
||||
* not exist. In this case the destination file directory
|
||||
* name must be fully specified.
|
||||
*/
|
||||
|
||||
char *p;
|
||||
|
||||
for (p = *pDst; *p; p++) {
|
||||
if (*p == '*' || *p == '?') {
|
||||
fprintf(stderr, "nsinstall: %s: No such file or directory\n",
|
||||
*pDst);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not include the trailing \, if any, unless it is a root
|
||||
* directory (\ or X:\).
|
||||
*/
|
||||
|
||||
if (p > *pDst && p[-1] == '\\' && p != *pDst + 1 && p[-2] != ':') {
|
||||
p[-1] = '\0';
|
||||
}
|
||||
strcpy(dstData.pathName, *pDst);
|
||||
dstData.dwFileAttributes = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there are two or more source files, the destination has
|
||||
* to be a directory.
|
||||
*/
|
||||
|
||||
if (pDst - pSrc > 1 && !dstIsDir) {
|
||||
fprintf(stderr, "nsinstall: cannot copy more than"
|
||||
" one file to the same destination file\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (dstIsDir) {
|
||||
arg.dstFileNameMarker = arg.dstFileName + strlen(arg.dstFileName);
|
||||
|
||||
/*
|
||||
* Now arg.dstFileNameMarker is pointing to the null byte at the
|
||||
* end of string. We want to make sure that there is a \ at the
|
||||
* end of string, and arg.dstFileNameMarker should point right
|
||||
* after that \.
|
||||
*/
|
||||
|
||||
if (arg.dstFileNameMarker[-1] != '\\') {
|
||||
*(arg.dstFileNameMarker++) = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
if (!dstIsDir) {
|
||||
struct sh_FileData srcData;
|
||||
|
||||
assert(pDst - pSrc == 1);
|
||||
changeForwardSlashesTpBackSlashes(*pSrc);
|
||||
sh_EnumerateFiles(*pSrc, *pSrc, sh_RecordFileData, &srcData, &n);
|
||||
if (n == 0) {
|
||||
fprintf(stderr, "nsinstall: %s: No such file or directory\n",
|
||||
*pSrc);
|
||||
retVal = 3;
|
||||
} else if (n > 1) {
|
||||
fprintf(stderr, "nsinstall: cannot copy more than one file or "
|
||||
"directory to the same destination\n");
|
||||
retVal = 3;
|
||||
} else {
|
||||
assert(n == 1);
|
||||
if (sh_DoCopy(srcData.pathName, srcData.dwFileAttributes,
|
||||
dstData.pathName, dstData.dwFileAttributes,
|
||||
arg.force, arg.recursive) == FALSE) {
|
||||
retVal = 3;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
for ( ; *pSrc != *pDst; pSrc++) {
|
||||
BOOL rv;
|
||||
|
||||
changeForwardSlashesTpBackSlashes(*pSrc);
|
||||
rv = sh_EnumerateFiles(*pSrc, *pSrc, sh_CpFileCmd, &arg, &n);
|
||||
if (rv == FALSE) {
|
||||
retVal = 3;
|
||||
} else {
|
||||
if (n == 0) {
|
||||
fprintf(stderr, "nsinstall: %s: No such file or directory\n",
|
||||
*pSrc);
|
||||
retVal = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*
|
||||
* sh_EnumerateFiles --
|
||||
*
|
||||
* Enumerate all the files in the specified pattern, which is a pathname
|
||||
* containing possibly wildcard characters such as * and ?. fileFcn
|
||||
* is called on each file, passing the expanded file name, a pointer
|
||||
* to the file's WIN32_FILE_DATA, and the arg pointer.
|
||||
*
|
||||
* It is assumed that there are no wildcard characters before the
|
||||
* character pointed to by 'where'.
|
||||
*
|
||||
* On return, *nFiles stores the number of files enumerated. *nFiles is
|
||||
* set to this number whether sh_EnumerateFiles or 'fileFcn' succeeds
|
||||
* or not.
|
||||
*
|
||||
* Return TRUE if the files are successfully enumerated and all
|
||||
* 'fileFcn' invocations succeeded. Return FALSE if something went
|
||||
* wrong.
|
||||
*/
|
||||
|
||||
static BOOL sh_EnumerateFiles(
|
||||
const char *pattern,
|
||||
const char *where,
|
||||
sh_FileFcn fileFcn,
|
||||
void *arg,
|
||||
int *nFiles
|
||||
)
|
||||
{
|
||||
WIN32_FIND_DATA fileData;
|
||||
HANDLE hSearch;
|
||||
const char *src;
|
||||
char *dst;
|
||||
char fileName[_MAX_PATH];
|
||||
char *fileNameMarker = fileName;
|
||||
char *oldFileNameMarker;
|
||||
BOOL hasWildcard = FALSE;
|
||||
BOOL retVal = TRUE;
|
||||
BOOL patternEndsInDotStar = FALSE;
|
||||
BOOL patternEndsInDot = FALSE; /* a special case of
|
||||
* patternEndsInDotStar */
|
||||
int numDotsInPattern;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Windows expands patterns ending in ".", ".*", ".**", etc.
|
||||
* differently from the glob expansion on Unix. For example,
|
||||
* both "foo." and "foo.*" match "foo", and "*.*" matches
|
||||
* everything, including filenames with no dots. So we need
|
||||
* to throw away extra files returned by the FindNextFile()
|
||||
* function. We require that a matched filename have at least
|
||||
* the number of dots in the pattern.
|
||||
*/
|
||||
len = strlen(pattern);
|
||||
if (len >= 2) {
|
||||
/* Start from the end of pattern and go backward */
|
||||
const char *p = &pattern[len - 1];
|
||||
|
||||
/* We can have zero or more *'s */
|
||||
while (p >= pattern && *p == '*') {
|
||||
p--;
|
||||
}
|
||||
if (p >= pattern && *p == '.') {
|
||||
patternEndsInDotStar = TRUE;
|
||||
if (p == &pattern[len - 1]) {
|
||||
patternEndsInDot = TRUE;
|
||||
}
|
||||
p--;
|
||||
numDotsInPattern = 1;
|
||||
while (p >= pattern && *p != '\\') {
|
||||
if (*p == '.') {
|
||||
numDotsInPattern++;
|
||||
}
|
||||
p--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*nFiles = 0;
|
||||
|
||||
/*
|
||||
* Copy pattern to fileName, but only up to and not including
|
||||
* the first \ after the first wildcard letter.
|
||||
*
|
||||
* Make fileNameMarker point to one of the following:
|
||||
* - the start of fileName, if fileName does not contain any \.
|
||||
* - right after the \ before the first wildcard letter, if there is
|
||||
* a wildcard character.
|
||||
* - right after the last \, if there is no wildcard character.
|
||||
*/
|
||||
|
||||
dst = fileName;
|
||||
src = pattern;
|
||||
while (src < where) {
|
||||
if (*src == '\\') {
|
||||
oldFileNameMarker = fileNameMarker;
|
||||
fileNameMarker = dst + 1;
|
||||
}
|
||||
*(dst++) = *(src++);
|
||||
}
|
||||
|
||||
while (*src && *src != '*' && *src != '?') {
|
||||
if (*src == '\\') {
|
||||
oldFileNameMarker = fileNameMarker;
|
||||
fileNameMarker = dst + 1;
|
||||
}
|
||||
*(dst++) = *(src++);
|
||||
}
|
||||
|
||||
if (*src) {
|
||||
/*
|
||||
* Must have seen the first wildcard letter
|
||||
*/
|
||||
|
||||
hasWildcard = TRUE;
|
||||
while (*src && *src != '\\') {
|
||||
*(dst++) = *(src++);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now src points to either null or \ */
|
||||
|
||||
assert(*src == '\0' || *src == '\\');
|
||||
assert(hasWildcard || *src == '\0');
|
||||
*dst = '\0';
|
||||
|
||||
/*
|
||||
* If the pattern does not contain any wildcard characters, then
|
||||
* we don't need to go the FindFirstFile route.
|
||||
*/
|
||||
|
||||
if (!hasWildcard) {
|
||||
/*
|
||||
* See if it is the root directory, \, or X:\.
|
||||
*/
|
||||
|
||||
assert(!strcmp(fileName, pattern));
|
||||
assert(strlen(fileName) >= 1);
|
||||
if (dst[-1] == '\\' && (dst == fileName + 1 || dst[-2] == ':')) {
|
||||
fileData.cFileName[0] = '\0';
|
||||
} else {
|
||||
/*
|
||||
* Do not include the trailing \, if any
|
||||
*/
|
||||
|
||||
if (dst[-1] == '\\') {
|
||||
assert(*fileNameMarker == '\0');
|
||||
dst[-1] = '\0';
|
||||
fileNameMarker = oldFileNameMarker;
|
||||
}
|
||||
strcpy(fileData.cFileName, fileNameMarker);
|
||||
}
|
||||
fileData.dwFileAttributes = GetFileAttributes(fileName);
|
||||
if (fileData.dwFileAttributes == 0xFFFFFFFF) {
|
||||
return TRUE;
|
||||
}
|
||||
*nFiles = 1;
|
||||
return (*fileFcn)(fileName, &fileData, arg);
|
||||
}
|
||||
|
||||
hSearch = FindFirstFile(fileName, &fileData);
|
||||
if (hSearch == INVALID_HANDLE_VALUE) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
do {
|
||||
if (!strcmp(fileData.cFileName, ".")
|
||||
|| !strcmp(fileData.cFileName, "..")) {
|
||||
/*
|
||||
* Skip over . and ..
|
||||
*/
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (patternEndsInDotStar) {
|
||||
int nDots = 0;
|
||||
char *p = fileData.cFileName;
|
||||
while (*p) {
|
||||
if (*p == '.') {
|
||||
nDots++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
/* Now p points to the null byte at the end of file name */
|
||||
if (patternEndsInDot && (p == fileData.cFileName
|
||||
|| p[-1] != '.')) {
|
||||
/*
|
||||
* File name does not end in dot. Skip this file.
|
||||
* Note: windows file name probably cannot end in dot,
|
||||
* but we do this check anyway.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (nDots < numDotsInPattern) {
|
||||
/*
|
||||
* Not enough dots in file name. Must be an extra
|
||||
* file in matching .* pattern. Skip this file.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(fileNameMarker, fileData.cFileName);
|
||||
if (*src && *(src + 1)) {
|
||||
/*
|
||||
* More to go. Recurse.
|
||||
*/
|
||||
|
||||
int n;
|
||||
|
||||
assert(*src == '\\');
|
||||
where = fileName + strlen(fileName);
|
||||
strcat(fileName, src);
|
||||
sh_EnumerateFiles(fileName, where, fileFcn, arg, &n);
|
||||
*nFiles += n;
|
||||
} else {
|
||||
assert(strchr(fileName, '*') == NULL);
|
||||
assert(strchr(fileName, '?') == NULL);
|
||||
(*nFiles)++;
|
||||
if ((*fileFcn)(fileName, &fileData, arg) == FALSE) {
|
||||
retVal = FALSE;
|
||||
}
|
||||
}
|
||||
} while (FindNextFile(hSearch, &fileData));
|
||||
|
||||
FindClose(hSearch);
|
||||
return retVal;
|
||||
}
|
||||
@ -1,141 +0,0 @@
|
||||
# NMAKE file for building nsinstall.exe.
|
||||
#
|
||||
# This file is edited from an NMAKE file generated by
|
||||
# Microsoft Developer Studio, Format Version 4.20
|
||||
#
|
||||
# To build, say
|
||||
# nmake /f nsinstall.mak CFG=Release
|
||||
# or
|
||||
# nmake /f nsinstall.mak CFG=Debug
|
||||
# If CFG is omitted, a release build is assumed.
|
||||
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=Release
|
||||
!MESSAGE No configuration specified. Defaulting Release.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "Release" && "$(CFG)" != "Debug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE on this makefile
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "nsinstall.mak" CFG="Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Release" (based on "Win32 Console Application")
|
||||
!MESSAGE "Debug" (based on "Win32 Console Application")
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
################################################################################
|
||||
# Begin Project
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "Release"
|
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
|
||||
ALL : "$(OUTDIR)\nsinstall.exe"
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\nsinstall.obj"
|
||||
-@erase "$(OUTDIR)\nsinstall.exe"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
|
||||
/Fp"$(INTDIR)/nsinstall.pch" /YX /Fo"$(INTDIR)/" /c
|
||||
CPP_OBJS=.\Release/
|
||||
CPP_SBRS=.\.
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)/nsinstall.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=/nologo\
|
||||
/subsystem:console /incremental:no /pdb:"$(OUTDIR)/nsinstall.pdb"\
|
||||
/out:"$(OUTDIR)/nsinstall.exe"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\nsinstall.obj"
|
||||
|
||||
"$(OUTDIR)\nsinstall.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ELSEIF "$(CFG)" == "Debug"
|
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
|
||||
ALL : "$(OUTDIR)\nsinstall.exe"
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\nsinstall.obj"
|
||||
-@erase "$(INTDIR)\vc40.idb"
|
||||
-@erase "$(INTDIR)\vc40.pdb"
|
||||
-@erase "$(OUTDIR)\nsinstall.exe"
|
||||
-@erase "$(OUTDIR)\nsinstall.ilk"
|
||||
-@erase "$(OUTDIR)\nsinstall.pdb"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /MD /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "DEBUG"\
|
||||
/D "_CONSOLE" /Fp"$(INTDIR)/nsinstall.pch" /YX /Fo"$(INTDIR)/"\
|
||||
/Fd"$(INTDIR)/" /c
|
||||
CPP_OBJS=.\Debug/
|
||||
CPP_SBRS=.\.
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)/nsinstall.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=/nologo\
|
||||
/subsystem:console /incremental:yes /pdb:"$(OUTDIR)/nsinstall.pdb" /debug\
|
||||
/out:"$(OUTDIR)/nsinstall.exe"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\nsinstall.obj"
|
||||
|
||||
"$(OUTDIR)\nsinstall.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ENDIF
|
||||
|
||||
.c{$(CPP_OBJS)}.obj:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
.c{$(CPP_SBRS)}.sbr:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
################################################################################
|
||||
# Begin Target
|
||||
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsinstall.c
|
||||
DEP_CPP_SHMSD=\
|
||||
{$(INCLUDE)}"\sys\stat.h"\
|
||||
{$(INCLUDE)}"\sys\types.h"\
|
||||
|
||||
|
||||
"$(INTDIR)\nsinstall.obj" : $(SOURCE) $(DEP_CPP_SHMSD) "$(INTDIR)"
|
||||
|
||||
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
################################################################################
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,141 +0,0 @@
|
||||
# NMAKE file for building shmsdos.exe.
|
||||
#
|
||||
# This file is edited from an NMAKE file generated by
|
||||
# Microsoft Developer Studio, Format Version 4.20
|
||||
#
|
||||
# To build, say
|
||||
# nmake /f shmsdos.mak CFG=Release
|
||||
# or
|
||||
# nmake /f shmsdos.mak CFG=Debug
|
||||
# If CFG is omitted, a release build is assumed.
|
||||
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=Release
|
||||
!MESSAGE No configuration specified. Defaulting Release.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "Release" && "$(CFG)" != "Debug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE on this makefile
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "shmsdos.mak" CFG="Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Release" (based on "Win32 Console Application")
|
||||
!MESSAGE "Debug" (based on "Win32 Console Application")
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
################################################################################
|
||||
# Begin Project
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "Release"
|
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
|
||||
ALL : "$(OUTDIR)\shmsdos.exe"
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\shmsdos.obj"
|
||||
-@erase "$(OUTDIR)\shmsdos.exe"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
|
||||
/Fp"$(INTDIR)/shmsdos.pch" /YX /Fo"$(INTDIR)/" /c
|
||||
CPP_OBJS=.\Release/
|
||||
CPP_SBRS=.\.
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)/shmsdos.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=/nologo\
|
||||
/subsystem:console /incremental:no /pdb:"$(OUTDIR)/shmsdos.pdb"\
|
||||
/out:"$(OUTDIR)/shmsdos.exe"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\shmsdos.obj"
|
||||
|
||||
"$(OUTDIR)\shmsdos.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ELSEIF "$(CFG)" == "Debug"
|
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
|
||||
ALL : "$(OUTDIR)\shmsdos.exe"
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\shmsdos.obj"
|
||||
-@erase "$(INTDIR)\vc40.idb"
|
||||
-@erase "$(INTDIR)\vc40.pdb"
|
||||
-@erase "$(OUTDIR)\shmsdos.exe"
|
||||
-@erase "$(OUTDIR)\shmsdos.ilk"
|
||||
-@erase "$(OUTDIR)\shmsdos.pdb"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /MD /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "DEBUG"\
|
||||
/D "_CONSOLE" /Fp"$(INTDIR)/shmsdos.pch" /YX /Fo"$(INTDIR)/"\
|
||||
/Fd"$(INTDIR)/" /c
|
||||
CPP_OBJS=.\Debug/
|
||||
CPP_SBRS=.\.
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)/shmsdos.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=/nologo\
|
||||
/subsystem:console /incremental:yes /pdb:"$(OUTDIR)/shmsdos.pdb" /debug\
|
||||
/out:"$(OUTDIR)/shmsdos.exe"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\shmsdos.obj"
|
||||
|
||||
"$(OUTDIR)\shmsdos.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ENDIF
|
||||
|
||||
.c{$(CPP_OBJS)}.obj:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
.c{$(CPP_SBRS)}.sbr:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
################################################################################
|
||||
# Begin Target
|
||||
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shmsdos.c
|
||||
DEP_CPP_SHMSD=\
|
||||
{$(INCLUDE)}"\sys\stat.h"\
|
||||
{$(INCLUDE)}"\sys\types.h"\
|
||||
|
||||
|
||||
"$(INTDIR)\shmsdos.obj" : $(SOURCE) $(DEP_CPP_SHMSD) "$(INTDIR)"
|
||||
|
||||
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
################################################################################
|
||||
@ -1,9 +0,0 @@
|
||||
This directory contains the source for uname.exe on Win32.
|
||||
This version of uname.exe returns the string "WINNT" when
|
||||
you say 'uname -s' on Windows NT.
|
||||
|
||||
To build it, you need Microsoft Visual C++ and nmake.
|
||||
Issue the command:
|
||||
nmake /f uname.mak
|
||||
The output is Release\uname.exe. Copy it to a directory
|
||||
on your Path.
|
||||
@ -1,155 +0,0 @@
|
||||
/***********************************************************
|
||||
* uname - returns name of OS
|
||||
**********************************************************/
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define index(s, c) strchr((s), (c))
|
||||
#define streq(a, b) (strcmp ((a), (b)) == 0)
|
||||
|
||||
static char ** getlistOfOptions (char **pArgv, char * pOptions);
|
||||
static void getUnameOption ( char option );
|
||||
|
||||
/***********************************************************************
|
||||
* -a Print all information.
|
||||
*
|
||||
* -m Print the machine hardware name.
|
||||
*
|
||||
* -n Print the nodename (the nodename is the name by which
|
||||
* the system is known to a communications network).
|
||||
*
|
||||
* -p Print the current host's processor type.
|
||||
*
|
||||
* -r Print the operating system release.
|
||||
*
|
||||
* -s Print the name of the operating system. This is the
|
||||
* default.
|
||||
*
|
||||
* -v Print the operating system version.
|
||||
*
|
||||
* -S systemname
|
||||
* The nodename may be changed by specifying a system name
|
||||
* argument. The system name argument is restricted to
|
||||
* SYS_NMLN characters. SYS_NMLN is an implementation
|
||||
* specific value defined in <sys/utsname.h>. Only the
|
||||
* super-user is allowed this capability.
|
||||
***********************************************************************/
|
||||
|
||||
main( int argc, char *argv[ ], char *envp[ ] )
|
||||
{
|
||||
char options[1024];
|
||||
char *pOptions;
|
||||
char **pArgv;
|
||||
char c;
|
||||
|
||||
pArgv = &argv[1];
|
||||
pArgv = getlistOfOptions (pArgv, options);
|
||||
|
||||
/* if no options specified, then return operating system */
|
||||
pOptions = options;
|
||||
if ( *pOptions == '\0' ) {
|
||||
options[0] = 's';
|
||||
options[1] = '\0';
|
||||
}
|
||||
while (c = *pOptions++ ) {
|
||||
if ( c == 'a' ) {
|
||||
getUnameOption ( 's' );
|
||||
printf (" " );
|
||||
getUnameOption ( 'n' );
|
||||
printf (" " );
|
||||
getUnameOption ( 'r' );
|
||||
printf (" " );
|
||||
getUnameOption ( 'v' );
|
||||
printf (" " );
|
||||
getUnameOption ( 'm' );
|
||||
printf (" " );
|
||||
getUnameOption ( 'p' );
|
||||
} else
|
||||
getUnameOption ( c );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char **
|
||||
getlistOfOptions (char **pArgv, char * pOptions)
|
||||
{
|
||||
char *pArg;
|
||||
while ( *pArgv && (**pArgv == '-') ) {
|
||||
pArg = *pArgv;
|
||||
pArg++; /* skip over '-' */
|
||||
while ( *pArg )
|
||||
*pOptions++ = *pArg++;
|
||||
pArgv++;
|
||||
}
|
||||
*pOptions = '\0';
|
||||
return pArgv;
|
||||
}
|
||||
void getUnameOption ( char option )
|
||||
{
|
||||
char computerName[128];
|
||||
SYSTEM_INFO systemInfo;
|
||||
OSVERSIONINFO versionInfo;
|
||||
DWORD computerNameLength = sizeof(computerName);
|
||||
|
||||
GetSystemInfo( &systemInfo);
|
||||
GetComputerName( (LPTSTR)&computerName, &computerNameLength );
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
GetVersionEx( &versionInfo );
|
||||
|
||||
switch ( option ) {
|
||||
case 'a':
|
||||
printf ( getenv ("OS") );
|
||||
break;
|
||||
case 'm':
|
||||
printf ( "xx" );
|
||||
break;
|
||||
case 'n':
|
||||
printf ( computerName );
|
||||
break;
|
||||
case 'p':
|
||||
switch ( systemInfo.wProcessorArchitecture ) {
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
printf("I386");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_MIPS:
|
||||
printf("MIPS");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_ALPHA:
|
||||
printf("ALPHA");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_PPC:
|
||||
printf("PPC");
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN_PROCESSOR");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
printf ("%d.%d", versionInfo.dwMajorVersion, versionInfo.dwMinorVersion );
|
||||
break;
|
||||
case 's':
|
||||
switch ( versionInfo.dwPlatformId ) {
|
||||
case VER_PLATFORM_WIN32s:
|
||||
printf("WIN32S");
|
||||
break;
|
||||
case VER_PLATFORM_WIN32_WINDOWS:
|
||||
printf("WIN95");
|
||||
break;
|
||||
case VER_PLATFORM_WIN32_NT:
|
||||
printf("WINNT");
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN_OS");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
printf ("%d", versionInfo.dwBuildNumber );
|
||||
break;
|
||||
default:
|
||||
printf ( "uname -%c is unimplemented", option );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1,141 +0,0 @@
|
||||
# NMAKE file for building uname.exe.
|
||||
#
|
||||
# This file is edited from an NMAKE file generated by
|
||||
# Microsoft Developer Studio, Format Version 4.20
|
||||
#
|
||||
# To build, say
|
||||
# nmake /f uname.mak CFG=Release
|
||||
# or
|
||||
# nmake /f uname.mak CFG=Debug
|
||||
# If CFG is omitted, a release build is assumed.
|
||||
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=Release
|
||||
!MESSAGE No configuration specified. Defaulting Release.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "Release" && "$(CFG)" != "Debug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE on this makefile
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "uname.mak" CFG="Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Release" (based on "Win32 Console Application")
|
||||
!MESSAGE "Debug" (based on "Win32 Console Application")
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
################################################################################
|
||||
# Begin Project
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "Release"
|
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
|
||||
ALL : "$(OUTDIR)\uname.exe"
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\uname.obj"
|
||||
-@erase "$(OUTDIR)\uname.exe"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
|
||||
/Fp"$(INTDIR)/uname.pch" /YX /Fo"$(INTDIR)/" /c
|
||||
CPP_OBJS=.\Release/
|
||||
CPP_SBRS=.\.
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)/uname.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=/nologo\
|
||||
/subsystem:console /incremental:no /pdb:"$(OUTDIR)/uname.pdb"\
|
||||
/out:"$(OUTDIR)/uname.exe"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\uname.obj"
|
||||
|
||||
"$(OUTDIR)\uname.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ELSEIF "$(CFG)" == "Debug"
|
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
|
||||
ALL : "$(OUTDIR)\uname.exe"
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\uname.obj"
|
||||
-@erase "$(INTDIR)\vc40.idb"
|
||||
-@erase "$(INTDIR)\vc40.pdb"
|
||||
-@erase "$(OUTDIR)\uname.exe"
|
||||
-@erase "$(OUTDIR)\uname.ilk"
|
||||
-@erase "$(OUTDIR)\uname.pdb"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /MD /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "DEBUG"\
|
||||
/D "_CONSOLE" /Fp"$(INTDIR)/uname.pch" /YX /Fo"$(INTDIR)/"\
|
||||
/Fd"$(INTDIR)/" /c
|
||||
CPP_OBJS=.\Debug/
|
||||
CPP_SBRS=.\.
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)/uname.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=/nologo\
|
||||
/subsystem:console /incremental:yes /pdb:"$(OUTDIR)/uname.pdb" /debug\
|
||||
/out:"$(OUTDIR)/uname.exe"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\uname.obj"
|
||||
|
||||
"$(OUTDIR)\uname.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ENDIF
|
||||
|
||||
.c{$(CPP_OBJS)}.obj:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
.c{$(CPP_SBRS)}.sbr:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
################################################################################
|
||||
# Begin Target
|
||||
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\uname.c
|
||||
DEP_CPP_SHMSD=\
|
||||
{$(INCLUDE)}"\sys\stat.h"\
|
||||
{$(INCLUDE)}"\sys\types.h"\
|
||||
|
||||
|
||||
"$(INTDIR)\uname.obj" : $(SOURCE) $(DEP_CPP_SHMSD) "$(INTDIR)"
|
||||
|
||||
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
################################################################################
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user