This file contains diffs from version 3.62 of GNU Make to version 3.63. Changes in files that are generated by etags and TeX have been omitted. diff -ruN make-3.62/CHANGES make-3.63/CHANGES --- make-3.62/CHANGES Tue Sep 24 01:18:29 1991 +++ make-3.63/CHANGES @@ -1,289 +0,0 @@ -User-visible changes in GNU Make, excluding bug fixes, since version 3.05: -========================================================================== - -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 Make do it.) - -Version 3.05 - -Local Variables: -version-control: never -End: diff -ruN make-3.62/ChangeLog make-3.63/ChangeLog --- make-3.62/ChangeLog Tue Oct 29 21:01:31 1991 +++ make-3.63/ChangeLog Fri Jan 22 19:09:02 1993 @@ -1,3 +1,1403 @@ +Fri Jan 22 14:46:16 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.63. + + * job.c [!HAVE_UNION_WAIT] (WTERMSIG, WCOREDUMP, WEXITSTATUS): + Don't define if already defined. + + * remake.c (update_file): Don't keep track of the command_state before + calling update_file_1. Remove local variable COMMANDS_FINISHED, + and don't test it to decide to print the "is up to date" msg. + Testing for files_remade having changed should always be sufficient. + The old method lost when we are called in the goal chain run on a + makefile, because the makefile's command_state is already + `cs_finished' from the makefile chain run. + + * misc.c [HAVE_SETRE[GU]ID]: Test these to decl setre[gu]id. + + * configure.in: Rewrote wait checking. + Use AC_HAVE_HEADERS to check for . + Use AC_HAVE_FUNCS to check for waitpid and wait3. + Use a compile check to test just for `union wait'. + * job.c: Rewrote conditionals accordingly. + [HAVE_WAITPID]: Test this only to define WAIT_NOHANG. + [HAVE_WAIT3]: Likewise. + [HAVE_UNION_WAIT]: Test this to define WAIT_T and W*. + + * configure.in: Set CFLAGS and LDFLAGS before all checks. + + * dir.c: Add static forward decls of {open,read}_dirstream. + +Thu Jan 21 17:18:00 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.31. + + * job.c [NGROUPS_MAX && NGROUPS_MAX==0]: #undef NGROUPS_MAX. + + * compatMakefile (CFLAGS, LDFLAGS): Set to @CFLAGS@/@LDFLAGS@. + * build.template (CFLAGS, LDFLAGS): Same here. + * configure.in: AC_SUBST(CFLAGS) and LDFLAGS. + Set them to -g if not defined in the environment. + + * remake.c (library_search): Use LIBNAME consistently, setting it + only once, to be the passed name sans `-l'. + Pass new var FILE to be modified by vpath_search. + +Mon Jan 18 14:53:54 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.30. + + * job.c (start_waiting_jobs): Return when job_slots_used is equal to + job_slots. + + * configure.in: Add AC_CONST for the sake of getopt. + + * read.c (read_makefile): Continue after parsing `override' + directive, rather than falling through to lossage. + Check for EOL or blank after "override define". + + * compatMakefile (.c.o, remote.o): Put $(CFLAGS) after other switches. + +Fri Jan 15 12:52:52 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.29. + + * main.c (define_makeflags): After writing everything into + FLAGSTRING, only back up two chars if [-1] is a dash, meaning we + just wrote " -". Always terminate the string at *P. + + * remake.c (library_search): When constructing names in std dirs, + use &(*LIB)[2] for the stem, not LIBNAME (which points at the + buffer we are writing into!). + +Thu Jan 14 13:50:06 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * read.c (read_makefile): Set IN_IGNORED_DEFINE for "override + define" when IGNORING is true. + + * compatMakefile (distclean): Remove config.status and build.sh. + +Wed Jan 13 16:01:12 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.28. + + * misc.c (xmalloc, xrealloc): Cast result of malloc/realloc to + (char *). + + * arscan.c (ar_scan) [AIAMAG]: Cast read arg to (char *). + + * variable.c (define_automatic_variables): Override SHELL value for + origin o_env_override as well as o_env. + + * GNUmakefile (build.sh.in): Don't replace %globobjs%. Instead, + add the names of the glob objects (w/subdir) to %objs%. + * build.template (globobjs): Removed. + Take basename of $objs before linking. + +Tue Jan 12 12:31:06 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.27. + + * configure.in (AC_OUTPUT): Also edit build.sh. + * build.template: New file. + * GNUmakefile (build.sh.in): New rule to create it from build.template. + (make-$(version).tar.Z): Depend on build.sh.in. + + * main.c (die): Call print_data_base if -p. + (main): Don't call it here. + + * compatMakefile (defines): Add @DEFS@. configure should turn this + into -DHAVE_CONFIG_H. + +Mon Jan 11 14:39:23 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.26. + + * misc.c (init_access): Surround with #ifdef GETLOADAVG_PRIVILEGED. + ({make,user,child}_access) [! GETLOADAVG_PRIVILEGED]: Make no-op. + * compatMakefile (install_setgid): New var, set by configure. + (install): Install setgid $(group) only if $(install_setgid) is true. + +Fri Jan 8 15:31:55 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * job.c (load_too_high): If getloadavg fails with errno==0, give a + message saying that load limits are not supported. + + * vpath.c (construct_vpath_list): Rewrote path deletion code to + not try to use PATH's next link after freeing PATH. + + * main.c (define_makeflags): Rewritten; now handles string-valued + option, and has no arbitrary limits. + (switches): Set `toenv' flag for -I and -v. + + * main.c (decode_env_switches): Cast return value of alloca to char *. + + * misc.c (child_access) [HAVE_SETREUID, HAVE_SETREGID]: Use + setre[gu]id in place of set[gu]id. + +Wed Jan 6 15:06:12 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * main.c (main): Define MAKEOVERRIDES, MAKE, and MAKE_COMMAND with + origin o_default. + + * make.h [POSIX]: Don't test this to use ANSI_STRING. + Testing STDC_HEADERS should be sufficient. + + * job.h: Declare start_waiting_jobs. + + * read.c (read_makefile): Add missing parens in if stmt that find + conditional directives. + + * main.c (main): Declare init_dir. + * implicit.c (pattern_search): Always use two % specs in a + DEBUGP2, and always pass two non-nil args. + Cast field width args to int. + Add missing parens in !RULE->subdir if stmt. + * function.c (expand_function, patsubst_expand): Add parens around + assignments inside `while' stmts. + * commands.c (print_commands): Cast field width args to int. + + * read.c (do_define): Cast return value of alloca to (char *). + + * main.c (init_switches): New function, broken out of decode_switches. + (decode_switches): Take new arg ENV. If set, ignore non-option + args; print no error msgs; ignore options with clear `env' flags. + (decode_env_switches): Rewritten to chop envar value into words + and pass them to decode_switches. + (switches): Set `env' flag for -I and -v. + + * dir.c (init_dir): Cast free to __glob_closedir_hook's type. + +Tue Jan 5 14:52:15 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.25. + + * job.c [HAVE_SYS_WAIT || !USG]: Don't #include and + . interacts badly with , and + we don't need these anyway. + + * configure.in (AC_HAVE_FUNCS): Check for setre[gu]id. + * misc.c ({user,make}_access): Test #ifndef HAVE_SETRE[GU]ID, not + #ifdef POSIX || USG. SunOS 4.1 is supposedly POSIX.1 compliant, + but its set[gu]id functions aren't; its setre[gu]id functions work. + + * misc.c ({user,make,child}_access): Give name of caller in error msgs. + + * job.c (load_too_high): Say "cannot enforce load limit" in error msg. + + * configure.in: Call AC_PROG_CC. + * compatMakefile (CC): Define to @CC@ (autoconf magic). + + * compatMakefile: Add .NOEXPORT magic target. + +Mon Jan 4 17:00:03 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * main.c (print_version): Updated copyright to include 93. + +Thu Dec 31 12:26:15 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * make.h [_AIX]: Don't declare alloca. + +Tue Dec 29 13:45:13 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.24. + + * compatMakefile (objs): Add signame.o. + (srcs): Add signame.[ch]. + + * compatMakefile (srcs): Add config.h.in. + (remote.o): Add -I. before -I$(srcdir). + +Mon Dec 28 15:51:26 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.23. + + * read.c (readline): Fatal when LEN==0, indicating a line starting + with a NUL. + (readline): Take new arg LINENO, for use in error msg. + (read_makefile, do_define): Pass it. + + * compatMakefile (glob/libglob.a): Pass -DHAVE_CONFIG_H in CPPFLAGS. + (.c.o): Add -I. before -I$(srcdir). + +Wed Dec 23 12:12:04 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * read.c (read_makefile): Accept and ignore a rule with no targets. + + * compatMakefile (ALLOCA_SRC): New variable. + (srcs): Include its value. + + * read.c (struct conditional): Renamed member `max_ignoring' to + `allocated'; added new member `seen_else'. + (conditional_line): Initialize seen_else flag when starting an `if...'; + set it when we see an `else'; fatal if set when we see `else'. + (read_makefile): Fatal "missing `endif'" if there are any pending + conditionals, not just if we are still ignoring. + +Tue Dec 22 15:36:28 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * compatMakefile (manext): Set to 1, not l. + ($(mandir)/$(instname).$(manext)): Use $(srcdir) for make.man in cmds. + + * file.c (file_hash_enter): Don't call uniquize_deps here. + * read.c (record_files): Likewise. + * implicit.c (pattern_search): Likewise. + * commands.c (set_file_variables): Call it only here. + + * default.c (default_variables) [__convex__]: FC=fc. + + * variable.c (target_environment): Expand the values of recursively + expanded variables when putting them into the environment. + * expand.c (recursively_expand): Made global. + * make.h (recursively_expand): Declare it. + + * remake.c (check_dep): Set FILE->command_state to cs_deps_running + when a dep's command_state is cs_running or cs_deps_running. + + * read.c (read_makefile): Changed error msg for spurious cmds to + not say "first target". + +Sun Dec 20 17:56:09 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * configure.in: Do AC_CONFIG_HEADER right after AC_INIT. + * make.h (HAVE_CONFIG_H): #include "config.h", then #define this. + * compatMakefile (config.h, configure, config.h.in): New rules. + (defines): Removed @DEFS@. + +Thu Dec 17 16:11:40 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * compatMakefile (realclean): Just depend on distclean; no cmds. + (distclean): Do what realclean did before; also remove Makefile and + config.h; don't remove configure. + (info, dvi): New targets; depend on make.{info,dvi}. + (doc): Removed target. + (MAKEINFO, TEXI2DVI): New vars. + (make.info, make.dvi): Use them instead of explicit cmds. + +Wed Dec 16 16:25:24 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in: Added fcntl.h to AC_HAVE_HEADERS. getloadavg cares. + +Wed Dec 9 15:21:01 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * main.c (long_option_aliases): Add --new-file alias for -W. + + * default.c (default_variables): Change all C++ to CXX and C++FLAGS + to CXXFLAGS. + + * read.c (do_define): Expand the variable name before using it. + + * main.c (main): Define variable "MAKE_COMMAND" to argv[0]; + define "MAKE=$(MAKE_COMMAND) $(MAKEOVERRIDES)" always. + + * remake.c (library_search): Search for libNAME.a in cwd; look in + vpath before looking in standard dirs, not after. + Changed order of std dirs to: /lib, /usr/lib, ${prefix}/lib. + +Mon Nov 23 14:57:34 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * default.c (default_pattern_rules, default_terminal_rules): Added + brackets around initializers. + + * variable.c (try_variable_definition): Don't check for LINE[0]=='\t'. + (try_variable_definition): Expand the name before defining the var. + + * job.c (init_siglist): Removed function. + Removed decl of `sys_siglist'. + * make.h [! HAVE_SYS_SIGLIST]: #include "signame.h". + [HAVE_SYS_SIGLIST && !SYS_SIGLIST_DECLARED]: Declare sys_siglist + only under these conditions. + * main.c (main): Don't declare init_siglist. + (main) [! HAVE_SYS_SIGLIST]: Call signame_init instead of init_siglist. + +Wed Nov 18 14:52:51 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * read.c (record_files): Don't try to append to FIRSTDEPS if it's + nil; instead just set it to MOREDEPS. + +Mon Nov 16 17:49:17 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * vpath.c (construct_vpath_list): Initialize P to DIRPATH before + loop that sets MAXELEM. + +Fri Nov 13 18:23:18 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.22. + +Thu Nov 12 15:45:31 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * job.c (start_job_command): Under -n, increment files_remade after + processing (i.e., printing) all command lines. + +Tue Nov 10 15:33:53 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * read.c (record_files): Append new deps if this rule has no + commands; prepend them to existing deps if this rule has no commands. + + * dir.c (open_dirstream): Return nil if DIR->contents->files is nil. + + * read.c (parse_file_seq): Removed last arg STRIP. Always strip `./'s. + (read_makefile): Changed callers. + * function.c (string_glob): Likewise. + * rule.c (install_pattern_rule): Likewise. + +Mon Nov 9 17:50:16 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * remake.c (files_remade): Made global. + (notice_finished_file): Don't increment files_remade here; this + function gets called in many situations where no remaking was in + fact done. + * job.c (reap_children): Do it here instead, when we know that + actual commands have been run for the file. + * make.h (files_remade): Declare it. + +Thu Nov 5 18:26:10 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * vpath.c (construct_vpath_list): Allow blanks as well as colons to + separate elts in the search path. + + * read.c (read_makefile): Don't fatal on extra tokens in `vpath'. + The search path can contain spaces now. + +Tue Nov 3 20:44:32 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * compatMakefile (check): New target; no-op. + + * file.c (file_hash_enter): Mod OLDHASH by FILE_BUCKETS after + testing for OLDHASH==0 but before using the value. + (rename_file): Don't mod OLDHASH by FILE_BUCKETS before passing it + to file_hash_enter. + + * file.c (rename_file): Notice when OLDFILE->cmds came from + default.c, and don't try to print ->filename in that case. + +Sun Oct 25 01:48:23 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * remake.c (update_file): Don't process F->also_make here. + (notice_finished_file): Don't process FILE->also_make if no attempt + to update FILE was actually made. + Fixed to call f_mtime directly to refresh their modtimes. + +Sat Oct 24 22:08:59 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * read.c (find_percent): Don't increment P again after skipping + an escaped %. + + * expand.c (variable_expand): In call to patsubst_expand, don't + find `%'s ourselves; let that function do it. + + * read.c (read_makefile: record_waiting_files): Don't call + record_files if FILENAMES is nil. + (read_makefile): All alternatives in the parsing, except for rule + lines, fall through to the end of the loop. At the end of the + loop, do record_waiting_files so we notice later spurious cmds. + +Fri Oct 23 15:57:37 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * variable.c (define_automatic_variables): Free old value of SHELL + before replacing it. + +Thu Oct 15 18:57:56 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * compatMakefile (.c.o): Add -I$(srcdir)/glob to flags. + + * dir.c (open_dirstream): Cast return value to __ptr_t. + + * default.c (default_variables: "GET") [_IBMR2]: Use USG defn. + + * make.h (MAXPATHLEN): Moved out of #ifndef POSIX. + (GET_PATH_MAX): Moved from #ifdef POSIX to #ifdef PATH_MAX #else. + Define as (get_path_max ()). + [! PATH_MAX] (NEED_GET_PATH_MAX): Define. + [! PATH_MAX] (get_path_max): Declare fn. + * misc.c [NEED_GET_PATH_MAX] (get_path_max): New function. + +Mon Oct 12 13:34:45 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.21. + + * job.c (sys_siglist): Only declare #ifndef SYS_SIGLIST_DECLARED. + * make.h [! HAVE_SYS_SIGLIST && HAVE__SYS_SIGLIST]: #define + SYS_SIGLIST_DECLARED. + + * dir.c (file_impossible): When initializing DIR->contents, set + DIR->contents->dirstream to nil. + + * compatMakefile (GLOB): Define new variable. + (objs): Use it, rather than glob/libglob.a explicitly. + + * read.c (parse_file_seq): When stripping "./", handle cases like + ".///foo" and "./////". + * file.c (lookup_file, enter_file): Likewise. + +Sun Oct 11 17:00:35 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * dir.c (struct dirstream, {open,read}_dirstream): New + data type and functions to read a directory sequentially. + (init_dir): New function to hook it into glob. + * main.c (main): Call init_dir. + + * compatMakefile (objs): Added glob/libglob.a. + * configure.in: Remove code to test for glob. + +Fri Oct 9 12:08:30 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * read.c (record_files): Generalized test for NAME pointing + somewhere into F->name. + + * variable.c (define_variable_in_set): Free old value when replacing. + + * read.c (do_define): Free the linebuffer before returning. + (record_files): When clearing .SUFFIXES deps, free their data. + (multi_glob): Free OLD and its data when replacing it with results + of glob run. + + * commands.c (set_file_variables): Use alloca in place of xmalloc + for temp space for $^, $?, et al. + + * dir.c (struct directory): New member `contents' replaces `files' + and `dirstream'. + (struct directory_contents): New type. + (directories_contents): New hash table. + (dir_struct_file_exists_p): Take a struct directory_contents. + (dir_file_exists_p): Pass it the `contents' member of the dir found. + (dir_struct_file_exists_p): Renamed to dir_contents_file_exists_p; + made static. Return 0 if DIR is nil (meaning it couldn't be stat'd). + (dir_file_exists_p, find_directory): Change all callers. + (file_impossible): Use DIR->contents, initializing it if nil. + (print_dir_data_base): Use DIR->contents, and print out device and + inode numbers with each directory. + + * Changes for performance win from John Gilmore : + * dir.c (DIRECTORY_BUCKETS): Increase to 199. + (DIRFILE_BUCKETS): Decrease to 107. + (find_directory): Allocate and zero a multiple of + sizeof (struct dirfile *), not of sizeof (struct dirfile). + (dir_struct_file_exists_p): New function, nearly all code from + dir_file_exists_p. + (dir_file_exists_p): Just call find_directory+dir_struct_file_exists_p. + * vpath.c (selective_vpath_search): Remove redundant + dir_file_exists_p call. + + * configure.in: Comment out glob check; always use our code. + +Fri Oct 2 19:41:20 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * make.h [! HAVE_SYS_SIGLIST && HAVE__SYS_SIGLIST]: #define + HAVE_SYS_SIGLIST; after doing #define sys_siglist _sys_siglist, we + do have it. + +Wed Sep 30 19:21:01 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * main.c (main): Don't do -w automatically if -s. + +Tue Sep 29 21:07:55 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * main.c (printed_version): Move variable inside print_version. + (print_version): Return immediately if printed_version is set. + (die): Don't test printed_version here. + (decode_switches): Under -v, do print_version before giving usage. + (DESCRIPTION_COLUMN): New macro. + (decode_switches): Use it when printing the usage message. + Leave at least two spaces between options and their descriptions. + +Fri Sep 25 13:12:42 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.20. + +Wed Sep 16 16:15:22 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * read.c (read_makefile): Save errno value from trying to open + FILENAME, and restore it before erring; otherwise we get the errno + value from the last elt of the search path. + +Tue Sep 15 15:12:47 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * main.c (long_option_aliases): Add --stop for -S. + + * read.c (word1eq): Do strncmp before dereferencing someplace that + may be out in space. + +Wed Sep 9 15:50:41 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * remake.c (notice_finished_file): If all the command lines were + recursive, don't do the touching. + + * job.c (start_job_command): Don't check for + here. + * commands.c (chop_commands): Do it here instead. + + * default.c (default_terminal_rules): Prepend + to cmds for RCS. + +Wed Sep 2 17:53:08 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * compatMakefile (objs): Include $(ALLOCA). + + * make.h [CRAY]: Move #define signal bsdsignal to before #includes. + +Thu Aug 27 17:45:43 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * read.c (default_include_directories): Add INCLUDEDIR first. + * compatMakefile (includedir): Define. + (defines): Add -D for INCLUDEDIR="$(includedir)". + + * read.c (read_makefile): Grok multiple files in `include'; + globbing too. + + * remake.c (library_search): New function. + (library_file_mtime): Remove function. + (f_mtime): Use library_search instead of library_file_mtime. + * compatMakefile (libdir): Define. + (defines): Add -D for LIBDIR="$(libdir)". + * make.texinfo (Libraries/Search): Document change. + + * file.c (rename_file): Fix file_hash_enter call with missing arg. + +Wed Aug 26 17:10:46 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.19. + + * main.c (main): Set command_state to cs_finished for temp files + made for stdin makefiles. + + * main.c (decode_switches): Don't tell getopt to return non-option + args in order. + Ignore an argument of `-'. + +Thu Aug 20 13:36:04 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * job.c (start_job_command): If (touch_flag && !RECURSIVE), ignore + the command line and go to the next. + (notice_finished_file): Under -t, touch FILE. + * remake.c (remake_file): Don't touch it here. + +Wed Aug 19 16:06:09 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * function.c (pattern_matches): Use temporary for strlen (WORD) + instead of two function calls. + + * compatMakefile (LOAD_AVG): Remove variable and comments. + +Tue Aug 18 14:58:58 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * make.texinfo (Running): Node renamed to `make Invocation'. + +Fri Aug 14 12:27:10 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * arscan.c (ar_name_equal): Don't compare [MAX-3..MAX] if + NAMELEN != MEMLEN. + +Thu Aug 13 17:50:09 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.18. + + * main.c: Don't #include ; make.h already does. + +Mon Aug 10 17:03:01 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * implicit.c (pattern_search): Fixed copying of suffix when building + also_make elts. + + * function.c (expand_function: `shell'): Make sure BUFFER is + null-terminated before replacing newlines. + + * compatMakefile (mandir): Use man$(manext), not always manl. + +Sun Aug 2 01:42:50 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * rule.c (new_pattern_rule): Not static. + * rule.h: Declare it. + + * file.c (file_hash_enter): New function, most code from rename_file. + (rename_file): Call it. + * file.h (file_hash_enter): Declare it. + + * dep.h: Doc fix. + +Thu Jul 30 15:40:48 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * main.c (decode_switches): Handle usage_and_exit when building + long options vector. + + * default.c (default_terminal_rules): Make RCS rules use $(CHECKOUT,v). + (default_variables): Define CHECKOUT,v (hairy). + + * make.h [!HAVE_SYS_SIGLIST && HAVE__SYS_SIGLIST]: #define + sys_siglist to _sys_siglist. + +Sun Jul 26 16:56:32 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * NEWS: Add header and tail copyright info like Emacs NEWS. + + * make.h [ANSI_STRING]: Don't #define index, rindex, bcmp, bzero, + bcopy if already #define'd. + [STDC_HEADERS] (qsort, abort, exit): Declare here. + [! __GNU_LIBRARY__ && !POSIX]: Not here. + + * make.h [_AIX]: #pragma alloca first thing. + + * job.c (start_waiting_job): Set the command_state to cs_running + when we queue a job on waiting_jobs. + +Fri Jul 24 02:16:28 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * variable.c (define_automatic_variables): Use "" instead of nil + for empty value. + +Thu Jul 23 22:31:18 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.17. + + * main.c (struct command_switch.type): Add alternative usage_and_exit. + (command_switches): Add -h/--help. + +Thu Jul 16 14:27:50 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * GNUmakefile (make-$(version).tar.Z): Include NEWS, not CHANGES. + * README.template: Mention NEWS. + * CHANGES: Renamed to NEWS. + + * main.c [! STDC_HEADERS] [sun]: Don't declare exit. + +Tue Jul 14 18:48:41 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * main.c (main): Set -o files' command_states to cs_finished. + + * rule.c (count_implicit_rule_limits): Decrement num_pattern_rules + when tossing a rule. + + * main.c (main): Use alloca only in simple local var assignment, + for braindead SGI compiler. + + * rule.c (print_rule_data_base): Barf if num_pattern_rules is + inconsistent with the number computed when listing them. + +Mon Jul 13 17:51:53 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * commands.c (set_file_variables): For $? and $^ elts that are archive + member refs, use member name only. + +Fri Jul 10 00:05:04 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * variable.h (struct variable.export): Add new alternative v_ifset. + * variable.c (target_environment): Check for it. + (define_automatic_variables): Set it for MAKEFILES. + +Thu Jul 9 21:24:28 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * compatMakefile (objs): Remove getloadavg.o; $(extras) gets it. + (remote.o): Use $(srcdir)/remote.c, not $remote.c<. + (distclean, mostlyclean): New targets. + +Tue Jul 7 19:12:49 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.16. + + * compatMakefile (config.status): Remove rule. + + * job.c (start_waiting_job): Free C after using C->file, not before. + +Sat Jul 4 20:51:49 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * commands.c, job.c, main.c, make.h, remote-cstms.c: Use #ifdef + HAVE_* instead of #ifndef *_MISSING. + * configure.in: Use AC_HAVE_FUNCS instead of AC_MISSING_FUNCS (gone). + +Thu Jul 2 18:47:52 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * main.c (main): makelevel>0 or -C implies -w. + +Tue Jun 30 20:50:17 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * file.c, job.c, function.c: Don't #include . + make.h: Do it here instead. + * arscan.c (ar_member_touch): Don't declare errno. + +Thu Jun 25 17:06:55 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * GNUmakefile (make-$(version).tar.Z): Depend on INSTALL, configure.in. + + * remake.c (update_file): If commands or deps are running after + update_file_1 returns, break out of the :: rule (->prev) loop and + just return. + + * job.c (job_next_command): New function; code from start_job. + (start_job_command): Renamed from start_job. Call job_next_command + and recurse for empty command lines and -n. + (start_waiting_job): Call start_job_command, not start_job. + (new_job): Call job_next_command to prime the child structure, and + then call start_waiting_job. + (reap_children): Use job_next_command and start_job_command. + (start_waiting_job): Call start_remote_job_p here, and store its + result in C->remote. If zero, check the load average and + maybe put C on waiting_jobs. + (start_job_command): Test CHILD->remote rather than calling + start_remote_job_p. Don't do load avg checking at all here. + + * main.c (main): Don't handle SIGILL, SIGIOT, SIGEMT, SIGBUS, + SIGSEGV, SIGFPE or SIGTRAP. + + * compatMakefile (glob/libglob.a): Don't pass srcdir to sub-make. + configure will set it in glob/Makefile. + +Wed Jun 24 19:40:34 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * dir.c [DIRENT] (direct): Don't define to dirent. + [! DIRENT] (direct): Define to dirent. + (dir_file_exists_p): Use struct dirent instead of struct direct. + + * make.h (getcwd): No space between macro and ( for args! + + * job.c (start_job): Don't put the job on waiting_jobs if + job_slots_used==0. + + * make.texinfo (Missing): Shortened title. + +Tue Jun 23 18:42:21 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * file.c (remove_intermediates): Print "rm" commands under -n. + +Mon Jun 22 16:20:02 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.15. + +Fri Jun 19 16:20:26 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * arscan.c [M_UNIX]: #undef M_XENIX. + +Wed Jun 17 17:59:28 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * default.c (default_terminal_rules): Put @ prefix on RCS cmds. + +Tue Jun 16 19:24:17 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * compatMakefile (getloadavg.o): Removed special rule. + (CFLAGS): Don't include $(defines). + (.c.o): Define suffix rule. + (glob/libglob.a): Pass CPPFLAGS=$(defines) to submake. + (GETOPT_SRC, srcs, tagsrcs): Prefix files with $(srcdir)/. + + * arscan.c (ar_name_equal): Moved local vars inside #if'd block. + + * make.h (max): Removed. + * expand.c (variable_buffer_output): Don't use it. + + * compatMakefile (INSTALL): Define. + (Makefile): New rule to make from Makefile.in. + (srcdir): Define. + (VPATH): Define. + (getloadavg.o, remote.o): Use autoconf $foo< hack. + + * commands.c (fatal_error_signal): Removed return. + +Mon Jun 15 17:42:51 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.14. + + * make.texinfo (Summary): New node. + (Special Targets): Mention .EXPORT_ALL_VARIABLES here. + + * variable.c (max): Moved to make.h. + + * compatMakefile (objs, srcs): Added ar & arscan. + + * job.c (start_waiting_job): New function, 2nd half of new_job. + (new_job): Call it. + (start_waiting_jobs): New function. + * remake.c (update_goal_chain): Call start_waiting_jobs at the top + of the main loop. + * compatMakefile (objs, srcs): Removed load, added getloadavg. + +Fri Jun 12 19:33:16 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * job.c (load_too_high): New function. Uses getloadavg. + (waiting_jobs): New variable. + (start_job): Don't call wait_to_start_job. Instead, if + load_too_high returns nonzero, add the child to the + `waiting_jobs' chain and return without starting the job. + +Thu Jun 11 00:05:28 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * expand.c (variable_buffer_output): Made global again. + * variable.h: And declare it. + + * arscan.c (PORTAR): Define for all systems if PORT5AR is not defined. + (AR_NAMELEN, AR_TRAILING_SLASH): Removed. + (ar_scan): Don't use it. Don't #ifdef AR_TRAILING_SLASH; just look + for a slash in the archive at run time. + (ar_name_equal): Rewrote .o hacking to not use AR_NAMELEN, and to + cope with trailing-slash and non-trailing-slash archives. + + * main.c (main) [! SETVBUF_REVERSED]: Test this instead of USGr3 et al. + [SETVBUF_REVERSED]: Always allocate a buffer ourselves. + + * load.c (load_average) [sgi]: Use sysmp call. + + * compatMakefile (INSTALL_DATA, INSTALL_PROGRAM): Define. + ($(bindir)/$(instname), $(mandir)/make.$(manext)): Use them. + + * make.h [HAVE_VFORK_H]: #include . + (vfork, VFORK_NAME): Don't define. + * job.c (start_job): Use "vfork" in place of VFORK_NAME. + + * make.h [HAVE_LIMITS_H, HAVE_SYS_PARAM_H]: If #define'd, #include + the each file. Rearranged PATH_MAX hacking. + * job.c: Rearranged NGROUPS_MAX hacking. + + * remake.c (fstat, time): Don't declare. + + * compatMakefile (defines): Value is @DEFS@. + (LOADLIBES): Value is @LIBS@. + (extras): Value is @LIBOBJS@. + (ARCHIVES, ARCHIVES_SRC, ALLOCASRC): Removed. + * arscan.c, ar.c: Surround body with #ifndef NO_ARCHIVES. + + * misc.c [! HAVE_UNISTD_H]: Test instead of !POSIX to decl get*id. + + * make.h [GETCWD_MISSING]: Test instead of !USG && !POSIX et al. + (getcwd): Just declare if present. If not, declare as a macro + using getwd, and declare getwd. + [PATH_MAX] (GET_PATH_MAX): #define to PATH_MAX. + * main.c (main, log_working_directory): Use getcwd instead of getwd. + + * main.c (main) [SETLINEBUF_MISSING]: Test this instead of USG. + + * make.h (SIGHANDLER, SIGNAL): Removed. + (RETSIGTYPE): Define if not #define'd. + * main.c (main): Use signal in place of SIGNAL. + + * main.c [SYS_SIGLIST_MISSING]: Test instead of USG. + + * job.c (search_path) [GETGROUPS_MISSING]: Test instead of USG. + [HAVE_UNISTD_H]: Test instead of POSIX to not decl getgroups. + + * main.c [! HAVE_UNISTD_H]: Test instead of !POSIX to decl chdir. + [! STDC_HEADERS]: Test instead of !POSIX to decl exit & atof. + + * job.c (child_handler), commands.c (fatal_error_signal): Return + RETSIGTYPE instead of int. + * main.c (main): Declare fatal_error_signal and child_handler here + to return RETSIGTYPE; removed top-level decl of former. + + * commands.c (fatal_error_signal), job.c (unblock_sigs, start_job), + main.c [SIGSETMASK_MISSING]: Test this instead of USG. + +Wed Jun 10 22:06:13 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * job.c [HAVE_WAITPID]: Test this instead of USG. + [! HAVE_UNISTD_H]: Test this instead of !POSIX to declare misc fns. + (GID_T): Don't #define. + (search_path): Use gid_t instead of GID_T. + [GETDTABLESIZE_MISSING, SYS_SIGLIST_MISSING, DUP2_MISSING]: Test + these individually instead of USG for all. + * make.h (ctime): Don't declare. #include time.h instead. + [HAVE_UNISTD_H]: #include and #define POSIX #ifdef + _POSIX_VERSION. + * dir.c [__GNU_LIBRARY__] (D_NAMLEN): Define to use d_namlen member. + * make.h [NEED_MEMORY_H]: Only include memory.h #ifdef this. + + * arscan.c: Removed #ifdef mess about string.h et al. + Just #include make.h instead. + * make.h (fstat, atol): Declare. + + * commands.c (fatal_error_signal): Don't use sigmask to check for + propagated signals; use ||s instead. + (PROPAGATED_SIGNAL_MASK): Removed. + (fatal_error_signal) [POSIX]: Use sigprocmask in place of sigsetmask. + + * variable.c (variable_buffer, variable_buffer_length, + initialize_variable_output, variable_output): Moved to expand.c; + made all static. + (struct output_state, save_variable_output, + restore_variable_output): Removed. + * expand.c (initialize_variable_output): Put a NUL at the beginning + of the new buffer after allocating it. + (allocated_variable_expand_for_file): Don't use + {save,restore}_variable_output. Do it by hand instead, keeping + state on the stack instead of malloc'ing it. + (allocated_variable_expand): Removed. + * variable.h (allocated_variable_expand): Define here as macro. + (variable_buffer_output, initialize_variable_output, + save_variable_output, restore_variable_output): Removed decls. + + * read.c (conditional_line): For an if cmd, if any elt of the + conditionals stack is ignoring, just push a new level that ignores + and return 1; don't evaluate the condition. + +Thu Jun 4 21:01:20 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * main.c (main): Put #ifdef's around frobbing SIGSYS and SIGBUS. + + * job.c (getdtablesize): Don't declare or #define if already #define'd. + +Wed Jun 3 23:42:36 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * file.c (snap_deps): If `.EXPORT_ALL_VARIABLES' is a target, set + export_all_variables. + * make.texinfo (Variables/Recursion): Document .EXPORT_ALL_VARIABLES. + +Tue Jun 2 21:08:35 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.13. + + * commands.c (set_file_variables): Calculate length for ^D and ?D + individually, making sure to give them at least enough space for "./". + + * make.h [CRAY]: #define signal to bsdsignal. + + * default.c (default_variables) [CRAY]: Define PC, SEGLDR, + CF77PPFLAGS, CF77PP, CFT, CF, and FC. + + * arscan.c (AR_HDR_SIZE): Define to sizeof (struct ar_hdr), if it + wasn't defined by . + +Thu May 28 00:56:53 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.12. + +Tue May 26 01:26:30 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * rule.c (new_pattern_rule): Initialize LASTRULE to nil, not + pattern_rules. + +Mon May 25 19:02:15 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * main.c (decode_switches): Initialize all the long_option elt members. + +Thu May 21 16:34:24 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * make.texinfo (Text Functions): Correct filter-out description. + +Tue May 19 20:50:01 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * compatMakefile (realclean): Don't remove backup files. + + * main.c (decode_switches): Allocate ARGC+1 elts in `other_args'. + +Sun May 17 16:38:48 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * Version 3.62.11. + +Thu May 14 16:42:33 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * job.c (reap_children): Don't die if wait returns EINTR. + +Wed May 13 18:28:25 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * job.c (reap_children): Always run the next command for a + successful target. If we are going to die, we don't want to leave + the target partially made. + +Tue May 12 00:39:19 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * job.c (construct_command_argv_internal): After loop, if we only + have one word, check it for being a shell command. + + * main.c (decode_switches): Allocate ARGC slots in other_args to + begin with, so we never need to worry about growing it. + If we get a non-option arg and POSIXLY_CORRECT is in the + environment, break out of the loop. After the loop, add all remaining + args to other_args list. + + * main.c (decode_switches): For positive_int and floating switches + when optarg is nil, use next arg if it looks right (start with a + digit, or maybe decimal point for floating). + + * variable.c (define_automatic_variables): Always set SHELL to + default if it comes from the environment. Set its export bit. + * make.texinfo (Environment): Document change. + +Mon May 11 00:32:46 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * Version 3.62.10. + + * compatMakefile (tags, TAGS): Use vars for cmds. + (ETAGS, CTAGS): Define. + + * main.c (decode_switches): If a switches elt has a nil long_name, + make the long option name elt be "". + Fixed loop to not ignore all the options. + + * make.texinfo (Option Summary): Added long options. + + * main.c (switches): Changed -m's description to "-b". + (decode_switches): When printing the usage message, don't print + switches whose descriptions start with -. + When constructing the list of names for switch -C, search the + switches vector for switches whose descriptions are "-C". + + * main.c (switches): Call -S --no-keep-going, not --dont-keep-going. + Call -I --include-dir, not --include-path. + (long_option_aliases): Added --new == -W, --assume-new == -W, + --assume-old == -o, --max-load == -l, --dry-run == -n, --recon == -n, + --makefile == -f. + + * main.c (switches): Removed bogus "silent" elt. + (long_option_aliases): Define new var. + (decode_switches): Add long_option_aliases onto the end of the long + options vector created for getopt_long. + Look through long_option_aliases for extra names to list + in usage message. + +Sat May 9 00:21:05 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * main.c (log_working_directory): Fixed to properly not print the + leaving message when we haven't printed the entering message. + +Fri May 8 21:55:35 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * main.c (struct command_switch): Added elts `long_name', + `description', and `argdesc'. + (switches): Added initializers for new members. + (decode_switches): Rewritten to use getopt_long. + * compatMakefile (GETOPT, GETOPT_SRC): Define. + (objs, srcs): Include them. + + * job.c (child_died): Renamed to dead_children; made static. + (child_handler): Increment dead_children instead of setting child_died. + (reap_children): Decrement dead_children instead of clearing + child_died. The point of all this is to avoid printing "waiting + for unfinished jobs" when we don't actually need to block. + This happened when multiple SIGCHLDs before reap_children was called. + + * job.c (reap_children): If ERR is set, so we don't call start_job + on the child being reaped, instead set its command_state to + cs_finished. + (reap_children, child_handler, new_job): I added several + debugging printf's while fixing this. I left them in if (debug_flag) + because they may be useful for debugging this stuff again. + +Wed May 6 22:02:37 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * read.c (read_makefile): v_export is not 1. + +Mon May 4 17:27:37 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.9. + + * variable.c (export_all_variables): New variable. + (target_environment): Export variables whose `export' member is + v_default if export_all_variables is set and their names are benign. + * variable.h: Declare export_all_variables. + * read.c (read_makefile): If export or unexport is given with no + args, set or clear export_all_variables, respectively. + + * variable.c (target_environment): Exclude MAKELEVEL in the loop, + so it isn't duplicated when we add it at the end. + +Sun May 3 17:44:48 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.8. + + * variable.h (struct variable): Added new member `export'. + * variable.c (define_variable_in_set): Initialize it to v_default. + (target_environment): Don't check for .NOEXPORT. + Export variables whose `export' member is v_default and that would + have been exported under .NOEXPORT, and variables whose `export' + member is v_export. + (try_variable_definition): Return the variable defined. + * variable.h (try_variable_definition): Changed decl. + * read.c (read_makefile): Recognize `export' and `unexport' directives. + +Fri May 1 11:39:38 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * main.c (main) [POSIX]: Reversed args to sigaddset. + +Thu Apr 30 17:33:32 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * job.c [POSIX || !USG] (unblock_sigs): New fn. + (start_job): Block signals before forking. + (new_job): Unblock signals after putting the new child on the chain. + * main.c (main) [POSIX]: Use sigset_t fatal_signal_set instead of + int fatal_signal_mask. + + * load.c [sgi] (LDAV_CVT): Define. + +Wed Apr 29 17:15:59 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * Version 3.62.7. + + * load.c (load_average) [sgi]: Clear the high bit of the address + from the symbol table before looking it up in kmem. + + * misc.c (fatal, makefile_fatal): Put *** in fatal error messages. + (remake_file): No longer needed in message here. + + * main.c (die): Call reap_children with BLOCK==1. + +Tue Apr 28 20:44:35 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * rule.c (freerule): Don't set LASTRULE->next if LASTRULE is nil. + +Sun Apr 26 15:09:51 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * rule.c (count_implicit_rule_limits): Initialize LASTRULE to nil, + not to head of chain. Extract next ptr before we might do + freerule, and use that for next iteration. + (freerule): Still do next ptr frobbing if LASTRULE is nil. + +Tue Apr 21 03:16:29 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * job.c (child_error): Removed extra %s from error msg format. + + * Version 3.62.6. + + * job.c (reap_children): Don't start later commands in a sequence + if ERR is nonzero. + + * job.c (new_job): Always call reap_children with BLOCK==0 first thing. + + * job.c (reap_children): New function; work that used to be done in + child_handler. + (child_died): New global var. + (child_handler): Now just sets child_died. + (wait_for_children): Removed. + (unknown_children_possible, block_signals, unblock_signals, + push_signals_blocked_p, pop_signals_blocked_p): Removed. + (child_execute_job): Removed call to unblock_signals. + (new_job): Removed calls to push_signals_blocked_p and + pop_signals_blocked_p. + * job.h: Declare reap_children, not wait_for_children. + * commands.c (fatal_error_signal), job.c (new_job), + load.c [LDAV_BASED] (wait_to_start_job), main.c (die), + remake.c (update_goal_chain), function.c (expand_function: `shell'): + Changed wait_for_children calls to reap_children. + Some needed to be loops to wait for all children to die. + * commands.c (fatal_error_signal), main.c (main, + log_working_directory), function.c (expand_function): Removed calls + to push_signals_blocked_p and pop_signals_blocked_p. + * job.h: Removed decls. + + * job.h: Added copyright notice. + +Wed Apr 15 02:02:40 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * job.c (child_error): No *** for ignored error. + +Tue Apr 14 18:31:21 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * implicit.c (DEBUGP2): Use do ... while (0) instead of if ... else to + avoid compiler warnings. + + * read.c (parse_file_seq): Don't remove ./ when it is followed by a + blank. + +Mon Apr 13 21:56:15 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * make.h (DEBUGPR): Use do ... while (0) instead of if ... else to + avoid compiler warnings. + + * remake.c (notice_finished_file): Run file_mtime on the also_make + files, so vpath_search can happen. + + * GNUmakefile (tests): Use perl test suite from csa@sw.stratus.com. + (alpha-files): Include test suite tar file. + +Fri Apr 3 00:50:13 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 3.62.5. + +Wed Apr 1 05:31:18 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * remake.c (update_file, update_file_1): Do check_renamed on elts + of dep chains when traversing them. Something unrelated might have + renamed one of the files the dep chain points to. + + * file.c (rename_file): If FILE has been renamed, follow its + `renamed' ptr, so we get to the final real FILE. Using the renamed + ones loses because they are not in the hash table, so the removal + code loops infinitely. + + * read.c (read_all_makefiles): Clobber null terminator into + MAKEFILES expansion, so string passed to read_makefile is properly + terminated. + +Mon Mar 30 20:18:02 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * commands.c (set_file_variables): $* for archive member with + explicit cmds is stem of member, not of whole `lib(member)'. + +Thu Mar 26 15:24:38 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * Version 3.62.4. + +Tue Mar 24 05:20:51 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * rule.c (new_pattern_rule): Rules are identical only if all their + targets match (regardless of order). + +Wed Mar 11 13:49:54 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * remake.c (remake_file): Changed error "no way to make" to "no + rule to make". Fiat Hugh. + + * make.texinfo (Last Resort): Describe %:: rules and new .DEFAULT + behavior. + + * remake.c (update_file_1): Only use .DEFAULT cmds if FILE is not a + target. + +Tue Mar 10 18:13:13 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * remote-stub.c, remote-cstms.c (start_remote_job): Take new arg, + environment to pass to child. + * job.c (start_job): Pass it. + +Mon Mar 9 19:00:11 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * file.c (enter_file): Also strip ./s here, to get command-line + target names. + + * remote-cstms.c: Add comment telling people to leave me alone. + + * compatMakefile (manpage install): Remove target before copying. + +Tue Mar 3 18:43:21 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * make.texinfo (Missing): Renamed to "Incompatibilities and ...". + Added paragraph describing $? incompatibility with Unix and POSIX.2. + +Sun Mar 1 15:50:54 1992 Roland McGrath (roland@nutrimat.gnu.ai.mit.edu) + + * function.c (expand_function: `shell'): Don't declare fork or pipe. + Use vfork instead of fork. + +Tue Feb 25 22:05:32 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * make.texinfo (Chained Rules): Clarify .PRECIOUS to save + intermediate files. + + * load.c [sun] (LDAV_CVT): Define to divide by FSCALE. + +Sun Feb 16 02:05:16 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * Version 3.62.3. + +Sat Feb 15 17:12:20 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * compatMakefile (makeinfo): Use emacs batch-texinfo-format fn. + +Fri Feb 14 00:11:55 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * read.c (read_makefile): Correctly handle define & endef in ifdefs. + + * read.c (record_files): Pass arg for %s in error msg. + + * main.c (main) [__IBMR2, POSIX]: Use correct (a la USGr3) setvbuf + call. + +Wed Feb 12 12:07:39 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * make.texinfo (Libraries/Search): Say it does /usr/local/lib too. + +Sun Feb 9 23:06:24 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * read.c (read_makefile): Check for extraneous `endef' when ignoring. + +Thu Feb 6 16:15:48 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 3.62.2. + +Tue Feb 4 20:04:46 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * job.c (construct_command_argv_internal): Correctly ignore + whitespace after backslash-NL. + +Fri Jan 31 18:30:05 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * compatMakefile: Ignore errors from chgrp and chmod when installing. + +Wed Jan 29 18:13:30 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * main.c (main): When setting MAKELEVEL in the env to re-exec, + allocate space so as not to clobber past the end of the old string. + + * make.h [HAVE_ALLOCA_H]: Include + * compatMakefile (defines): Document HAVE_ALLOCA_H. + +Mon Jan 20 13:40:05 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * make.h [VFORK_MISSING]: Use fork instead. + * compatMakefile (defines): Document same. + + * job.c (construct_command_argv_internal): Don't create an empty + arg if backslash-NL is at beginning of word. + +Sun Jan 19 16:26:53 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * main.c [DGUX]: Call setvbuf as for USGr3. + + * job.c (construct_command_argv_internal): Notice correctly that + backslash-NL is the end of the arg (because it is replaced with a + space). + +Thu Jan 16 18:42:38 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * job.c (construct_command_argv_internal): If SHELL is nil, set it + to default_shell before proceeding. + + * make.h [sgi]: No alloca.h, after all. + +Wed Jan 15 12:30:04 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * read.c (multi_glob): Cons up the chain of the results of glob + from back to front, so it comes out in forward order. + + * job.c (construct_command_argv_internal): Don't eat char following + backslash-NL. + +Mon Jan 13 19:16:56 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * Version 3.62.1. + + * default.c (default_variables) [ultrix]: GET=get, like USG. + + * job.c (construct_command_argv_internal): Remove tabs following + backslash-NL combos in the input line, so they don't show up when + that line is printed. + + * read.c (read_makefile): Don't collapse_continuations the line on + input; do it on the copy we do remove_comments on. + For rule lines, collapse_continuations the line after chopping + ";cmds" off the end, so we don't eat conts in the cmds. + Give error for ";cmds" with no rule. + * job.c (construct_command_argv_internal): Eat backslash-NL combos + when constructing the line to recurse on for slow, too. + +Sat Jan 11 02:20:27 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * file.c (enter_file): Don't strip leading `./'s. + * read.c (parse_file_seq): Take new arg STRIP; if nonzero, do it here. + * default.c (set_default_suffixes), function.c (string_glob), + read.c (read_makefile), rule.c (install_pattern_rule): Change callers. + + * default.c (default_variables) [_IBMR2]: FC=xlf + + * job.c (construct_command_argv_internal): Turn backslash-NL and + following whitespace into a single space, rather than just eating + the backslash. + + * make.texinfo (Copying): @include gpl.texinfo, rather than + duplicating its contents. + +Fri Nov 8 20:06:03 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * job.c (construct_command_argv_internal): Make sure not to bother + processing an empty line. + + * Version 3.62.0. + + * job.c (construct_command_argv_internal): Always recurse for slow; + simple case didn't handle finding newlines. + +Tue Nov 5 18:51:10 1991 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * job.c (construct_command_argv_internal): Set RESTP properly when + slow; don't \ify past a newline. + +Fri Nov 1 19:34:28 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * make.h [sgi]: #include . + Tue Oct 29 20:57:36 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62. @@ -44,7 +1444,7 @@ at cmds->lines_recurse[CHILD->command_line - 1] instead of [CHILD->command_line]. - * dirc [sgi]: , not ndir or anything else. + * dir.c [sgi]: , not ndir or anything else. Thu Oct 17 16:28:55 1991 Roland McGrath (roland@geech.gnu.ai.mit.edu) @@ -2308,7 +3708,7 @@ (read_makefile): Allocate storage for the makefile name in the `struct file' in read_makefiles. - * make.texinfo (Running: Instead of Execution): Document the affect of + * make.texinfo (Running: Instead of Execution): Document the effect of + and $(MAKE)/${MAKE}. * make.texinfo (Functions: Foreach Function): Document that if the @@ -2941,7 +4341,7 @@ if it didn't need to be remade. * remake.c (update_file): Only write the "up to date" message if the - target when from `not_started' state to `finished' state without + target went from `not_started' state to `finished' state without incrementing the count of files remade. * commands.c [USG] (init_siglist): If both SIGCHLD and SIGCLD are @@ -4980,8 +6380,5 @@ * Split the monolithic `make.c' into several smaller files. Local Variables: -mode: indented-text -left-margin: 8 -version-control: never -make-backup-files: nil +eval: (if (fboundp 'change-log-mode) (change-log-mode) (indented-text-mode) (setq left-margin 8)) End: diff -ruN make-3.62/INSTALL make-3.63/INSTALL --- make-3.62/INSTALL +++ make-3.63/INSTALL Fri Jan 22 12:16:53 1993 @@ -0,0 +1,117 @@ +This is a generic INSTALL file for utilities distributions. +If this package does not come with, e.g., installable documentation or +data files, please ignore the references to them below. + +To compile this package: + +1. Configure the package for your system. In the directory that this +file is in, type `./configure'. 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. + +The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation, and +creates the Makefile(s) (one in each subdirectory of the source +directory). In some packages it creates a C header file containing +system-dependent definitions. It also creates a file `config.status' +that you can run in the future to recreate the current configuration. + +Running `configure' takes a minute or two. While it is running, it +prints some messages that tell what it is doing. If you don't want to +see the messages, run `configure' with its standard output redirected +to `/dev/null'; for example, `./configure >/dev/null'. + +To compile the package in a different directory from the one +containing the source code, 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 +`configure'. `configure' automatically checks for the source code in +the directory that `configure' is in and in `..'. If for some reason +`configure' is not in the source code directory that you are +configuring, then it will report that it can't find the source code. +In that case, run `configure' with the option `--srcdir=DIR', where +DIR is the directory that contains the source code. + +By default, `make install' will install the package's files in +/usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify +an installation prefix other than /usr/local by giving `configure' the +option `--prefix=PATH'. Alternately, you can do so by giving a value +for the `prefix' variable when you run `make', e.g., + make prefix=/usr/gnu + +You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If +you give `configure' the option `--exec-prefix=PATH' or set the +`make' variable `exec_prefix' to PATH, the package will use PATH as +the prefix for installing programs and libraries. Data files and +documentation will still use the regular prefix. Normally, all files +are installed using the regular prefix. + +Another `configure' option is useful mainly in `Makefile' rules for +updating `config.status' and `Makefile'. The `--no-create' option +figures out the configuration for your system and records it in +`config.status', without actually configuring the package (creating +`Makefile's and perhaps a configuration header file). Later, you can +run `./config.status' to actually configure the package. You can also +give `config.status' the `--recheck' option, which makes it re-run +`configure' with the same arguments you used before. This option is +useful if you change `configure'. + +Some packages pay attention to `--with-PACKAGE' options to `configure', +where PACKAGE is something like `gnu-libc' or `x' (for the X Window System). +The README should mention any --with- options that the package recognizes. + +`configure' ignores any other arguments that you give it. + +If your system requires unusual options for compilation or linking +that `configure' doesn't know about, you can give `configure' initial +values for some variables by setting them in the environment. In +Bourne-compatible shells, you can do that on the command line like +this: + CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure + +The `make' variables that you might want to override with environment +variables when running `configure' are: + +(For these variables, any value given in the environment overrides the +value that `configure' would choose:) +CC C compiler program. + Default is `cc', or `gcc' if `gcc' is in your PATH. +INSTALL Program to use to install files. + Default is `install' if you have it, `cp' otherwise. + +(For these variables, any value given in the environment is added to +the value that `configure' chooses:) +DEFS Configuration options, in the form `-Dfoo -Dbar ...' + Do not use this variable in packages that create a + configuration header file. +LIBS Libraries to link with, in the form `-lfoo -lbar ...' + +If you need to do unusual things to compile the package, we encourage +you to figure out how `configure' could check whether to do them, and +mail diffs or instructions to the address given in the README so we +can include them in the next release. + +2. Type `make' to compile the package. If you want, you can override +the `make' variables CFLAGS and LDFLAGS like this: + + make CFLAGS=-O2 LDFLAGS=-s + +3. If the package comes with self-tests and you want to run them, +type `make check'. If you're not sure whether there are any, try it; +if `make' responds with something like + make: *** No way to make target `check'. Stop. +then the package does not come with self-tests. + +4. Type `make install' to install programs, data files, and +documentation. + +5. You can remove the program binaries and object files from the +source directory by typing `make clean'. To also remove the +Makefile(s), the header file containing system-dependent definitions +(if the package uses one), and `config.status' (all the files that +`configure' created), type `make distclean'. + +The file `configure.in' is used as a template to create `configure' by +a program called `autoconf'. You will only need it if you want to +regenerate `configure' using a newer version of `autoconf'. diff -ruN make-3.62/Makefile make-3.63/Makefile --- make-3.62/Makefile Tue Oct 29 21:04:26 1991 +++ make-3.63/Makefile @@ -1,203 +0,0 @@ -# Copyright (C) 1988, 1989, 1991 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 -# - -CFLAGS = $(defines) -g -LDFLAGS = -g - -# Define these for your system as follows: -# -DUSG System V -# -DUSGr3 SVR3 (also define USG) -# -DHPUX HP-UX (also define USG and USGr3 appropriately) -# -DHAVE_SYS_WAIT USG, but have and wait3 -# -DHAVE_SIGLIST USG, but have sys_siglist -# -DHAVE_DUP2 USG and not USGr3, but have dup2 -# -DNO_MINUS_C_MINUS_O cc can't handle "cc -c foo.c -o foo.o" -# -DPOSIX A 1003.1 system (or trying to be) -# -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. -defines = - -# Define these for your system as follows: -# -DUMAX Encore UMAX -# -DUMAX_43 Encore UMAX 4.3 (also define UMAX) -# -DNO_LDAV Disable load-average checking. -# To read /dev/kmem (most Unix systems), define these if different from the -# given defaults: -# -DKERNEL_FILE_NAME=\"/vmunix\" -# -DLDAV_SYMBOL=\"_avenrun\" -# -DLDAV_CVT="(double) load" -# Define: -# -DNLIST_NAME_UNION If `struct nlist' has a n_un member. -# -DNLIST_NAME_ARRAY If `n_name' is an array. -LOAD_AVG = - -# If you don't want archive support, comment these out. -ARCHIVES = arscan.o ar.o -ARCHIVES_SRC = arscan.c ar.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 (below) instead on those machines. SGI Irix needs -lmld -# for nlist. -LOADLIBES = - -# If your system doesn't have alloca, or the one provided is bad, -# get it from the Emacs distribution and define these. -#ALLOCA = alloca.o -#ALLOCASRC = alloca.c - -# If there are remote execution facilities defined, -# enable them with switches here (see remote-*.c). -REMOTE = - -# Any extra object files your system needs. -extras = - -# Comment this out if POSIX.2 glob is installed on your system -# (it's in the GNU C Library, so if you're using that, this is -# not needed at all.) -globdep = glob/libglob.a - -# Library containing POSIX.2 `glob' function. -# Comment this line out if it's in the C library (which is the case if you -# are using the GNU C Library), or change it to the appropriate file name -# or -l switch. -globlib = $(globdep) - -# Name under which to install GNU make. -instname = make -# Directory to install `make' in. -bindir = $(prefix)/usr/local/bin -# Directory to install the man page in. -mandir = $(prefix)/usr/local/man/manl -# Number to put on the man page filename. -manext = l - -# Install make setgid to this group so it can read /dev/kmem. -group = kmem - -objs = commands.o job.o dir.o file.o load.o misc.o main.o read.o \ - remake.o remote.o rule.o implicit.o default.o variable.o expand.o \ - function.o vpath.o version.o $(ARCHIVES) $(ALLOCA) $(extras) -srcs = commands.c job.c dir.c file.c load.c misc.c main.c read.c \ - remake.c remote.c rule.c implicit.c default.c variable.c expand.c \ - function.c vpath.c version.c $(ALLOCASRC) $(ARCHIVES_SRC) \ - commands.h dep.h file.h job.h make.h rule.h variable.h - - -.SUFFIXES: -.SUFFIXES: .o .c .h .ps .dvi .texinfo - -.PHONY: all doc -all: make -doc: make.info make.dvi - - -# Take your pick. -#makeinfo = emacs -batch make.texinfo -f texinfo-format-buffer -f save-buffer -makeinfo = makeinfo make.texinfo - -make.info: make.texinfo - $(makeinfo) - - -make.dvi: make.texinfo - -tex make.texinfo - texindex make.cp make.fn make.ky make.pg make.tp make.vr - -tex make.texinfo - -make.ps: make.dvi - dvi2ps make.dvi > make.ps - -make: $(objs) $(globdep) - $(CC) $(LDFLAGS) $(objs) $(globlib) $(LOADLIBES) -o make.new - mv -f make.new make - -load.o: load.c - $(CC) $(CFLAGS) $(LOAD_AVG) -c load.c -remote.o: remote.c - $(CC) $(CFLAGS) $(REMOTE) -c remote.c - -# For some losing Unix makes. -MAKE = make - -glob/libglob.a: force - cd glob; $(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) -I..' libglob.a -force: - -TAGS: $(srcs) - etags -tw $(srcs) -tags: $(srcs) - ctags -tw $(srcs) - -.PHONY: install -install: $(bindir)/$(instname) $(mandir)/$(instname).$(manext) - -$(bindir)/$(instname): make - cp make $@.new -# These are necessary for load-average checking to work on most Unix machines. - chgrp $(group) $@.new - chmod g+s $@.new - mv $@.new $@ - -$(mandir)/$(instname).$(manext): make.man - cp make.man $@ - -.PHONY: clean realclean -clean: glob-clean - -rm -f make *.o core -realclean: clean glob-realclean - -rm -f TAGS tags make.info* make-* make.dvi *~ - -rm -f make.?? make.??s make.log make.toc make.*aux - -.PHONY: glob-clean glob-realclean -glob-clean glob-realclean: - cd glob; $(MAKE) $@ - -# 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 -load.o : load.c make.h commands.h job.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 -read.o : read.c make.h commands.h dep.h file.h variable.h -remake.o : remake.c make.h commands.h job.h dep.h file.h -remote.o : remote.c remote-stub.c make.h commands.h -rule.o : rule.c make.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 -arscan.o : arscan.c -ar.o : ar.c make.h file.h diff -ruN make-3.62/Makefile.in make-3.63/Makefile.in --- make-3.62/Makefile.in +++ make-3.63/Makefile.in Fri Jan 22 19:27:19 1993 @@ -0,0 +1,242 @@ +# 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. + +# +# Makefile for GNU Make +# + +srcdir = @srcdir@ +VPATH = $(srcdir) + +CC = @CC@ + +CFLAGS = @CFLAGS@ +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. +defines = @DEFS@ -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\" + +# 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@ + +# If there are remote execution facilities defined, +# enable them with switches here (see remote-*.c). +REMOTE = + +# Any extra object files your system needs. +extras = @LIBOBJS@ + +# Common prefix for machine-independent installed files. +prefix = /usr/local +# Common prefix for machine-dependent installed files. +exec_prefix = /usr/local + +# Name under which to install GNU make. +instname = make +# 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 man page in. +mandir = $(prefix)/man/man$(manext) +# Number to put on the man page filename. +manext = 1 + +# 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 + +# 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 -tw +CTAGS = ctags -tw + +objs = commands.o job.o dir.o file.o misc.o main.o read.o remake.o \ + remote.o rule.o implicit.o default.o variable.o expand.o \ + function.o vpath.o version.o ar.o arscan.o signame.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)/remote.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)/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 .texinfo + +.PHONY: all check info dvi +all: make +check: # No tests. +info: make.info +dvi: make.dvi + +make.info: make.texinfo + $(MAKEINFO) $(srcdir)/make.texinfo + +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 \ + $(CFLAGS) $< $(OUTPUT_OPTION) +remote.o: remote.c + $(CC) $(defines) $(REMOTE) -c -I. -I$(srcdir) \ + $(CFLAGS) $(srcdir)/remote.c + +# For some losing Unix makes. +MAKE = make + +glob/libglob.a: force + cd glob; $(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) -I..' \ + CPPFLAGS='$(CPPFLAGS) -DHAVE_CONFIG_H' \ + libglob.a +force: + +tagsrcs = $(srcs) $(srcdir)/remote-*.c +TAGS: $(tagsrcs) + $(ETAGS) $(tagsrcs) +tags: $(tagsrcs) + $(CTAGS) $(tagsrcs) + +.PHONY: install +install: $(bindir)/$(instname) $(mandir)/$(instname).$(manext) + +$(bindir)/$(instname): make + $(INSTALL_PROGRAM) make $@.new +# These are necessary for load-average checking to work on most Unix machines. + if $(install_setgid); then \ + chgrp $(group) $@.new && chmod g+s $@.new; \ + else true; fi + mv $@.new $@ + +$(mandir)/$(instname).$(manext): make.man + $(INSTALL_DATA) $(srcdir)/make.man $@ + +.PHONY: clean realclean distclean mostlyclean +clean: glob-clean + -rm -f make *.o core +distclean: clean glob-realclean + -rm -f Makefile config.h config.status build.sh + -rm -f TAGS tags make.info* make-* make.dvi + -rm -f make.?? make.??s make.log make.toc make.*aux +realclean: distclean +mostlyclean: clean + +.PHONY: glob-clean glob-realclean +glob-clean glob-realclean: + cd glob; $(MAKE) $@ + +Makefile: config.status $(srcdir)/Makefile.in + $(SHELL) config.status +config.h: config.status $(srcdir)/config.h.in + $(SHELL) config.status + +configure: configure.in + autoconf +config.h.in: configure.in + autoheader + +# This tells versions [3.59,3.63) of GNU make not to export all variables. +.NOEXPORT: + +# Automatically generated dependencies will be put at the end of the file. + +# Automatically generated dependencies. +commands.o : commands.c make.h config.h dep.h commands.h file.h variable.h \ + job.h +job.o : job.c make.h config.h commands.h job.h file.h variable.h +dir.o : dir.c make.h config.h +file.o : file.c make.h config.h commands.h dep.h file.h variable.h +misc.o : misc.c make.h config.h dep.h +main.o : main.c make.h config.h commands.h dep.h file.h variable.h job.h \ + getopt.h +read.o : read.c make.h config.h commands.h dep.h file.h variable.h glob/glob.h +remake.o : remake.c make.h config.h commands.h job.h dep.h file.h +remote.o : remote.c remote-stub.c make.h commands.h +rule.o : rule.c make.h commands.h dep.h file.h variable.h rule.h +implicit.o : implicit.c make.h config.h rule.h dep.h file.h +default.o : default.c make.h config.h rule.h dep.h file.h commands.h variable.h +variable.o : variable.c make.h config.h commands.h variable.h dep.h file.h +expand.o : expand.c make.h config.h commands.h file.h variable.h +function.o : function.c make.h config.h variable.h dep.h commands.h job.h +vpath.o : vpath.c make.h config.h file.h variable.h +version.o : version.c +ar.o : ar.c make.h file.h +arscan.o : arscan.c make.h config.h +signame.o : signame.c signame.h +getopt.o : getopt.c config.h getopt.h +getopt1.o : getopt1.c config.h getopt.h +getloadavg.o : getloadavg.c config.h diff -ruN make-3.62/NEWS make-3.63/NEWS --- make-3.62/NEWS +++ make-3.63/NEWS Wed Jan 13 17:10:27 1993 @@ -0,0 +1,402 @@ +GNU make NEWS -- history of user-visible changes. 13 January 1993 + +Copyright (C) 1992, 1993 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.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 Make do it.) + +Version 3.05 + +---------------------------------------------------------------------- +Copyright information: + +Copyright (C) 1992, 1993 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: diff -ruN make-3.62/README make-3.63/README --- make-3.62/README Mon Oct 28 20:30:48 1991 +++ make-3.63/README Fri Jan 22 19:26:46 1993 @@ -1,11 +1,18 @@ -This directory contains the 3.62 test release of GNU Make. +This directory contains the 3.63 test release of GNU Make. All bugs reported for previous test releases have been fixed. -Some bugs probably remain. +Some bugs surely remain. -To install, edit the file Makefile as directed in the comments, -and run `make install'. +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. -GNU Make is fully documented in make.texinfo. See the section entitled `Bugs' -for information on submitting bug reports. +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. diff -ruN make-3.62/alloca.c make-3.63/alloca.c --- make-3.62/alloca.c +++ make-3.63/alloca.c Tue Dec 1 13:25:53 1992 @@ -0,0 +1,197 @@ +/* + alloca -- (mostly) portable public-domain implementation -- D A Gwyn + + last edit: 86/05/30 rms + include config.h, since on VMS it renames some symbols. + Use xmalloc instead of malloc. + + 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. + + It should work under any C implementation that uses an + actual procedure stack (as opposed to a linked list of + frames). 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. +*/ +#ifndef lint +static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */ +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#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 */ + +#ifndef alloca /* If compiling with GCC, this file's not needed. */ + +#ifdef __STDC__ +typedef void *pointer; /* generic pointer type */ +#else +typedef char *pointer; /* generic pointer type */ +#endif + +#define NULL 0 /* null pointer constant */ + +extern void free(); +extern pointer xmalloc(); + +/* + 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 (/* void */) +{ + static char *addr = NULL; /* address of first + `dummy', once known */ + auto char dummy; /* to get stack address */ + + if (addr == NULL) + { /* initial entry */ + addr = &dummy; + + find_stack_direction (); /* recurse once */ + } + else /* second entry */ + if (&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; + +/* + alloca( size ) returns 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. +*/ + +static header *last_alloca_header = NULL; /* -> last alloca header */ + +pointer +alloca (size) /* returns pointer to storage */ + unsigned size; /* # bytes to allocate */ +{ + auto char probe; /* probes stack depth: */ + register char *depth = &probe; + +#if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* unknown growth direction */ + find_stack_direction (); +#endif + + /* Reclaim garbage, defined as all alloca()ed storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* traverses linked list */ + + 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 */ + } + + if (size == 0) + return NULL; /* no allocation required */ + + /* Allocate combined header + user data storage. */ + + { + register pointer new = xmalloc (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)); + } +} + +#endif /* no alloca */ diff -ruN make-3.62/ar.c make-3.63/ar.c --- make-3.62/ar.c Mon Jun 3 16:37:34 1991 +++ make-3.63/ar.c Thu Jun 11 00:58:08 1992 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988-1991 Free Software Foundation, Inc. +/* 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 @@ -18,6 +18,7 @@ #include "make.h" #include "file.h" +#ifndef NO_ARCHIVES /* Defined in arscan.c. */ extern long int ar_scan (); @@ -170,3 +171,5 @@ return val; } + +#endif diff -ruN make-3.62/arscan.c make-3.63/arscan.c --- make-3.62/arscan.c Tue Oct 22 21:30:25 1991 +++ make-3.63/arscan.c Wed Jan 13 16:18:56 1993 @@ -1,5 +1,5 @@ /* Library function for scanning an archive file. - Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. + Copyright (C) 1987, 1989, 1991, 1992, 1993 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 @@ -14,22 +14,8 @@ 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. */ - -/* 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(sun386) || defined(USGr3) || defined(HPUX) \ - && !defined(PORTAR) && !defined(PORT5AR)) -#define PORTAR 1 -#endif - -#include -#include -#include -#include +#include "make.h" #if defined (USG) || defined (POSIX) #include #else @@ -36,68 +22,28 @@ #include #endif -#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) \ - || defined (POSIX)) -#include -#include -#define ANSI_STRING -#else /* No standard headers. */ - -#ifdef USG - -#include -#include -#define ANSI_STRING - -#else /* Not USG. */ -#include +#ifndef NO_ARCHIVES + +/* 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. */ -#ifndef bcmp -extern int bcmp (); -#endif -#ifndef bzero -extern void bzero (); -#endif -#ifndef bcopy -extern void bcopy (); +#if (!defined (PORTAR) || PORTAR == 0) && (!defined (PORT5AR) || PORT5AR == 0) +#undef PORTAR +#define PORTAR 1 #endif -#endif /* USG. */ - -extern char *malloc (), *realloc (); -extern void free (); - -#endif /* Standard headers. */ - -#ifdef ANSI_STRING -#define index(s, c) strchr((s), (c)) -#define rindex(s, c) strrchr((s), (c)) - -#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) -#define bzero(s, n) memset ((s), 0, (n)) -#define bcopy(s, d, n) memcpy ((d), (s), (n)) -#endif ANSI_STRING -#undef ANSI_STRING - +#include -#ifndef AIAMAG -#if (defined(APOLLO) || defined(HPUX) || defined(hpux) || \ - (PORTAR == 1 && (defined(USGr3) || defined(u3b2) || defined(sun386)))) -#define AR_NAMELEN 14 -#define AR_TRAILING_SLASH /* Member names have a trailing slash. */ -#else -#define AR_NAMELEN 15 -#endif -#else /* AIX. */ -#define AR_NAMELEN 255 +/* Cray's apparently defines this. */ +#ifndef AR_HDR_SIZE +#define AR_HDR_SIZE (sizeof (struct ar_hdr)) #endif -#if defined(__GNU_LIBRARY__) || defined(POSIX) || defined(_IBMR2) -#include -#else -extern int read (), open (), close (), write (), fstat (); -extern long int lseek (), atol (); -extern int atoi (); +/* SCO Unix's compiler defines both of these. */ +#ifdef M_UNIX +#undef M_XENIX #endif /* Takes three arguments ARCHIVE, FUNCTION and ARG. @@ -151,7 +97,7 @@ #else #ifdef AIAMAG { - register int nread = read (desc, &fl_header, FL_HSZ); + register int nread = read (desc, (char *) &fl_header, FL_HSZ); if (nread != FL_HSZ || bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG)) { (void) close (desc); @@ -200,7 +146,7 @@ register int nread; struct ar_hdr member_header; #ifdef AIAMAG - char name[AR_NAMELEN + 1]; + char name[256]; int name_len; long int dateval; int uidval, gidval; @@ -219,8 +165,7 @@ } #ifdef AIAMAG -#define AR_MEMHDR \ - (sizeof (member_header) - sizeof (member_header._ar_name)) +#define AR_MEMHDR (AR_HDR_SIZE - sizeof (member_header._ar_name)) nread = read (desc, (char *) &member_header, AR_MEMHDR); if (nread != AR_MEMHDR) @@ -254,13 +199,13 @@ dateval, uidval, gidval, eltmode, arg); -#else - nread = read (desc, (char *) &member_header, sizeof (struct ar_hdr)); +#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 != sizeof (member_header) + if (nread != AR_HDR_SIZE #ifdef ARFMAG || bcmp (member_header.ar_fmag, ARFMAG, 2) #endif @@ -275,10 +220,10 @@ register char *p = name + sizeof member_header.ar_name; while (p > name && *--p == ' ') *p = '\0'; -#ifdef AR_TRAILING_SLASH + + /* On some systems, there is a slash after each member name. */ if (*p == '/') *p = '\0'; -#endif } #ifndef M_XENIX @@ -291,7 +236,7 @@ fnval = (*function) (desc, name, member_offset, - member_offset + sizeof (member_header), eltsize, + member_offset + AR_HDR_SIZE, eltsize, #ifndef M_XENIX atol (member_header.ar_date), atoi (member_header.ar_uid), @@ -303,7 +248,7 @@ #endif /* Not Xenix. */ eltmode, arg); -#endif /* Not AIAMAG */ +#endif /* AIAMAG. */ if (fnval) { @@ -312,8 +257,9 @@ } #ifdef AIAMAG - if (member_offset == last_member_offset) /* end of chain? */ - break; + if (member_offset == last_member_offset) + /* End of the chain. */ + break; sscanf (member_header.ar_nxtmem, "%12ld", &member_offset); @@ -323,8 +269,9 @@ return -2; } #else - member_offset += sizeof (member_header) + eltsize; - if (member_offset & 1) member_offset++; + member_offset += AR_HDR_SIZE + eltsize; + if (member_offset % 2 != 0) + member_offset++; #endif } } @@ -346,27 +293,37 @@ if (p != 0) name = p + 1; -#ifndef APOLLO +#if !defined (AIAMAG) && !defined (APOLLO) - if (!strncmp (name, mem, AR_NAMELEN)) - return 1; + { + /* `reallylongname.o' matches `reallylongnam.o'. + If member names have a trailing slash, that's `reallylongna.o'. */ - if (!strncmp (name, mem, AR_NAMELEN - 2)) - { - unsigned int namelen, memlen; - - namelen = strlen (name); - memlen = strlen (mem); - - if (memlen == AR_NAMELEN - && mem[AR_NAMELEN - 2] == '.' && mem[AR_NAMELEN - 1] == 'o' - && name[namelen - 2] == '.' && name[namelen -1] == 'o') - return 1; - } - return 0; + 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; -#else /* APOLLO. */ + return (namelen < max - 3 || !strcmp (name + max - 3, mem + max - 3)); + } + +#else /* AIX or APOLLO. */ + return !strcmp (name, mem); + #endif } @@ -399,7 +356,6 @@ register int fd; struct ar_hdr ar_hdr; register int i; - extern int errno; struct stat statbuf; if (pos < 0) @@ -413,12 +369,12 @@ /* Read in this member's header */ if (lseek (fd, pos, 0) < 0) goto lose; - if (sizeof ar_hdr != read (fd, (char *) &ar_hdr, sizeof ar_hdr)) + 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 (sizeof ar_hdr != write (fd, (char *) &ar_hdr, sizeof ar_hdr)) + if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE)) goto lose; /* The file's mtime is the time we we want. */ fstat (fd, &statbuf); @@ -436,7 +392,7 @@ /* Write back this member's header */ if (lseek (fd, pos, 0) < 0) goto lose; - if (sizeof ar_hdr != write (fd, (char *) &ar_hdr, sizeof ar_hdr)) + if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE)) goto lose; close (fd); return 0; @@ -475,3 +431,5 @@ } #endif /* TEST. */ + +#endif /* NO_ARCHIVES. */ diff -ruN make-3.62/build.sh.in make-3.63/build.sh.in --- make-3.62/build.sh.in +++ make-3.63/build.sh.in Thu Jan 21 18:51:53 1993 @@ -0,0 +1,66 @@ +#!/bin/sh + +# Shell script to build GNU Make in the absence of any `make' program. + +# Copyright (C) 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. + +# See Makefile.in for comments describing these variables. + +srcdir='@srcdir@' +CC='@CC@' +CFLAGS='@CFLAGS@' +LDFLAGS='@LDFLAGS@' +defines='@DEFS@ -DLIBDIR="${libdir}" -DINCLUDEDIR="${includedir}"' +ALLOCA='@ALLOCA@' +LOADLIBES='@LIBS@' +extras='@LIBOBJS@' + +# Common prefix for machine-independent installed files. +prefix=/usr/local +# Common prefix for machine-dependent installed files. +exec_prefix=/usr/local +# 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 remote.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 ${extras} ${ALLOCA}" + +# Compile the source files into those objects. +for file in `echo ${objs} | sed 's/\.o/.c/g'`; do + echo compiling ${file}... + $CC $CFLAGS $defines -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 diff -ruN make-3.62/commands.c make-3.63/commands.c --- make-3.62/commands.c Tue Oct 8 16:20:29 1991 +++ make-3.63/commands.c Wed Jan 6 17:57:24 1993 @@ -1,5 +1,5 @@ /* Command processing for GNU Make. -Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. +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 @@ -25,7 +25,7 @@ extern int remote_kill (); -#if !defined(POSIX) && !defined(__GNU_LIBRARY__) +#ifndef HAVE_UNISTD_H extern int getpid (); #endif @@ -74,13 +74,28 @@ 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 len = strlen (file->name); unsigned int slen = strlen (dep_name (d)); - if (len > slen && streq (dep_name (d), file->name + len - slen)) + if (len > slen && !strncmp (dep_name (d), name + len - slen, slen)) { - file->stem = savestring (file->name, len - slen); + file->stem = savestring (name, len - slen); break; } } @@ -115,6 +130,12 @@ DEFINE_VARIABLE ("%D", 2, DIRONLY (percent)); DEFINE_VARIABLE ("%F", 2, FILEONLY (percent)); + /* 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 $? and their F and D versions. */ { @@ -125,24 +146,34 @@ register char *qp, *qDp, *qFp; register struct dep *d; unsigned int len; + unsigned int caretD_len, qmarkD_len; caret_len = qmark_len = 0; + caretD_len = qmarkD_len = 0; for (d = file->deps; d != 0; d = d->next) { register unsigned int i = strlen (dep_name (d)) + 1; caret_len += i; + caretD_len += (i <= 2 ? 3 : i); if (d->changed) - qmark_len += i; + { + qmark_len += i; + qmarkD_len += (i <= 2 ? 3 : i); + } } len = caret_len == 0 ? 1 : caret_len; - cp = caret_value = (char *) xmalloc (len); - cDp = caretD_value = (char *) xmalloc (len); - cFp = caretF_value = (char *) xmalloc (len); + if (caretD_len == 0) + caretD_len = 1; + cp = caret_value = (char *) alloca (len); + cDp = caretD_value = (char *) alloca (caretD_len); + cFp = caretF_value = (char *) alloca (len); len = qmark_len == 0 ? 1 : qmark_len; - qp = qmark_value = (char *) xmalloc (len); - qDp = qmarkD_value = (char *) xmalloc (len); - qFp = qmarkF_value = (char *) xmalloc (len); + if (qmarkD_len == 0) + qmarkD_len = 1; + qp = qmark_value = (char *) alloca (len); + qDp = qmarkD_value = (char *) alloca (qmarkD_len); + qFp = qmarkF_value = (char *) alloca (len); for (d = file->deps; d != 0; d = d->next) { @@ -150,7 +181,17 @@ unsigned int Dlen, Flen; c = dep_name (d); - len = strlen (c); + +#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++ = ' '; @@ -287,12 +328,17 @@ cmds->lines_recurse = (char *) xmalloc (nlines); for (idx = 0; idx < nlines; ++idx) { - unsigned int len; int recursive; p = lines[idx]; - len = strlen (p); - recursive = (sindex (p, len, "$(MAKE)", 7) != 0 - || sindex (p, len, "${MAKE}", 7) != 0); + while (isblank (*p) || *p == '-' || *p == '@') + ++p; + recursive = *p == '+'; + if (!recursive) + { + unsigned int len = strlen (p); + recursive = (sindex (p, len, "$(MAKE)", 7) != 0 + || sindex (p, len, "${MAKE}", 7) != 0); + } cmds->lines_recurse[idx] = recursive; cmds->any_recurse |= recursive; } @@ -317,6 +363,9 @@ 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; @@ -332,19 +381,24 @@ new_job (file); } -#define PROPAGATED_SIGNAL_MASK \ - (sigmask (SIGTERM) | sigmask (SIGINT) | sigmask (SIGHUP) | sigmask (SIGQUIT)) - /* Handle fatal signals. */ -int +RETSIGTYPE fatal_error_signal (sig) int sig; { signal (sig, SIG_DFL); -#ifndef USG +#ifdef POSIX + { + sigset_t set; + sigemptyset (&set); + (void) sigprocmask (SIG_SETMASK, &set, (sigset_t *) 0); + } +#else +#ifdef HAVE_SIGSETMASK (void) sigsetmask (0); #endif +#endif /* A termination signal won't be sent to the entire process group, but it means we want to kill the children. */ @@ -352,20 +406,17 @@ if (sig == SIGTERM) { register struct child *c; - push_signals_blocked_p (1); for (c = children; c != 0; c = c->next) if (!c->remote) (void) kill (c->pid, SIGTERM); - pop_signals_blocked_p (); } /* If we got a signal that means the user wanted to kill make, remove pending targets. */ - if (PROPAGATED_SIGNAL_MASK & sigmask (sig)) + if (sig == SIGTERM || sig == SIGINT || sig == SIGHUP || sig == SIGQUIT) { register struct child *c; - push_signals_blocked_p (1); /* Remote children won't automatically get signals sent to the process group, so we must send them. */ @@ -376,15 +427,15 @@ for (c = children; c != 0; c = c->next) delete_child_targets (c); - pop_signals_blocked_p (); - /* Clean up the children. We don't just use the call below because we don't want to print the "Waiting for children" message. */ - wait_for_children (0, 0); + while (job_slots_used > 0) + reap_children (1, 0); } else /* Wait for our children to die. */ - wait_for_children (0, 1); + while (job_slots_used > 0) + reap_children (1, 1); /* Delete any non-precious intermediate files that were made. */ @@ -399,8 +450,6 @@ if (kill (getpid (), sig) < 0) /* It shouldn't return, but if it does, die anyway. */ pfatal_with_name ("kill"); - - return 0; } /* Delete all non-precious targets of CHILD unless they were already deleted. @@ -471,7 +520,7 @@ if (end == 0) end = s + strlen (s); - printf ("\t%.*s\n", end - s, s); + printf ("\t%.*s\n", (int) (end - s), s); s = end; } diff -ruN make-3.62/config.h.in make-3.63/config.h.in --- make-3.62/config.h.in +++ make-3.63/config.h.in Fri Jan 22 19:31:42 1993 @@ -0,0 +1,143 @@ +/* Generated automatically from configure.in by autoheader. DO NOT EDIT! */ + +/* Define if you have dirent.h. */ +#undef DIRENT + +/* Define if you have alloca.h and it should be used (not Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Define if you have the strcoll function and it is properly defined. */ +#undef HAVE_STRCOLL + +/* Define if you have unistd.h. */ +#undef HAVE_UNISTD_H + +/* Define if you have vfork.h. */ +#undef HAVE_VFORK_H + +/* Define vfork as fork if vfork does not work. */ +#undef vfork + +/* Define if you have memory.h, and string.h doesn't declare the + mem* functions. */ +#undef NEED_MEMORY_H + +/* 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 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 + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you don't have dirent.h, but have sys/dir.h. */ +#undef SYSDIR + +/* Define if you don't have dirent.h, but have sys/ndir.h. */ +#undef SYSNDIR + +/* Define if you do not have strings.h, index, bzero, etc.. */ +#undef USG + +/* Define if the closedir function returns void instead of int. */ +#undef VOID_CLOSEDIR + +/* Define if on AIX 3. */ +#undef _ALL_SOURCE + +/* Define if on MINIX. */ +#undef _MINIX + +/* Define if on MINIX. */ +#undef _POSIX_1_SOURCE + +/* Define if you need to in order for stat and other things to work. */ +#undef _POSIX_SOURCE + +/* Define on System V Release 4. */ +#undef SVR4 + +/* Define for Encore UMAX. */ +#undef UMAX + +/* Define for Encore UMAX 4.3 that has + instead of . */ +#undef UMAX4_3 + +/* Define to `int' if doesn't define. */ +#undef uid_t +#undef gid_t +#undef pid_t + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define for DGUX with . */ +#undef DGUX + +/* Define if the `getloadavg' function needs to be run setuid or setgid. */ +#undef GETLOADAVG_PRIVILEGED + +/* Define if `union wait' is the type of the first arg to wait functions. */ +#undef HAVE_UNION_WAIT + + +/* Define if you have getdtablesize. */ +#undef HAVE_GETDTABLESIZE + +/* Define if you have sys_siglist. */ +#undef HAVE_SYS_SIGLIST + +/* Define if you have _sys_siglist. */ +#undef HAVE__SYS_SIGLIST + +/* Define if you have dup2. */ +#undef HAVE_DUP2 + +/* Define if you have getcwd. */ +#undef HAVE_GETCWD + +/* Define if you have sigsetmask. */ +#undef HAVE_SIGSETMASK + +/* Define if you have getgroups. */ +#undef HAVE_GETGROUPS + +/* Define if you have setlinebuf. */ +#undef HAVE_SETLINEBUF + +/* Define if you have setreuid. */ +#undef HAVE_SETREUID + +/* Define if you have setregid. */ +#undef HAVE_SETREGID + +/* Define if you have waitpid. */ +#undef HAVE_WAITPID + +/* Define if you have wait3. */ +#undef HAVE_WAIT3 + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_WAIT_H diff -ruN make-3.62/configure make-3.63/configure --- make-3.62/configure +++ make-3.63/configure Fri Jan 22 17:16:47 1993 @@ -0,0 +1,1276 @@ +#!/bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf. +# Copyright (C) 1991, 1992, 1993 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. + +# Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create] +# [--prefix=PREFIX] [--exec-prefix=PREFIX] [--with-PACKAGE] [TARGET] +# Ignores all args except --srcdir, --prefix, --exec-prefix, --no-create, and +# --with-PACKAGE unless this script has special code to handle it. + + +for arg +do + # Handle --exec-prefix with a space before the argument. + if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix= + # Handle --host with a space before the argument. + elif test x$next_host = xyes; then next_host= + # Handle --prefix with a space before the argument. + elif test x$next_prefix = xyes; then prefix=$arg; next_prefix= + # Handle --srcdir with a space before the argument. + elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir= + else + case $arg in + # For backward compatibility, also recognize exact --exec_prefix. + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* | --exec=* | --exe=* | --ex=* | --e=*) + exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- | --exec | --exe | --ex | --e) + next_exec_prefix=yes ;; + + -gas | --gas | --ga | --g) ;; + + -host=* | --host=* | --hos=* | --ho=* | --h=*) ;; + -host | --host | --hos | --ho | --h) + next_host=yes ;; + + -nfp | --nfp | --nf) ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no) + no_create=1 ;; + + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + next_prefix=yes ;; + + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*) + srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s) + next_srcdir=yes ;; + + -with-* | --with-*) + package=`echo $arg|sed 's/-*with-//'` + # Delete all the valid chars; see if any are left. + if test -n "`echo $package|sed 's/[-a-zA-Z0-9_]*//g'`"; then + echo "configure: $package: invalid package name" >&2; exit 1 + fi + eval "with_`echo $package|sed s/-/_/g`=1" ;; + + *) ;; + esac + fi +done + +trap 'rm -f conftest* core; exit 1' 1 3 15 + +rm -f conftest* +compile='${CC-cc} $CFLAGS $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1' + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +unique_file=vpath.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + srcdirdefaulted=yes + # Try the directory containing this script, then `..'. + prog=$0 + confdir=`echo $prog|sed 's%/[^/][^/]*$%%'` + test "X$confdir" = "X$prog" && confdir=. + srcdir=$confdir + if test ! -r $srcdir/$unique_file; then + srcdir=.. + fi +fi +if test ! -r $srcdir/$unique_file; then + if test x$srcdirdefaulted = xyes; then + echo "configure: Can not find sources in \`${confdir}' or \`..'." 1>&2 + else + echo "configure: Can not find sources in \`${srcdir}'." 1>&2 + fi + exit 1 +fi +# Preserve a srcdir of `.' to avoid automounter screwups with pwd. +# But we can't avoid them for `..', to make subdirectories work. +case $srcdir in + .|/*|~*) ;; + *) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute. +esac + + +# We want these before the checks, so the checks can modify their values. +test -z "$CFLAGS" && CFLAGS=-g +test -z "$LDFLAGS" && LDFLAGS=-g + +if test -z "$CC"; then + echo checking for gcc + saveifs="$IFS"; IFS="${IFS}:" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/gcc; then + CC="gcc" + break + fi + done + IFS="$saveifs" +fi +test -z "$CC" && CC="cc" + +# Find out if we are using GNU C, under whatever name. +cat > conftest.c < conftest.out 2>&1 +if egrep yes conftest.out >/dev/null 2>&1; then + GCC=1 # For later tests. +fi +rm -f conftest* + +# Make sure to not get the incompatible SysV /etc/install and +# /usr/sbin/install, which might be in PATH before a BSD-like install, +# or the SunOS /usr/etc/install directory, or the AIX /bin/install, +# or the AFS install, which mishandles nonexistent args. (Sigh.) +if test -z "$INSTALL"; then + echo checking for install + saveifs="$IFS"; IFS="${IFS}:" + for dir in $PATH; do + test -z "$dir" && dir=. + case $dir in + /etc|/usr/sbin|/usr/etc|/usr/afsws/bin) ;; + *) + if test -f $dir/install; then + if grep dspmsg $dir/install >/dev/null 2>&1; then + : # AIX + else + INSTALL="$dir/install -c" + INSTALL_PROGRAM='$(INSTALL)' + INSTALL_DATA='$(INSTALL) -m 644' + break + fi + fi + ;; + esac + done + IFS="$saveifs" +fi +INSTALL=${INSTALL-cp} +INSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'} +INSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'} + +if test -z "$RANLIB"; then + echo checking for ranlib + saveifs="$IFS"; IFS="${IFS}:" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/ranlib; then + RANLIB="ranlib" + break + fi + done + IFS="$saveifs" +fi +test -z "$RANLIB" && RANLIB="@:" + +echo checking how to run the C preprocessor +if test -z "$CPP"; then + CPP='${CC-cc} -E' + cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + : +else + CPP=/lib/cpp +fi +rm -f conftest* +fi + echo checking for AIX +cat > conftest.c < conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + DEFS="$DEFS -D_ALL_SOURCE=1" +SEDDEFS="${SEDDEFS}\${SEDdA}_ALL_SOURCE\${SEDdB}_ALL_SOURCE\${SEDdC}1\${SEDdD} +\${SEDuA}_ALL_SOURCE\${SEDuB}_ALL_SOURCE\${SEDuC}1\${SEDuD} +\${SEDeA}_ALL_SOURCE\${SEDeB}_ALL_SOURCE\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + + +echo checking for POSIXized ISC +if test -d /etc/conf/kconfig.d && + grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 +then + ISC=1 # If later tests want to check for ISC. + DEFS="$DEFS -D_POSIX_SOURCE=1" +SEDDEFS="${SEDDEFS}\${SEDdA}_POSIX_SOURCE\${SEDdB}_POSIX_SOURCE\${SEDdC}1\${SEDdD} +\${SEDuA}_POSIX_SOURCE\${SEDuB}_POSIX_SOURCE\${SEDuC}1\${SEDuD} +\${SEDeA}_POSIX_SOURCE\${SEDeB}_POSIX_SOURCE\${SEDeC}1\${SEDeD} +" + if test -n "$GCC"; then + CC="$CC -posix" + else + CC="$CC -Xp" + fi +fi + +echo checking for minix/config.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + MINIX=1 +fi +rm -f conftest* + +# The Minix shell can't assign to the same variable on the same line! +if test -n "$MINIX"; then + DEFS="$DEFS -D_POSIX_SOURCE=1" +SEDDEFS="${SEDDEFS}\${SEDdA}_POSIX_SOURCE\${SEDdB}_POSIX_SOURCE\${SEDdC}1\${SEDdD} +\${SEDuA}_POSIX_SOURCE\${SEDuB}_POSIX_SOURCE\${SEDuC}1\${SEDuD} +\${SEDeA}_POSIX_SOURCE\${SEDeB}_POSIX_SOURCE\${SEDeC}1\${SEDeD} +" + DEFS="$DEFS -D_POSIX_1_SOURCE=2" +SEDDEFS="${SEDDEFS}\${SEDdA}_POSIX_1_SOURCE\${SEDdB}_POSIX_1_SOURCE\${SEDdC}2\${SEDdD} +\${SEDuA}_POSIX_1_SOURCE\${SEDuB}_POSIX_1_SOURCE\${SEDuC}2\${SEDuD} +\${SEDeA}_POSIX_1_SOURCE\${SEDeB}_POSIX_1_SOURCE\${SEDeC}2\${SEDeD} +" + DEFS="$DEFS -D_MINIX=1" +SEDDEFS="${SEDDEFS}\${SEDdA}_MINIX\${SEDdB}_MINIX\${SEDdC}1\${SEDdD} +\${SEDuA}_MINIX\${SEDuB}_MINIX\${SEDuC}1\${SEDuD} +\${SEDeA}_MINIX\${SEDeB}_MINIX\${SEDeC}1\${SEDeD} +" +fi + +echo checking for ANSI C header files +cat > conftest.c < +#include +#include +#include +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + # SunOS string.h does not declare mem*, contrary to ANSI. +echo '#include ' > conftest.c +eval "$CPP $DEFS conftest.c > conftest.out 2>&1" +if egrep "memchr" conftest.out >/dev/null 2>&1; then + # SGI's /bin/cc from Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +cat > conftest.c < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e,f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +eval $compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + DEFS="$DEFS -DSTDC_HEADERS=1" +SEDDEFS="${SEDDEFS}\${SEDdA}STDC_HEADERS\${SEDdB}STDC_HEADERS\${SEDdC}1\${SEDdD} +\${SEDuA}STDC_HEADERS\${SEDuB}STDC_HEADERS\${SEDuC}1\${SEDuD} +\${SEDeA}STDC_HEADERS\${SEDeB}STDC_HEADERS\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* +fi +rm -f conftest* + +fi +rm -f conftest* + +echo checking whether string.h declares mem functions +echo '#include ' > conftest.c +eval "$CPP $DEFS conftest.c > conftest.out 2>&1" +if egrep "memchr" conftest.out >/dev/null 2>&1; then + : +else + echo checking for memory.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DNEED_MEMORY_H=1" +SEDDEFS="${SEDDEFS}\${SEDdA}NEED_MEMORY_H\${SEDdB}NEED_MEMORY_H\${SEDdC}1\${SEDdD} +\${SEDuA}NEED_MEMORY_H\${SEDuB}NEED_MEMORY_H\${SEDuC}1\${SEDuD} +\${SEDeA}NEED_MEMORY_H\${SEDeB}NEED_MEMORY_H\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + +fi +rm -f conftest* + + +echo checking for unistd.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DHAVE_UNISTD_H=1" +SEDDEFS="${SEDDEFS}\${SEDdA}HAVE_UNISTD_H\${SEDdB}HAVE_UNISTD_H\${SEDdC}1\${SEDdD} +\${SEDuA}HAVE_UNISTD_H\${SEDuB}HAVE_UNISTD_H\${SEDuC}1\${SEDuD} +\${SEDeA}HAVE_UNISTD_H\${SEDeB}HAVE_UNISTD_H\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + +echo checking for directory library header +echo checking for dirent.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DDIRENT=1" +SEDDEFS="${SEDDEFS}\${SEDdA}DIRENT\${SEDdB}DIRENT\${SEDdC}1\${SEDdD} +\${SEDuA}DIRENT\${SEDuB}DIRENT\${SEDuC}1\${SEDuD} +\${SEDeA}DIRENT\${SEDeB}DIRENT\${SEDeC}1\${SEDeD} +" dirheader=dirent.h +fi +rm -f conftest* + +if test -z "$dirheader"; then +echo checking for sys/ndir.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DSYSNDIR=1" +SEDDEFS="${SEDDEFS}\${SEDdA}SYSNDIR\${SEDdB}SYSNDIR\${SEDdC}1\${SEDdD} +\${SEDuA}SYSNDIR\${SEDuB}SYSNDIR\${SEDuC}1\${SEDuD} +\${SEDeA}SYSNDIR\${SEDeB}SYSNDIR\${SEDeC}1\${SEDeD} +" dirheader=sys/ndir.h +fi +rm -f conftest* + +fi +if test -z "$dirheader"; then +echo checking for sys/dir.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DSYSDIR=1" +SEDDEFS="${SEDDEFS}\${SEDdA}SYSDIR\${SEDdB}SYSDIR\${SEDdC}1\${SEDdD} +\${SEDuA}SYSDIR\${SEDuB}SYSDIR\${SEDuC}1\${SEDuD} +\${SEDeA}SYSDIR\${SEDeB}SYSDIR\${SEDeC}1\${SEDeD} +" dirheader=sys/dir.h +fi +rm -f conftest* + +fi +if test -z "$dirheader"; then +echo checking for ndir.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DNDIR=1" +SEDDEFS="${SEDDEFS}\${SEDdA}NDIR\${SEDdB}NDIR\${SEDdC}1\${SEDdD} +\${SEDuA}NDIR\${SEDuB}NDIR\${SEDuC}1\${SEDuD} +\${SEDeA}NDIR\${SEDeB}NDIR\${SEDeC}1\${SEDeD} +" dirheader=ndir.h +fi +rm -f conftest* + +fi + +echo checking for closedir return value +cat > conftest.c < +#include <$dirheader> +int closedir(); main() { exit(0); } +EOF +eval $compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + DEFS="$DEFS -DVOID_CLOSEDIR=1" +SEDDEFS="${SEDDEFS}\${SEDdA}VOID_CLOSEDIR\${SEDdB}VOID_CLOSEDIR\${SEDdC}1\${SEDdD} +\${SEDuA}VOID_CLOSEDIR\${SEDuB}VOID_CLOSEDIR\${SEDuC}1\${SEDuD} +\${SEDeA}VOID_CLOSEDIR\${SEDeB}VOID_CLOSEDIR\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + +echo checking for uid_t in sys/types.h +echo '#include ' > conftest.c +eval "$CPP $DEFS conftest.c > conftest.out 2>&1" +if egrep "uid_t" conftest.out >/dev/null 2>&1; then + : +else + DEFS="$DEFS -Duid_t=int" +SEDDEFS="${SEDDEFS}\${SEDdA}uid_t\${SEDdB}uid_t\${SEDdC}int\${SEDdD} +\${SEDuA}uid_t\${SEDuB}uid_t\${SEDuC}int\${SEDuD} +\${SEDeA}uid_t\${SEDeB}uid_t\${SEDeC}int\${SEDeD} +" DEFS="$DEFS -Dgid_t=int" +SEDDEFS="${SEDDEFS}\${SEDdA}gid_t\${SEDdB}gid_t\${SEDdC}int\${SEDdD} +\${SEDuA}gid_t\${SEDuB}gid_t\${SEDuC}int\${SEDuD} +\${SEDeA}gid_t\${SEDeB}gid_t\${SEDeC}int\${SEDeD} +" +fi +rm -f conftest* + echo checking for pid_t in sys/types.h +echo '#include ' > conftest.c +eval "$CPP $DEFS conftest.c > conftest.out 2>&1" +if egrep "pid_t" conftest.out >/dev/null 2>&1; then + : +else + DEFS="$DEFS -Dpid_t=int" +SEDDEFS="${SEDDEFS}\${SEDdA}pid_t\${SEDdB}pid_t\${SEDdC}int\${SEDdD} +\${SEDuA}pid_t\${SEDuB}pid_t\${SEDuC}int\${SEDuD} +\${SEDeA}pid_t\${SEDeB}pid_t\${SEDeC}int\${SEDeD} +" +fi +rm -f conftest* + +echo checking for return type of signal handlers +cat > conftest.c < +#include +#ifdef signal +#undef signal +#endif +extern void (*signal ()) (); +main() { exit(0); } +t() { int i; } +EOF +if eval $compile; then + DEFS="$DEFS -DRETSIGTYPE=void" +SEDDEFS="${SEDDEFS}\${SEDdA}RETSIGTYPE\${SEDdB}RETSIGTYPE\${SEDdC}void\${SEDdD} +\${SEDuA}RETSIGTYPE\${SEDuB}RETSIGTYPE\${SEDuC}void\${SEDuD} +\${SEDeA}RETSIGTYPE\${SEDeB}RETSIGTYPE\${SEDeC}void\${SEDeD} +" +else + DEFS="$DEFS -DRETSIGTYPE=int" +SEDDEFS="${SEDDEFS}\${SEDdA}RETSIGTYPE\${SEDdB}RETSIGTYPE\${SEDdC}int\${SEDdD} +\${SEDuA}RETSIGTYPE\${SEDuB}RETSIGTYPE\${SEDuC}int\${SEDuD} +\${SEDeA}RETSIGTYPE\${SEDeB}RETSIGTYPE\${SEDeC}int\${SEDeD} +" +fi +rm -f conftest* + + +for hdr in limits.h sys/param.h fcntl.h +do +trhdr=HAVE_`echo $hdr | tr '[a-z]./' '[A-Z]__'` +echo checking for ${hdr} +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -D${trhdr}=1" +SEDDEFS="${SEDDEFS}\${SEDdA}${trhdr}\${SEDdB}${trhdr}\${SEDdC}1\${SEDdD} +\${SEDuA}${trhdr}\${SEDuB}${trhdr}\${SEDuC}1\${SEDuD} +\${SEDeA}${trhdr}\${SEDeB}${trhdr}\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* +done + +echo 'foo(){}' > conftest.c +if ${CC-cc} -c conftest.c -o conftesto >/dev/null 2>&1 && test -f conftesto +then + : +else + DEFS="$DEFS -DNO_MINUS_C_MINUS_O=1" +SEDDEFS="${SEDDEFS}\${SEDdA}NO_MINUS_C_MINUS_O\${SEDdB}NO_MINUS_C_MINUS_O\${SEDdC}1\${SEDdD} +\${SEDuA}NO_MINUS_C_MINUS_O\${SEDuB}NO_MINUS_C_MINUS_O\${SEDuC}1\${SEDuD} +\${SEDeA}NO_MINUS_C_MINUS_O\${SEDeB}NO_MINUS_C_MINUS_O\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + +prog='/* Ultrix mips cc rejects this. */ +typedef int charset[2]; const charset x; +/* SunOS 4.1.1 cc rejects this. */ +char const *const *p; +char **p2; +/* HPUX 7.0 cc rejects these. */ +++p; +p2 = (char const* const*) p;' +echo checking for working const +cat > conftest.c < conftest.c < +main() { exit(0); } +t() { rindex(0, 0); bzero(0, 0); } +EOF +if eval $compile; then + : +else + DEFS="$DEFS -DUSG=1" +SEDDEFS="${SEDDEFS}\${SEDdA}USG\${SEDdB}USG\${SEDdC}1\${SEDdD} +\${SEDuA}USG\${SEDuB}USG\${SEDuC}1\${SEDuD} +\${SEDeA}USG\${SEDeB}USG\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + + + + +for func in getdtablesize sys_siglist _sys_siglist \ + dup2 getcwd sigsetmask getgroups setlinebuf \ + setreuid setregid +do +trfunc=HAVE_`echo $func | tr '[a-z]' '[A-Z]'` +echo checking for ${func} +cat > conftest.c < +main() { exit(0); } +t() { +#ifdef __stub_${func} +choke me +#else +/* Override any gcc2 internal prototype to avoid an error. */ +extern char ${func}(); ${func}(); +#endif + } +EOF +if eval $compile; then + DEFS="$DEFS -D${trfunc}=1" +SEDDEFS="${SEDDEFS}\${SEDdA}${trfunc}\${SEDdB}${trfunc}\${SEDdC}1\${SEDdD} +\${SEDuA}${trfunc}\${SEDuB}${trfunc}\${SEDuC}1\${SEDuD} +\${SEDeA}${trfunc}\${SEDeB}${trfunc}\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* +#endif +done + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +echo checking for working alloca.h +cat > conftest.c < +main() { exit(0); } +t() { char *p = alloca(2 * sizeof(int)); } +EOF +if eval $compile; then + DEFS="$DEFS -DHAVE_ALLOCA_H=1" +SEDDEFS="${SEDDEFS}\${SEDdA}HAVE_ALLOCA_H\${SEDdB}HAVE_ALLOCA_H\${SEDdC}1\${SEDdD} +\${SEDuA}HAVE_ALLOCA_H\${SEDuB}HAVE_ALLOCA_H\${SEDuC}1\${SEDuD} +\${SEDeA}HAVE_ALLOCA_H\${SEDeB}HAVE_ALLOCA_H\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + +decl="#ifdef __GNUC__ +#define alloca __builtin_alloca +#else +#if HAVE_ALLOCA_H +#include +#else +#ifdef _AIX + #pragma alloca +#else +char *alloca (); +#endif +#endif +#endif +" +echo checking for alloca +cat > conftest.c < conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DHAVE_VFORK_H=1" +SEDDEFS="${SEDDEFS}\${SEDdA}HAVE_VFORK_H\${SEDdB}HAVE_VFORK_H\${SEDdC}1\${SEDdD} +\${SEDuA}HAVE_VFORK_H\${SEDuB}HAVE_VFORK_H\${SEDuC}1\${SEDuD} +\${SEDeA}HAVE_VFORK_H\${SEDeB}HAVE_VFORK_H\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + +echo checking for working vfork +cat > conftest.c < +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_VFORK_H +#include +#endif +main() { + pid_t parent = getpid(); + pid_t child = vfork(); + + if (child == 0) { + /* On sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. + The compiler is told about this with #include , + but some compilers (e.g. gcc -O) don't grok . + Test for this by using lots of local variables, at least + as many local variables as main has allocated so far + including compiler temporaries. 4 locals are enough for + gcc 1.40.3 on a sparc, but we use 8 to be safe. + A buggy compiler should reuse the register of parent + for one of the local variables, since it will think that + parent can't possibly be used any more in this routine. + Assigning to the local variable will thus munge parent + in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), + vfork doesn't separate parent from child file descriptors. + If the child closes a descriptor before it execs or exits, + this munges the parent's descriptor as well. + Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + exit( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +EOF +eval $compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + DEFS="$DEFS -Dvfork=fork" +SEDDEFS="${SEDDEFS}\${SEDdA}vfork\${SEDdB}vfork\${SEDdC}fork\${SEDdD} +\${SEDuA}vfork\${SEDuB}vfork\${SEDuC}fork\${SEDuD} +\${SEDeA}vfork\${SEDeB}vfork\${SEDeC}fork\${SEDeD} +" +fi +rm -f conftest* + +cat > conftest.c < +main () { + /* If setvbuf has the reversed format, exit 0. */ + setvbuf(stdout, _IOLBF, (char *) 0, BUFSIZ); /* The reversed way. */ + putc('\r', stdout); + exit(0); /* Non-reversed systems segv here. */ +} +EOF +eval $compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + DEFS="$DEFS -DSETVBUF_REVERSED=1" +SEDDEFS="${SEDDEFS}\${SEDdA}SETVBUF_REVERSED\${SEDdB}SETVBUF_REVERSED\${SEDdC}1\${SEDdD} +\${SEDuA}SETVBUF_REVERSED\${SEDuB}SETVBUF_REVERSED\${SEDuC}1\${SEDuD} +\${SEDeA}SETVBUF_REVERSED\${SEDeB}SETVBUF_REVERSED\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* +rm -f core + +# Some definitions of getloadavg require that the program be installed setgid. +NEED_SETGID=false + +# Check for the 4.4BSD definition of getloadavg. +libname=`echo "utils" | sed 's/lib\([^\.]*\)\.a/\1/;s/-l//'` +LIBS_save="${LIBS}" +LIBS="${LIBS} -l${libname}" +have_lib="" +echo checking for -l${libname} +cat > conftest.c < conftest.c < conftest.c < conftest.c < conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DDGUX=1" +SEDDEFS="${SEDDEFS}\${SEDdA}DGUX\${SEDdB}DGUX\${SEDdC}1\${SEDdD} +\${SEDuA}DGUX\${SEDuB}DGUX\${SEDuC}1\${SEDuD} +\${SEDeA}DGUX\${SEDeB}DGUX\${SEDeC}1\${SEDeD} +" have_sym=1 +fi +rm -f conftest* + +if test -z "$have_sym"; then +echo checking for dwarf.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DSVR4=1" +SEDDEFS="${SEDDEFS}\${SEDdA}SVR4\${SEDdB}SVR4\${SEDdC}1\${SEDdD} +\${SEDuA}SVR4\${SEDuB}SVR4\${SEDuC}1\${SEDuD} +\${SEDeA}SVR4\${SEDeB}SVR4\${SEDeC}1\${SEDeD} +" LIBS="$LIBS -lelf" have_sym=1 +fi +rm -f conftest* + +fi +if test -z "$have_sym"; then +# Solaris 2 does not use dwarf, but it's still SVR4. +echo checking for elf.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DSVR4=1" +SEDDEFS="${SEDDEFS}\${SEDdA}SVR4\${SEDdB}SVR4\${SEDdC}1\${SEDdD} +\${SEDuA}SVR4\${SEDuB}SVR4\${SEDuC}1\${SEDuD} +\${SEDeA}SVR4\${SEDeB}SVR4\${SEDeC}1\${SEDeD} +" LIBS="$LIBS -lelf" have_sym=1 + libname=`echo "kvm" | sed 's/lib\(^\.*\)\.a/\1/;s/-l//'` +LIBS_save="${LIBS}" +LIBS="${LIBS} -l${libname}" +have_lib="" +echo checking for -l${libname} +cat > conftest.c < conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DUMAX4_3=1" +SEDDEFS="${SEDDEFS}\${SEDdA}UMAX4_3\${SEDdB}UMAX4_3\${SEDdC}1\${SEDdD} +\${SEDuA}UMAX4_3\${SEDuB}UMAX4_3\${SEDuC}1\${SEDuD} +\${SEDeA}UMAX4_3\${SEDeB}UMAX4_3\${SEDeC}1\${SEDeD} +" DEFS="$DEFS -DUMAX=1" +SEDDEFS="${SEDDEFS}\${SEDdA}UMAX\${SEDdB}UMAX\${SEDdC}1\${SEDdD} +\${SEDuA}UMAX\${SEDuB}UMAX\${SEDuC}1\${SEDuD} +\${SEDeA}UMAX\${SEDeB}UMAX\${SEDeC}1\${SEDeD} +" have_sym=1 +fi +rm -f conftest* + +fi +if test -z "$have_sym"; then +echo checking for sys/cpustats.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DUMAX=1" +SEDDEFS="${SEDDEFS}\${SEDdA}UMAX\${SEDdB}UMAX\${SEDdC}1\${SEDdD} +\${SEDuA}UMAX\${SEDuB}UMAX\${SEDuC}1\${SEDuD} +\${SEDeA}UMAX\${SEDeB}UMAX\${SEDeC}1\${SEDeD} +" have_sym=1 +fi +rm -f conftest* + +fi +if test -z "$have_sym"; then +echo checking for nlist.h +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -DNLIST_STRUCT=1" +SEDDEFS="${SEDDEFS}\${SEDdA}NLIST_STRUCT\${SEDdB}NLIST_STRUCT\${SEDdC}1\${SEDdD} +\${SEDuA}NLIST_STRUCT\${SEDuB}NLIST_STRUCT\${SEDuC}1\${SEDuD} +\${SEDeA}NLIST_STRUCT\${SEDeB}NLIST_STRUCT\${SEDeC}1\${SEDeD} +" +echo checking for n_un in struct nlist +cat > conftest.c < +main() { exit(0); } +t() { struct nlist n; n.n_un.n_name = 0; } +EOF +if eval $compile; then + DEFS="$DEFS -DNLIST_NAME_UNION=1" +SEDDEFS="${SEDDEFS}\${SEDdA}NLIST_NAME_UNION\${SEDdB}NLIST_NAME_UNION\${SEDdC}1\${SEDdD} +\${SEDuA}NLIST_NAME_UNION\${SEDuB}NLIST_NAME_UNION\${SEDuC}1\${SEDuD} +\${SEDeA}NLIST_NAME_UNION\${SEDeB}NLIST_NAME_UNION\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + +fi +rm -f conftest* +fi + +# Figure out whether we will need to install setgid. +cat > conftest.c < conftest.out 2>&1" +if egrep "Yowza Am I SETGID yet" conftest.out >/dev/null 2>&1; then + DEFS="$DEFS -DGETLOADAVG_PRIVILEGED=1" +SEDDEFS="${SEDDEFS}\${SEDdA}GETLOADAVG_PRIVILEGED\${SEDdB}GETLOADAVG_PRIVILEGED\${SEDdC}1\${SEDdD} +\${SEDuA}GETLOADAVG_PRIVILEGED\${SEDuB}GETLOADAVG_PRIVILEGED\${SEDuC}1\${SEDuD} +\${SEDeA}GETLOADAVG_PRIVILEGED\${SEDeB}GETLOADAVG_PRIVILEGED\${SEDeC}1\${SEDeD} +" NEED_SETGID=true +fi +rm -f conftest* +;; +esac + +echo checking for strcoll +cat > conftest.c < +main() { exit(0); } +t() { strcoll ("abc", "abc"); } +EOF +if eval $compile; then + DEFS="$DEFS -DHAVE_STRCOLL=1" +SEDDEFS="${SEDDEFS}\${SEDdA}HAVE_STRCOLL\${SEDdB}HAVE_STRCOLL\${SEDdC}1\${SEDdD} +\${SEDuA}HAVE_STRCOLL\${SEDuB}HAVE_STRCOLL\${SEDuC}1\${SEDuD} +\${SEDeA}HAVE_STRCOLL\${SEDeB}HAVE_STRCOLL\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + + +for hdr in sys/wait.h +do +trhdr=HAVE_`echo $hdr | tr '[a-z]./' '[A-Z]__'` +echo checking for ${hdr} +cat > conftest.c < +EOF +err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` +if test -z "$err"; then + DEFS="$DEFS -D${trhdr}=1" +SEDDEFS="${SEDDEFS}\${SEDdA}${trhdr}\${SEDdB}${trhdr}\${SEDdC}1\${SEDdD} +\${SEDuA}${trhdr}\${SEDuB}${trhdr}\${SEDuC}1\${SEDuD} +\${SEDeA}${trhdr}\${SEDeB}${trhdr}\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* +done + for func in waitpid wait3 +do +trfunc=HAVE_`echo $func | tr '[a-z]' '[A-Z]'` +echo checking for ${func} +cat > conftest.c < +main() { exit(0); } +t() { +#ifdef __stub_${func} +choke me +#else +/* Override any gcc2 internal prototype to avoid an error. */ +extern char ${func}(); ${func}(); +#endif + } +EOF +if eval $compile; then + DEFS="$DEFS -D${trfunc}=1" +SEDDEFS="${SEDDEFS}\${SEDdA}${trfunc}\${SEDdB}${trfunc}\${SEDdC}1\${SEDdD} +\${SEDuA}${trfunc}\${SEDuB}${trfunc}\${SEDuC}1\${SEDuD} +\${SEDeA}${trfunc}\${SEDeB}${trfunc}\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* +#endif +done + +echo checking for union wait +cat > conftest.c < +#include +main() { exit(0); } +t() { union wait status; return wait (&status); } +EOF +if eval $compile; then + DEFS="$DEFS -DHAVE_UNION_WAIT=1" +SEDDEFS="${SEDDEFS}\${SEDdA}HAVE_UNION_WAIT\${SEDdB}HAVE_UNION_WAIT\${SEDdC}1\${SEDdD} +\${SEDuA}HAVE_UNION_WAIT\${SEDuB}HAVE_UNION_WAIT\${SEDuC}1\${SEDuD} +\${SEDeA}HAVE_UNION_WAIT\${SEDeB}HAVE_UNION_WAIT\${SEDeC}1\${SEDeD} +" +fi +rm -f conftest* + + +# The presence of the following is not meant to imply +# that make necessarily works on those systems. +echo checking for DYNIX/ptx libseq +cat > conftest.c < conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + SEQUENT=1 +fi +rm -f conftest* + +test -n "$SEQUENT" && test -f /usr/lib/libseq.a && + LIBS="$LIBS -lseq" + +echo checking for Xenix +cat > conftest.c < conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + XENIX=1 +fi +rm -f conftest* + +if test -n "$XENIX"; then + DEFS="$DEFS -DVOID_CLOSEDIR=1" +SEDDEFS="${SEDDEFS}\${SEDdA}VOID_CLOSEDIR\${SEDdB}VOID_CLOSEDIR\${SEDdC}1\${SEDdD} +\${SEDuA}VOID_CLOSEDIR\${SEDuB}VOID_CLOSEDIR\${SEDuC}1\${SEDuD} +\${SEDeA}VOID_CLOSEDIR\${SEDeB}VOID_CLOSEDIR\${SEDeC}1\${SEDeD} +" + LIBS="$LIBS -lx" + case "$DEFS" in + *SYSNDIR*) ;; + *) LIBS="-ldir $LIBS" ;; # Make sure -ldir precedes any -lx. + esac +fi + + +if test -n "$prefix"; then + test -z "$exec_prefix" && exec_prefix='${prefix}' + prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%" +fi +if test -n "$exec_prefix"; then + prsub="$prsub +s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%\ +exec_prefix\\1=\\2$exec_prefix%" +fi + +trap 'rm -f config.status; exit 1' 1 3 15 +echo creating config.status +rm -f config.status +cat > config.status </dev/null`: +# +# $0 $* + +for arg +do + case "\$arg" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + exec /bin/sh $0 $* ;; + *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;; + esac +done + +trap 'rm -f Makefile build.sh glob/Makefile config.h conftest*; exit 1' 1 3 15 +CFLAGS='$CFLAGS' +LDFLAGS='$LDFLAGS' +CC='$CC' +INSTALL='$INSTALL' +INSTALL_PROGRAM='$INSTALL_PROGRAM' +INSTALL_DATA='$INSTALL_DATA' +RANLIB='$RANLIB' +CPP='$CPP' +LIBOBJS='$LIBOBJS' +ALLOCA='$ALLOCA' +NEED_SETGID='$NEED_SETGID' +LIBS='$LIBS' +srcdir='$srcdir' +prefix='$prefix' +exec_prefix='$exec_prefix' +prsub='$prsub' +EOF +cat >> config.status <<\EOF + +top_srcdir=$srcdir +for file in .. Makefile build.sh glob/Makefile; do if [ "x$file" != "x.." ]; then + srcdir=$top_srcdir + # Remove last slash and all that follows it. Not all systems have dirname. + dir=`echo $file|sed 's%/[^/][^/]*$%%'` + if test "$dir" != "$file"; then + test "$top_srcdir" != . && srcdir=$top_srcdir/$dir + test ! -d $dir && mkdir $dir + fi + echo creating $file + rm -f $file + echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file + sed -e " +$prsub +s%@CFLAGS@%$CFLAGS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@CC@%$CC%g +s%@INSTALL@%$INSTALL%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@RANLIB@%$RANLIB%g +s%@CPP@%$CPP%g +s%@LIBOBJS@%$LIBOBJS%g +s%@ALLOCA@%$ALLOCA%g +s%@NEED_SETGID@%$NEED_SETGID%g +s%@LIBS@%$LIBS%g +s%@srcdir@%$srcdir%g +s%@DEFS@%-DHAVE_CONFIG_H%" $top_srcdir/${file}.in >> $file +fi; done +echo creating config.h +# These sed commands are put into SEDDEFS when defining a macro. +# They are broken into pieces to make the sed script easier to manage. +# They are passed to sed as "A NAME B NAME C VALUE D", where NAME +# is the cpp macro being defined and VALUE is the value it is being given. +# Each defining turns into a single global substitution command. +# +# SEDd sets the value in "#define NAME VALUE" lines. +SEDdA='s@^\([ ]*\)#\([ ]*define[ ][ ]*\)' +SEDdB='\([ ][ ]*\)[^ ]*@\1#\2' +SEDdC='\3' +SEDdD='@g' +# SEDu turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +SEDuA='s@^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +SEDuB='\([ ]\)@\1#\2define\3' +SEDuC=' ' +SEDuD='\4@g' +# SEDe turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +SEDeA='s@^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +SEDeB='$@\1#\2define\3' +SEDeC=' ' +SEDeD='@g' +rm -f conftest.sed +cat > conftest.sed <> config.status <> config.status <<\EOF +CONFEOF +# This sed command replaces #undef's with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it in +# config.h. +cat >> conftest.sed <<\CONFEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +CONFEOF +rm -f conftest.h +# Break up the sed commands because old seds have small limits. +maxsedlines=20 +cp $top_srcdir/config.h.in conftest.h1 +while : +do + lines=`grep -c . conftest.sed` + if test -z "$lines" || test "$lines" -eq 0; then break; fi + rm -f conftest.s1 conftest.s2 conftest.h2 + sed ${maxsedlines}q conftest.sed > conftest.s1 # Like head -20. + sed 1,${maxsedlines}d conftest.sed > conftest.s2 # Like tail +21. + sed -f conftest.s1 < conftest.h1 > conftest.h2 + rm -f conftest.s1 conftest.h1 conftest.sed + mv conftest.h2 conftest.h1 + mv conftest.s2 conftest.sed +done +rm -f conftest.sed conftest.h +echo "/* config.h. Generated automatically by configure. */" > conftest.h +cat conftest.h1 >> conftest.h +rm -f conftest.h1 +if cmp -s config.h conftest.h 2>/dev/null; then + # The file exists and we would not be changing it. + rm -f conftest.h +else + rm -f config.h + mv conftest.h config.h +fi + + +exit 0 +EOF +chmod +x config.status +test -n "$no_create" || ./config.status + + diff -ruN make-3.62/configure.in make-3.63/configure.in --- make-3.62/configure.in +++ make-3.63/configure.in Fri Jan 22 17:16:40 1993 @@ -0,0 +1,58 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(vpath.c) dnl A distinctive file to look for in srcdir. +AC_CONFIG_HEADER(config.h) + +# We want these before the checks, so the checks can modify their values. +test -z "$CFLAGS" && CFLAGS=-g AC_SUBST(CFLAGS) +test -z "$LDFLAGS" && LDFLAGS=-g AC_SUBST(LDFLAGS) + +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_RANLIB +AC_PROG_CPP dnl Later checks need this. +AC_AIX +AC_ISC_POSIX +AC_MINIX +AC_STDC_HEADERS +AC_MEMORY_H +AC_UNISTD_H +AC_DIR_HEADER +AC_UID_T dnl Also does gid_t. +AC_PID_T +AC_RETSIGTYPE +AC_HAVE_HEADERS(limits.h sys/param.h fcntl.h) +AC_MINUS_C_MINUS_O +AC_CONST dnl getopt needs this. +AC_USG + +AC_SUBST(LIBOBJS) + +AC_HAVE_FUNCS(getdtablesize sys_siglist _sys_siglist \ + dup2 getcwd sigsetmask getgroups setlinebuf \ + setreuid setregid) +AC_ALLOCA +AC_VFORK +AC_SETVBUF_REVERSED +AC_GETLOADAVG +AC_STRCOLL + +dnl Check out the wait reality. +AC_HAVE_HEADERS(sys/wait.h) AC_HAVE_FUNCS(waitpid wait3) +AC_COMPILE_CHECK(union wait, [#include +#include ], + [union wait status; return wait (&status);], + AC_DEFINE(HAVE_UNION_WAIT)) + +# The presence of the following is not meant to imply +# that make necessarily works on those systems. +AC_DYNIX_SEQ +AC_XENIX_DIR + +AC_OUTPUT(Makefile build.sh glob/Makefile) + +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: diff -ruN make-3.62/default.c make-3.63/default.c --- make-3.62/default.c Fri Oct 4 17:42:22 1991 +++ make-3.63/default.c Tue Dec 22 17:31:16 1992 @@ -1,5 +1,5 @@ /* Data base of default implicit rules for GNU Make. -Copyright (C) 1988-1991 Free Software Foundation, Inc. +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 @@ -34,33 +34,33 @@ static struct pspec default_pattern_rules[] = { - "(%)", "%", - "$(AR) $(ARFLAGS) $@ $<", + { "(%)", "%", + "$(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 $< $@", + { "%.out", "%", + "@rm -f $@ \n cp $< $@" }, - 0, 0, 0 + { 0, 0, 0 } }; static struct pspec default_terminal_rules[] = { /* RCS. */ - "%", "%,v", - "test -f $@ || $(CO) $(COFLAGS) $< $@", - "%", "RCS/%,v", - "test -f $@ || $(CO) $(COFLAGS) $< $@", + { "%", "%,v", + "+$(CHECKOUT,v)" }, + { "%", "RCS/%,v", + "+$(CHECKOUT,v)" }, /* SCCS. */ - "%", "s.%", - "$(GET) $(GFLAGS) $<", - "%", "SCCS/s.%", - "$(GET) $(GFLAGS) $<", + { "%", "s.%", + "$(GET) $(GFLAGS) $<" }, + { "%", "SCCS/s.%", + "$(GET) $(GFLAGS) $<" }, - 0, 0, 0 + { 0, 0, 0 } }; static char *default_suffix_rules[] = @@ -128,8 +128,7 @@ ".y.ln", "$(YACC.y) $< \n $(LINT.c) -C$* y.tab.c \n $(RM) y.tab.c", ".l.ln", - "@$(RM) $*.c \n $(LEX.l) $< > $*.c \n\ -$(LINT.c) -i $*.c -o $@ \n $(RM) $*.c", + "@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c", ".y.c", "$(YACC.y) $< \n mv -f y.tab.c $@", @@ -177,8 +176,8 @@ ".web.tex", "$(WEAVE) $<", - 0} -; + 0, 0, + }; static char *default_variables[] = { @@ -186,15 +185,38 @@ "ARFLAGS", "rv", "AS", "as", "CC", "cc", - "C++", "g++", + "CXX", "g++", + + /* 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)", -#ifdef USG +#endif /* Cray. */ +#if defined (USG) || defined (ultrix) || defined (_IBMR2) "GET", "get", #else "GET", "/usr/sccs/get", @@ -206,8 +228,13 @@ #ifdef pyr "PC", "pascal", #else +#ifdef CRAY + "PC", "PASCAL", + "SEGLDR", "segldr", +#else "PC", "pc", -#endif +#endif /* CRAY. */ +#endif /* pyr. */ "YACC", "yacc", /* Or "bison -y" */ "MAKEINFO", "makeinfo", "TEX", "tex", @@ -222,9 +249,9 @@ "LINK.o", "$(CC) $(LDFLAGS) $(TARGET_ARCH)", "COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", "LINK.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", - "COMPILE.cc", "$(C++) $(C++FLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", + "COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", "COMPILE.C", "$(COMPILE.cc)", - "LINK.cc", "$(C++) $(C++FLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", + "LINK.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", "LINK.C", "$(LINK.cc)", "YACC.y", "$(YACC) $(YFLAGS)", "LEX.l", "$(LEX) $(LFLAGS) -t", diff -ruN make-3.62/dep.h make-3.63/dep.h --- make-3.62/dep.h Mon Jun 3 16:37:31 1991 +++ make-3.63/dep.h Sun Aug 2 01:42:58 1992 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. +/* Copyright (C) 1988, 1989, 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 @@ -19,7 +19,7 @@ Each struct file's `deps' points to a chain of these, chained through the `next'. - Note that the first three words of this match a struct nameseq. */ + Note that the first two words of this match a struct nameseq. */ struct dep { @@ -30,7 +30,7 @@ }; -/* Structure used in chains of names, for parsing and globbing */ +/* Structure used in chains of names, for parsing and globbing. */ struct nameseq { diff -ruN make-3.62/dir.c make-3.63/dir.c --- make-3.62/dir.c Fri Oct 18 15:26:24 1991 +++ make-3.63/dir.c Fri Jan 22 14:46:10 1993 @@ -1,5 +1,5 @@ /* Directory hashing for GNU Make. -Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. +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 @@ -27,9 +27,13 @@ #if defined (POSIX) || defined (DIRENT) || defined (__GNU_LIBRARY__) #include -#define direct dirent +#ifndef __GNU_LIBRARY__ #define D_NAMLEN(d) strlen((d)->d_name) +#else +#define D_NAMLEN(d) ((d)->d_namlen) +#endif #else /* not POSIX or DIRENT */ +#define direct dirent #define D_NAMLEN(d) ((d)->d_namlen) #if defined (USG) && !defined (sgi) #if defined (SYSNDIR) @@ -49,21 +53,39 @@ #else #define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) #endif /* POSIX */ - + /* Hash table of directories. */ -struct directory +#ifndef DIRECTORY_BUCKETS +#define DIRECTORY_BUCKETS 199 +#endif + +struct directory_contents { - struct directory *next; - char *name; /* Name of the directory. */ + struct directory_contents *next; + + int dev, ino; /* Device and inode numbers of this dir. */ + struct dirfile **files; /* Files in this directory. */ DIR *dirstream; /* Stream reading this directory. */ }; -#ifndef DIRECTORY_BUCKETS -#define DIRECTORY_BUCKETS 23 -#endif +/* 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]; @@ -84,9 +106,11 @@ }; #ifndef DIRFILE_BUCKETS -#define DIRFILE_BUCKETS 1007 +#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 * @@ -107,30 +131,72 @@ if (dir == 0) { - /* The directory was not found. Create a new entry - for it and start its directory stream reading. */ + 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); - dir->dirstream = opendir (name); - if (dir->dirstream == 0) - /* Couldn't open the directory. Mark this by - setting the `files' member to a nil pointer. */ - dir->files = 0; + + /* The directory is not in the name hash table. + Find its device and inode numbers, and look it up by them. */ + + if (stat (name, &st) < 0) + /* Couldn't stat the directory. Mark this by + setting the `contents' member to a nil pointer. */ + dir->contents = 0; else { - /* Allocate an array of hash buckets for files and zero it. */ - dir->files = (struct dirfile **) - xmalloc (sizeof (struct dirfile) * DIRFILE_BUCKETS); - bzero ((char *) dir->files, - sizeof (struct dirfile) * DIRFILE_BUCKETS); - - /* Keep track of how many directories are open. */ - ++open_directories; - if (open_directories == MAX_OPEN_DIRECTORIES) - /* Read the entire directory and then close it. */ - (void) dir_file_exists_p (dir->name, (char *) 0); + /* Search the contents hash table; device and inode are the key. */ + + struct directory_contents *dc; + + hash = ((unsigned int) st.st_dev << 16) | (unsigned int) st.st_ino; + hash %= DIRECTORY_BUCKETS; + + for (dc = directories_contents[hash]; dc != 0; dc = dc->next) + if (dc->dev == st.st_dev && dc->ino == st.st_ino) + 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; + dc->ino = st.st_ino; + 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; } } @@ -137,24 +203,21 @@ return dir; } -/* Return 1 if the name FILENAME in directory DIRNAME - is entered in the dir hash table. +/* Return 1 if the name FILENAME is entered in DIR's hash table. FILENAME must contain no slashes. */ -int -dir_file_exists_p (dirname, filename) - register char *dirname; +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 directory *dir; register struct dirfile *df; - register struct direct *d; - dir = find_directory (dirname); + register struct dirent *d; - if (dir->files == 0) - /* The directory could not be opened. */ + if (dir == 0 || dir->files == 0) + /* The directory could not be stat'd or opened. */ return 0; hash = 0; @@ -218,6 +281,19 @@ 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. */ @@ -273,19 +349,31 @@ HASH (hash, *p); hash %= DIRFILE_BUCKETS; - if (dir->files == 0) + 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)); + dir->contents->dev = dir->contents->ino = 0; + 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->files = (struct dirfile **) + dir->contents->files = (struct dirfile **) xmalloc (sizeof (struct dirfile) * DIRFILE_BUCKETS); - bzero ((char *) dir->files, 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->files[hash]; - dir->files[hash] = new; + new->next = dir->contents->files[hash]; + dir->contents->files[hash] = new; new->name = savestring (filename, strlen (filename)); new->impossible = 1; } @@ -299,22 +387,22 @@ char *dirend; register char *p = filename; register unsigned int hash; - register struct directory *dir; + register struct directory_contents *dir; register struct dirfile *next; dirend = rindex (filename, '/'); if (dirend == 0) - dir = find_directory ("."); + 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); + dir = find_directory (dirname)->contents; p = dirend + 1; } - if (dir->files == 0) + if (dir == 0 || dir->files == 0) /* There are no files entered for this directory. */ return 0; @@ -354,8 +442,11 @@ for (dir = directories[i]; dir != 0; dir = dir->next) { ++dirs; - if (dir->files == 0) - printf ("# %s: could not be opened.\n", dir->name); + if (dir->contents == 0) + printf ("# %s: could not be stat'd.\n", dir->name); + else if (dir->contents->files == 0) + printf ("# %s (device %d, inode %d): could not be opened.\n", + dir->name, dir->contents->dev, dir->contents->ino); else { register unsigned int f = 0, im = 0; @@ -362,12 +453,13 @@ register unsigned int j; register struct dirfile *df; for (j = 0; j < DIRFILE_BUCKETS; ++j) - for (df = dir->files[j]; df != 0; df = df->next) + for (df = dir->contents->files[j]; df != 0; df = df->next) if (df->impossible) ++im; else ++f; - printf ("# %s: ", dir->name); + printf ("# %s (device %d, inode %d): ", + dir->name, dir->contents->dev, dir->contents->ino); if (f == 0) fputs ("No", stdout); else @@ -378,7 +470,7 @@ else printf ("%u", im); fputs (" impossibilities", stdout); - if (dir->dirstream == 0) + if (dir->contents->dirstream == 0) puts ("."); else puts (" so far."); @@ -398,4 +490,76 @@ else printf ("%u", impossible); printf (" impossibilities in %u directories.\n", dirs); +} + +/* Hooks for globbing. */ + +#include + +/* 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; + } + 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; } diff -ruN make-3.62/expand.c make-3.63/expand.c --- make-3.62/expand.c Fri Sep 13 19:39:37 1991 +++ make-3.63/expand.c Tue Dec 22 18:44:03 1992 @@ -1,5 +1,5 @@ /* Variable expansion functions for GNU Make. -Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. +Copyright (C) 1988, 1989, 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 @@ -21,10 +21,64 @@ #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. */ -/* Recursively expand V. The returned string is malloc'd. */ +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; { @@ -197,7 +251,7 @@ p = savestring (subst_beg, subst_len); p1 = savestring (replace_beg, replace_len); o = patsubst_expand (o, value, p, p1, - index (p, '%'), index (p1, '%')); + (char *) 0, (char *) 0); free (p); free (p1); } @@ -313,30 +367,30 @@ return result; } -/* Like variable_expand, but the returned string is malloc'd. */ -char * -allocated_variable_expand (line) - char *line; -{ - return allocated_variable_expand_for_file (line, (struct file *) 0); -} +/* Like variable_expand_for_file, but the returned string is malloc'd. + This function is called a lot. It wants to be efficient. */ -/* Like variable_expand_for_file, but the returned string is malloc'd. */ - char * allocated_variable_expand_for_file (line, file) char *line; struct file *file; { - char *save; char *value; - save = save_variable_output (); + char *obuf = variable_buffer; + unsigned int olen = variable_buffer_length; + + variable_buffer = 0; value = variable_expand_for_file (line, file); - value = savestring (value, strlen (value)); + +#if 0 + /* Waste a little memory and save time. */ + value = xrealloc (value, strlen (value)) +#endif - restore_variable_output (save); + variable_buffer = obuf; + variable_buffer_length = olen; return value; } diff -ruN make-3.62/file.c make-3.63/file.c --- make-3.62/file.c Thu Oct 17 17:29:16 1991 +++ make-3.63/file.c Tue Dec 22 17:31:13 1992 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. +/* 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 @@ -20,12 +20,8 @@ #include "dep.h" #include "file.h" #include "variable.h" -#include -extern int errno; - - /* Hash table of files the makefile knows how to make. */ #ifndef FILE_BUCKETS @@ -54,9 +50,21 @@ 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; + { + 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); @@ -79,9 +87,27 @@ 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; + { + name += 2; + while (*name == '/') + /* Skip following slashes: ".//foo" is "foo", not "/foo". */ + ++name; + } + if (*name == '\0') + { + /* It was all slashes! Move back to the dot and truncate + it after the first slash, so it becomes just "./". */ + do + --name; + while (name[0] != '.'); + name[2] = '\0'; + } + hashval = 0; for (n = name; *n != '\0'; ++n) HASH (hashval, *n); @@ -126,10 +152,11 @@ char *name; { char *oldname = file->name; - register unsigned int oldhash, newhash; + register unsigned int oldhash; register char *n; - register struct file *f; - struct file *oldfile; + + while (file->renamed != 0) + file = file->renamed; /* Find the hash values of the old and new names. */ @@ -136,8 +163,22 @@ oldhash = 0; for (n = oldname; *n != '\0'; ++n) HASH (oldhash, *n); - oldhash %= FILE_BUCKETS; + 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; +{ + register unsigned int newhash; + struct file *oldfile; + register char *n; + register struct file *f; + newhash = 0; for (n = name; *n != '\0'; ++n) HASH (newhash, *n); @@ -149,12 +190,14 @@ if (streq (oldfile->name, name)) break; - if (newhash != oldhash || oldfile != 0) + if (oldhash != 0 && (newhash != oldhash || oldfile != 0)) { /* Remove FILE from its hash bucket. */ struct file *lastf = 0; + oldhash %= FILE_BUCKETS; + for (f = files[oldhash]; f != file; f = f->next) lastf = f; @@ -196,9 +239,17 @@ /* 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. */ - makefile_error (file->cmds->filename, file->cmds->lineno, - "Commands were specified for file `%s' at %s:%u,", - oldname, oldfile->cmds->filename, oldfile->cmds->lineno); + 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'.", @@ -220,7 +271,6 @@ while (d->next != 0) d = d->next; d->next = file->deps; - uniquize_deps (oldfile->deps); } merge_variable_set_lists (&oldfile->variables, file->variables); @@ -284,7 +334,7 @@ { if (sig) error ("*** Deleting file `%s'", f->name); - else if (!silent_flag && !just_print_flag) + else if (!silent_flag) { if (!doneany) { @@ -347,6 +397,10 @@ 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; } /* Print the data base of files. */ @@ -415,10 +469,10 @@ switch (f->command_state) { case cs_running: - puts ("# Commands currently running (?!)."); + puts ("# Commands currently running (THIS IS A BUG)."); break; case cs_deps_running: - puts ("# Dependencies currently being made (?!)."); + puts ("# Dependencies commands running (THIS IS A BUG)."); break; case cs_not_started: case cs_finished: diff -ruN make-3.62/file.h make-3.63/file.h --- make-3.62/file.h Tue Oct 8 16:04:17 1991 +++ make-3.63/file.h Sun Aug 2 07:28:01 1992 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. +/* 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 @@ -80,7 +80,7 @@ extern struct file *lookup_file (), *enter_file (); extern void remove_intermediates (), snap_deps (); -extern void rename_file (); +extern void rename_file (), file_hash_enter (); extern time_t f_mtime (); diff -ruN make-3.62/function.c make-3.63/function.c --- make-3.62/function.c Mon Oct 21 17:44:24 1991 +++ make-3.63/function.c Wed Jan 6 17:57:35 1993 @@ -1,5 +1,5 @@ /* Variable function expansion for GNU Make. -Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. +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 @@ -21,10 +21,7 @@ #include "dep.h" #include "commands.h" #include "job.h" -#include -extern int errno; - static char *string_glob (); /* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing @@ -134,7 +131,7 @@ pattern_prepercent_len = pattern_percent - pattern; pattern_postpercent_len = strlen (pattern_percent + 1); - while (t = find_next_token (&text, &len)) + while ((t = find_next_token (&text, &len)) != 0) { int fail = 0; @@ -268,7 +265,7 @@ pattern_matches (pattern, percent, word) register char *pattern, *percent, *word; { - unsigned int len; + unsigned int sfxlen, wordlen; if (percent == 0) { @@ -281,13 +278,14 @@ return streq (pattern, word); } - len = strlen (percent + 1); + sfxlen = strlen (percent + 1); + wordlen = strlen (word); - if (strlen (word) < (percent - pattern) + len + if (wordlen < (percent - pattern) + sfxlen || strncmp (pattern, word, percent - pattern)) return 0; - return !strcmp (percent + 1, word + (strlen (word) - len)); + return !strcmp (percent + 1, word + (wordlen - sfxlen)); } int shell_function_pid = 0, shell_function_completed; @@ -326,8 +324,6 @@ case function_shell: { - extern int fork (); - extern int pipe (); char **argv; char *error_prefix; int pipedes[2]; @@ -357,9 +353,7 @@ break; } - push_signals_blocked_p (1); - - pid = fork (); + pid = vfork (); if (pid < 0) perror_with_name (error_prefix, "fork"); else if (pid == 0) @@ -405,7 +399,7 @@ /* Loop until child_handler sets shell_function_completed to the status of our child shell. */ while (shell_function_completed == 0) - wait_for_children (1, 0); + reap_children (1, 0); shell_function_pid = 0; @@ -430,6 +424,8 @@ { if (buffer[i - 1] == '\n') buffer[--i] = '\0'; + else + buffer[i] = '\0'; p = buffer; while ((p = index (p, '\n')) != 0) *p++ = ' '; @@ -442,8 +438,6 @@ free (buffer); } - pop_signals_blocked_p (); - free (text); break; } @@ -502,7 +496,7 @@ /* Chop TEXT into words and put them in WORDS. */ t = text; - while (p = find_next_token (&t, &len)) + while ((p = find_next_token (&t, &len)) != 0) { if (wordi >= nwords - 1) { diff -ruN make-3.62/getloadavg.c make-3.63/getloadavg.c --- make-3.62/getloadavg.c +++ make-3.63/getloadavg.c Fri Jan 22 18:02:43 1993 @@ -0,0 +1,641 @@ +/* Get the system load averages. + Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93 + 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. + + 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. + NeXT + sgi + sony_news NEWS-OS (works at least for 4.1C) + UMAX + UMAX4_3 + VMS + + 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. */ + +/* 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 +#endif + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* 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 , which + conflicts with the definition understood in this file, that this + really is BSD. */ +#undef BSD +#endif + +/* Set values that are different from the defaults, which are + set a little farther down with #ifndef. */ + + +/* Some shorthands. */ +#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(MORE_BSD) || defined(sun) || defined(decstation) || defined(_SEQUENT_) || defined(sgi) || defined(SVR4) || defined(sony_news) +#define LOAD_AVE_TYPE long +#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 + +#ifdef sgi +#define FSCALE 1000.0 +#endif + +#ifdef FSCALE +#define LDAV_CVT(n) (((double) (n)) / FSCALE) +#endif + +#endif /* Not FSCALE. */ + + +#if !defined(NLIST_STRUCT) && (defined(MORE_BSD) || defined(sun) || defined(decstation) || defined(hpux) || defined(_SEQUENT_) || defined(sequent) || defined(sgi) || defined(SVR4) || defined(sony_news)) +#define NLIST_STRUCT +#endif + + +#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)) +#define KERNEL_FILE "/unix" +#endif + + +#if !defined (LDAV_SYMBOL) && defined (alliant) +#define LDAV_SYMBOL "_Loadavg" +#endif + +#if !defined(LDAV_SYMBOL) && (defined(hpux) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi)) +#define LDAV_SYMBOL "avenrun" +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION) +#include +#else +#include +#endif + +#include +#include + +#ifndef errno +extern int errno; +#endif + +/* 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 +#else /* NLIST_STRUCT */ +#include +#endif /* NLIST_STRUCT */ + +#ifdef SUNOS_5 +#include +#include +#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 +#include +#else /* eunice */ +#include +#endif /* eunice */ +#endif /* VMS */ + +#ifndef LDAV_CVT +#define LDAV_CVT(n) ((double) (n)) +#endif /* !LDAV_CVT */ + +#endif /* LOAD_AVE_TYPE */ + +#ifdef NeXT +#include +#endif /* NeXT */ + +#ifdef sgi +#include +#include +#endif /* sgi */ + +#ifdef UMAX +#include +#include +#include +#include +#include +#include + +#ifdef UMAX_43 +#include +#include +#include +#include +#include +#else /* Not UMAX_43. */ +#include +#include +#include +#include +#include +#include +#endif /* Not UMAX_43. */ +#endif /* UMAX */ + +#ifdef DGUX +#include +#endif + +/* Avoid static vars inside a function since in HPUX they dump as pure. */ + +#ifdef NeXT +static processor_set_t default_set; +static int 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 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), + or -1 if an error occurred. */ + +int +getloadavg (loadavg, nelem) + double loadavg[]; + int nelem; +{ + int elem = 0; /* Return value. */ + +#if !defined (LDAV_DONE) && defined (NeXT) +#define LDAV_DONE + /* The NeXT code was adapted from iscreen 3.2. + We only know how to get the 1-minute average for this system. */ + + host_t host; + struct processor_set_basic_info info; + unsigned info_count; + + if (!initialized) + { + if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS) + initialized = 1; + } + + if (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) + initialized = 0; + else + { + if (nelem > 0) + loadavg[elem++] = (double) info.load_average / LOAD_SCALE; + } + } + + if (!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 (VMS) +#define LDAV_DONE + /* VMS specific code -- read from the Load Ave driver. */ + + LOAD_AVE_TYPE load_ave[3]; +#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 (!initialized) + { + /* Attempt to open the channel. */ +#ifdef eunice + descriptor.size = 18; + descriptor.ptr = "$$VMS_LOAD_AVERAGE"; +#else + $DESCRIPTOR (descriptor, "LAV0:"); +#endif + if (sys$assign (&descriptor, &channel, 0, 0) & 1) + initialized = 1; + } + + /* Read the load average vector. */ + if (initialized && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0, + load_ave, 12, 0, 0, 0, 0) & 1)) + { + sys$dassgn (channel); + initialized = 0; + } + + if (!initialized) + return -1; +#endif /* VMS */ + +#if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS) +#define LDAV_DONE + /* 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 SUNOS_5 +#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 */ + + if (nlist (KERNEL_FILE, nl) >= 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; + } +#else /* sgi */ + int ldav_off; + + ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); + if (ldav_off != -1) + offset = (long) ldav_off & 0x7fffffff; +#endif /* sgi */ +#endif /* !SUNOS_5 */ + } + + /* Make sure we have /dev/kmem open. */ + if (!initialized) + { +#ifndef SUNOS_5 + channel = open ("/dev/kmem", 0); + if (channel >= 0) + initialized = 1; +#else /* SUNOS_5 */ + kd = kvm_open (0, 0, 0, O_RDONLY, 0); + if (kd != 0) + { + kvm_nlist (kd, nl); + initialized = 1; + } +#endif /* SUNOS_5 */ + } + + /* If we can, get the load average values. */ + if (offset && 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); + initialized = 0; + } +#else /* SUNOS_5 */ + if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave)) + != sizeof (load_ave)) + { + kvm_close (kd); + initialized = 0; + } +#endif /* SUNOS_5 */ + } + + if (offset == 0 || !initialized) + return -1; +#endif /* LOAD_AVE_TYPE and not VMS */ + +#ifdef 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]); +#endif /* 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 +} + +#ifdef TEST +void +main (argc, argv) + int argc; + char **argv; +{ + int naptime = 0; + + if (argc > 1) + naptime = atoi (argv[1]); + + if (naptime == 0) + naptime = 5; + + 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'); + sleep (naptime); + } +} +#endif /* TEST */ diff -ruN make-3.62/getopt.c make-3.63/getopt.c --- make-3.62/getopt.c +++ make-3.63/getopt.c Sun Jan 17 19:50:27 1993 @@ -0,0 +1,687 @@ +/* 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, 1993 + 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. */ + +/* NOTE!!! AIX requires this to be the first thing in the file. + Do not put ANYTHING before it! */ +#if !defined (__GNUC__) && defined (_AIX) + #pragma alloca +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not __GNUC__ */ +#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__)))) +#include +#else +#ifndef _AIX +char *alloca (); +#endif +#endif /* alloca.h */ +#endif /* not __GNUC__ */ + +#if !__STDC__ && !defined(const) && IN_GCC +#define const +#endif + +#include + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#undef alloca +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +#include +#else /* Not GNU C library. */ +#define __alloca alloca +#endif /* GNU C library. */ + +/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a + long-named option. Because this is not POSIX.2 compliant, it is + being phased out. */ +/* #define GETOPT_COMPAT */ + +/* 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 = 0; + +/* 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. */ + +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; + +/* 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; + +#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 +#define my_index strchr +#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n)) +#else + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +char *getenv (); + +static char * +my_index (string, chr) + char *string; + int chr; +{ + while (*string) + { + if (*string == chr) + return string; + string++; + } + return 0; +} + +static void +my_bcopy (from, to, size) + char *from, *to; + int size; +{ + int i; + for (i = 0; i < size; i++) + to[i] = from[i]; +} +#endif /* GNU C 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 nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *); + char **temp = (char **) __alloca (nonopts_size); + + /* Interchange the two blocks of data in ARGV. */ + + my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size); + my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt], + (optind - last_nonopt) * sizeof (char *)); + my_bcopy ((char *) temp, + (char *) &argv[first_nonopt + optind - last_nonopt], + nonopts_size); + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* 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; +{ + int option_index; + + optarg = 0; + + /* Initialize the internal data when the first call is made. + 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. */ + + if (optind == 0) + { + first_nonopt = last_nonopt = optind = 1; + + nextchar = NULL; + + /* 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 (getenv ("POSIXLY_CORRECT") != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + } + + if (nextchar == NULL || *nextchar == '\0') + { + 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; + + /* Now skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc + && (argv[optind][0] != '-' || argv[optind][1] == '\0') +#ifdef GETOPT_COMPAT + && (longopts == NULL + || argv[optind][0] != '+' || argv[optind][1] == '\0') +#endif /* GETOPT_COMPAT */ + ) + optind++; + last_nonopt = optind; + } + + /* 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') +#ifdef GETOPT_COMPAT + && (longopts == NULL + || argv[optind][0] != '+' || argv[optind][1] == '\0') +#endif /* GETOPT_COMPAT */ + ) + { + if (ordering == REQUIRE_ORDER) + return EOF; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Start decoding its characters. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + if (longopts != NULL + && ((argv[optind][0] == '-' + && (argv[optind][1] == '-' || long_only)) +#ifdef GETOPT_COMPAT + || argv[optind][0] == '+' +#endif /* GETOPT_COMPAT */ + )) + { + const struct option *p; + char *s = nextchar; + int exact = 0; + int ambig = 0; + const struct option *pfound = NULL; + int indfound; + + while (*s && *s != '=') + s++; + + /* Test all options for either exact match or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; + p++, option_index++) + if (!strncmp (p->name, nextchar, s - nextchar)) + { + if (s - 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 nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*s) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = s + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + "%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, "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return '?'; + } + } + 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] == '-' +#ifdef GETOPT_COMPAT + || argv[optind][0] == '+' +#endif /* GETOPT_COMPAT */ + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + return '?'; + } + } + + /* Look at and handle the next 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 (c < 040 || c >= 0177) + fprintf (stderr, "%s: unrecognized option, character code 0%o\n", + argv[0], c); + else + fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], 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 = 0; + 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) + fprintf (stderr, "%s: option `-%c' requires an argument\n", + argv[0], c); + 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); +} + +#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 */ diff -ruN make-3.62/getopt.h make-3.63/getopt.h --- make-3.62/getopt.h +++ make-3.63/getopt.h Wed Jan 13 15:28:00 1993 @@ -0,0 +1,125 @@ +/* Declarations for getopt. + Copyright (C) 1989, 1990, 1991, 1992 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; + +/* 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 __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 __STDC__ +#if defined(__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 /* not __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 /* not __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H */ diff -ruN make-3.62/getopt1.c make-3.63/getopt1.c --- make-3.62/getopt1.c +++ make-3.63/getopt1.c Sun Jan 17 19:51:30 1993 @@ -0,0 +1,161 @@ +/* Getopt for GNU. + Copyright (C) 1987, 88, 89, 90, 91, 1992 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 !__STDC__ && !defined(const) && IN_GCC +#define const +#endif + +#include + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#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); +} + +#ifdef TEST + +#include + +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 */ diff -ruN make-3.62/glob/Makefile make-3.63/glob/Makefile --- make-3.62/glob/Makefile Tue Oct 22 23:51:10 1991 +++ make-3.63/glob/Makefile @@ -1,42 +0,0 @@ -# Copyright (C) 1991 Free Software Foundation, Inc. -# This file is part of the GNU C Library. - -# The GNU C 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. - -# The GNU C 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 the GNU C Library; see the file COPYING.LIB. If -# not, write to the Free Software Foundation, Inc., 675 Mass Ave, -# Cambridge, MA 02139, USA. - -# Makefile for standalone distribution of libglob.a (fnmatch, glob). - -.PHONY: all -all: libglob.a - -libglob.a: glob.o fnmatch.o - ar rv $@ glob.o fnmatch.o - -ranlib $@ - -glob.o: glob.h fnmatch.h -fnmatch.o: fnmatch.h - -.c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c $< $(OUTPUT_OPTION) - -.PHONY: clean realclean glob-clean glob-realclean -clean glob-clean: - -rm -f libglob.a *.o core -realclean glob-realclean: clean - -rm -f TAGS tags *~ - -# For inside the C library. -glob.tar glob.tar.Z: - $(MAKE) -C .. $@ diff -ruN make-3.62/glob/Makefile.in make-3.63/glob/Makefile.in --- make-3.62/glob/Makefile.in +++ make-3.63/glob/Makefile.in Fri Jan 22 19:32:17 1993 @@ -0,0 +1,54 @@ +# Makefile for standalone distribution of libglob.a (fnmatch, glob). + +# Copyright (C) 1991, 1992, 1993 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. + +srcdir = @srcdir@ +VPATH = $(srcdir) + +CPPFLAGS = @DEFS@ + +# How the 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) $@ + +glob.o: $(srcdir)/glob.h $(srcdir)/fnmatch.h +fnmatch.o: $(srcdir)/fnmatch.h + +.c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -I$(srcdir) -c $< $(OUTPUT_OPTION) + +.PHONY: clean realclean glob-clean glob-realclean +clean glob-clean: + -rm -f libglob.a *.o core +realclean glob-realclean: clean + -rm -f TAGS tags Makefile + +# For inside the C library. +glob.tar glob.tar.Z: + $(MAKE) -C .. $@ diff -ruN make-3.62/glob/fnmatch.c make-3.63/glob/fnmatch.c --- make-3.62/glob/fnmatch.c Sat Oct 19 16:39:24 1991 +++ make-3.63/glob/fnmatch.c Fri Jan 22 19:32:19 1993 @@ -1,22 +1,20 @@ -/* Copyright (C) 1991 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. -The GNU C Library is free software; you can redistribute it and/or +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. -The GNU C Library is distributed in the hope that it will be useful, +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 the GNU C Library; see the file COPYING.LIB. If +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. */ -/* */ #include #include @@ -27,12 +25,12 @@ /* Match STRING against the filename pattern PATTERN, returning zero if it matches, nonzero if not. */ int -fnmatch(pattern, string, flags) - char *pattern; - char *string; +fnmatch (pattern, string, flags) + const char *pattern; + const char *string; int flags; { - register char *p = pattern, *n = string; + register const char *p = pattern, *n = string; register char c; if ((flags & ~__FNM_FLAGS) != 0) @@ -42,128 +40,133 @@ } while ((c = *p++) != '\0') - switch (c) - { - case '?': - if (*n == '\0') - return FNM_NOMATCH; - else if ((flags & FNM_PATHNAME) && *n == '/') - return FNM_NOMATCH; - else if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) - return FNM_NOMATCH; - else - ++n; - break; - - case '\\': - if (!(flags & FNM_NOESCAPE)) - c = *p++; - if (*n++ != c) - return FNM_NOMATCH; - break; - - case '*': - if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) - return FNM_NOMATCH; - - for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) - if (((flags & FNM_PATHNAME) && *n == '/') || - (c == '?' && *n == '\0')) - return FNM_NOMATCH; - - if (c == '\0') - return 0; - - { - char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; - for (--p; *n != '\0'; ++n) - if ((c == '[' || *n == c1) && - fnmatch(p, n, flags & ~FNM_PERIOD) == 0) - return 0; - return FNM_NOMATCH; - } - - case '[': + { + switch (c) { - /* Nonzero if this if the sense of - the character class is inverted. */ - register int not; - + case '?': if (*n == '\0') return FNM_NOMATCH; + else if ((flags & FNM_PATHNAME) && *n == '/') + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + c = *p++; + if (*n != c) + return FNM_NOMATCH; + break; + case '*': if ((flags & FNM_PERIOD) && *n == '.' && (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) return FNM_NOMATCH; - not = *p == '!'; - if (not) - ++p; - - c = *p++; - for (;;) - { - register char cstart = c, cend = c; - - if (!(flags & FNM_NOESCAPE) && c == '\\') - cstart = cend = *p++; - - if (c == '\0') - /* [ (unterminated) loses. */ - return FNM_NOMATCH; - - c = *p++; - if ((flags & FNM_PATHNAME) && c == '/') - /* [/] can never match. */ - return FNM_NOMATCH; - - if (c == '-') - { - cend = *p++; - if (!(flags & FNM_NOESCAPE) && cend == '\\') - cend = *p++; - if (cend == '\0') - return FNM_NOMATCH; - c = *p++; - } - if (*n >= cstart && *n <= cend) - goto matched; - - if (c == ']') - break; - } - if (!not) + for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) + if (((flags & FNM_PATHNAME) && *n == '/') || + (c == '?' && *n == '\0')) + return FNM_NOMATCH; + + if (c == '\0') + return 0; + + { + char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; + for (--p; *n != '\0'; ++n) + if ((c == '[' || *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_PATHNAME) && 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++; + + if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + + if ((flags & FNM_PATHNAME) && 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; + c = *p++; + } + + if (*n >= cstart && *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 == '\\') + /* 1003.2d11 is unclear if this is right. %%% */ + ++p; + } + 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 == '\\') - /* 1003.2d11 is unclear if this is right. %%% */ - ++p; - } - if (not) + default: + if (c != *n) return FNM_NOMATCH; - - ++n; } - break; - default: - if (c != *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; diff -ruN make-3.62/glob/fnmatch.h make-3.63/glob/fnmatch.h --- make-3.62/glob/fnmatch.h Sat Oct 19 16:39:25 1991 +++ make-3.63/glob/fnmatch.h Fri Jan 22 19:32:20 1993 @@ -1,18 +1,17 @@ -/* Copyright (C) 1991 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. -The GNU C Library is free software; you can redistribute it and/or +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. -The GNU C Library is distributed in the hope that it will be useful, +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 the GNU C Library; see the file COPYING.LIB. If +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. */ @@ -20,11 +19,30 @@ #define _FNMATCH_H 1 +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(args) args +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(args) () +#undef const +#define const +#endif /* C++ or ANSI C. */ + /* 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. */ -#define __FNM_FLAGS (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD) +#define __FNM_FLAGS (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD|FNM_LEADING_DIR) + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_BSD_SOURCE) +#define FNM_LEADING_DIR (1 << 3)/* Ignore `/...' after a match. */ +#define FNM_FILE_NAME FNM_PATHNAME +#endif /* Value returned by `fnmatch' if STRING does not match PATTERN. */ #define FNM_NOMATCH 1 @@ -31,6 +49,11 @@ /* Match STRING against the filename pattern PATTERN, returning zero if it matches, FNM_NOMATCH if not. */ -extern int fnmatch(); +extern int fnmatch __P ((const char *__pattern, const char *__string, + int __flags)); + +#ifdef __cplusplus +} +#endif #endif /* fnmatch.h */ diff -ruN make-3.62/glob/glob.c make-3.63/glob/glob.c --- make-3.62/glob/glob.c Sat Oct 19 16:39:23 1991 +++ make-3.63/glob/glob.c Fri Jan 22 19:32:18 1993 @@ -1,32 +1,33 @@ -/* Copyright (C) 1991 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. -The GNU C Library is free software; you can redistribute it and/or +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. -The GNU C Library is distributed in the hope that it will be useful, +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 the GNU C Library; see the file COPYING.LIB. If +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. */ -/* */ - -#include -#include +/* AIX requires this to be the first thing in the file. */ +#if defined (_AIX) && !defined (__GNUC__) + #pragma alloca +#endif -#ifdef SHELL +#ifdef HAVE_CONFIG_H #include "config.h" #endif #include -#ifdef __GNU_LIBRARY__ +#include + +#ifdef STDC_HEADERS #include #endif @@ -34,137 +35,183 @@ extern int errno; #endif +#ifndef NULL +#define NULL 0 +#endif + #if defined (USGr3) && !defined (DIRENT) #define DIRENT -#endif /* USGr3 and not DIRENT. */ +#endif /* USGr3 */ #if defined (Xenix) && !defined (SYSNDIR) #define SYSNDIR -#endif /* Xenix and not SYSNDIR. */ +#endif /* Xenix */ #if defined (POSIX) || defined (DIRENT) || defined (__GNU_LIBRARY__) -#ifdef USG -#include -#endif #include +#ifndef __GNU_LIBRARY__ +#define D_NAMLEN(d) strlen((d)->d_name) #else -#if defined (USG) && !defined (sgi) -#ifdef SYSNDIR +#define HAVE_D_NAMLEN +#define D_NAMLEN(d) ((d)->d_namlen) +#endif +#else /* not POSIX or DIRENT */ +#define dirent direct +#define D_NAMLEN(d) ((d)->d_namlen) +#define HAVE_D_NAMLEN +#if defined (USG) && !defined (sgi) +#if defined (SYSNDIR) #include -#else /* not SYSNDIR */ +#else /* SYSNDIR */ #include "ndir.h" -#endif /* SYSNDIR */ +#endif /* not SYSNDIR */ #else /* not USG */ -#include #include #endif /* USG */ -#undef dirent -#define dirent direct #endif /* POSIX or DIRENT or __GNU_LIBRARY__ */ -#if defined(__GNU_LIBRARY__) || !defined(POSIX) && !defined(USG) -#define D_NAMLEN(d) ((d)->d_namlen) -#else -#define D_NAMLEN(d) strlen((d)->d_name) -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#if defined(POSIX) && !defined(__GNU_LIBRARY__) +#if 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 +#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* POSIX */ -#if defined(__GNU_LIBRARY__) || defined(POSIX) +#ifdef HAVE_UNISTD_H #include #endif -#if defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) - +#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) \ + || defined (POSIX)) #include #include +#define ANSI_STRING +#else /* No standard headers. */ -#define STDC_STRINGS - -#else /* Not STDC_HEADERS and not __GNU_LIBRARY__. */ - #ifdef USG + #include -#ifndef POSIX +#ifdef NEED_MEMORY_H #include -#endif /* Not POSIX. */ -#define STDC_STRINGS -#else /* Not USG. */ +#endif +#define ANSI_STRING + +#else /* Not USG. */ + #ifdef NeXT + #include -#else /* Not NeXT. */ + +#else /* Not NeXT. */ + #include -#endif /* NeXT. */ -/* Declaring bcopy causes errors on systems whose declarations are different. - If the declaration is omitted, everything works fine. */ -#endif /* Not USG. */ - -extern char *malloc(); -extern char *realloc(); -extern void free(); -extern void qsort(); -#ifdef __GNUC__ -__inline +#ifndef bcmp +extern int bcmp (); #endif -static char * -my_realloc(p, n) - char *p; - unsigned int n; -{ - if (p == NULL) - return malloc(n); - return realloc(p, n); -} +#ifndef bzero +extern void bzero (); +#endif +#ifndef bcopy +extern void bcopy (); +#endif -#define realloc my_realloc +#endif /* NeXT. */ -#define strcoll strcmp +#endif /* USG. */ -#endif /* Not STDC_HEADERS or __GNU_LIBRARY__. */ +extern char *malloc (), *realloc (); +extern void free (); +extern void qsort (); -#ifndef STDC_STRINGS +#endif /* Standard headers. */ + +#ifndef ANSI_STRING #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 + + +#ifndef __GNU_LIBRARY__ +#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__ -#define alloca __builtin_alloca -#else /* Not GCC. */ -#ifdef sparc +#ifdef __GNUC__ +#undef alloca +#define alloca(n) __builtin_alloca (n) +#else /* Not GCC. */ +#if defined (sparc) || defined (HAVE_ALLOCA_H) #include -#else /* Not sparc. */ -extern char *alloca(); -#endif /* sparc. */ -#endif /* GCC. */ +#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 __STDC__ +#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 to take precedence. */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD +#include + +/* Some system header files erroneously define these. + We want our own definitions from 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 -static int glob_pattern_p(); -static int glob_in_dir(); -static int prefix_array(); -static int collated_compare(); +__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)); +static int collated_compare __P ((const __ptr_t, const __ptr_t)); /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. @@ -174,16 +221,14 @@ `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) - char *pattern; + int + glob (pattern, flags, errfunc, pglob) + const char *pattern; int flags; - - int (*errfunc) (); - + int (*errfunc) __P ((const char *, int)); glob_t *pglob; { - char *filename; + const char *filename; char *dirname; size_t dirlen; int status; @@ -196,7 +241,7 @@ } /* Find the filename. */ - filename = strrchr(pattern, '/'); + filename = strrchr (pattern, '/'); if (filename == NULL) { filename = pattern; @@ -213,15 +258,20 @@ else { dirlen = filename - pattern; - dirname = (char *) __alloca(dirlen + 1); - memcpy(dirname, pattern, dirlen); + dirname = (char *) __alloca (dirlen + 1); + memcpy (dirname, pattern, dirlen); dirname[dirlen] = '\0'; ++filename; } - if (filename[0] == '\0') + if (filename[0] == '\0' && dirlen > 1) /* "pattern/". Expand "pattern", appending slashes. */ - return glob(dirname, flags | GLOB_MARK, errfunc, pglob); + { + int ret = glob (dirname, flags | GLOB_MARK, errfunc, pglob); + if (ret == 0) + pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK); + return ret; + } if (!(flags & GLOB_APPEND)) { @@ -231,7 +281,7 @@ oldcount = pglob->gl_pathc; - if (glob_pattern_p(dirname, !(flags & GLOB_NOESCAPE))) + 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 @@ -239,9 +289,10 @@ glob_t dirs; register int i; - status = glob(dirname, ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) | - GLOB_NOSORT), - errfunc, &dirs); + status = glob (dirname, + ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) | + GLOB_NOSORT), + errfunc, &dirs); if (status != 0) return status; @@ -259,8 +310,8 @@ if (interrupt_state) { - globfree(&dirs); - globfree(&files); + globfree (&dirs); + globfree (&files); return GLOB_ABEND; } } @@ -267,29 +318,69 @@ #endif /* SHELL. */ oldcount = pglob->gl_pathc; - status = glob_in_dir(filename, dirs.gl_pathv[i], - flags | GLOB_APPEND, errfunc, pglob); + 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); + 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)) + if (prefix_array (dirs.gl_pathv[i], + &pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount)) { - globfree(&dirs); - globfree(pglob); + globfree (&dirs); + globfree (pglob); return GLOB_NOSPACE; } } + + flags |= GLOB_MAGCHAR; + + if (pglob->gl_pathc == oldcount) + /* No matches. */ + if (flags & GLOB_NOCHECK) + { + const 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_flags = flags; + } + else + return GLOB_NOMATCH; } else { - status = glob_in_dir(filename, dirname, flags, errfunc, pglob); + status = glob_in_dir (filename, dirname, flags, errfunc, pglob); if (status != 0) return status; @@ -296,19 +387,20 @@ if (dirlen > 0) { /* Stick the directory on the front of each name. */ - if (prefix_array(dirname, - &pglob->gl_pathv[oldcount], - pglob->gl_pathc - oldcount)) + if (prefix_array (dirname, + &pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount)) { - globfree(pglob); + globfree (pglob); return GLOB_NOSPACE; } } - } - if (!(flags & GLOB_NOSORT)) - qsort((char *) &pglob->gl_pathv[oldcount], pglob->gl_pathc - oldcount, - sizeof(char *), collated_compare); + if (!(flags & GLOB_NOSORT)) + qsort ((__ptr_t) & pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount, + sizeof (char *), collated_compare); + } return 0; } @@ -316,7 +408,7 @@ /* Free storage allocated in PGLOB by a previous `glob' call. */ void -globfree(pglob) +globfree (pglob) register glob_t *pglob; { if (pglob->gl_pathv != NULL) @@ -324,8 +416,8 @@ register int i; for (i = 0; i < pglob->gl_pathc; ++i) if (pglob->gl_pathv[i] != NULL) - free((char *) pglob->gl_pathv[i]); - free((char *) pglob->gl_pathv); + free ((__ptr_t) pglob->gl_pathv[i]); + free ((__ptr_t) pglob->gl_pathv); } } @@ -332,12 +424,12 @@ /* Do a collated comparison of A and B. */ static int -collated_compare(a, b) - char *a; - char *b; +collated_compare (a, b) + const __ptr_t a; + const __ptr_t b; { - char *s1 = *(char **) a; - char *s2 = *(char **) b; + const char *const s1 = *(const char *const * const) a; + const char *const s2 = *(const char *const * const) b; if (s1 == s2) return 0; @@ -345,7 +437,7 @@ return 1; if (s2 == NULL) return -1; - return strcoll(s1, s2); + return strcoll (s1, s2); } @@ -354,29 +446,29 @@ A slash is inserted between PREFIX and each elt of ARRAY. Each old element of ARRAY is freed. */ static int -prefix_array(prefix, array, n) - char *prefix; +prefix_array (prefix, array, n) + const char *prefix; char **array; - size_t n; + const size_t n; { register size_t i; - size_t prelen = strlen(prefix); + const size_t prelen = strlen (prefix); for (i = 0; i < n; ++i) { - size_t eltlen = strlen(array[i]) + 1; - char *new = (char *) malloc(prelen + 1 + eltlen); + const size_t eltlen = strlen (array[i]) + 1; + char *new = (char *) malloc (prelen + 1 + eltlen); if (new == NULL) { while (i > 0) - free((char *) array[--i]); + free ((__ptr_t) array[--i]); return 1; } - memcpy(new, prefix, prelen); + memcpy (new, prefix, prelen); new[prelen] = '/'; - memcpy(&new[prelen + 1], array[i], eltlen); - free((char *) array[i]); + memcpy (&new[prelen + 1], array[i], eltlen); + free ((__ptr_t) array[i]); array[i] = new; } @@ -387,11 +479,11 @@ /* Return nonzero if PATTERN contains any metacharacters. Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ static int -glob_pattern_p(pattern, quote) - char *pattern; - int quote; +glob_pattern_p (pattern, quote) + const char *pattern; + const int quote; { - register char *p; + register const char *p; int open = 0; for (p = pattern; *p != '\0'; ++p) @@ -425,30 +517,34 @@ 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) - char *pattern; - char *directory; +glob_in_dir (pattern, directory, flags, errfunc, pglob) + const char *pattern; + const char *directory; int flags; - - int (*errfunc) (); + int (*errfunc) __P ((const char *, int)); glob_t *pglob; { - register DIR *stream; - register struct dirent *d; + __ptr_t stream; struct globlink - { - struct globlink *next; - char *name; - }; + { + struct globlink *next; + char *name; + }; struct globlink *names = NULL; size_t nfound = 0; - if (!glob_pattern_p(pattern, !(flags & GLOB_NOESCAPE))) - flags |= GLOB_NOCHECK; + if (!glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE))) + { + stream = NULL; + flags |= GLOB_NOCHECK; + } else { - stream = opendir(directory); + flags |= GLOB_MAGCHAR; + + stream = (__glob_opendir_hook ? (*__glob_opendir_hook) (directory) + : (__ptr_t) opendir (directory)); if (stream == NULL) { if ((errfunc != NULL && (*errfunc) (directory, errno)) || @@ -456,37 +552,66 @@ return GLOB_ABEND; } else - while ((d = readdir(stream)) != NULL) - if (REAL_DIR_ENTRY(d) && - fnmatch(pattern, d->d_name, - (!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) | - ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)) == 0) - { - struct globlink *new = (struct globlink *) - __alloca(sizeof(struct globlink)); - size_t len = D_NAMLEN(d); - new->name = (char *) malloc(len + - ((flags & GLOB_MARK) ? 1 : 0) + 1); - if (new->name == NULL) - goto memory_error; - memcpy((char *) new->name, d->d_name, len); - if (flags & GLOB_MARK) - new->name[len++] = '/'; - new->name[len] = '\0'; - new->next = names; - names = new; - ++nfound; - } + 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); + if (flags & GLOB_MARK) + new->name[len++] = '/'; + new->name[len] = '\0'; + new->next = names; + names = new; + ++nfound; + } + } } if (nfound == 0 && (flags & GLOB_NOCHECK)) { - size_t len = strlen(pattern); + size_t len = strlen (pattern); nfound = 1; - names = (struct globlink *) __alloca(sizeof(struct globlink)); + names = (struct globlink *) __alloca (sizeof (struct globlink)); names->next = NULL; - names->name = (char *) malloc(len + ((flags & GLOB_MARK) ? 1 : 0) + 1); - memcpy(names->name, pattern, len); + names->name = (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1); + if (names->name == NULL) + goto memory_error; + memcpy (names->name, pattern, len); if (flags & GLOB_MARK) names->name[len++] = '/'; names->name[len] = '\0'; @@ -493,11 +618,11 @@ } pglob->gl_pathv - = (char **) realloc(pglob->gl_pathv, - (pglob->gl_pathc + - ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + - nfound + 1) * - sizeof(char *)); + = (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; @@ -509,12 +634,32 @@ 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:; + memory_error: + { + int save = errno; + if (__glob_closedir_hook) + (*__glob_closedir_hook) (stream); + else + (void) closedir ((DIR *) stream); + errno = save; + } while (names != NULL) { - free((char *) names->name); + if (names->name != NULL) + free ((__ptr_t) names->name); names = names->next; } return GLOB_NOSPACE; diff -ruN make-3.62/glob/glob.h make-3.63/glob/glob.h --- make-3.62/glob/glob.h Sat Oct 19 16:39:24 1991 +++ make-3.63/glob/glob.h Fri Jan 22 19:17:13 1993 @@ -1,18 +1,17 @@ -/* Copyright (C) 1991 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. -The GNU C Library is free software; you can redistribute it and/or +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. -The GNU C Library is distributed in the hope that it will be useful, +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 the GNU C Library; see the file COPYING.LIB. If +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. */ @@ -20,6 +19,24 @@ #define _GLOB_H 1 +#ifdef __cplusplus +extern "C" +{ +#endif + +#undef __ptr_t +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(args) args +#define __ptr_t void * +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(args) () +#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. */ @@ -32,6 +49,10 @@ #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. */ @@ -39,11 +60,12 @@ /* 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'. */ -} glob_t; + { + 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. @@ -53,10 +75,23 @@ `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(); +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(); +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 */ diff -ruN make-3.62/gpl.texinfo make-3.63/gpl.texinfo --- make-3.62/gpl.texinfo Sat Jul 27 15:49:15 1991 +++ make-3.63/gpl.texinfo Thu Jan 14 17:25:02 1993 @@ -1,3 +1,5 @@ +@setfilename gpl.info + @unnumbered GNU GENERAL PUBLIC LICENSE @center Version 2, June 1991 @@ -103,7 +105,7 @@ distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: -@alphaenumerate +@enumerate a @item You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. @@ -125,7 +127,7 @@ 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.) -@end alphaenumerate +@end enumerate These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, @@ -152,7 +154,7 @@ 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: -@alphaenumerate +@enumerate a @item Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections @@ -172,7 +174,7 @@ 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.) -@end alphaenumerate +@end enumerate The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source @@ -334,13 +336,13 @@ the ``copyright'' line and a pointer to where the full notice is found. @smallexample -@var{one line to give the program's name and a brief idea of what it does.} +@var{one line to give the program's name and an idea of what it does.} Copyright (C) 19@var{yy} @var{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 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 @@ -359,9 +361,10 @@ @smallexample Gnomovision version 69, Copyright (C) 19@var{yy} @var{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. +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. @end smallexample The hypothetical commands @samp{show w} and @samp{show c} should show @@ -374,13 +377,17 @@ school, if any, to sign a ``copyright disclaimer'' for the program, if necessary. Here is a sample; alter the names: -@example -Yoyodyne, Inc., hereby disclaims all copyright interest in the program -`Gnomovision' (which makes passes at compilers) written by James Hacker. +@smallexample +@group +Yoyodyne, Inc., hereby disclaims all copyright +interest in the program `Gnomovision' +(which makes passes at compilers) written +by James Hacker. @var{signature of Ty Coon}, 1 April 1989 Ty Coon, President of Vice -@end example +@end group +@end smallexample This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may diff -ruN make-3.62/implicit.c make-3.63/implicit.c --- make-3.62/implicit.c Tue Oct 8 16:04:11 1991 +++ make-3.63/implicit.c Wed Jan 6 17:57:30 1993 @@ -1,5 +1,5 @@ /* Implicit rule searching for GNU Make. -Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. +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 @@ -50,9 +50,11 @@ return pattern_search (file, 0, depth, 0); } -#define DEBUGP2(msg, a1, a2) \ - if (debug_flag) \ - { print_spaces (depth); printf (msg, a1, a2); fflush (stdout); } else +#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 @@ -174,7 +176,7 @@ don't use it here. */ if (rule->in_use) { - DEBUGP2 ("Avoiding implicit rule recursion.\n", 0, 0); + DEBUGP2 ("Avoiding implicit rule recursion.%s%s\n", "", ""); continue; } @@ -315,7 +317,7 @@ } DEBUGP2 ("Trying pattern rule with stem `%.*s'.\n", - stemlen, stem); + (int) stemlen, stem); /* Try each dependency; see if it "exists". */ @@ -362,7 +364,7 @@ DEBUGP2 ("Trying %s dependency `%s'.\n", p == depname ? "implicit" : "rule", p); - if (!rule->subdir && lookup_file (p) != 0 || file_exists_p (p)) + if (!rule->subdir && (lookup_file (p) != 0 || file_exists_p (p))) { found_files[deps_found++] = savestring (p, strlen (p)); continue; @@ -371,7 +373,7 @@ "lib/foo.c", and VPATH=src, searches for "src/lib/foo.c". */ if (vpath_search (&p)) { - DEBUGP2 ("Found dependent as `%s'.\n", p, 0); + DEBUGP2 ("Found dependency as `%s'.%s\n", p, ""); found_files[deps_found++] = p; continue; } @@ -386,8 +388,8 @@ intermediate_file = (struct file *) alloca (sizeof (struct file)); - DEBUGP2 ("Looking for a rule with intermediate file `%s'.\n", - p, 0); + DEBUGP2 ("Looking for a rule with %s file `%s'.\n", + "intermediate", p); bzero ((char *) intermediate_file, sizeof (struct file)); intermediate_file->name = p; @@ -526,8 +528,6 @@ file->deps = dep; } - uniquize_deps (file->deps); - if (!checked_lastslash[foundrule]) file->stem = stem[stemlen] == '\0' ? stem : savestring (stem, stemlen); else @@ -557,8 +557,7 @@ bcopy (stem, p, stemlen); p += stemlen; bcopy (rule->suffixes[i], p, - rule->lens[i] - - (rule->suffixes[i] - rule->targets[i] - 1) + 1); + 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; diff -ruN make-3.62/job.c make-3.63/job.c --- make-3.62/job.c Thu Oct 24 17:58:33 1991 +++ make-3.63/job.c Fri Jan 22 17:31:27 1993 @@ -1,5 +1,5 @@ /* Job execution and handling for GNU Make. -Copyright (C) 1988-1991 Free Software Foundation, Inc. +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 @@ -21,7 +21,6 @@ #include "job.h" #include "file.h" #include "variable.h" -#include /* Default path to search for executables. */ static char default_path[] = ":/bin:/usr/bin"; @@ -29,44 +28,40 @@ /* Default shell to use. */ char default_shell[] = "/bin/sh"; -extern int errno; +/* If NGROUPS_MAX == 0 then try other methods for finding a real value. */ +#if defined (NGROUPS_MAX) && NGROUPS_MAX == 0 +#undef NGROUPS_MAX +#endif /* NGROUPS_MAX == 0 */ -#if defined(POSIX) || defined(__GNU_LIBRARY__) -#include -#include +#ifndef NGROUPS_MAX +#ifdef POSIX #define GET_NGROUPS_MAX sysconf (_SC_NGROUPS_MAX) #else /* Not POSIX. */ -#ifndef USG -#include #define NGROUPS_MAX NGROUPS -#endif /* Not USG. */ #endif /* POSIX. */ - -#ifdef POSIX -#include - -#define WAIT_NOHANG(status) waitpid(-1, (status), WNOHANG) - -#else /* Not POSIX. */ +#endif -#if defined(HAVE_SYS_WAIT) || !defined(USG) +#ifdef HAVE_SYS_WAIT_H #include -#include -#include +#endif +#ifdef HAVE_WAITPID +#define WAIT_NOHANG(status) waitpid (-1, (status), WNOHANG) +#else /* Don't have waitpid. */ +#ifdef HAVE_WAIT3 #ifndef wait3 extern int wait3 (); #endif -#define WAIT_NOHANG(status) \ - wait3((union wait *) (status), WNOHANG, (struct rusage *) 0) +#define WAIT_NOHANG(status) wait3 ((status), WNOHANG, (struct rusage *) 0) +#endif /* Have wait3. */ +#endif /* Have waitpid. */ #if !defined (wait) && !defined (POSIX) extern int wait (); #endif -#endif /* HAVE_SYS_WAIT || !USG */ -#endif /* POSIX. */ + +#ifndef HAVE_UNION_WAIT -#if defined(WTERMSIG) || (defined(USG) && !defined(HAVE_SYS_WAIT)) #define WAIT_T int #ifndef WTERMSIG @@ -85,12 +80,18 @@ #define WIFEXITED(x) (WTERMSIG (x) == 0) #endif -#else /* WTERMSIG not defined and have or not USG. */ +#else /* Have `union wait'. */ #define WAIT_T union wait +#ifndef WTERMSIG #define WTERMSIG(x) ((x).w_termsig) +#endif +#ifndef WCOREDUMP #define WCOREDUMP(x) ((x).w_coredump) +#endif +#ifndef WEXITSTATUS #define WEXITSTATUS(x) ((x).w_retcode) +#endif #ifndef WIFSIGNALED #define WIFSIGNALED(x) (WTERMSIG(x) != 0) #endif @@ -98,48 +99,35 @@ #define WIFEXITED(x) (WTERMSIG(x) == 0) #endif -#endif /* WTERMSIG defined or USG and don't have . */ - +#endif /* Don't have `union wait'. */ -#if defined(__GNU_LIBRARY__) || defined(POSIX) -#include -#define GID_T gid_t - -#else /* Not GNU C library. */ - -#define GID_T int - +#ifndef HAVE_UNISTD_H extern int dup2 (); extern int execve (); extern void _exit (); extern int geteuid (), getegid (); extern int setgid (), getgid (); -#endif /* GNU C library. */ +#endif -#ifndef USG +#ifndef getdtablesize +#ifdef HAVE_GETDTABLESIZE extern int getdtablesize (); #else #include #define getdtablesize() NOFILE #endif +#endif -extern void wait_to_start_job (); +extern int getloadavg (); extern int start_remote_job_p (); extern int start_remote_job (), remote_status (); - -#if (defined(USG) && !defined(HAVE_SIGLIST)) || defined(DGUX) -static char *sys_siglist[NSIG]; -void init_siglist (); -#else /* Not (USG and HAVE_SIGLIST), or DGUX. */ -extern char *sys_siglist[]; -#endif /* USG and not HAVE_SIGLIST, or DGUX. */ - -int child_handler (); -static void free_child (), start_job (); +RETSIGTYPE child_handler (); +static void free_child (), start_job_command (); +static int load_too_high (), job_next_command (); -/* Chain of all children. */ +/* Chain of all live (or recently deceased) children. */ struct child *children = 0; @@ -150,6 +138,10 @@ /* Nonzero if the `good' standard input is in use. */ static int good_stdin_used = 0; + +/* Chain of children waiting to run until the load average goes down. */ + +static struct child *waiting_jobs = 0; /* Write an error message describing the exit status given in EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME. @@ -161,10 +153,10 @@ int exit_code, exit_sig, coredump; int ignored; { - char *ignore_string = ignored ? " (ignored)" : ""; - if (exit_sig == 0) - error ("*** [%s] Error %d%s", target_name, exit_code, ignore_string); + error (ignored ? "[%s] Error %d (ignored)" : + "*** [%s] Error %d", + target_name, exit_code); else { char *coredump_string = coredump ? " (core dumped)" : ""; @@ -176,152 +168,36 @@ } } -extern void block_remote_children (), unblock_remote_children (); - -extern int fatal_signal_mask; - -#ifdef USG -/* Set nonzero in the interval when it's possible that we may see a dead - child that's not in the `children' chain. */ -static int unknown_children_possible = 0; -#endif - - -/* Block the child termination signal and fatal signals. */ - -static void -block_signals () -{ -#ifdef USG - - /* Tell child_handler that it might see children that aren't yet - in the `children' chain. */ - unknown_children_possible = 1; - - /* Ignoring SIGCLD makes wait always return -1. - Using the default action does the right thing. */ - (void) SIGNAL (SIGCLD, SIG_DFL); - -#else /* Not USG. */ - - /* Block the signals. */ - (void) sigblock (fatal_signal_mask | sigmask (SIGCHLD)); - -#endif - - block_remote_children (); -} +static unsigned int dead_children = 0; -/* Unblock the child termination signal and fatal signals. */ -static void -unblock_signals () -{ -#ifdef USG - - (void) SIGNAL (SIGCLD, child_handler); - - /* It should no longer be possible for children not in the chain to die. */ - unknown_children_possible = 0; - -#else /* Not USG. */ - - /* Unblock the signals. */ - (void) sigsetmask (sigblock (0) & ~(fatal_signal_mask | sigmask (SIGCHLD))); - -#endif - - unblock_remote_children (); -} - -static char *signals_blocked_p_stack = 0; -static unsigned int signals_blocked_p_max; -static unsigned int signals_blocked_p_depth; - -/* Make signals blocked in FLAG is nonzero, unblocked if FLAG is zero. - Push this setting on the signals_blocked_p_stack, so it can be - popped off by pop_signals_blocked_p. */ - -void -push_signals_blocked_p (flag) - int flag; +/* Notice that a child died. + reap_children should be called when convenient. */ +RETSIGTYPE +child_handler (sig) + int sig; { - int blocked; - - if (signals_blocked_p_stack == 0) - { - signals_blocked_p_max = 8; - signals_blocked_p_stack = (char *) xmalloc (8); - signals_blocked_p_depth = 1; - signals_blocked_p_stack[0] = flag; - - blocked = 0; - } - else - { - if (signals_blocked_p_depth == signals_blocked_p_max) - { - signals_blocked_p_max += 8; - signals_blocked_p_stack - = (char *) xrealloc(signals_blocked_p_stack, - signals_blocked_p_max); - } - - blocked = (signals_blocked_p_depth > 0 - && signals_blocked_p_stack[signals_blocked_p_depth - 1]); - - signals_blocked_p_stack[++signals_blocked_p_depth - 1] = flag; - } + ++dead_children; - if (blocked && !flag) - unblock_signals (); - else if (flag && !blocked) - block_signals (); + if (debug_flag) + printf ("Got a SIGCHLD; %d unreaped children.\n", dead_children); } -/* Pop the signals_blocked_p setting from the stack - and block or unblock signals as appropriate. */ - -void -pop_signals_blocked_p () -{ - int blocked, block; - - blocked = (signals_blocked_p_depth > 0 - && signals_blocked_p_stack[signals_blocked_p_depth-- - 1]); - - block = (signals_blocked_p_depth > 0 - && signals_blocked_p_stack[signals_blocked_p_depth - 1]); - - if (block && !blocked) - block_signals (); - else if (blocked && !block) - unblock_signals (); -} - extern int shell_function_pid, shell_function_completed; -/* Handle a child-termination signal (SIGCHLD, or SIGCLD for USG), - storing the returned status and the new command state (`cs_finished') - in the `file' member of the `struct child' for the dead child, - and removing the child from the chain. - - If we were called as a signal handler, SIG should be SIGCHLD - (SIGCLD for USG). If instead it is zero, we were called explicitly - and should block waiting for running children. - If SIG is < 0, - SIG is the maximum number of children to bury (record - status of and remove from the chain). */ +/* Reap dead children, storing the returned status and the new command + state (`cs_finished') in the `file' member of the `struct child' for the + dead child, and removing the child from the chain. If BLOCK nonzero, + reap at least one child, waiting for it to die if necessary. If ERR is + nonzero, print an error message first. */ -int -child_handler (sig) - int sig; +void +reap_children (block, err) + int block, err; { WAIT_T status; - unsigned int dead_children = 0; - - if (sig > 0) - block_signals (); - while (1) + while ((children != 0 || shell_function_pid != 0) && + (block || dead_children > 0)) { int remote = 0; register int pid; @@ -329,27 +205,56 @@ register struct child *lastc, *c; int child_failed; + if (err && dead_children == 0) + { + /* We might block for a while, so let the user know why. */ + fflush (stdout); + error ("*** Waiting for unfinished jobs...."); + } + + /* We have one less dead child to reap. + The test and decrement are not atomic; if it is compiled into: + register = dead_children - 1; + dead_children = register; + a SIGCHLD could come between the two instructions. + child_handler increments dead_children. + The second instruction here would lose that increment. But the + only effect of dead_children being wrong is that we might wait + longer than necessary to reap a child, and lose some parallelism; + and we might print the "Waiting for unfinished jobs" message above + when not necessary. */ + + if (dead_children != 0) + --dead_children; + + if (debug_flag) + for (c = children; c != 0; c = c->next) + printf ("Live child 0x%08lx PID %d%s\n", + (unsigned long int) c, + c->pid, c->remote ? " (remote)" : ""); + /* First, check for remote children. */ pid = remote_status (&exit_code, &exit_sig, &coredump, 0); - if (pid < 0) + if (pid <= 0) { /* No remote children. Check for local children. */ #ifdef WAIT_NOHANG - if (sig > 0) + if (!block) pid = WAIT_NOHANG (&status); else +#endif pid = wait (&status); -#else /* USG and don't HAVE_SYS_WAIT. */ - /* System V cannot do non-blocking waits, so we have two - choices if called as a signal handler: handle only one - child (there may be more if the signal was blocked), - or block waiting for more. The latter option makes - parallelism useless, so we must choose the former. */ - pid = wait (&status); -#endif /* HAVE_SYS_WAIT or not USG. */ - if (pid <= 0) + if (pid < 0) + { +#ifdef EINTR + if (errno == EINTR) + continue; +#endif + pfatal_with_name ("wait"); + } + else if (pid == 0) /* No local children. */ break; else @@ -372,17 +277,7 @@ shell_function_completed = -1; else shell_function_completed = 1; - - /* Check if we have reached our quota of children. */ - ++dead_children; - if (sig < 0 && dead_children == -sig) - break; -#if defined(USG) && !defined(HAVE_SYS_WAIT) - else if (sig > 0) - break; -#endif - else - continue; + break; } child_failed = exit_sig != 0 || exit_code != 0; @@ -396,23 +291,22 @@ if (c == 0) { /* An unknown child died. */ -#ifdef USG - if (!unknown_children_possible) - { -#endif - char buf[100]; - sprintf (buf, "Unknown%s job %d", remote ? " remote" : "", pid); - if (child_failed) - child_error (buf, exit_code, exit_sig, coredump, - ignore_errors_flag); - else - error ("%s finished.", buf); -#ifdef USG - } -#endif + char buf[100]; + sprintf (buf, "Unknown%s job %d", remote ? " remote" : "", pid); + if (child_failed) + child_error (buf, exit_code, exit_sig, coredump, + ignore_errors_flag); + else + error ("%s finished.", buf); } else { + if (debug_flag) + printf ("Reaping %s child 0x%08lx PID %d%s\n", + child_failed ? "losing" : "winning", + (unsigned long int) c, + c->pid, c->remote ? " (remote)" : ""); + /* If this child had the good stdin, say it is now free. */ if (c->good_stdin) good_stdin_used = 0; @@ -437,7 +331,8 @@ } /* If there are more commands to run, try to start them. */ - start_job (c); + if (job_next_command (c)) + start_job_command (c); switch (c->file->command_state) { @@ -447,23 +342,30 @@ case cs_finished: if (c->file->update_status != 0) - { - /* We failed to start the commands. */ - delete_child_targets (c); - } + /* We failed to start the commands. */ + delete_child_targets (c); + + /* Tell update_file that some actual work has been done. */ + ++files_remade; break; default: - error ("internal error: `%s' command_state \ -%d in child_handler", c->file->name); + error ("internal error: `%s' has bogus command_state \ +%d in reap_children", + c->file->name, (int) c->file->command_state); abort (); break; } } - /* Set the state flag to say the commands have finished. */ + /* Notice if the target of the commands has been changed. */ notice_finished_file (c->file); + if (debug_flag) + printf ("Removing child 0x%08lx PID %d%s from chain.\n", + (unsigned long int) c, + c->pid, c->remote ? " (remote)" : ""); + /* Remove the child from the chain and free it. */ if (lastc == 0) children = c->next; @@ -474,55 +376,15 @@ /* There is now another slot open. */ --job_slots_used; - /* If the job failed, and the -k flag was not given, die. */ - if (child_failed && !keep_going_flag) + /* If the job failed, and the -k flag was not given, die, + unless we are already in the process of dying. */ + if (!err && child_failed && !keep_going_flag) die (1); - - /* See if we have reached our quota for blocking. */ - ++dead_children; - if (sig < 0 && dead_children == -sig) - break; -#if defined(USG) && !defined(HAVE_SYS_WAIT) - else if (sig > 0) - break; -#endif } - } - -#ifdef USG - if (sig > 0) - (void) SIGNAL (sig, child_handler); -#endif - - if (sig > 0) - unblock_signals (); - - return 0; -} - - -/* Wait for N children, blocking if necessary. - If N is zero, wait until we run out of children. - If ERR is nonzero and we have any children to wait for, - print a message on stderr. */ -void -wait_for_children (n, err) - unsigned int n; - int err; -{ - push_signals_blocked_p (1); - - if (err && (children != 0 || shell_function_pid != 0)) - { - fflush (stdout); - error ("*** Waiting for unfinished jobs...."); + /* Only block for one child. */ + block = 0; } - - /* Call child_handler to do the work. */ - (void) child_handler (- (int) n); - - pop_signals_blocked_p (); } /* Free the storage allocated for CHILD. */ @@ -550,11 +412,30 @@ free ((char *) child); } +#ifdef POSIX +extern sigset_t fatal_signal_set; + +static void +unblock_sigs () +{ + sigset_t empty; + sigemptyset (&empty); + sigprocmask (SIG_SETMASK, &empty, (sigset_t *) 0); +} +#else +#ifdef HAVE_SIGSETMASK +extern int fatal_signal_mask; +#define unblock_sigs() sigsetmask (0) +#else +#define unblock_sigs() +#endif +#endif + /* Start a job to run the commands specified in CHILD. CHILD is updated to reflect the commands and ID of the child process. */ static void -start_job (child) +start_job_command (child) register struct child *child; { static int bad_stdin = -1; @@ -562,31 +443,7 @@ char noprint = 0, recursive; char **argv; - if (child->command_ptr == 0 || *child->command_ptr == '\0') - { - /* There are no more lines in the expansion of this line. */ - if (child->command_line == child->file->cmds->ncommand_lines) - { - /* There are no more lines to be expanded. */ - child->command_ptr = 0; - child->file->command_state = cs_finished; - child->file->update_status = 0; - return; - } - else - { - /* Get the next line to run, and set RECURSIVE - if the unexpanded line contains $(MAKE). */ - child->command_ptr = child->command_lines[child->command_line]; - recursive = child->file->cmds->lines_recurse[child->command_line]; - ++child->command_line; - } - } - else - /* Still executing the last line we started. */ - recursive = child->file->cmds->lines_recurse[child->command_line - 1]; - - /* Find the end of this line. Backslash-newlines don't mean the end. */ + recursive = child->file->cmds->lines_recurse[child->command_line - 1]; p = child->command_ptr; child->noerror = 0; @@ -596,9 +453,7 @@ noprint = 1; else if (*p == '-') child->noerror = 1; - else if (*p == '+') - recursive = 1; - else if (!isblank (*p)) + else if (!isblank (*p) && *p != '+') break; ++p; } @@ -610,9 +465,9 @@ /* There may be some preceding whitespace left if there was nothing but a backslash on the first line. */ p = next_token (p); - + /* Figure out an argument list from this command line. */ - + { char *end; argv = construct_command_argv (p, &end, child->file); @@ -625,18 +480,28 @@ } } - /* Print out the command. */ - - if (just_print_flag || (!noprint && !silent_flag)) - puts (p); + if (touch_flag && !recursive) + { + /* Go on to the next command. It might be the recursive one. + We construct ARGV only to find the end of the command line. */ + free (argv[0]); + free ((char *) argv); + argv = 0; + } if (argv == 0) { /* This line has no commands. Go to the next. */ - start_job (child); + if (job_next_command (child)) + start_job_command (child); return; } + /* Print out the command. */ + + if (just_print_flag || (!noprint && !silent_flag)) + puts (p); + /* If -n was given, recurse to get the next line in the sequence. */ if (just_print_flag && !recursive) @@ -643,7 +508,13 @@ { free (argv[0]); free ((char *) argv); - start_job (child); + if (job_next_command (child)) + start_job_command (child); + else + /* Normally, this is set by reap_children to indicate that + some commands were actually run. Under -n, reap_children + never gets called, so we increment it here. */ + ++files_remade; return; } @@ -682,10 +553,12 @@ if (child->environment == 0) child->environment = target_environment (child->file); - if (start_remote_job_p ()) + /* start_waiting_job has set CHILD->remote if we can start a remote job. */ + if (child->remote) { int is_remote, id, used_stdin; - if (start_remote_job (argv, child->good_stdin ? 0 : bad_stdin, + if (start_remote_job (argv, child->environment, + child->good_stdin ? 0 : bad_stdin, &is_remote, &id, &used_stdin)) goto error; else @@ -701,27 +574,30 @@ } else { - if (child->command_line - 1 == 0) - { - /* Wait for the load to be low enough if this - is the first command in the sequence. */ - make_access (); - wait_to_start_job (); - user_access (); - } - /* Fork the child process. */ +#ifdef POSIX + (void) sigprocmask (SIG_BLOCK, &fatal_signal_set, (sigset_t *) 0); +#else +#ifdef HAVE_SIGSETMASK + (void) sigblock (fatal_signal_mask); +#endif +#endif + child->remote = 0; child->pid = vfork (); if (child->pid == 0) - /* We are the child side. */ - child_execute_job (child->good_stdin ? 0 : bad_stdin, 1, - argv, child->environment); + { + /* We are the child side. */ + unblock_sigs (); + child_execute_job (child->good_stdin ? 0 : bad_stdin, 1, + argv, child->environment); + } else if (child->pid < 0) { /* Fork failed! */ - perror_with_name (VFORK_NAME, ""); + unblock_sigs (); + perror_with_name ("vfork", ""); goto error; } } @@ -743,6 +619,57 @@ child->file->command_state = cs_finished; } +static void +start_waiting_job (c) + struct child *c; +{ + /* If we can start a job remotely, we always want to, and don't care about + the local load average. We record that the job should be started + remotely in C->remote for start_job_command to test. */ + + c->remote = start_remote_job_p (); + + /* If this job is to be started locally, and we are already running + some jobs, make this one wait if the load average is too high. */ + if (!c->remote && job_slots_used > 0 && load_too_high ()) + { + /* Put this child on the chain of children waiting + for the load average to go down. */ + c->file->command_state = cs_running; + c->next = waiting_jobs; + waiting_jobs = c; + return; + } + + /* Start the first command; reap_children will run later command lines. */ + start_job_command (c); + + switch (c->file->command_state) + { + case cs_running: + c->next = children; + if (debug_flag) + printf ("Putting child 0x%08lx PID %05d%s on the chain.\n", + (unsigned long int) c, + c->pid, c->remote ? " (remote)" : ""); + children = c; + /* One more job slot is in use. */ + ++job_slots_used; + unblock_sigs (); + break; + + case cs_finished: + notice_finished_file (c->file); + free_child (c); + break; + + default: + error ("internal error: `%s' command_state == %d in new_job", + c->file->name, (int) c->file->command_state); + abort (); + break; + } +} /* Create a `struct child' for FILE and start its commands running. */ @@ -755,13 +682,16 @@ char **lines; register unsigned int i; + /* Reap any children that might have finished recently. */ + reap_children (0, 0); + /* Chop the commands up into lines if they aren't already. */ chop_commands (cmds); - if (job_slots > 0) + if (job_slots != 0) /* Wait for a job slot to be freed up. */ while (job_slots_used == job_slots) - wait_for_children (1, 0); + reap_children (1, 0); /* Expand the command lines and store the results in LINES. */ lines = (char **) xmalloc (cmds->ncommand_lines * sizeof (char *)); @@ -772,8 +702,6 @@ /* Start the command sequence, record it in a new `struct child', and add that to the chain. */ - push_signals_blocked_p (1); - c = (struct child *) xmalloc (sizeof (struct child)); c->file = file; c->command_lines = lines; @@ -780,36 +708,99 @@ c->command_line = 0; c->command_ptr = 0; c->environment = 0; - start_job (c); - switch (file->command_state) + + /* Fetch the first command line to be run. */ + if (! job_next_command (c)) + /* There were no commands! */ + free_child (c); + else { - case cs_running: - c->next = children; - children = c; - /* One more job slot is in use. */ - ++job_slots_used; - break; + /* The job is now primed. Start it running. */ + start_waiting_job (c); - case cs_finished: - free_child (c); - notice_finished_file (file); - break; + if (job_slots == 1) + /* Since there is only one job slot, make things run linearly. + Wait for the child to die, setting the state to `cs_finished'. */ + while (file->command_state == cs_running) + reap_children (1, 0); + } +} + +/* Move CHILD's pointers to the next command for it to execute. + Returns nonzero if there is another command. */ - default: - error ("internal error: `%s' command_state == %d in new_job", - file->name, (int) file->command_state); - abort (); - break; +static int +job_next_command (child) + struct child *child; +{ + if (child->command_ptr == 0 || *child->command_ptr == '\0') + { + /* There are no more lines in the expansion of this line. */ + if (child->command_line == child->file->cmds->ncommand_lines) + { + /* There are no more lines to be expanded. */ + child->command_ptr = 0; + child->file->command_state = cs_finished; + child->file->update_status = 0; + return 0; + } + else + /* Get the next line to run. */ + child->command_ptr = child->command_lines[child->command_line++]; + } + return 1; +} + +static int +load_too_high () +{ + extern int getloadavg (); + double load; + + if (max_load_average < 0) + return 0; + + make_access (); + if (getloadavg (&load, 1) != 1) + { + static int lossage = -1; + /* Complain only once for the same error. */ + if (lossage == -1 || errno != lossage) + { + if (errno == 0) + /* An errno value of zero means getloadavg is just unsupported. */ + error ("cannot enforce load limits on this operating system"); + else + perror_with_name ("cannot enforce load limit: ", "getloadavg"); + } + lossage = errno; + load = 0; } + user_access (); + + return load >= max_load_average; +} - pop_signals_blocked_p (); +/* Start jobs that are waiting for the load to be lower. */ - if (job_slots == 1 && file->command_state == cs_running) +void +start_waiting_jobs () +{ + while (waiting_jobs != 0) { - /* Since there is only one job slot, make things run linearly. - Wait for the child to finish, setting the state to `cs_finished'. */ - while (file->command_state != cs_finished) - wait_for_children (1, 0); + struct child *c; + + /* Check for recently deceased descendants. */ + reap_children (0, 0); + + if (job_slots_used > 0 + && (job_slots_used == job_slots || load_too_high ())) + /* We have started all the jobs we can at the moment. */ + return; + + c = waiting_jobs; + waiting_jobs = c->next; + start_waiting_job (c); } } @@ -835,9 +826,6 @@ (void) close (d); } - /* Don't block signals for the new process. */ - unblock_signals (); - /* Run the command. */ exec_command (argv, envp); } @@ -862,26 +850,26 @@ { unsigned int len; -#if !defined (USG) || defined (POSIX) -#ifndef POSIX +#ifdef HAVE_GETGROUPS +#ifndef HAVE_UNISTD_H extern int getgroups (); #endif static int ngroups = -1; #ifdef NGROUPS_MAX - static GID_T groups[NGROUPS_MAX]; + static gid_t groups[NGROUPS_MAX]; #define ngroups_max NGROUPS_MAX #else - static GID_T *groups = 0; + static gid_t *groups = 0; static int ngroups_max; if (groups == 0) { ngroups_max = GET_NGROUPS_MAX; - groups = (GID_T *) malloc (ngroups_max * sizeof (GID_T)); + groups = (gid_t *) malloc (ngroups_max * sizeof (gid_t)); } #endif if (groups != 0 && ngroups == -1) ngroups = getgroups (ngroups_max, groups); -#endif /* POSIX or not USG. */ +#endif /* Have getgroups. */ len = strlen (file) + 1; do @@ -912,7 +900,7 @@ perm = (st.st_mode & 0010); else { -#ifndef USG +#ifdef HAVE_GETGROUPS register int i; for (i = 0; i < ngroups; ++i) if (groups[i] == st.st_gid) @@ -920,7 +908,7 @@ if (i < ngroups) perm = (st.st_mode & 0010); else -#endif /* Not USG. */ +#endif /* Have getgroups. */ perm = (st.st_mode & 0001); } @@ -1043,8 +1031,19 @@ int instring; char **new_argv = 0; + if (restp != NULL) + *restp = NULL; + + /* Make sure not to bother processing an empty line. */ + while (isblank (*line)) + ++line; + if (*line == '\0') + return 0; + /* See if it is safe to parse commands internally. */ - if (shell != 0 && strcmp (shell, default_shell)) + if (shell == 0) + shell = default_shell; + else if (strcmp (shell, default_shell)) goto slow; if (ifs != 0) @@ -1061,9 +1060,6 @@ ap = new_argv[0] = (char *) xmalloc (i); end = ap + i; - if (restp != NULL) - *restp = NULL; - /* I is how many complete arguments have been found. */ i = 0; instring = 0; @@ -1089,7 +1085,28 @@ { case '\\': /* Backslash-newline combinations are eaten. */ - if (p[1] != '\0' && p[1] != '\n') + if (p[1] == '\n') + { + /* Eat the backslash, the newline, and following whitespace, + replacing it all with a single space. */ + p += 2; + + /* If there is a tab after a backslash-newline, + remove it from the source line which will be echoed, + since it was most likely used to line + up the continued line with the previous one. */ + if (*p == '\t') + strcpy (p, p + 1); + + if (ap != new_argv[i]) + /* Treat this as a space, ending the arg. + But if it's at the beginning of the arg, it should + just get eaten, rather than becoming an empty arg. */ + goto end_of_arg; + else + p = next_token (p) - 1; + } + else if (p[1] != '\0') /* Copy and skip the following char. */ *ap++ = *++p; break; @@ -1112,6 +1129,7 @@ case ' ': case '\t': + end_of_arg: /* We have the end of an argument. Terminate the text of the argument. */ *ap++ = '\0'; @@ -1151,6 +1169,14 @@ ++i; new_argv[i] = 0; + if (i == 1) + { + register int j; + for (j = 0; sh_cmds[j] != 0; ++j) + if (streq (sh_cmds[j], new_argv[0])) + goto slow; + } + if (new_argv[0] == 0) /* Line was empty. */ return 0; @@ -1167,49 +1193,63 @@ free (new_argv); } - if (shell == 0 || !strcmp (shell, default_shell)) - { - /* The shell is the default, or we're in a recursive call to construct - the argument list for the real shell. Construct a simple argument - list using the default shell. */ - new_argv = (char **) xmalloc (4 * sizeof (char *)); - new_argv[0] = savestring (default_shell, sizeof (default_shell) - 1); - new_argv[1] = "-c"; - new_argv[2] = savestring (line, strlen (line)); - new_argv[3] = 0; - } - else - { - /* SHELL may be a multi-word command. Construct a command line - "SHELL -c LINE", with all special chars in LINE escaped. - Then recurse, expanding this command line to get the final - argument list. */ - - unsigned int shell_len = strlen (shell); - static char minus_c[] = " -c "; - unsigned int line_len = strlen (line); - - char *new_line = (char *) alloca (shell_len + (sizeof (minus_c) - 1) - + (line_len * 2) + 1); - - ap = new_line; - bcopy (shell, ap, shell_len); - ap += shell_len; - bcopy (minus_c, ap, sizeof (minus_c) - 1); - ap += sizeof (minus_c) - 1; - for (p = line; *p != '\0'; ++p) - { - if (*p == '\\' || *p == '\'' - || isspace (*p) - || index (sh_chars, *p) != 0) + { + /* SHELL may be a multi-word command. Construct a command line + "SHELL -c LINE", with all special chars in LINE escaped. + Then recurse, expanding this command line to get the final + argument list. */ + + unsigned int shell_len = strlen (shell); + static char minus_c[] = " -c "; + unsigned int line_len = strlen (line); + + char *new_line = (char *) alloca (shell_len + (sizeof (minus_c) - 1) + + (line_len * 2) + 1); + + ap = new_line; + bcopy (shell, ap, shell_len); + ap += shell_len; + bcopy (minus_c, ap, sizeof (minus_c) - 1); + ap += sizeof (minus_c) - 1; + for (p = line; *p != '\0'; ++p) + { + if (restp != NULL && *p == '\n') + { + *restp = p; + break; + } + else if (*p == '\\' && p[1] == '\n') + { + /* Eat the backslash, the newline, and following whitespace, + replacing it all with a single space (which is escaped + from the shell). */ + p += 2; + + /* If there is a tab after a backslash-newline, + remove it from the source line which will be echoed, + since it was most likely used to line + up the continued line with the previous one. */ + if (*p == '\t') + strcpy (p, p + 1); + + p = next_token (p); + --p; *ap++ = '\\'; - *ap++ = *p; - } - *ap = '\0'; + *ap++ = ' '; + continue; + } - new_argv = construct_command_argv_internal (new_line, restp, - (char *) 0, (char *) 0); - } + if (*p == '\\' || *p == '\'' + || isspace (*p) + || index (sh_chars, *p) != 0) + *ap++ = '\\'; + *ap++ = *p; + } + *ap = '\0'; + + new_argv = construct_command_argv_internal (new_line, (char **) NULL, + (char *) 0, (char *) 0); + } return new_argv; } @@ -1243,162 +1283,7 @@ return argv; } -#if (defined(USG) && !defined(HAVE_SIGLIST)) || defined(DGUX) -/* Initialize sys_siglist. */ - -void -init_siglist () -{ - char buf[100]; - register unsigned int i; - - for (i = 0; i < NSIG; ++i) - switch (i) - { - default: - sprintf (buf, "Signal %u", i); - sys_siglist[i] = savestring (buf, strlen (buf)); - break; - case SIGHUP: - sys_siglist[i] = "Hangup"; - break; - case SIGINT: - sys_siglist[i] = "Interrupt"; - break; - case SIGQUIT: - sys_siglist[i] = "Quit"; - break; - case SIGILL: - sys_siglist[i] = "Illegal Instruction"; - break; - case SIGTRAP: - sys_siglist[i] = "Trace Trap"; - break; - case SIGIOT: - sys_siglist[i] = "IOT Trap"; - break; -#ifdef SIGEMT - case SIGEMT: - sys_siglist[i] = "EMT Trap"; - break; -#endif -#ifdef SIGDANGER - case SIGDANGER: - sys_siglist[i] = "Danger signal"; - break; -#endif - case SIGFPE: - sys_siglist[i] = "Floating Point Exception"; - break; - case SIGKILL: - sys_siglist[i] = "Killed"; - break; - case SIGBUS: - sys_siglist[i] = "Bus Error"; - break; - case SIGSEGV: - sys_siglist[i] = "Segmentation fault"; - break; - case SIGSYS: - sys_siglist[i] = "Bad Argument to System Call"; - break; - case SIGPIPE: - sys_siglist[i] = "Broken Pipe"; - break; - case SIGALRM: - sys_siglist[i] = "Alarm Clock"; - break; - case SIGTERM: - sys_siglist[i] = "Terminated"; - break; -#if !defined (SIGIO) || SIGUSR1 != SIGIO - case SIGUSR1: - sys_siglist[i] = "User-defined signal 1"; - break; -#endif -#if !defined (SIGURG) || SIGUSR2 != SIGURG - case SIGUSR2: - sys_siglist[i] = "User-defined signal 2"; - break; -#endif -#ifdef SIGCLD - case SIGCLD: -#endif -#if defined(SIGCHLD) && !defined(SIGCLD) - case SIGCHLD: -#endif - sys_siglist[i] = "Child Process Exited"; - break; -#ifdef SIGPWR - case SIGPWR: - sys_siglist[i] = "Power Failure"; - break; -#endif -#ifdef SIGVTALRM - case SIGVTALRM: - sys_siglist[i] = "Virtual Timer Alarm"; - break; -#endif -#ifdef SIGPROF - case SIGPROF: - sys_siglist[i] = "Profiling Alarm Clock"; - break; -#endif -#ifdef SIGIO - case SIGIO: - sys_siglist[i] = "I/O Possible"; - break; -#endif -#ifdef SIGWINDOW - case SIGWINDOW: - sys_siglist[i] = "Window System Signal"; - break; -#endif -#ifdef SIGSTOP - case SIGSTOP: - sys_siglist[i] = "Stopped (signal)"; - break; -#endif -#ifdef SIGTSTP - case SIGTSTP: - sys_siglist[i] = "Stopped"; - break; -#endif -#ifdef SIGCONT - case SIGCONT: - sys_siglist[i] = "Continued"; - break; -#endif -#ifdef SIGTTIN - case SIGTTIN: - sys_siglist[i] = "Stopped (tty input)"; - break; -#endif -#ifdef SIGTTOU - case SIGTTOU: - sys_siglist[i] = "Stopped (tty output)"; - break; -#endif -#ifdef SIGURG - case SIGURG: - sys_siglist[i] = "Urgent Condition on Socket"; - break; -#endif -#ifdef SIGXCPU - case SIGXCPU: - sys_siglist[i] = "CPU Limit Exceeded"; - break; -#endif -#ifdef SIGXFSZ - case SIGXFSZ: - sys_siglist[i] = "File Size Limit Exceeded"; - break; -#endif - } -} -#endif /* USG and not HAVE_SIGLIST. */ - -#if defined(USG) && !defined(USGr3) && !defined(HAVE_DUP2) +#ifndef HAVE_DUP2 int dup2 (old, new) int old, new; @@ -1416,4 +1301,4 @@ return fd; } -#endif /* USG and not USGr3 and not HAVE_DUP2. */ +#endif diff -ruN make-3.62/job.h make-3.63/job.h --- make-3.62/job.h Sat Mar 23 09:10:48 1991 +++ make-3.63/job.h Wed Jan 6 17:57:14 1993 @@ -1,3 +1,20 @@ +/* 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 @@ -24,8 +41,8 @@ extern struct child *children; extern void new_job (); -extern void wait_for_children (); -extern void push_signals_blocked_p (), pop_signals_blocked_p (); +extern void reap_children (); +extern void start_waiting_jobs (); extern char **construct_command_argv (); extern void child_execute_job (); diff -ruN make-3.62/load.c make-3.63/load.c --- make-3.62/load.c Thu Sep 26 04:43:13 1991 +++ make-3.63/load.c @@ -1,311 +0,0 @@ -/* Copyright (C) 1988, 1989, 1991 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" - -#ifdef UMAX - -#define LDAV_BASED - -/* 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. */ -#include -#include - -#include -#include -#include -#include - -#ifdef UMAX_43 -#include -#include -#include -#include -#include -#else /* Not UMAX_43. */ -#include -#include -#include -#include -#include -#include -#endif - -double -load_average () -{ - static unsigned int cpus = 0, samples; - 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 0.0; - - 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 0.0; - - 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 0.0; - - 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; - } - - return (load / samples / cpus); -} - -#else /* Not UMAX. */ - -#ifdef apollo - -/* Apollo code from lisch@mentorg.com (Ray Lischner). */ - -#define LDAV_BASED - -/* Return the current load average as a double. - - 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. */ - -double -load_average () -{ - extern void proc1_$get_loadav (); - unsigned long int loadav[3]; - proc1_$get_loadav(loadav); - return loadav[0] / 65536.0; -} - -#else /* Not apollo. */ - -#ifndef NO_LDAV - -#define LDAV_BASED - -#if defined(hp300) && !defined(USG) -#define LDAV_CVT (((double) load) / 2048.0) -#endif - -#if defined(ultrix) && defined(vax) -#define LDAV_TYPE double -#define LDAV_CVT (load) -#endif - -#ifndef KERNEL_FILE_NAME -#define KERNEL_FILE_NAME "/vmunix" -#endif -#ifndef LDAV_SYMBOL -#define LDAV_SYMBOL "_avenrun" -#endif -#ifndef LDAV_TYPE -#define LDAV_TYPE long int -#endif -#ifndef LDAV_CVT -#define LDAV_CVT ((double) load) -#endif - -#include -#ifdef NLIST_NAME_UNION -#define nl_name n_un.n_name -#else -#define nl_name n_name -#endif - -#ifdef USG -#include -#else -#include -#endif - -/* Return the current load average as a double. */ - -double -load_average () -{ - extern int nlist (); - LDAV_TYPE load; - static int complained = 0; - static int kmem = -1; - static unsigned long int offset = 0; - - if (kmem < 0) - { - kmem = open ("/dev/kmem", O_RDONLY); - if (kmem < 0) - { - if (!complained) - perror_with_name ("open: ", "/dev/kmem"); - goto lose; - } - } - - if (offset == 0) - { - struct nlist nl[2]; - -#ifdef NLIST_NAME_ARRAY - strcpy (nl[0].nl_name, LDAV_SYMBOL); - strcpy (nl[1].nl_name, ""); -#else /* Not NLIST_NAME_ARRAY. */ - nl[0].nl_name = LDAV_SYMBOL; - nl[1].nl_name = 0; -#endif /* NLIST_NAME_ARRAY. */ - - if (nlist (KERNEL_FILE_NAME, nl) < 0 || nl[0].n_type == 0) - { - if (!complained) - perror_with_name ("nlist: ", KERNEL_FILE_NAME); - goto lose; - } - offset = nl[0].n_value; - } - - if (lseek (kmem, offset, 0) == -1L) - { - if (!complained) - perror_with_name ("lseek: ", "/dev/kmem"); - goto lose; - } - if (read (kmem, &load, sizeof load) < 0) - { - if (!complained) - perror_with_name ("read: ", "/dev/kmem"); - goto lose; - } - - if (complained) - { - error ("Load average limits will be enforced again."); - complained = 0; - } - return LDAV_CVT; - - lose:; - if (!complained) - { - error ("Load average limits will not be enforced."); - complained = 1; - } - return 0.0; -} - -#endif /* Not NO_LDAV. */ - -#endif /* Apollo. */ -#endif /* UMAX. */ - - -#ifdef LDAV_BASED - -extern unsigned int job_slots_used; - -extern unsigned int sleep (); - -/* Don't return until a job should be started. */ - -void -wait_to_start_job () -{ - register unsigned int loops = 0; - - if (max_load_average < 0.0) - return; - - while (job_slots_used > 0) - { - double load = load_average (); - - if (load < max_load_average) - return; - - ++loops; - if (loops == 5 || load > max_load_average * 2) - { - /* If the load is still too high after five loops or it is very - high, just wait for a child to die before checking again. */ - loops = 0; - wait_for_children (1, 0); - } - else - /* Don't check the load again immediately, because that will - just worsen the load. Check it progressively more slowly. */ - sleep (loops); - } -} - -#else /* Not LDAV_BASED. */ - -/* How else to do it? */ - -void -wait_to_start_job () -{ - return; -} -#endif /* LDAV_BASED. */ diff -ruN make-3.62/main.c make-3.63/main.c --- make-3.62/main.c Mon Sep 9 19:36:14 1991 +++ make-3.63/main.c Fri Jan 15 13:18:29 1993 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988-1991 Free Software Foundation, Inc. +/* Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify @@ -21,13 +21,11 @@ #include "file.h" #include "variable.h" #include "job.h" -#include +#include "getopt.h" extern char *version_string; -extern int fatal_error_signal (); - extern struct dep *read_all_makefiles (); extern void print_variable_data_base (); @@ -36,10 +34,13 @@ extern void print_file_data_base (); extern void print_vpath_data_base (); -#if !defined(__GNU_LIBRARY__) && !defined(POSIX) +#ifndef HAVE_UNISTD_H extern int chdir (); +#endif +#ifndef STDC_HEADERS +#ifndef sun /* Sun has an incorrect decl in a header. */ extern void exit (); -extern time_t time (); +#endif extern double atof (); #endif extern char *mktemp (); @@ -81,15 +82,16 @@ struct command_switch { - char c; /* The switch character. */ - enum /* Type of the value. */ + char c; /* The switch character. */ + enum /* Type of the value. */ { - flag, /* Turn int flag on. */ - flag_off, /* Turn int flag off. */ - string, /* One string per switch, may be in the same word. */ - positive_int, /* A positive integer. */ - floating, /* A floating-point number (double). */ - ignore /* Ignored. */ + flag, /* Turn int flag on. */ + flag_off, /* Turn int flag off. */ + string, /* One string per switch. */ + positive_int, /* A positive integer. */ + floating, /* A floating-point number (double). */ + ignore, /* Ignored. */ + usage_and_exit /* Ignored; exit after processing switches. */ } type; char *value_ptr; /* Pointer to the value-holding variable. */ @@ -100,6 +102,10 @@ char *noarg_value; /* Pointer to value used if no argument is given. */ char *default_value;/* Pointer to default value. */ + + char *long_name; /* Long option name. */ + char *argdesc; /* Descriptive word for argument. */ + char *description; /* Description for usage message. */ }; @@ -208,45 +214,113 @@ /* List of files given with -W switches. */ static struct stringlist *new_files = 0; - + /* The table of command switches. */ static struct command_switch switches[] = { - { 'b', ignore, 0, 0, 0, 0, 0, 0 }, - { 'C', string, (char *) &directories, 0, 0, 0, 0, 0 }, - { 'd', flag, (char *) &debug_flag, 1, 1, 0, 0, 0 }, - { 'e', flag, (char *) &env_overrides, 1, 1, 0, 0, 0 }, - { 'f', string, (char *) &makefiles, 0, 0, 0, 0, 0 }, - { 'i', flag, (char *) &ignore_errors_flag, 1, 1, 0, 0, 0 }, - { 'I', string, (char *) &include_directories, 0, 0, 0, 0, 0 }, + { 'b', ignore, 0, 0, 0, 0, 0, 0, + 0, 0, + "Ignored for compatibility" }, + { 'C', string, (char *) &directories, 0, 0, 0, 0, 0, + "directory", "DIRECTORY", + "Change to DIRECTORY before doing anything" }, + { 'd', flag, (char *) &debug_flag, 1, 1, 0, 0, 0, + "debug", 0, + "Print lots of debugging information" }, + { 'e', flag, (char *) &env_overrides, 1, 1, 0, 0, 0, + "environment-overrides", 0, + "Environment variables override makefiles" }, + { 'f', string, (char *) &makefiles, 0, 0, 0, 0, 0, + "file", "FILE", + "Read FILE as a makefile" }, + { 'h', usage_and_exit, 0, 0, 0, 0, 0, 0, + "help", 0, + "Print this message and exit" }, + { 'i', flag, (char *) &ignore_errors_flag, 1, 1, 0, 0, 0, + "ignore-errors", 0, + "Ignore errors from commands" }, + { 'I', string, (char *) &include_directories, 1, 1, 0, 0, 0, + "include-dir", "DIRECTORY", + "Search DIRECTORY for included makefiles" }, { 'j', positive_int, (char *) &job_slots, 1, 1, 0, - (char *) &inf_jobs, (char *) &default_job_slots }, + (char *) &inf_jobs, (char *) &default_job_slots, + "jobs", "N", + "Allow N jobs at once; infinite jobs with no arg" }, { 'k', flag, (char *) &keep_going_flag, 1, 1, 0, - 0, (char *) &default_keep_going_flag }, + 0, (char *) &default_keep_going_flag, + "keep-going", 0, + "Keep going when some targets can't be made" }, { 'l', floating, (char *) &max_load_average, 1, 1, 0, - (char *) &default_load_average, (char *) &default_load_average }, - { 'm', ignore, 0, 0, 0, 0, 0, 0 }, - { 'n', flag, (char *) &just_print_flag, 1, 1, 1, 0, 0 }, - { 'o', string, (char *) &old_files, 0, 0, 0, 0, 0 }, - { 'p', flag, (char *) &print_data_base_flag, 1, 1, 0, 0, 0 }, - { 'q', flag, (char *) &question_flag, 1, 1, 1, 0, 0 }, - { 'r', flag, (char *) &no_builtin_rules_flag, 1, 1, 0, 0, 0 }, - { 's', flag, (char *) &silent_flag, 1, 1, 0, 0, 0 }, + (char *) &default_load_average, (char *) &default_load_average, + "load-average", "N", + "Don't start multiple jobs unless load is below N" }, + { 'm', ignore, 0, 0, 0, 0, 0, 0, + 0, 0, + "-b" }, + { 'n', flag, (char *) &just_print_flag, 1, 1, 1, 0, 0, + "just-print", 0, + "Don't actually run any commands; just print them" }, + { 'o', string, (char *) &old_files, 0, 0, 0, 0, 0, + "old-file", "FILE", + "Consider FILE to be very old and don't remake it" }, + { 'p', flag, (char *) &print_data_base_flag, 1, 1, 0, 0, 0, + "print-data-base", 0, + "Print make's internal database" }, + { 'q', flag, (char *) &question_flag, 1, 1, 1, 0, 0, + "question", 0, + "Run no commands; exit status says if up to date" }, + { 'r', flag, (char *) &no_builtin_rules_flag, 1, 1, 0, 0, 0, + "no-builtin-rules", 0, + "Disable the built-in implicit rules" }, + { 's', flag, (char *) &silent_flag, 1, 1, 0, 0, 0, + "silent", 0, + "Don't echo commands" }, { 'S', flag_off, (char *) &keep_going_flag, 1, 1, 0, - 0, (char *) &default_keep_going_flag }, - { 't', flag, (char *) &touch_flag, 1, 1, 1, 0, 0 }, - { 'v', flag, (char *) &print_version_flag, 0, 0, 0, 0, 0 }, - { 'w', flag, (char *) &print_directory_flag, 1, 1, 0, 0, 0 }, - { 'W', string, (char *) &new_files, 0, 0, 0, 0, 0 }, - { '\0', ignore, 0, 0, 0, 0, 0 } + 0, (char *) &default_keep_going_flag, + "no-keep-going", 0, + "Turns off -k" }, + { 't', flag, (char *) &touch_flag, 1, 1, 1, 0, 0, + "touch", 0, + "Touch targets instead of remaking them" }, + { 'v', flag, (char *) &print_version_flag, 1, 1, 0, 0, 0, + "version", 0, + "Print the version number of make" }, + { 'w', flag, (char *) &print_directory_flag, 1, 1, 0, 0, 0, + "print-directory", 0, + "Print the current directory" }, + { 'W', string, (char *) &new_files, 0, 0, 0, 0, 0, + "what-if", "FILE", + "Consider FILE to be infinitely new" }, + { '\0', } }; -/* List of non-switch arguments. */ +/* Secondary long names for options. */ -struct stringlist *other_args = 0; +static struct option long_option_aliases[] = + { + { "quiet", no_argument, 0, 's' }, + { "stop", no_argument, 0, 'S' }, + { "new", required_argument, 0, 'W' }, + { "new-file", required_argument, 0, 'W' }, + { "assume-new", required_argument, 0, 'W' }, + { "assume-old", required_argument, 0, 'o' }, + { "max-load", optional_argument, 0, 'l' }, + { "dry-run", no_argument, 0, 'n' }, + { "recon", no_argument, 0, 'n' }, + { "makefile", required_argument, 0, 'f' }, + }; + +/* The usage message prints the descriptions of options starting in + this column. Make sure it leaves enough room for the longest + description to fit in less than 80 characters. */ +#define DESCRIPTION_COLUMN 30 + +/* List of non-switch arguments. */ +struct stringlist *other_args = 0; + /* The name we were invoked with. */ char *program; @@ -268,7 +342,14 @@ struct file *default_file; /* Mask of signals that are being caught with fatal_error_signal. */ + +#ifdef POSIX +sigset_t fatal_signal_set; +#else +#ifdef HAVE_SIGSETMASK int fatal_signal_mask; +#endif +#endif int main (argc, argv, envp) @@ -276,10 +357,8 @@ char **argv; char **envp; { -#if (defined(USG) && !defined(HAVE_SIGLIST)) || defined(DGUX) - extern void init_siglist (); -#endif - extern int child_handler (); + extern void init_dir (); + extern RETSIGTYPE fatal_error_signal (), child_handler (); register struct file *f; register unsigned int i; register char *cmd_defs; @@ -295,36 +374,36 @@ reading_filename = 0; reading_lineno_ptr = 0; -#if (defined(USG) && !defined(HAVE_SIGLIST)) || defined(DGUX) - init_siglist (); +#ifndef HAVE_SYS_SIGLIST + signame_init (); #endif +#ifdef POSIX + sigemptyset (&fatal_signal_set); +#define ADD_SIG(sig) sigaddset (&fatal_signal_set, sig) +#else +#ifdef HAVE_SIGSETMASK fatal_signal_mask = 0; +#define ADD_SIG(sig) fatal_signal_mask |= sigmask (sig) +#else +#define ADD_SIG(sig) +#endif +#endif #define FATAL_SIG(sig) \ - if (SIGNAL ((sig), (SIGHANDLER) fatal_error_signal) \ - == (SIGHANDLER) SIG_IGN) \ - (void) SIGNAL ((sig), SIG_IGN); \ + if (signal ((sig), fatal_error_signal) == SIG_IGN) \ + (void) signal ((sig), SIG_IGN); \ else \ - fatal_signal_mask |= sigmask (sig); + ADD_SIG (sig); FATAL_SIG (SIGHUP); FATAL_SIG (SIGQUIT); FATAL_SIG (SIGINT); - FATAL_SIG (SIGILL); - FATAL_SIG (SIGTRAP); - FATAL_SIG (SIGIOT); -#ifdef SIGEMT - FATAL_SIG (SIGEMT); -#endif + FATAL_SIG (SIGTERM); + #ifdef SIGDANGER FATAL_SIG (SIGDANGER); #endif - FATAL_SIG (SIGFPE); - FATAL_SIG (SIGBUS); - FATAL_SIG (SIGSEGV); - FATAL_SIG (SIGSYS); - FATAL_SIG (SIGTERM); #ifdef SIGXCPU FATAL_SIG (SIGXCPU); #endif @@ -336,20 +415,19 @@ /* Make sure stdout is line-buffered. */ -#if (defined (USGr3) || defined (HPUX) || defined (hpux) \ - || defined (M_XENIX) || defined (APOLLO)) +#ifdef HAVE_SETLINEBUF + setlinebuf (stdout); +#else +#ifndef SETVBUF_REVERSED setvbuf (stdout, (char *) 0, _IOLBF, BUFSIZ); -#else /* Not USGr3 and not HPUX et al. */ -#ifdef USG -#ifdef sgi +#else /* setvbuf not reversed. */ + /* Some buggy systems lose if we pass 0 instead of allocating ourselves. */ setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ); -#else - setvbuf (stdout, _IOLBF, (char *) 0, BUFSIZ); -#endif -#else /* Not USG. */ - setlinebuf (stdout); -#endif /* USG. */ -#endif /* USGr3. */ +#endif /* setvbuf reversed. */ +#endif /* setlinebuf missing. */ + + /* Initialize the directory hashing code. */ + init_dir (); /* Set up to access user data (files). */ user_access (); @@ -371,13 +449,9 @@ /* Figure out where we are. */ -#ifdef USG - /* In some System V's, `getcwd' spawns a child running /bin/pwd. */ - push_signals_blocked_p (1); -#endif - if (getwd (current_directory) == 0) + if (getcwd (current_directory, GET_PATH_MAX) == 0) { -#ifdef USG +#ifdef HAVE_GETCWD perror_with_name ("getcwd: ", ""); #else error ("getwd: %s", current_directory); @@ -384,9 +458,6 @@ #endif current_directory[0] = '\0'; } -#ifdef USG - pop_signals_blocked_p (); -#endif /* Read in variables from the environment. It is important that this be done before `MAKE' and `MAKEOVERRIDES' are figured out so their @@ -402,7 +473,9 @@ /* Decode the switches. */ - decode_switches (argc, argv); + decode_env_switches ("MAKEFLAGS", 9); + decode_env_switches ("MFLAGS", 6); + decode_switches (argc, argv, 0); /* Print version information. */ @@ -474,35 +547,30 @@ if (cmd_defs_idx > 0) { cmd_defs[cmd_defs_idx - 1] = '\0'; - (void) define_variable ("MAKEOVERRIDES", 13, cmd_defs, o_override, 0); + (void) define_variable ("MAKEOVERRIDES", 13, cmd_defs, o_default, 0); } + free (cmd_defs); - /* Set the "MAKE" variable to the name we were invoked with. + /* Set the "MAKE_COMMAND" variable to the name we were invoked with. (If it is a relative pathname with a slash, prepend our directory name so the result will run the same program regardless of the current dir. If it is a name with no slash, we can only hope that PATH did not - find it in the current directory.) + find it in the current directory.) */ - Append the command-line variable definitions gathered above - so sub-makes will get them as command-line definitions. */ - if (current_directory[0] != '\0' && argv[0] != 0 && argv[0][0] != '/' && index (argv[0], '/') != 0) argv[0] = concat (current_directory, "/", argv[0]); - if (cmd_defs_idx > 0) - { - char *str = concat (argv[0], " ", cmd_defs); - (void) define_variable ("MAKE", 4, str, o_env, 0); - free (str); - } - else - (void) define_variable ("MAKE", 4, argv[0], o_env, 0); + (void) define_variable ("MAKE_COMMAND", 12, argv[0], o_default, 0); - free (cmd_defs); + /* Append the command-line variable definitions gathered above + so sub-makes will get them as command-line definitions. */ - /* If there were -c flags, move ourselves about. */ + (void) define_variable ("MAKE", 4, + "$(MAKE_COMMAND) $(MAKEOVERRIDES)", o_default, 1); + /* If there were -C flags, move ourselves about. */ + if (directories != 0) for (i = 0; directories->list[i] != 0; ++i) { @@ -520,6 +588,10 @@ makelevel = 0; } + /* Except under -s, always do -w in sub-makes and under -C. */ + if (!silent_flag && (directories != 0 || makelevel > 0)) + print_directory_flag = 1; + /* Construct the list of include directories to search. */ construct_include_path (include_directories == 0 ? (char **) 0 @@ -573,6 +645,7 @@ f = enter_file (savestring (name, sizeof name - 1)); f->updated = 1; f->update_status = 0; + f->command_state = cs_finished; /* Let it be removed when we're done. */ f->intermediate = 1; /* But don't mention it. */ @@ -584,9 +657,9 @@ reading in the makefiles so that `shell' function calls will work. */ #if defined (SIGCHLD) && !defined (USG) - (void) SIGNAL (SIGCHLD, child_handler); + (void) signal (SIGCHLD, child_handler); #else - (void) SIGNAL (SIGCLD, child_handler); + (void) signal (SIGCLD, child_handler); #endif /* Define the initial list of suffixes for old-style rules. */ @@ -612,6 +685,7 @@ read_makefiles = read_all_makefiles (makefiles == 0 ? (char **) 0 : makefiles->list); + /* Decode switches again, in case the variables were set by the makefile. */ decode_env_switches ("MAKEFLAGS", 9); decode_env_switches ("MFLAGS", 6); @@ -658,6 +732,7 @@ f->last_mtime = (time_t) 1; f->updated = 1; f->update_status = 0; + f->command_state = cs_finished; } if (new_files != 0) @@ -690,39 +765,37 @@ { register struct file *f = d->file; if (f->double_colon) - { - do - { - if (f->deps == 0 && f->cmds != 0) - { - /* This makefile is a :: target with commands, but - no dependencies. So, it will always be remade. - This might well cause an infinite loop, so don't - try to remake it. (This will only happen if - your makefiles are written exceptionally - stupidly; but if you work for Athena, that's how - you write your makefiles.) */ - - if (debug_flag) - printf ("Makefile `%s' might loop; not remaking it.\n", - f->name); - - if (last == 0) - read_makefiles = d->next; - else - last->next = d->next; + do + { + if (f->deps == 0 && f->cmds != 0) + { + /* This makefile is a :: target with commands, but + no dependencies. So, it will always be remade. + This might well cause an infinite loop, so don't + try to remake it. (This will only happen if + your makefiles are written exceptionally + stupidly; but if you work for Athena, that's how + you write your makefiles.) */ + + if (debug_flag) + printf ("Makefile `%s' might loop; not remaking it.\n", + f->name); + + if (last == 0) + read_makefiles = d->next; + else + last->next = d->next; - /* Free the storage. */ - free ((char *) d); + /* Free the storage. */ + free ((char *) d); - d = last == 0 ? 0 : last->next; + d = last == 0 ? 0 : last->next; - break; - } - f = f->prev; - } - while (f != NULL); - } + break; + } + f = f->prev; + } + while (f != NULL); if (f == NULL || !f->double_colon) { if (makefile_mtimes == 0) @@ -862,6 +935,12 @@ for (p = environ; *p != 0; ++p) if (!strncmp (*p, "MAKELEVEL=", 10)) { + /* The SGI compiler apparently can't understand + the concept of storing the result of a function + in something other than a local variable. */ + char *sgi_loses; + sgi_loses = (char *) alloca (40); + *p = sgi_loses; sprintf (*p, "MAKELEVEL=%u", makelevel); break; } @@ -914,10 +993,6 @@ } } - /* Print the data base under -p. */ - if (print_data_base_flag) - print_data_base (); - if (goals == 0) { if (read_makefiles == 0) @@ -933,353 +1008,537 @@ return 0; } +/* Parsing of arguments, decoding of switches. */ + +static char options[sizeof (switches) / sizeof (switches[0]) * 3]; +static struct option long_options[(sizeof (switches) / sizeof (switches[0])) + + (sizeof (long_option_aliases) / + sizeof (long_option_aliases[0]))]; + +/* Fill in the string and vector for getopt. */ +static void +init_switches () +{ + register char *p; + register int c; + register unsigned int i; + + if (options[0] != '\0') + /* Already done. */ + return; + + p = options; + for (i = 0; switches[i].c != '\0'; ++i) + { + long_options[i].name = (switches[i].long_name == 0 ? "" : + switches[i].long_name); + long_options[i].flag = 0; + *p++ = long_options[i].val = switches[i].c; + switch (switches[i].type) + { + case flag: + case flag_off: + case ignore: + case usage_and_exit: + long_options[i].has_arg = no_argument; + break; + + case string: + case positive_int: + case floating: + *p++ = ':'; + if (switches[i].noarg_value != 0) + { + *p++ = ':'; + long_options[i].has_arg = optional_argument; + } + else + long_options[i].has_arg = required_argument; + break; + } + } + *p = '\0'; + for (c = 0; c < (sizeof (long_option_aliases) / + sizeof (long_option_aliases[0])); + ++c) + long_options[i++] = long_option_aliases[c]; + long_options[i].name = 0; +} + +/* Decode switches from ARGC and ARGV. + They came from the environment if ENV is nonzero. */ + static void -decode_switches (argc, argv) +decode_switches (argc, argv, env) int argc; char **argv; + int env; { - char bad = 0; - register unsigned int i; - register char *sw; + int bad = 0; register struct command_switch *cs; register struct stringlist *sl; - char *arg; + register int c; - decode_env_switches ("MAKEFLAGS", 9); - decode_env_switches ("MFLAGS", 6); + if (!env) + { + other_args = (struct stringlist *) xmalloc (sizeof (struct stringlist)); + other_args->max = argc + 1; + other_args->list = (char **) xmalloc ((argc + 1) * sizeof (char *)); + other_args->idx = 1; + other_args->list[0] = savestring (argv[0], strlen (argv[0])); + } + + /* getopt does most of the parsing for us. + First, get its vectors set up. */ - other_args = (struct stringlist *) xmalloc (sizeof (struct stringlist)); - other_args->max = 5; - other_args->list = (char **) xmalloc (5 * sizeof (char *)); - other_args->idx = 1; - other_args->list[0] = savestring (argv[0], strlen (argv[0])); + init_switches (); - for (i = 1; i < argc; i++) + /* Let getopt produce error messages for the command line, + but not for options from the environment. */ + opterr = !env; + /* Reset getopt's state. */ + optind = 0; + + while ((c = getopt_long (argc, argv, + options, long_options, (int *) 0)) != EOF) { - sw = argv[i]; - if (*sw++ == '-') - while (*sw != '\0') - { - for (cs = switches; cs->c != '\0'; ++cs) - if (cs->c == *sw) + if (c == '?') + /* Bad option. We will print a usage message and die later. + But continue to parse the other options so the user can + see all he did wrong. */ + bad = 1; + else + for (cs = switches; cs->c != '\0'; ++cs) + if (cs->c == c) + { + /* Whether or not we will actually do anything with + this switch. We test this individually inside the + switch below rather than just once outside it, so that + options which are to be ignored still consume args. */ + int doit = !env || cs->env; + + switch (cs->type) { - ++sw; - switch (cs->type) + default: + abort (); + + case ignore: + break; + + case usage_and_exit: + bad = 1; + break; + + case flag: + case flag_off: + if (doit) + *(int *) cs->value_ptr = cs->type == flag; + break; + + case string: + if (!doit) + break; + + if (optarg == 0) + optarg = cs->noarg_value; + + sl = *(struct stringlist **) cs->value_ptr; + if (sl == 0) { - default: - abort (); - case ignore: - break; - case flag: - case flag_off: - *(int *) cs->value_ptr = cs->type == flag; - break; - case string: - if (*sw == '\0') - { - arg = argv[++i]; - if (arg == 0) - { - arg = cs->noarg_value; - if (arg == 0) - { - error ("argument required for `-%c' option", - cs->c); - bad = 1; - break; - } - } - } - else - arg = sw; + sl = (struct stringlist *) + xmalloc (sizeof (struct stringlist)); + sl->max = 5; + sl->idx = 0; + sl->list = (char **) xmalloc (5 * sizeof (char *)); + *(struct stringlist **) cs->value_ptr = sl; + } + else if (sl->idx == sl->max - 1) + { + sl->max += 5; + sl->list = (char **) + xrealloc ((char *) sl->list, + sl->max * sizeof (char *)); + } + sl->list[sl->idx++] = savestring (optarg, strlen (optarg)); + sl->list[sl->idx] = 0; + break; - sl = *(struct stringlist **) cs->value_ptr; - if (sl == 0) - { - sl = (struct stringlist *) - xmalloc (sizeof (struct stringlist)); - sl->max = 5; - sl->idx = 0; - sl->list = (char **) xmalloc (5 * sizeof (char *)); - *(struct stringlist **) cs->value_ptr = sl; - } - else if (sl->idx == sl->max - 1) - { - sl->max += 5; - sl->list = (char **) - xrealloc ((char *) sl->list, - sl->max * sizeof (char *)); - } - sl->list[sl->idx++] = savestring (arg, strlen (arg)); - sl->list[sl->idx] = 0; - sw = ""; - break; + case positive_int: + if (optarg == 0 && argc > optind + && isdigit (argv[optind][0])) + optarg = argv[optind++]; - case positive_int: - if (*sw == '\0') - arg = argv[++i]; - else - arg = sw; - if (arg != 0 && isdigit (*arg)) - { - int i = atoi (arg); - if (arg == sw) - while (isdigit (*sw)) - ++sw; - if (i < 1) - { - error ("the `-%c' option requires a \ -positive integral argument", - cs->c); - bad = 1; - } - else - *(unsigned int *) cs->value_ptr = i; - } - else - { - if (cs->noarg_value != 0) - *(unsigned int *) cs->value_ptr - = *(unsigned int *) cs->noarg_value; - else - { - error ("the `-%c' option requires an argument", - cs->c); - bad = 1; - } - - if (arg == argv[i]) - /* We moved to the next arg, so move back. */ - --i; - } - break; + if (!doit) + break; - case floating: - if (*sw == '\0') - arg = argv[++i]; - else - arg = sw; - if (arg != 0 && (*arg == '.' || isdigit (*arg))) + if (optarg != 0) + { + int i = atoi (optarg); + if (i < 1) { - *(double *) cs->value_ptr = atof (arg); - if (arg == sw) - while (*sw == '.' || isdigit (*sw)) - ++sw; + if (doit) + error ("the `-%c' option requires a \ +positive integral argument", + cs->c); + bad = 1; } else - { - if (cs->noarg_value != 0) - *(double *) cs->value_ptr - = *(double *) cs->noarg_value; - else - { - error ("the `-%c' option requires an argument", - cs->c); - bad = 1; - } - - if (arg == argv[i]) - /* We moved to the next arg, so move back. */ - --i; - } - break; + *(unsigned int *) cs->value_ptr = i; } + else + *(unsigned int *) cs->value_ptr + = *(unsigned int *) cs->noarg_value; + break; + + case floating: + if (optarg == 0 && optind < argc + && (isdigit (argv[optind][0]) || argv[optind][0] == '.')) + optarg = argv[optind++]; + + if (doit) + *(double *) cs->value_ptr + = (optarg != 0 ? atof (optarg) + : *(double *) cs->noarg_value); - /* We've found the switch. Stop looking. */ break; } - - if (cs->c == '\0') - { - error ("unknown option `-%c'", *sw++); - bad = 1; - } - } - else - { - if (other_args->idx == other_args->max - 1) - { - other_args->max += 5; - other_args->list = (char **) - xrealloc ((char *) other_args->list, - other_args->max * sizeof (char *)); + + /* We've found the switch. Stop looking. */ + break; } - other_args->list[other_args->idx++] = argv[i]; + } + + if (!env) + { + /* Collect the remaining args in the `other_args' string list. */ + + while (optind < argc) + { + char *arg = argv[optind++]; + if (arg[0] != '-' || arg[1] != '\0') + other_args->list[other_args->idx++] = arg; } + other_args->list[other_args->idx] = 0; } - if (other_args != 0) - other_args->list[other_args->idx] = 0; + if (bad && !env) + { + /* Print a nice usage message. */ - if (bad) - die (1); -} + if (print_version_flag) + print_version (); -static void -decode_env_switches (envar, len) - char *envar; - unsigned int len; -{ - struct variable *v; - register char *args; - register struct command_switch *cs; + fprintf (stderr, "Usage: %s [options] [target] ...\n", program); - v = lookup_variable (envar, len); - if (v == 0 || *v->value == '\0') - return; + fputs ("Options:\n", stderr); + for (cs = switches; cs->c != '\0'; ++cs) + { + char buf[1024], arg[50], *p; + + if (cs->description[0] == '-') + continue; - for (args = v->value; *args != '\0'; ++args) - for (cs = switches; cs->c != '\0'; ++cs) - if (cs->c == *args) - if (cs->env) - switch (cs->type) + switch (long_options[cs - switches].has_arg) { - case string: - /* None of these allow environment changes. */ - default: - abort (); - case flag: - case flag_off: - *(int *) cs->value_ptr = cs->type == flag; + case no_argument: + arg[0] = '\0'; break; - case positive_int: - while (isspace (args[1])) - ++args; - if (isdigit(args[1])) - { - int i = atoi (&args[1]); - while (isdigit (args[1])) - ++args; - if (i >= 1) - *(unsigned int *) cs->value_ptr = i; - } - else - *(unsigned int *) cs->value_ptr - = *(unsigned int *) cs->noarg_value; + case required_argument: + sprintf (arg, " %s", cs->argdesc); + break; + case optional_argument: + sprintf (arg, " [%s]", cs->argdesc); break; - case floating: - while (isspace (args[1])) - ++args; - if (args[1] == '.' || isdigit (args[1])) + } + + p = buf; + sprintf (buf, " -%c%s", cs->c, arg); + p += strlen (p); + if (cs->long_name != 0) + { + unsigned int i; + sprintf (p, ", --%s%s", cs->long_name, arg); + p += strlen (p); + for (i = 0; i < (sizeof (long_option_aliases) / + sizeof (long_option_aliases[0])); + ++i) + if (long_option_aliases[i].val == cs->c) + { + sprintf (p, ", --%s%s", long_option_aliases[i].name, arg); + p += strlen (p); + } + } + { + struct command_switch *ncs = cs; + while ((++ncs)->c != '\0') + if (ncs->description[0] == '-' && + ncs->description[1] == cs->c) { - *(double *) cs->value_ptr = atof (&args[1]); - while (args[1] == '.' || isdigit (args[1])) - ++args; + /* This is another switch that does the same + one as the one we are processing. We want + to list them all together on one line. */ + sprintf (p, ", -%c%s", ncs->c, arg); + p += strlen (p); + if (ncs->long_name != 0) + { + sprintf (p, ", --%s%s", ncs->long_name, arg); + p += strlen (p); + } } - else - *(double *) cs->value_ptr = *(double *) cs->noarg_value; - break; + } + + if (p - buf > DESCRIPTION_COLUMN - 2) + /* The list of option names is too long to fit on the same + line with the description, leaving at least two spaces. + Print it on its own line instead. */ + { + fprintf (stderr, "%s\n", buf); + buf[0] = '\0'; } + + fprintf (stderr, "%*s%s.\n", + - DESCRIPTION_COLUMN, + buf, cs->description); + } + + die (1); + } +} + +/* Decode switches from environment variable ENVAR (which is LEN chars long). + We do this by chopping the value into a vector of words, prepending a + dash to the first word if it lacks one, and passing the vector to + decode_switches. */ + +static void +decode_env_switches (envar, len) + char *envar; + unsigned int len; +{ + char *varref = (char *) alloca (2 + len + 2); + char *value, *args; + int argc; + char **argv; + + /* Get the variable's value. */ + varref[0] = '$'; + varref[1] = '('; + bcopy (envar, &varref[2], len); + varref[2 + len] = ')'; + varref[2 + len + 1] = '\0'; + value = variable_expand (varref); + + /* Skip whitespace, and check for an empty value. */ + value = next_token (value); + len = strlen (value); + if (len == 0) + return; + + /* Make a copy of the value in ARGS, where we will munge it. + If it does not begin with a dash, prepend one. */ + args = (char *) alloca (1 + len + 2); + if (value[0] != '-') + args[0] = '-'; + bcopy (value, value[0] == '-' ? args : &args[1], len + 1); + /* Write an extra null terminator so our loop below will + never be in danger of looking past the end of the string. */ + args[(value[0] == '-' ? 0 : 1) + len + 1] = '\0'; + + /* Allocate a vector that is definitely big enough. */ + argv = (char **) alloca (1 + len * sizeof (char *)); + + /* getopt will look at the arguments starting at ARGV[1]. + Prepend a spacer word. */ + argv[0] = 0; + argc = 1; + do + { + argv[argc++] = args; + args = end_of_token (args); + *args++ = '\0'; + } while (*args != '\0'); + argv[argc] = 0; + + /* Parse those words. */ + decode_switches (argc, argv, 1); } /* Define the MAKEFLAGS and MFLAGS variables to reflect the settings of the - command switches. Include positive_int and floating options if PF. - Don't include options with the `no_makefile' flag is if MAKEFILE. */ + command switches. Include options with args if ALL is nonzero. + Don't include options with the `no_makefile' flag set if MAKEFILE. */ static void -define_makeflags (pf, makefile) - int pf, makefile; +define_makeflags (all, makefile) + int all, makefile; { register struct command_switch *cs; - char flags[200]; - register unsigned int i; + char *flagstring; - i = 0; + /* We will construct a linked list of `struct flag's describing + all the flags which need to go in MAKEFLAGS. Then, once we + know how many there are and their lengths, we can put them all + together in a string. */ + + struct flag + { + struct flag *next; + int c; + char *arg; + unsigned int arglen; + }; + struct flag *flags = 0; + unsigned int flagslen = 0; +#define ADD_FLAG(ARG, LEN) \ + do { \ + struct flag *new = (struct flag *) alloca (sizeof (struct flag)); \ + new->c = cs->c; \ + new->arg = (ARG); \ + new->arglen = (LEN); \ + new->next = flags; \ + flags = new; \ + if (new->arg == 0) \ + ++flagslen; /* Just a single flag letter. */ \ + else \ + flagslen += 1 + 1 + 1 + 1 + new->arglen; /* " -x foo" */ \ + } while (0) + for (cs = switches; cs->c != '\0'; ++cs) if (cs->toenv && (!makefile || !cs->no_makefile)) - { - if (i == 0 || flags[i - 1] == ' ') - flags[i++] = '-'; - switch (cs->type) - { - default: - abort (); + switch (cs->type) + { + default: + abort (); - case ignore: - break; + case ignore: + break; - case flag: - case flag_off: - if (!*(int *) cs->value_ptr == (cs->type == flag_off) - && (cs->default_value == 0 - || *(int *) cs->value_ptr != *(int *) cs->default_value)) - flags[i++] = cs->c; - break; + case flag: + case flag_off: + if (!*(int *) cs->value_ptr == (cs->type == flag_off) + && (cs->default_value == 0 + || *(int *) cs->value_ptr != *(int *) cs->default_value)) + ADD_FLAG (0, 0); + break; - case positive_int: - if (pf) - { - if ((cs->default_value != 0 - && (*(unsigned int *) cs->value_ptr - == *(unsigned int *) cs->default_value))) - break; - else if (cs->noarg_value != 0 - && (*(unsigned int *) cs->value_ptr == - *(unsigned int *) cs->noarg_value)) - flags[i++] = cs->c; - else - { - unsigned int value; - if (cs->c == 'j') - value = 1; - else - value = *(unsigned int *) cs->value_ptr; - sprintf (&flags[i], "%c%u ", cs->c, value); - i += strlen (&flags[i]); - } - } - break; + case positive_int: + if (all) + { + if ((cs->default_value != 0 + && (*(unsigned int *) cs->value_ptr + == *(unsigned int *) cs->default_value))) + break; + else if (cs->noarg_value != 0 + && (*(unsigned int *) cs->value_ptr == + *(unsigned int *) cs->noarg_value)) + ADD_FLAG (0, 0); + else if (cs->c == 'j') + /* Special case for `-j'. */ + ADD_FLAG ("1", 1); + else + { + char *buf = (char *) alloca (30); + sprintf (buf, "%u", *(unsigned int *) cs->value_ptr); + ADD_FLAG (buf, strlen (buf)); + } + } + break; - case floating: - if (pf) - { - if (cs->default_value != 0 - && (*(double *) cs->value_ptr - == *(double *) cs->default_value)) - break; - else if (cs->noarg_value != 0 - && (*(double *) cs->value_ptr - == *(double *) cs->noarg_value)) - flags[i++] = cs->c; - else - { - sprintf (&flags[i], "%c%f ", - cs->c, *(double *) cs->value_ptr); - i += strlen (&flags[i]); - } - } - break; - } - } + case floating: + if (all) + { + if (cs->default_value != 0 + && (*(double *) cs->value_ptr + == *(double *) cs->default_value)) + break; + else if (cs->noarg_value != 0 + && (*(double *) cs->value_ptr + == *(double *) cs->noarg_value)) + ADD_FLAG (0, 0); + else + { + char *buf = (char *) alloca (100); + sprintf (buf, "%f", *(double *) cs->value_ptr); + ADD_FLAG (buf, strlen (buf)); + } + } + break; + + case string: + if (all) + { + struct stringlist *sl = *(struct stringlist **) cs->value_ptr; + register unsigned int i; + if (sl != 0) + for (i = 0; i < sl->idx; ++i) + ADD_FLAG (sl->list[i], strlen (sl->list[i])); + } + break; + } + +#undef ADD_FLAG + + if (flags == 0) + /* No flags. Use a string of two nulls so [1] works below. */ + flagstring = "\0"; + else + { + /* Construct the value in FLAGSTRING. + We allocate enough space for a preceding dash and trailing null. */ + register char *p; + flagstring = (char *) alloca (1 + flagslen + 1); + p = flagstring; + *p++ = '-'; + do + { + /* Add the flag letter to the string. */ + *p++ = flags->c; + if (flags->arg != 0) + { + /* Add its argument too. */ + *p++ = ' '; + bcopy (flags->arg, p, flags->arglen); + p += flags->arglen; + /* Write a following space and dash, for the next flag. */ + *p++ = ' '; + *p++ = '-'; + } + flags = flags->next; + } while (flags != 0); - if (i == 0) - flags[0] = flags[1] = '\0'; - else if (flags[i - 1] == ' ' || flags[i - 1] == '-') - flags[i - 1] = '\0'; - flags[i] = '\0'; + if (p[-1] == '-') + /* Kill the final space and dash. */ + p -= 2; + + /* Terminate the string. */ + *p = '\0'; + } /* On Sun, the value of MFLAGS starts with a `-' but the value of MAKEFLAGS lacks the `-'. Be compatible. */ - (void) define_variable ("MAKEFLAGS", 9, &flags[1], o_env, 0); - (void) define_variable ("MFLAGS", 6, flags, o_env, 0); + (void) define_variable ("MAKEFLAGS", 9, &flagstring[1], o_env, 0); + (void) define_variable ("MFLAGS", 6, flagstring, o_env, 0); } -static int printed_version = 0; - /* Print version information. */ static void print_version () { + static int printed_version = 0; + extern char *remote_description; char *precede = print_data_base_flag ? "# " : ""; + if (printed_version) + /* Do it only once. */ + return; + printf ("%sGNU Make version %s", precede, version_string); if (remote_description != 0 && *remote_description != '\0') printf ("-%s", remote_description); printf (", by Richard Stallman and Roland McGrath.\n\ -%sCopyright (C) 1988-1991 Free Software Foundation, Inc.\n\ +%sCopyright (C) 1988, 89, 90, 91, 92, 93 Free Software Foundation, Inc.\n\ %sThis is free software; see the source for copying conditions.\n\ %sThere is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\ %sPARTICULAR PURPOSE.\n\n", precede, precede, precede, precede); @@ -1322,18 +1581,23 @@ if (!dying) { + int err; + dying = 1; - if (print_version_flag && !printed_version) + if (print_version_flag) print_version (); /* Wait for children to die. */ - wait_for_children (0, status != 0); + for (err = status != 0; job_slots_used > 0; err = 0) + reap_children (1, err); /* Remove the intermediate files. */ - remove_intermediates (0); + if (print_data_base_flag) + print_data_base (); + if (print_directory_flag) log_working_directory (0); } @@ -1352,12 +1616,12 @@ PATH_VAR (pwdbuf); char *message = entering ? "Entering" : "Leaving"; - if (entered && entering) + if (entering) + entered = 1; + else if (!entered) /* Don't print the leaving message if we haven't printed the entering message. */ return; - else - entered = 1; if (print_data_base_flag) fputs ("# ", stdout); @@ -1367,13 +1631,9 @@ else printf ("%s[%u]: %s ", program, makelevel, message); -#ifdef USG - /* In some System V's, `getcwd' spawns a child running /bin/pwd. */ - push_signals_blocked_p (1); -#endif - if (getwd (pwdbuf) == 0) + if (getcwd (pwdbuf, GET_PATH_MAX) == 0) { -#ifdef USG +#ifdef HAVE_GETCWD perror_with_name ("getcwd: ", ""); #else error ("getwd: %s", pwdbuf); @@ -1382,7 +1642,4 @@ } else printf ("directory `%s'\n", pwdbuf); -#ifdef USG - pop_signals_blocked_p (); -#endif } diff -ruN make-3.62/make-stds.texi make-3.63/make-stds.texi --- make-3.62/make-stds.texi +++ make-3.63/make-stds.texi Sun Jan 17 17:37:18 1993 @@ -0,0 +1,456 @@ +@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}.) + +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: + +@example +foo.1 : foo.man sedscript + sed -e sedscript foo.man > foo.1 +@end example + +@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. + +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. A +makefile target like + +@example +foo.o : bar.c + $(CC) $(CFLAGS) -I. -I$(srcdir) -c bar.c -o foo.o +@end example + +@noindent +should instead be written as + +@example +foo.o : bar.c + $(CC) $(CFLAGS) $< -o $@@ +@end example + +@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: + +@example +foo.1 : foo.man sedscript + sed -s $(srcdir)/sedscript $(srcdir)/foo.man > foo.1 +@end example + +@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 + +When you use @code{ranlib}, you should test whether it exists, and run +it only if it exists, so that the distribution will work on systems that +don't have @code{ranlib}. + +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 then run that +test. + +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. + +In the future, when we have a standard way of installing info files, +@samp{install} targets will be the proper place to do so. + +@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). + +@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 realclean +Delete everything from the current directory that can be reconstructed +with this Makefile. This typically includes everything deleted by +distclean, plus more: C source files produced by Bison, tags tables, +info files, and so on. + +One exception, however: @samp{make realclean} should not delete +@file{configure} even if @file{configure} can be remade using a rule in +the Makefile. More generally, @samp{make realclean} should not delete +anything that needs to exist in order to run @file{configure} +and then begin to build the program. + +@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: + +@example +info: foo.info + +foo.info: $(srcdir)/foo.texi $(srcdir)/chap1.texi $(srcdir)/chap2.texi + $(MAKEINFO) $(srcdir)/foo.texi +@end example + +@noindent +You must define the variable @code{MAKEINFO} in the Makefile. +It should run the Makeinfo program, which is part of the Texinfo2 distribution. + +@item dvi +Generate DVI files for all TeXinfo documentation. +For example: + +@example +dvi: foo.dvi + +foo.dvi: $(srcdir)/foo.texi $(srcdir)/chap1.texi $(srcdir)/chap2.texi + $(TEXI2DVI) $(srcdir)/foo.texi +@end example + +@noindent +You must define the variable @code{TEXI2DVI} in the Makefile. It should +run the program @code{texi2dvi}, which is part of the Texinfo2 +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 + +@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: + +@example +CFLAGS = -g +ALL_CFLAGS = $(CFLAGS) -I. +.c.o: + $(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $< +@end example + +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 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: + +@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} +(at least for now). + +@item exec_prefix +A prefix used in constructing the default values of the 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. + +@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 libdir +The directory for installing executable files to be run by the program +rather than by users. Object files and libraries of object code should +also go in this directory. The idea is that this directory is used for +files that pertain to a specific machine architecture, but need not be +in the path for commands. The value of @code{libdir} should normally be +@file{/usr/local/lib}, but write it as @file{$(exec_prefix)/lib}. + +@item datadir +The directory for installing read-only data files which the programs +refer to while they run. This directory is used for files which are +independent of the type of machine being used. This should normally be +@file{/usr/local/lib}, but write it as @file{$(prefix)/lib}. + +@item statedir +The directory for installing data files which the programs modify while +they run. These files should be independent of the type of machine +being used, and it should be possible to share them among machines at a +network installation. This should normally be @file{/usr/local/lib}, +but write it as @file{$(prefix)/lib}. + +@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. + +The way to tell whether @file{foo.h} came from the Foo package is to put +a magic string in the file---part of a comment---and grep for that +string. + +@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. + +@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. + +@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 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: + +@example +@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. +libdir = $(exec_prefix)/lib +# Where to put the Info files. +infodir = $(prefix)/info +@end example + +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. + diff -ruN make-3.62/make.h make-3.63/make.h --- make-3.62/make.h Sat Oct 26 17:19:58 1991 +++ make-3.63/make.h Fri Jan 15 13:05:49 1993 @@ -1,4 +1,5 @@ -/* Copyright (C) 1988-1991 Free Software Foundation, Inc. +/* 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 @@ -15,6 +16,21 @@ 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 + +#include "config.h" +#undef HAVE_CONFIG_H +#define HAVE_CONFIG_H + +#ifdef CRAY +/* This must happen before #include so + that the declaration therein is changed. */ +#define signal bsdsignal +#endif + #define _GNU_SOURCE #include #include @@ -21,7 +37,37 @@ #include #include #include +#include +#include + +#ifndef errno +extern int errno; +#endif + +#ifdef HAVE_UNISTD_H +#include +#ifdef _POSIX_VERSION +#define POSIX +#endif +#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 , 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 + #ifndef isblank #define isblank(c) ((c) == ' ' || (c) == '\t') #endif @@ -30,35 +76,37 @@ #define NSIG _NSIG #endif -#ifdef __STDC__ -#define SIGHANDLER void * -#else -#define SIGHANDLER int (*)() +#ifndef RETSIGTYPE +#define RETSIGTYPE void #endif -#define SIGNAL(sig, handler) \ - ((SIGHANDLER) signal((sig), (SIGHANDLER) (handler))) #ifndef sigmask #define sigmask(sig) (1 << ((sig) - 1)) #endif -#if defined(POSIX) || defined(__GNU_LIBRARY__) +#ifdef HAVE_LIMITS_H #include -#ifndef PATH_MAX -#define GET_PATH_MAX pathconf ("/", _PC_PATH_MAX) #endif -#else /* Not POSIX. */ +#ifdef HAVE_SYS_PARAM_H #include +#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. */ -#define PATH_MAX MAXPATHLEN -#endif /* No PATH_MAX. */ -#endif /* POSIX. */ + #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 @@ -79,8 +127,7 @@ #endif -#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) \ - || defined (POSIX)) +#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)) #include #include #define ANSI_STRING @@ -89,7 +136,9 @@ #ifdef USG #include +#ifdef NEED_MEMORY_H #include +#endif #define ANSI_STRING #else /* Not USG. */ @@ -119,16 +168,29 @@ extern char *malloc (), *realloc (); extern void free (); +extern void qsort (); +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 +#endif /* ANSI_STRING. */ #undef ANSI_STRING @@ -136,11 +198,13 @@ #undef alloca #define alloca(n) __builtin_alloca (n) #else /* Not GCC. */ -#ifdef sparc +#if defined (sparc) || defined (HAVE_ALLOCA_H) #include -#else /* Not sparc. */ +#else /* Not sparc or HAVE_ALLOCA_H. */ +#ifndef _AIX extern char *alloca (); -#endif /* sparc. */ +#endif /* Not AIX. */ +#endif /* sparc or HAVE_ALLOCA_H. */ #endif /* GCC. */ #ifndef iAPX286 @@ -205,12 +269,9 @@ extern void user_access (), make_access (), child_access (); -#if defined(USG) && !defined(HAVE_VFORK) -#define vfork fork -#define VFORK_NAME "fork" -#else /* Have vfork or not USG. */ -#define VFORK_NAME "vfork" -#endif /* USG and don't have vfork. */ +#ifdef HAVE_VFORK_H +#include +#endif #if defined(__GNU_LIBRARY__) || defined(POSIX) @@ -223,25 +284,19 @@ extern int sigblock (); #endif extern int kill (); -extern void abort (), exit (); -extern int unlink (), stat (); -extern void qsort (); extern int atoi (); +extern long int atol (); +extern int unlink (), stat (), fstat (); extern int pipe (), close (), read (), write (), open (); extern long int lseek (); -extern char *ctime (); #endif /* GNU C library or POSIX. */ -#if defined(USG) || defined(POSIX) && !defined(__GNU_LIBRARY__) +#ifdef HAVE_GETCWD extern char *getcwd (); -#ifdef PATH_MAX -#define getwd(buf) getcwd (buf, PATH_MAX - 2) #else -#define getwd(buf) getcwd (buf, GET_PATH_MAX - 2) -#endif -#else /* USG or POSIX and not GNU C library. */ extern char *getwd (); -#endif /* Not USG or POSIX, or maybe GNU C library. */ +#define getcwd(buf, len) getwd (buf) +#endif #if !defined(__GNU_LIBRARY__) && (!defined(vfork) || !defined(POSIX)) #ifdef POSIX @@ -267,8 +322,9 @@ extern char *program; extern unsigned int makelevel; +extern unsigned int files_remade; -#define DEBUGPR(msg) \ - if (debug_flag) { print_spaces (depth); printf (msg, file->name); \ - fflush (stdout); } else +#define DEBUGPR(msg) \ + do if (debug_flag) { print_spaces (depth); printf (msg, file->name); \ + fflush (stdout); } while (0) diff -ruN make-3.62/make.texinfo make-3.63/make.texinfo --- make-3.62/make.texinfo Mon Sep 23 23:58:59 1991 +++ make-3.63/make.texinfo Fri Jan 15 14:56:31 1993 @@ -1,21 +1,72 @@ -\input texinfo @c -*- Texinfo -*- -@comment %**start of header (This is for running Texinfo on a region.) +\input texinfo @c -*- Texinfo -*- +@c %**start of header @setfilename make.info -@settitle Make +@settitle GNU @code{make} @setchapternewpage odd -@comment %**end of header (This is for running Texinfo on a region.) +@smallbook +@c %**end of header -@iftex -@finalout -@end iftex +@set EDITION 0.40 +@set VERSION 3.63 Beta +@set UPDATED 14 January 1993 +@set UPDATE-MONTH January 1993 + +@c finalout + +@c ISPELL CHECK: done, 14 Jan 1993 --bob + +@ifset two-level-index +@tex +% trying for a two-level index +% You need the rewritten texindex program for this to work. + +\gdef\singleindexerfoo#1, #2\par{% +% Use a box register to test if #2 is empty. +\setbox0=\hbox{#2}% +\ifvoid0{ % A one-level entry. +\doind{\indexname}{#1}}\else{ % A two-level entry. +\dosubind{\indexname}{#1}{#2} +}\fi}% +\gdef\singleindexer#1{\singleindexerfoo#1, \par}% + +% This version writes two sort strings. +\gdef\dosubind #1#2#3{% +{\count10=\lastpenalty % +{\indexdummies % Must do this here, since \bf, etc expand at this stage +\escapechar=`\\% +{\let\folio=0% +\def\rawbackslashxx{\indexbackslash}% +% +% Now process the index-string once, with all font commands turned off, +% to get the string to sort the index by. +{\indexnofonts +\xdef\tempa{#2}% +\xdef\tempb{#3}% +}% +% Now produce the complete index entry. We process the index-string again, +% this time with font commands expanded, to get what to print in the index. +\edef\temp{% +\write \csname#1indfile\endcsname{% +\realbackslash entry {\tempa}{\folio}{#2}{#3}{\tempb}}}% +\temp}% +}\penalty\count10}} +@end tex +@end ifset + +@c Combine the variable and function indices: +@syncodeindex vr fn +@c Combine the program and concept indices: +@syncodeindex pg cp -@comment Combine the variable and function indices. -@synindex vr fn - @ifinfo -This file documents the GNU Make utility. +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 @value{EDITION}, last updated @value{UPDATED}, +of @cite{The GNU Make Manual}, for @code{make}, Version @value{VERSION}. -Copyright (C) 1988-1991 Free Software Foundation, Inc. +Copyright (C) 1988, '89, '90, '91, '92, '93 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -29,9 +80,9 @@ @end ignore Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that -the section entitled ``GNU General Public License'' is included exactly as in -the original, and provided that the entire resulting derived work is +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU General Public License'' is included exactly as +in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. @@ -38,37 +89,27 @@ Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the text of the translations of the section -entitled ``GNU General Public License'' must be approved for accuracy by the -Foundation. +entitled ``GNU General Public License'' must be approved for accuracy +by the Foundation. @end ifinfo +@ifset shorttitlepage +@shorttitlepage GNU Make +@end ifset @titlepage -@sp 10 -@center @titlefont{GNU Make} -@sp 2 -@center A Program for Directing Recompilation -@sp 2 -@center by Richard M. Stallman and Roland McGrath -@sp 3 -@center Edition 0.28 Beta, -@sp 1 -@center last updated 23 September 1991, -@sp 1 -@center for @code{make}, Version 3.61 Beta. +@title GNU Make +@subtitle A Program for Directing Recompilation +@subtitle Edition @value{EDITION}, for @code{make} Version @value{VERSION}. +@subtitle @value{UPDATE-MONTH} +@author by Richard M. Stallman and Roland McGrath @page @vskip 0pt plus 1filll -Copyright @copyright{} 1988-1991 Free Software Foundation, Inc. -@sp 2 - -This is Edition 0.28 Beta of the @cite{GNU Make Manual}, @* -last updated 23 September 1991, @* -for @code{make} Version 3.61 Beta. - +Copyright @copyright{} 1988, '89, '90, '91, '92, '93 Free Software Foundation, Inc. @sp 2 Published by the Free Software Foundation @* 675 Massachusetts Avenue, @* Cambridge, MA 02139 USA @* -Printed copies are available for $15 each. +Printed copies are available for $20 each. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -86,68 +127,268 @@ versions, except that the text of the translation of the section entitled ``GNU General Public License'' must be approved for accuracy by the Foundation. +@sp 2 +Cover art by Etienne Suvasa. @end titlepage @page -@node Top, Overview, , (dir) -@comment node-name, next, previous, up - @ifinfo -The GNU @code{make} utility determines automatically which pieces of a +@node Top, Copying, (dir), (dir) +@top Make + +The GNU @code{make} utility automatically determines which pieces of a large program need to be recompiled, and issues the commands to -recompile them. This manual describes it and contains the following -chapters: +recompile them.@refill + +This is Edition @value{EDITION} of the @cite{GNU Make Manual}, +last updated @value{UPDATED} +for @code{make} Version @value{VERSION}.@refill + +This manual describes @code{make} and contains the following chapters:@refill @end ifinfo @menu -* Overview:: Introducing @code{make}. -* Copying:: Copying conditions for GNU @code{make}. -* Bugs:: If you have problems, or think you've found a bug. -* Simple:: A simple example explained. -* Makefiles:: The data base contains rules and variable definitions. -* Rules:: A rule says how and when to remake one file. -* Commands:: A rule contains shell commands that say how to remake. -* Variables:: A variable holds a text string for substitution into rules. -* Conditionals::Makefiles that do one thing or another depending on - variable values. -* Functions:: Functions can do text-processing within @code{make}. - -* Running:: How to run @code{make}; how you can adjust the way - @code{make} uses the makefile. - -* Implicit:: Implicit rules take over if the makefile doesn't say - how a file is to be remade. -* Archives:: How to use @code{make} to update archive files. - -* Features:: GNU @code{make}'s advanced features and how GNU @code{make} - relates to other versions of @code{make}. -* Missing:: Features of other @code{make}s not supported - by GNU @code{make}. - -* Concept Index::Index of cross-references to where concepts are discussed. -* Name Index:: Index of cross-references for names of @code{make}'s - variables, functions, special targets and directives. +* Copying:: +* Overview:: Overview of @code{make}. +* Introduction:: An introduction to @code{make}. +* Makefiles:: Makefiles tell @code{make} what to do. +* Rules:: Rules describe when a file must be remade. +* Commands:: Commands say how to remake a file. +* Using Variables:: You can use variables to avoid repetition. +* Conditionals:: Use or ignore parts of the makefile based + on the values of variables. +* Functions:: Many powerful ways to manipulate text. +* make Invocation: Running. How to invoke @code{make} on the command line. +* Implicit Rules:: Use implicit rules to treat many files alike, + based on their file names. +* Archives:: How @code{make} can update library archives. +* Features:: Features GNU @code{make} has over other @code{make}s. +* Missing:: What GNU @code{make} lacks from other @code{make}s. +* Makefile Conventions:: Conventions for makefiles in GNU programs. +* Quick Reference:: A quick reference for experienced users. +* Complex Makefile:: A real example of a straightforward, + but nontrivial, makefile. +* Concept Index:: Index of Concepts +* Name Index:: Index of Functions, Variables, & Directives + + --- The Detailed Node Listing --- + +Overview of @code{make} + +* Preparing:: Preparing and Running Make +* Reading:: On Reading this Text +* Bugs:: Problems and Bugs + +An Introduction to Makefiles + +* Rule Introduction:: What a rule looks like. +* Simple Makefile:: A Simple Makefile +* How Make Works:: How @code{make} Processes This Makefile +* Variables Simplify:: Variables Make Makefiles Simpler +* make Deduces:: Letting @code{make} Deduce the Commands +* Combine By Dependency:: Another Style of Makefile +* Cleanup:: Rules for Cleaning the Directory + +Writing Makefiles + +* Makefile Contents:: What makefiles contain. +* Makefile Names:: How to name your makefile. +* Include:: How one makefile can use another makefile. +* MAKEFILES Variable:: The environment can specify extra makefiles. +* Remaking Makefiles:: How makefiles get remade. +* Overriding Makefiles:: How to override part of one makefile + with another makefile. + +Writing Rules + +* Rule Example:: An example explained. +* Rule Syntax:: General syntax explained. +* Wildcards:: Using wildcard characters such as `*'. +* Directory Search:: Searching other directories for source files. +* Phony Targets:: Using a target that is not a real file's name. +* Force Targets:: You can use a target without commands + or dependencies to mark other + targets as phony. +* Empty Targets:: When only the date matters and the + files are empty. +* Special Targets:: Targets with special built-in meanings. +* Multiple Targets:: When to make use of several targets in a rule. +* Multiple Rules:: How to use several rules with the same target. +* Static Pattern:: Static pattern rules apply to multiple targets + and can vary the dependencies according to + the target name. +* Double-Colon:: How to use a special kind of rule to allow + several independent rules for one target. +* Automatic Dependencies:: How to automatically generate rules giving + dependencies from the source files themselves. + +Using Wildcard Characters in File Names + +* Wildcard Examples:: Several examples +* Wildcard Pitfall:: Problems to avoid. +* Wildcard Function:: How to cause wildcard expansion where + it does not normally take place. + +Searching Directories for Dependencies + +* General Search:: Specifying a search path that applies + to every dependency. +* Selective Search:: Specifying a search path + for a specified class of names. +* Commands/Search:: How to write shell commands that work together + with search paths. +* Implicit/Search:: How search paths affect implicit rules. +* Libraries/Search:: Directory search for link libraries. + +Static Pattern Rules + +* Static Usage:: The syntax of static pattern rules. +* Static versus Implicit:: When are they better than implicit rules? + +Writing the Commands in Rules + +* Echoing:: How to control when commands are echoed. +* Execution:: How commands are executed. +* Parallel:: How commands can be executed in parallel. +* Errors:: What happens after a command execution error. +* Interrupts:: What happens when a command is interrupted. +* Recursion:: Invoking @code{make} from makefiles. +* Sequences:: Defining canned sequences of commands. +* Empty Commands:: Defining useful, do-nothing commands. + +Recursive Use of @code{make} + +* MAKE Variable:: The special effects of using @samp{$(MAKE)}. +* Variables/Recursion:: How to communicate variables to a sub-@code{make}. +* Options/Recursion:: How to communicate options to a sub-@code{make}. +* -w Option:: How the @samp{-w} or @samp{--print-directory} option + helps debug use of recursive @code{make} commands. + +How to Use Variables + +* Reference:: How to use the value of a variable. +* Flavors:: Variables come in two flavors. +* Advanced:: Advanced features for referencing a variable. +* Values:: All the ways variables get their values. +* Setting:: How to set a variable in the makefile. +* Override Directive:: How to set a variable in the makefile even if + the user has set it with a command argument. +* Defining:: An alternate way to set a variable + to a verbatim string. +* Environment:: Variable values can come from the environment. + +Advanced Features for Reference to Variables + +* Substitution Refs:: Referencing a variable with + substitutions on the value. +* Computed Names:: Computing the name of the variable to refer to. + +Conditional Parts of Makefiles + +* Conditional Example:: Example of a conditional +* Conditional Syntax:: The syntax of conditionals. +* Testing Flags:: Conditionals that test flags. + +Functions for Transforming Text + +* Syntax of Functions:: How to write a function call. +* Text Functions:: General-purpose text manipulation functions. +* Filename Functions:: Functions for manipulating file names. +* Foreach Function:: Repeat some text with controlled variation. +* Origin Function:: Find where a variable got its value. +* Shell Function:: Substitute the output of a shell command. + +How to Run @code{make} + +* Makefile Arguments:: How to specify which makefile to use. +* Goals:: How to use goal arguments to specify which + parts of the makefile to use. +* Instead of Execution:: How to use mode flags to specify what + kind of thing to do with the commands + in the makefile other than simply + execute them. +* Avoiding Compilation:: How to avoid recompiling certain files. +* Overriding:: How to override a variable to specify + an alternate compiler and other things. +* Testing:: How to proceed past some errors, to + test compilation. +* Options Summary:: Summary of Options + +Using Implicit Rules + +* Using Implicit:: How to use an existing implicit rule + to get the commands for updating a file. +* Catalogue of Rules:: A list of built-in implicit rules. +* Implicit Variables:: How to change what predefined rules do. +* Chained Rules:: How to use a chain of implicit rules. +* Pattern Rules:: How to define new implicit rules. +* Last Resort:: How to defining commands for rules + which cannot find any. +* Suffix Rules:: The old-fashioned style of implicit rule. +* Search Algorithm:: The precise algorithm for applying + implicit rules. + +Defining and Redefining Pattern Rules + +* Pattern Intro:: An introduction to pattern rules. +* Pattern Examples:: Examples of pattern rules. +* Automatic:: How to use automatic variables in the + commands of implicit rules. +* Pattern Match:: How patterns match. +* Match-Anything Rules:: Precautions you should take prior to + defining rules that can match any + target file whatever. +* Canceling Rules:: How to override or cancel built-in rules. + +Using @code{make} to Update Archive Files + +* Archive Members:: Archive members as targets. +* Archive Update:: The implicit rule for archive member targets. +* Archive Suffix Rules:: You can write a special kind of suffix rule + for updating archives. + +Implicit Rule for Archive Member Targets + +* Archive Symbols:: How to update archive symbol directories. @end menu +@node Copying, Overview, Top, Top +@include gpl.texinfo -@node Overview, Copying, Top, Top +@node Overview, Introduction, Copying, Top +@comment node-name, next, previous, up @chapter Overview of @code{make} -The purpose of the @code{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 -@code{make}, which was implemented by Richard Stallman and Roland McGrath. +The @code{make} utility automatically determines which pieces of a large +program need to be recompiled, and issues commands to recompile them. +This manual describes GNU @code{make}, which was implemented by Richard +Stallman and Roland McGrath. GNU @code{make} conforms to section 6.2 of +@cite{IEEE Standard 1003.2-1992} (POSIX.2). +@cindex POSIX +@cindex IEEE Standard 1003.2 +@cindex standards conformance Our examples show C programs, since they are most common, but you can use @code{make} with any programming language whose compiler can be run with a -shell command. In fact, @code{make} is not limited to programs. You can +shell command. Indeed, @code{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. +@menu +* Preparing:: Preparing and Running Make +* Reading:: On Reading this Text +* Bugs:: Problems and Bugs +@end menu + +@node Preparing, Reading, , Overview +@ifinfo +@heading Preparing and Running Make +@end ifinfo + To prepare to use @code{make}, you must write a file called the @dfn{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 +in your program and provides 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.@refill Once a suitable makefile exists, each time you change some source files, @@ -163,70 +404,201 @@ decide which of the files need to be updated. For each of those files, it issues the commands recorded in the data base. -@iftex -Command arguments to @code{make} can be used to control which files should -be recompiled, or how. @xref{Running}. +You can provide command line arguments to @code{make} to control which +files should be recompiled, or how. @xref{Running, ,How to Run +@code{make}}. + +@node Reading, Bugs, Preparing, Overview +@section How to Read This Manual + +If you are new to @code{make}, or are looking for a general +introduction, read the first few sections of each chapter, skipping the +later sections. In each chapter, the first few sections contain +introductory or general information and the later sections contain +specialized or technical information. +@ifinfo +The exception is the second chapter, @ref{Introduction, ,An +Introduction to Makefiles}, all of which is introductory. +@end ifinfo +@iftex +The exception is @ref{Introduction, ,An Introduction to Makefiles}, +all of which is introductory. @end iftex -@node Copying, Bugs, Overview, Top - -@include gpl.texinfo - -@node Bugs, Simple, Copying, Top -@chapter Problems and Bugs +If you are familiar with other @code{make} programs, see @ref{Features, +,Features of GNU @code{make}}, which lists the enhancements GNU +@code{make} has, and @ref{Missing, ,Incompatibilities and Missing +Features}, which explains the few things GNU @code{make} lacks that +others have. + +For a quick summary, see @ref{Options Summary}, @ref{Quick Reference}, +and @ref{Special Targets}. + +@node Bugs, , Reading, Overview +@section Problems and Bugs +@cindex reporting bugs +@cindex bugs, reporting +@cindex problems and bugs, reporting If you have problems with GNU @code{make} or think you've found a bug, -please report it to Roland McGrath; he doesn't promise to do anything -but he might well want to fix it. +please report it to the developers; we cannot promise to do anything but +we might well want to fix it. Before reporting a bug, make sure you've actually found a real bug. Carefully reread the documentation and see if it really says you can do what you're trying to do. If it's not clear whether you should be able -to do something or not, report that too; it's a bug in the documentation! +to do something or not, report that too; it's a bug in the +documentation! -Before reporting a bug or trying to fix it yourself, try to isolate it to -the smallest possible makefile that reproduces the problem. Then send -us the makefile and the exact results @code{make} gave you. Also say what -you expected to occur; this will help us decide whether the problem -was really in the documentation. - -Once you've got a precise problem, send email to (Internet) -@samp{bug-gnu-utils@@prep.ai.mit.edu} or (UUCP) -@samp{mit-eddie!prep.ai.mit.edu!bug-gnu-utils}. Please include the version -number of @code{make} you are using. You can get this information with the -command @samp{make -v -f /dev/null}.@refill - -Non-bug suggestions are always welcome as well. -If you have questions about things that are unclear in the documentation -or are just obscure features, ask Roland McGrath; he'll be happy to help -you out (but no promises). You can send him electronic mail at Internet -address @samp{roland@@prep.ai.mit.edu} or UUCP path -@samp{mit-eddie!prep.ai.mit.edu!roland}.@refill - -@node Simple, Makefiles, Bugs, Top -@chapter Simple Example of @code{make} - -Suppose we have a text editor consisting of eight C source files and three -header files. We need a makefile to tell @code{make} how to compile and -link the editor. Assume that all the C files include @file{defs.h}, but -only those defining editing commands include @file{commands.h} and only low -level files that change the editor buffer include @file{buffer.h}. +Before reporting a bug or trying to fix it yourself, try to isolate it +to the smallest possible makefile that reproduces the problem. Then +send us the makefile and the exact results @code{make} gave you. Also +say what you expected to occur; this will help us decide whether the +problem was really in the documentation. + +Once you've got a precise problem, please send electronic mail either +through the Internet or via UUCP: + +@example +@group +@r{Internet address:} + bug-gnu-utils@@prep.ai.mit.edu + +@r{UUCP path:} + mit-eddie!prep.ai.mit.edu!bug-gnu-utils +@end group +@end example + +@noindent +Please include the version number of @code{make} you are using. You can +get this information with the command @samp{make --version -f /dev/null}. +Be sure also to include the type of machine and operating system you are +using. If possible, include the contents of the file @file{config.h} +that is generated by the configuration process. + +Non-bug suggestions are always welcome as well. If you have questions +about things that are unclear in the documentation or are just obscure +features, contact Roland McGrath; he will try to help you out, although +he may not have time to fix the problem.@refill + +You can send electronic mail to Roland McGrath either through the +@w{Internet} or via UUCP: + +@example +@group +@r{Internet address:} + roland@@prep.ai.mit.edu + +@r{UUCP path:} + mit-eddie!prep.ai.mit.edu!roland +@end group +@end example + +@node Introduction, Makefiles, Overview, Top +@comment node-name, next, previous, up +@chapter An Introduction to Makefiles + +You need a file called a @dfn{makefile} to tell @code{make} what to do. +Most often, the makefile tells @code{make} how to compile and link a +program. +@cindex makefile + +In this chapter, we will discuss a simple makefile that describes how to +compile and link a text editor which consists of eight C source files +and three header files. The makefile can also tell @code{make} how to +run miscellaneous commands when explicitly asked (for example, to remove +certain files as a clean-up operation). To see a more complex example +of a makefile, see @ref{Complex Makefile}. + +When @code{make} recompiles the editor, each changed C source file +must be recompiled. If a header file has changed, each C source file +that includes the header file must be recompiled to be safe. Each +compilation produces an object file corresponding to the source file. +Finally, if any source file has been recompiled, all the object files, +whether newly made or saved from previous compilations, must be linked +together to produce the new executable editor. +@cindex recompilation +@cindex editor -To recompile the editor, each changed C source file must be recompiled. If -a header file has changed, to be safe each C source file that -includes the header file must be recompiled. Each compilation produces an -object file corresponding to the source file. Finally, if any source file -has been recompiled, all the object files, whether newly made or saved from -previous compilations, must be linked together to produce the new -executable editor. +@menu +* Rule Introduction:: What a rule looks like. +* Simple Makefile:: A Simple Makefile +* How Make Works:: How @code{make} Processes This Makefile +* Variables Simplify:: Variables Make Makefiles Simpler +* make Deduces:: Letting @code{make} Deduce the Commands +* Combine By Dependency:: Another Style of Makefile +* Cleanup:: Rules for Cleaning the Directory +@end menu + +@node Rule Introduction, Simple Makefile, , Introduction +@comment node-name, next, previous, up +@section What a Rule Looks Like +@cindex rule, introduction to +@cindex makefile rule parts +@cindex parts of makefile rule + +A simple makefile consists of ``rules'' with the following shape: + +@cindex targets, introduction to +@cindex dependencies, introduction to +@cindex commands, introduction to +@example +@group +@var{target} @dots{} : @var{dependencies} @dots{} + @var{command} + @dots{} + @dots{} +@end group +@end example + +A @dfn{target} is usually the name of a file that is generated by a +program; examples of targets are executable or object files. A target +can also be the name of an action to carry out, such as @samp{clean} +(@pxref{Phony Targets}). + +A @dfn{dependency} is a file that is used as input to create the +target. A target often depends on several files. + +@cindex tabs in rules +A @dfn{command} is an action that @code{make} carries out. +A rule may have more than one command, each on its own line. +@strong{Please note:} you need to put a tab character at the beginning of +every command line! This is an obscurity that catches the unwary. + +Usually a command is in a rule with dependencies and serves to create a +target file if any of the dependencies change. However, the rule that +specifies commands for the target need not have dependencies. For +example, the rule containing the delete command associated with the +target @samp{clean} does not have dependencies. + +A @dfn{rule}, then, explains how and when to remake certain files +which are the targets of the particular rule. @code{make} carries out +the commands on the dependencies to create or update the target. A +rule can also explain how and when to carry out an action. +@xref{Rules, , Writing Rules}. + +A makefile may contain other text besides rules, but a simple makefile +need only contain rules. Rules may look somewhat more complicated +than shown in this template, but all fit the pattern more or less. + +@node Simple Makefile, How Make Works, Rule Introduction, Introduction +@section A Simple Makefile +@cindex simple makefile +@cindex makefile, simple + +Here is a straightforward makefile that describes the way an +executable file called @code{edit} depends on eight object files +which, in turn, depend on eight C source and three header files. -Here is a straightforward makefile that describes these criteria and says -how to compile and link when the time comes: +In this example, all the C files include @file{defs.h}, but only those +defining editing commands include @file{command.h}, and only low +level files that change the editor buffer include @file{buffer.h}. @example -edit : main.o kbd.o commands.o display.o \ +@group +edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o - cc -o edit main.o kbd.o commands.o display.o \ + cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o main.o : main.c defs.h @@ -233,8 +605,8 @@ cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c -commands.o : command.c defs.h command.h - cc -c commands.c +command.o : command.c defs.h command.h + cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h @@ -245,110 +617,219 @@ cc -c files.c utils.o : utils.c defs.h cc -c utils.c +clean : + rm edit main.o kbd.o command.o display.o \ + insert.o search.o files.o utils.o +@end group @end example -We split each long line into two lines using a backslash-newline; this is +@noindent +We split each long line into two lines using backslash-newline; this is like using one long line, but is easier to read. +@cindex continuation lines +@cindex @code{\} (backslash), for continuation lines +@cindex backslash (@code{\}), for continuation lines +@cindex quoting newline, in makefile +@cindex newline, quoting, in makefile + +To use this makefile to create the executable file called @file{edit}, +type: + +@example +make +@end example + +To use this makefile to delete the executable file and all the object +files from the directory, type: + +@example +make clean +@end example -Each file that is generated by a program---that is to say, each file except -for source files---is the @dfn{target} of a @dfn{rule} (@pxref{Rules}). -(In this example, these are the object files such as @file{main.o}, -@file{kbd.o}, etc., and the executable file @file{edit}.) The target -appears at the beginning of a line, followed by a colon. - -After the colon come the target's @dfn{dependencies}: all the files that -are used as input when the target file is updated. A target file needs to -be recompiled or relinked if any of its dependencies changes. In addition, -any dependencies that are themselves automatically generated should be -updated first. In this example, @file{edit} depends on each of the eight -object files; the object file @file{main.o} depends on the source file -@file{main.c} and on the header file @file{defs.h}. +In the example makefile, the targets include the executable file +@samp{edit}, and the object files @samp{main.o} and @samp{kbd.o}. The +dependencies are files such as @samp{main.c} and @samp{defs.h}. +In fact, each @samp{.o} file is both a target and a dependency. +Commands include @w{@samp{cc -c main.c}} and @w{@samp{cc -c kbd.c}}. + +When a target is a file, it needs to be recompiled or relinked if any +of its dependencies change. In addition, any dependencies that are +themselves automatically generated should be updated first. In this +example, @file{edit} depends on each of the eight object files; the +object file @file{main.o} depends on the source file @file{main.c} and +on the header file @file{defs.h}. + +A shell command follows each line that contains a target and +dependencies. These shell commands say how to update the target file. +A tab character must come at the beginning of every command line to +distinguish commands lines from other lines in the makefile. (Bear in +mind that @code{make} does not know anything about how the commands +work. It is up to you to supply commands that will update the target +file properly. All @code{make} does is execute the commands in the rule +you have specified when the target file needs to be updated.) +@cindex shell command + +The target @samp{clean} is not a file, but merely the name of an +action. Since you +normally +do not want to carry out the actions in this rule, @samp{clean} is not a dependency of any other rule. +Consequently, @code{make} never does anything with it unless you tell +it specifically. Note that this rule not only is not a dependency, it +also does not have any dependencies, so the only purpose of the rule +is to run the specified commands. Targets that do not refer to files +but are just actions are called @dfn{phony targets}. @xref{Phony +Targets}, for information about this kind of target. @xref{Errors, , +Errors in Commands}, to see how to cause @code{make} to ignore errors +from @code{rm} or any other command. +@cindex @code{clean} target +@cindex @code{rm} (shell command) + +@node How Make Works, Variables Simplify, Simple Makefile, Introduction +@comment node-name, next, previous, up +@section How @code{make} Processes a Makefile +@cindex processing a makefile +@cindex makefile, how @code{make} processes By default, @code{make} starts with the first rule (not counting rules -whose target names start with @samp{.}). This is called the @dfn{default -goal}. Therefore, we put the rule for the executable program @file{edit} -first. The other rules are processed because their targets appear as -dependencies of the goal. - -After each line containing a target and dependencies come one or more lines -of shell commands that say how to update the target file. These lines -start with a tab to tell @code{make} that they are command lines. But -@code{make} does not know anything about how the commands work. It is up -to you to supply commands that will update the target file properly. -All @code{make} does is execute the commands you have specified when the -target file needs to be updated. - -@section How @code{make} Processes This Makefile - -After reading the makefile, @code{make} begins its real work by processing -the first rule, the one for relinking @file{edit}; but before it can fully -process this rule, it must process the rules for the files @file{edit} -depends on: all the object files. Each of these files is processed -according to its own rule. These rules say to update the @samp{.o} file by -compiling its source file. The recompilation must be done if the source -file, or any of the header files named as dependencies, is more recent than -the object file, or if the object file does not exist. +whose target names start with @samp{.}). This is called the +@dfn{default goal}. (@dfn{Goals} are the targets that @code{make} +strives ultimately to update. @xref{Goals, , Arguments to Specify the +Goals}.) +@cindex default goal +@cindex goal, default +@cindex goal + +In the simple example of the previous section, the default goal is to +update the executable program @file{edit}; therefore, we put that rule +first. + +Thus, when you give the command: +@example +make +@end example + +@noindent +@code{make} reads the makefile in the current directory and begins by +processing the first rule. In the example, this rule is for relinking +@file{edit}; but before @code{make} can fully process this rule, it +must process the rules for the files that @file{edit} depends on, +which in this case are the object files. Each of these files is +processed according to its own rule. These rules say to update each +@samp{.o} file by compiling its source file. The recompilation must +be done if the source file, or any of the header files named as +dependencies, is more recent than the object file, or if the object +file does not exist. + +The other rules are processed because their targets appear as +dependencies of the goal. If some other rule is not depended on by the +goal (or anything it depends on, etc.), that rule is not processed, +unless you tell @code{make} to do so (with a command such as +@w{@code{make clean}}). + Before recompiling an object file, @code{make} considers updating its dependencies, the source file and header files. This makefile does not specify anything to be done for them---the @samp{.c} and @samp{.h} files -are not the targets of any rules---so nothing needs to be done. But -automatically generated C programs, such as made by Bison or Yacc, would -be updated by their own rules at this time. +are not the targets of any rules---so @code{make} does nothing for these +files. But @code{make} would update automatically generated C programs, +such as those made by Bison or Yacc, by their own rules at this time. -After recompiling whichever object files need it, @code{make} can now -decide whether to relink @file{edit}. This must be done if the file +After recompiling whichever object files need it, @code{make} decides +whether to relink @file{edit}. This must be done if the file @file{edit} does not exist, or if any of the object files are newer than it. If an object file was just recompiled, it is now newer than -@file{edit}, so @file{edit} will be relinked. +@file{edit}, so @file{edit} is relinked. +@cindex relinking Thus, if we change the file @file{insert.c} and run @code{make}, @code{make} will compile that file to update @file{insert.o}, and then link @file{edit}. If we change the file @file{command.h} and run @code{make}, @code{make} will recompile the object files @file{kbd.o}, -@file{commands.o} and @file{files.o} and then link file @file{edit}. +@file{command.o} and @file{files.o} and then link the file @file{edit}. +@node Variables Simplify, make Deduces, How Make Works, Introduction @section Variables Make Makefiles Simpler +@cindex variables +@cindex simplifying with variables In our example, we had to list all the object files twice in the rule for @file{edit} (repeated here): @example -edit : main.o kbd.o commands.o display.o \ +@group +edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o - cc -o edit main.o kbd.o commands.o display.o \ + cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o +@end group @end example -@vindex objects +@cindex @code{objects} Such duplication is error-prone; if a new object file is added to the system, we might add it to one list and forget the other. We can eliminate -the risk and simplify the makefile by using a @dfn{variable}. Variables +the risk and simplify the makefile by using a variable. @dfn{Variables} allow a text string to be defined once and substituted in multiple places -later (@pxref{Variables}). +later (@pxref{Using Variables, ,How to Use Variables}). +@cindex @code{OBJECTS} +@cindex @code{objs} +@cindex @code{OBJS} +@cindex @code{obj} +@cindex @code{OBJ} It is standard practice for every makefile to have a variable named -@code{objects}, @code{OBJECTS}, @code{objs}, @code{OBJS}, @code{obj} or -@code{OBJ} which is a list of all object file names. We would define -such a variable @code{objects} with a line like this in the makefile:@refill +@code{objects}, @code{OBJECTS}, @code{objs}, @code{OBJS}, @code{obj}, +or @code{OBJ} which is a list of all object file names. We would +define such a variable @code{objects} with a line like this in the +makefile:@refill @example -objects = main.o kbd.o commands.o display.o \ - insert.o search.o files.o utils.o +@group +objects = main.o kbd.o command.o display.o \ + insert.o search.o files.o utils.o +@end group @end example @noindent Then, each place we want to put a list of the object file names, we can substitute the variable's value by writing @samp{$(objects)} -(@pxref{Variables}). Here is how the rule for @code{edit} looks as a -result: +(@pxref{Using Variables, ,How to Use Variables}). + +Here is how the complete simple makefile looks when you use a variable +for the object files: @example +@group +objects = main.o kbd.o command.o display.o \ + insert.o search.o files.o utils.o + edit : $(objects) cc -o edit $(objects) +main.o : main.c defs.h + cc -c main.c +kbd.o : kbd.c defs.h command.h + cc -c kbd.c +command.o : command.c defs.h command.h + cc -c command.c +display.o : display.c defs.h buffer.h + cc -c display.c +insert.o : insert.c defs.h buffer.h + cc -c insert.c +search.o : search.c defs.h buffer.h + cc -c search.c +files.o : files.c defs.h buffer.h command.h + cc -c files.c +utils.o : utils.c defs.h + cc -c utils.c +clean : + rm edit $(objects) +@end group @end example +@node make Deduces, Combine By Dependency, Variables Simplify, Introduction @section Letting @code{make} Deduce the Commands +@cindex deducing commands (implicit rules) +@cindex implicit rule, introduction to +@cindex rule, implicit, introduction to It is not necessary to spell out the commands for compiling the individual C source files, because @code{make} can figure them out: it has an @@ -356,7 +837,7 @@ named @samp{.c} file using a @samp{cc -c} command. For example, it will use the command @samp{cc -c main.c -o main.o} to compile @file{main.c} into @file{main.o}. We can therefore omit the commands from the rules for the -object files. @xref{Implicit}.@refill +object files. @xref{Implicit Rules, ,Using Implicit Rules}.@refill When a @samp{.c} file is used automatically in this way, it is also automatically added to the list of dependencies. We can therefore omit @@ -366,8 +847,9 @@ @code{objects} as suggested above: @example -objects = main.o kbd.o commands.o display.o \ - insert.o search.o files.o utils.o +@group +objects = main.o kbd.o command.o display.o \ + insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) @@ -374,38 +856,53 @@ main.o : defs.h kbd.o : defs.h command.h -commands.o : defs.h command.h +command.o : defs.h command.h display.o : defs.h buffer.h insert.o : defs.h buffer.h search.o : defs.h buffer.h files.o : defs.h buffer.h command.h utils.o : defs.h + +.PHONY : clean +clean : + -rm edit $(objects) +@end group @end example @noindent -This is how we would write the makefile in actual practice. +This is how we would write the makefile in actual practice. (The +complications associated with @samp{clean} are described elsewhere. +See @ref{Phony Targets}, and @ref{Errors, ,Errors in Commands}.) + +Because implicit rules are so convenient, they are important. You +will see them used frequently.@refill +@node Combine By Dependency, Cleanup, make Deduces, Introduction @section Another Style of Makefile +@cindex combining rules by dependency -Since the rules for the object files specify only dependencies, no -commands, one can alternatively combine them by dependency instead of by -target. Here is what it looks like: +When the objects of a makefile are created only by implicit rules, an +alternative style of makefile is possible. In this style of makefile, +you group entries by their dependencies instead of by their targets. +Here is what one looks like: @example -objects = main.o kbd.o commands.o display.o \ - insert.o search.o files.o utils.o +@group +objects = main.o kbd.o command.o display.o \ + insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) $(objects) : defs.h -kbd.o commands.o files.o : command.h +kbd.o command.o files.o : command.h display.o insert.o search.o files.o : buffer.h +@end group @end example @noindent Here @file{defs.h} is given as a dependency of all the object files; -@file{commands.h} and @file{buffer.h} are dependencies of the specific +@file{command.h} and @file{buffer.h} are dependencies of the specific object files listed for them. Whether this is better is a matter of taste: it is more compact, but some @@ -412,86 +909,127 @@ people dislike it because they find it clearer to put all the information about each target in one place. +@node Cleanup, , Combine By Dependency, Introduction @section Rules for Cleaning the Directory +@cindex cleaning up +@cindex removing, to clean up -Compiling a program isn't the only thing you might want to write rules +Compiling a program is not the only thing you might want to write rules for. Makefiles commonly tell how to do a few other things besides -compiling the program: for example, how to delete all the object files -and executables so that the directory is ``clean''. Here is how we -would write a @code{make} rule for cleaning our example editor: +compiling a program: for example, how to delete all the object files +and executables so that the directory is @samp{clean}. +@cindex @code{clean} target +Here is how we +could write a @code{make} rule for cleaning our example editor: + @example +@group clean: rm edit $(objects) +@end group +@end example + +In practice, we might want to write the rule in a somewhat more +complicated manner to handle unanticipated situations. We would do this: + +@example +@group +.PHONY : clean +clean : + -rm edit $(objects) +@end group @end example @noindent -This rule would be added at the end of the makefile, because we don't -want it to run by default! We want the rule for @code{edit}, which -recompiles the editor, to remain the default goal. +This prevents @code{make} from getting confused by an actual file +called @file{clean} and causes it to continue in spite of errors from +@code{rm}. (See @ref{Phony Targets}, and @ref{Errors, ,Errors in +Commands}.) + +@noindent +A rule such as this should not be placed at the beginning of the +makefile, because we do not want it to run by default! Thus, in the +example makefile, we want the rule for @code{edit}, which recompiles +the editor, to remain the default goal. -Since @code{clean} is not a dependency of @code{edit}, this rule won't +Since @code{clean} is not a dependency of @code{edit}, this rule will not run at all if we give the command @samp{make} with no arguments. In order to make the rule run, we have to type @samp{make clean}. +@xref{Running, ,How to Run @code{make}}. -@node Makefiles, Rules, Simple, Top +@node Makefiles, Rules, Introduction, Top @chapter Writing Makefiles -@cindex makefile +@cindex makefile, how to write The information that tells @code{make} how to recompile a system comes from reading a data base called the @dfn{makefile}. @menu -* Contents: Makefile Contents. Overview of what you put in a makefile. -* Names: Makefile Names. Where @code{make} finds the makefile. -* Include:: How one makefile can use another makefile. -* MAKEFILES Variable:: The environment can specify extra makefiles. -* Remaking Makefiles:: How makefiles get remade. -* Overriding Makefiles:: How to override part of one makefile +* Makefile Contents:: What makefiles contain. +* Makefile Names:: How to name your makefile. +* Include:: How one makefile can use another makefile. +* MAKEFILES Variable:: The environment can specify extra makefiles. +* Remaking Makefiles:: How makefiles get remade. +* Overriding Makefiles:: How to override part of one makefile with another makefile. @end menu -@node Makefile Contents, Makefile Names, Makefiles, Makefiles +@node Makefile Contents, Makefile Names, , Makefiles @section What Makefiles Contain -Makefiles contain four kinds of things: @dfn{rules}, @dfn{variable -definitions}, @dfn{directives} and @dfn{comments}. Rules, variables and -directives are described at length in later chapters.@refill +Makefiles contain five kinds of things: @dfn{explicit rules}, +@dfn{implicit rules}, @dfn{variable definitions}, @dfn{directives}, +and @dfn{comments}. Rules, variables, and directives are described at +length in later chapters.@refill @itemize @bullet +@cindex rule, explicit, definition of +@cindex explicit rule, definition of +@item +An @dfn{explicit rule} says when and how to remake one or more files, +called the rule's targets. It lists the other files that the targets +@dfn{depend on}, and may also give commands to use to create or update +the targets. @xref{Rules, ,Writing Rules}. + +@cindex rule, implicit, definition of +@cindex implicit rule, definition of @item -A rule says when and how to remake one or more files, called the rule's -@dfn{targets}. It lists the other files that the targets @dfn{depend on}, -and may also give commands to use to create or update the targets. -@xref{Rules}. +An @dfn{implicit rule} says when and how to remake a class of files +based on their names. It describes how a target may depend on a file +with a name similar to the target and gives commands to create or +update such a target. @xref{Implicit Rules, ,Using Implicit Rules}. +@cindex variable definition @item -A variable definition is a line that specifies a text string value -for a @dfn{variable} that can be substituted into the text later. -The simple makefile example (@pxref{Simple}) shows a variable definition -for @code{objects} as a list of all object files. -@xref{Variables}, for full details. +A @dfn{variable definition} is a line that specifies a text string +value for a variable that can be substituted into the text later. The +simple makefile example shows a variable definition for @code{objects} +as a list of all object files (@pxref{Variables Simplify, , Variables +Make Makefiles Simpler}). +@cindex directive @item -A directive is a command for @code{make} to do something special while +A @dfn{directive} is a command for @code{make} to do something special while reading the makefile. These include: @itemize @bullet @item -Reading another makefile (@pxref{Include}). +Reading another makefile (@pxref{Include, ,Including Other Makefiles}). @item Deciding (based on the values of variables) whether to use or -ignore a part of the makefile (@pxref{Conditionals}). +ignore a part of the makefile (@pxref{Conditionals, ,Conditional Parts of Makefiles}). @item Defining a variable from a verbatim string containing multiple lines -(@pxref{Defining}). +(@pxref{Defining, ,Defining Variables Verbatim}). @end itemize +@cindex comments, in makefile +@cindex @code{#} (comments), in makefile @item -@cindex comments -@samp{#} in a line of a makefile starts a comment. It and the rest of +@samp{#} in a line of a makefile starts a @dfn{comment}. It and the rest of the line are ignored, except that a trailing backslash not escaped by another backslash will continue the comment across multiple lines. Comments may appear on any of the lines in the makefile, except within a @@ -502,13 +1040,20 @@ @node Makefile Names, Include, Makefile Contents, Makefiles @section What Name to Give Your Makefile -@cindex makefile names -@cindex names of makefiles -@cindex default makefile names +@cindex makefile name +@cindex name of makefile +@cindex default makefile name +@cindex file name of makefile + +@c following paragraph rewritten to avoid overfull hbox +By default, when @code{make} looks for the makefile, it tries the +following names, in order: @file{GNUmakefile}, @file{makefile} +and @file{Makefile}.@refill +@findex Makefile +@findex GNUmakefile +@findex makefile -By default, when @code{make} looks for the makefile, it tries the names -@file{GNUmakefile}, @file{makefile} and @file{Makefile}, in that order. - +@cindex @code{README} Normally you should call your makefile either @file{makefile} or @file{Makefile}. (We recommend @file{Makefile} because it appears prominently near the beginning of a directory listing, right near other @@ -516,71 +1061,124 @@ @file{GNUmakefile}, is not recommended for most makefiles. You should use this name if you have a makefile that is specific to GNU @code{make}, and will not be understood by other versions of -@code{make}. +@code{make}. Other @code{make} programs look for @file{makefile} and +@file{Makefile}, but not @file{GNUmakefile}. If @code{make} finds none of these names, it does not use any makefile. Then you must specify a goal with a command argument, and @code{make} will attempt to figure out how to remake it using only its built-in -implicit rules. @xref{Implicit}. +implicit rules. @xref{Implicit Rules, ,Using Implicit Rules}. @cindex @code{-f} +@cindex @code{--file} +@cindex @code{--makefile} If you want to use a nonstandard name for your makefile, you can specify -the makefile name with the @samp{-f} option. The arguments @samp{-f -@var{name}} tell @code{make} to read the file @var{name} as the -makefile. If you use more than one @samp{-f} option, you can specify -several makefiles. All the makefiles are effectively concatenated in -the order specified. The default makefile names @file{GNUmakefile}, +the makefile name with the @samp{-f} or @samp{--file} option. The +arguments @w{@samp{-f @var{name}}} or @w{@samp{--file @var{name}}} tell +@code{make} to read the file @var{name} as the makefile. If you use +more than one @samp{-f} or @samp{--file} option, you can specify several +makefiles. All the makefiles are effectively concatenated in the order +specified. The default makefile names @file{GNUmakefile}, @file{makefile} and @file{Makefile} are not checked automatically if you -specify @samp{-f}.@refill +specify @samp{-f} or @samp{--file}.@refill +@cindex specifying makefile name +@cindex makefile name, how to specify +@cindex name of makefile, how to specify +@cindex file name of makefile, how to specify @node Include, MAKEFILES Variable, Makefile Names, Makefiles @section Including Other Makefiles +@cindex including other makefiles +@cindex makefile, including @findex include The @code{include} directive tells @code{make} to suspend reading the -current makefile and read another makefile before continuing. The -directive is a line in the makefile that looks like this: +current makefile and read one or more other makefiles before continuing. +The directive is a line in the makefile that looks like this: + +@example +include @var{filenames}@dots{} +@end example + +@noindent +@var{filenames} can contain shell file name patterns. +@cindex shell file name pattern (in @code{include}) +@cindex shell wildcards (in @code{include}) +@cindex wildcard, in @code{include} +Extra spaces are allowed and ignored at the beginning of the line, but +a tab is not allowed. (If the line begins with a tab, it will be +considered a command line.) Whitespace is required between +@code{include} and the file names, and between file names; extra +whitespace is ignored there and at the end of the directive. A +comment starting with @samp{#} is allowed at the end of the line. If +the file names contain any variable or function references, they are +expanded. @xref{Using Variables, ,How to Use Variables}. + +For example, if you have three @file{.mk} files, @file{a.mk}, +@file{b.mk}, and @file{c.mk}, and @code{$(bar)} expands to +@code{bish bash}, then the following expression + @example -include @var{filename} +include foo *.mk $(bar) @end example -Extra spaces are allowed and ignored at the beginning of the line, but a -tab is not allowed. (If the line begins with a tab, it will be considered -a command line.) Whitespace is required between @code{include} and -@var{filename}; extra whitespace is ignored there and at the end of the -directive. A comment starting with @samp{#} is allowed at the end of the -line. If @var{filename} contains any variable or function references, they -are expanded. (@xref{Variables}.) +is equivalent to + +@example +include foo a.mk b.mk c.mk bish bash +@end example When @code{make} processes an @code{include} directive, it suspends -reading of the containing makefile and reads from @var{filename} -instead. When that is finished, @code{make} resumes reading the +reading of the containing makefile and reads from each listed file in +turn. When that is finished, @code{make} resumes reading the makefile in which the directive appears. One occasion for using @code{include} directives is when several programs, handled by individual makefiles in various directories, need to use a -common set of variable definitions (@pxref{Setting}) or pattern rules -(@pxref{Pattern Rules}). - -Another such occasion is when you want to automatically generate -dependencies from source files; the dependencies can be put in a file that -is included by the main makefile. This practice is generally cleaner than -that of somehow appending the dependencies to the end of the main makefile -as has been traditionally done with other versions of @code{make}. - +common set of variable definitions +(@pxref{Setting, ,Setting Variables}) or pattern rules +(@pxref{Pattern Rules, ,Defining and Redefining Pattern Rules}). + +Another such occasion is when you want to generate dependencies from +source files automatically; the dependencies can be put in a file that +is included by the main makefile. This practice is generally cleaner +than that of somehow appending the dependencies to the end of the main +makefile as has been traditionally done with other versions of +@code{make}. @xref{Automatic Dependencies}. +@cindex dependencies, automatic generation +@cindex automatic generation of dependencies +@cindex generating dependencies automatically + +@cindex @code{-I} +@cindex @code{--include-dir} +@findex /usr/gnu/include +@findex /usr/local/include +@findex /usr/include If the specified name does not start with a slash, and the file is not found in the current directory, several other directories are searched. -First, any directories you have specified with the @samp{-I} option are -searched (@pxref{Options}). Then the following directories (if they -exist) are searched, in this order: @file{/usr/gnu/include}, -@file{/usr/local/include}, @file{/usr/include}. +First, any directories you have specified with the @samp{-I} or +@samp{--include-dir} option are searched +(@pxref{Options Summary, ,Summary of Options}). +Then the following directories (if they exist) +are searched, in this order: +@file{@var{prefix}/include} (normally @file{/usr/local/include}) +@file{/usr/gnu/include}, +@file{/usr/local/include}, @file{/usr/include}. + If an included makefile cannot be found in any of these directories, a -warning message is generated, but it is not a fatal error; processing -of the makefile containing the @code{include} continues.@refill +warning message is generated, but it is not an immediately fatal error; +processing of the makefile containing the @code{include} continues. +Once it has finished reading makefiles, @code{make} will try to remake +any that are out of date or don't exist. +@xref{Remaking Makefiles, ,How Makefiles Are Remade}. +Only after it has tried to find a way to remake a makefile and failed, +will @code{make} diagnose the missing makefile as a fatal error. @node MAKEFILES Variable, Remaking Makefiles, Include, Makefiles @section The Variable @code{MAKEFILES} +@cindex makefile, and @code{MAKEFILES} variable +@cindex including (@code{MAKEFILES} variable) @vindex MAKEFILES If the environment variable @code{MAKEFILES} is defined, @code{make} @@ -587,23 +1185,25 @@ considers its value as a list of names (separated by whitespace) of additional makefiles to be read before the others. This works much like the @code{include} directive: various directories are searched for those -files (@pxref{Include}). In addition, the default goal is never taken -from one of these makefiles and it is not an error if the files listed -in @code{MAKEFILES} are not found.@refill +files (@pxref{Include, ,Including Other Makefiles}). In addition, the +default goal is never taken from one of these makefiles and it is not an +error if the files listed in @code{MAKEFILES} are not found.@refill +@cindex recursion, and @code{MAKEFILES} variable The main use of @code{MAKEFILES} is in communication between recursive -invocations of @code{make} (@pxref{Recursion}). It usually isn't -desirable to set the environment variable before a top-level invocation -of @code{make}, because it is usually better not to mess with a makefile -from outside. However, if you are running @code{make} without a specific -makefile, a makefile in @code{MAKEFILES} can do useful things to help the -built-in implicit rules work better, such as defining search paths. +invocations of @code{make} (@pxref{Recursion, ,Recursive Use of +@code{make}}). It usually is not desirable to set the environment +variable before a top-level invocation of @code{make}, because it is +usually better not to mess with a makefile from outside. However, if +you are running @code{make} without a specific makefile, a makefile in +@code{MAKEFILES} can do useful things to help the built-in implicit +rules work better, such as defining search paths (@pxref{Directory Search}). Some users are tempted to set @code{MAKEFILES} in the environment automatically on login, and program makefiles to expect this to be done. This is a very bad idea, because such makefiles will fail to work if run by anyone else. It is much better to write explicit @code{include} directives -in the makefiles. +in the makefiles. @xref{Include, , Including Other Makefiles}. @node Remaking Makefiles, Overriding Makefiles, MAKEFILES Variable, Makefiles @section How Makefiles Are Remade @@ -610,7 +1210,7 @@ @cindex updating makefiles @cindex remaking makefiles -@cindex makefiles, remaking of +@cindex makefile, remaking of Sometimes makefiles can be remade from other files, such as RCS or SCCS files. If a makefile can be remade from other files, you probably want @code{make} to get an up-to-date version of the makefile to read in. @@ -618,25 +1218,29 @@ To this end, after reading in all makefiles, @code{make} will consider each as a goal target and attempt to update it. If a makefile has a rule which says how to update it (found either in that very makefile or -in another one) or if an implicit rule applies to it (@pxref{Implicit}), -it will be updated if necessary. After all makefiles have been checked, -if any have actually been changed, @code{make} starts with a clean slate -and reads all the makefiles over again. (It will also attempt to update -each of them over again, but normally this will not change them again, -since they are already up to date.)@refill - -If the makefiles specify commands to remake a file but no dependencies, -the file will always be remade. In the case of makefiles, a makefile -that has commands but no dependencies will be remade every time -@code{make} is run, and then again after @code{make} starts over and -reads the makefiles in again. This would cause an infinite loop; +in another one) or if an implicit rule applies to it (@pxref{Implicit +Rules, ,Using Implicit Rules}), it will be updated if necessary. After +all makefiles have been checked, if any have actually been changed, +@code{make} starts with a clean slate and reads all the makefiles over +again. (It will also attempt to update each of them over again, but +normally this will not change them again, since they are already up to +date.)@refill + +If the makefiles specify a double-colon rule to remake a file with +commands but no dependencies, that file will always be remade +(@pxref{Double-Colon}). In the case of makefiles, a makefile that has a +double-colon rule with commands but no dependencies will be remade every +time @code{make} is run, and then again after @code{make} starts over +and reads the makefiles in again. This would cause an infinite loop: @code{make} would constantly remake the makefile, and never do anything -else. So, to avoid this, @code{make} will @emph{not} attempt to remake -makefiles which are specified as targets but have no dependencies.@refill - -If you do not specify any makefiles to be read with @samp{-f} options, -@code{make} will try the default makefile names; @pxref{Makefile Names}. -Unlike makefiles explicitly requested with @samp{-f} options, +else. So, to avoid this, @code{make} will @strong{not} attempt to +remake makefiles which are specified as double-colon targets but have no +dependencies.@refill + +If you do not specify any makefiles to be read with @samp{-f} or +@samp{--file} options, @code{make} will try the default makefile names; +@pxref{Makefile Names, ,What Name to Give Your Makefile}. Unlike +makefiles explicitly requested with @samp{-f} or @samp{--file} options, @code{make} is not certain that these makefiles should exist. However, if a default makefile does not exist but can be created by running @code{make} rules, you probably want the rules to be run so that the @@ -644,18 +1248,21 @@ Therefore, if none of the default makefiles exists, @code{make} will try to make each of them in the same order in which they are searched for -(@pxref{Makefile Names}) until it succeeds in making one, or it runs out -of names to try. Note that it is not an error if @code{make} cannot -find or make any makefile; a makefile is not always necessary.@refill - -When you use the @samp{-t} option (touch targets), you would not want to -use an out-of-date makefile to decide which targets to touch. So the -@samp{-t} option has no effect on updating makefiles; they are really -updated even if @samp{-t} is specified. Likewise, @samp{-q} and -@samp{-n} do not prevent updating of makefiles, because an out-of-date -makefile would result in the wrong output for other targets. Thus, -@samp{make -f mfile -n foo} will update @file{mfile}, read it in, and -then print the commands to update @file{foo} and its dependencies +(@pxref{Makefile Names, ,What Name to Give Your Makefile}) +until it succeeds in making one, or it runs out of names to try. Note +that it is not an error if @code{make} cannot find or make any makefile; +a makefile is not always necessary.@refill + +When you use the @samp{-t} or @samp{--touch} option +(@pxref{Instead of Execution, ,Instead of Executing the Commands}), +you would not want to use an out-of-date makefile to decide which +targets to touch. So the @samp{-t} option has no effect on updating +makefiles; they are really updated even if @samp{-t} is specified. +Likewise, @samp{-q} (or @samp{--question}) and @samp{-n} (or +@samp{--just-print}) do not prevent updating of makefiles, because an +out-of-date makefile would result in the wrong output for other targets. +Thus, @samp{make -f mfile -n foo} will update @file{mfile}, read it in, +and then print the commands to update @file{foo} and its dependencies without running them. The commands printed for @file{foo} will be those specified in the updated contents of @file{mfile}. @@ -672,9 +1279,10 @@ specified by the existing contents of @file{mfile}. @node Overriding Makefiles, , Remaking Makefiles, Makefiles -@section Overriding Part of One Makefile with Another Makefile +@section Overriding Part of Another Makefile @cindex overriding makefiles +@cindex makefile, overriding Sometimes it is useful to have a makefile that is mostly just like another makefile. You can often use the @samp{include} directive to include one in the other, and add more targets or variable definitions. @@ -681,11 +1289,13 @@ However, if the two makefiles give different commands for the same target, @code{make} will not let you just do this. But there is another way. +@cindex @code{.DEFAULT}, used to override In the containing makefile (the one that wants to include the other), -you can use the @code{.DEFAULT} special target to say that to remake any -target that cannot be made from the information in the containing -makefile, @code{make} should look in another makefile. @xref{Last -Resort}, for more information on @code{.DEFAULT}. +you can use the @code{.DEFAULT} special target to say that to remake +any target that cannot be made from the information in the containing +makefile, @code{make} should look in another makefile. +@xref{Last Resort, , Defining Last-Resort Default Rules}, +for more information on @code{.DEFAULT}. For example, if you have a makefile called @file{Makefile} that says how to make the target @samp{foo} (and other targets), you can write a @@ -710,53 +1320,59 @@ @node Rules, Commands, Makefiles, Top @chapter Writing Rules - -@cindex rule +@cindex writing rules +@cindex rule, how to write @cindex target @cindex dependency + A @dfn{rule} appears in the makefile and says when and how to remake -certain files, called the rule's @dfn{targets} (usually only one per rule). +certain files, called the rule's @dfn{targets} (most often only one per rule). It lists the other files that are the @dfn{dependencies} of the target, and @dfn{commands} to use to create or update the target. +@cindex default goal +@cindex goal, default The order of rules is not significant, except for determining the @dfn{default goal}: the target for @code{make} to consider, if you do not otherwise specify one. The default goal is the target of the first -rule in the first makefile, except that targets starting with a period -do not count unless they contain slashes as well; also, a target that -defines a pattern rule (@pxref{Pattern Rules}) or a suffix rule -(@pxref{Suffix Rules}) has no effect on the default goal. +rule in the first makefile. If the first rule has multiple targets, +only the first target is taken as the default. There are two +exceptions: a target starting with a period is not a default unless it +contains one or more slashes, @samp{/}, as well; and, a target that +defines a pattern rule has no effect on the default goal. +(@xref{Pattern Rules, ,Defining and Redefining Pattern Rules}.) Therefore, we usually write the makefile so that the first rule is the one for compiling the entire program or all the programs described by -the makefile. @xref{Goals}. +the makefile (often with a target called @samp{all}). +@xref{Goals, ,Arguments to Specify the Goals}. @menu -* Rule Example:: An explained example of a rule. -* Rule Syntax:: General syntax of rules, with explanation. - -* Wildcards:: Using wildcard characters like `*' in file names. -* Directory Search:: Searching other directories for source files. - -* Phony Targets:: Using a target that isn't a real file's name. -* Force Targets:: A target without commands or dependencies can - be used to mark other targets as phony. -* Special Targets:: Targets with special built-in meanings. -* Empty Targets:: Real files that are empty--only the date matters. -* Multiple Targets:: When it is useful to have several targets in a rule. -* Static Pattern:: Static pattern rules apply to multiple targets - and can vary the dependencies according to the - target name. -* Multiple Rules:: Using several rules with the same target. -* Double-Colon:: Special kind of rule allowing - several independent rules for one target. -* Commands:: Special features and details of how commands - in a rule are executed. +* Rule Example:: An example explained. +* Rule Syntax:: General syntax explained. +* Wildcards:: Using wildcard characters such as `*'. +* Directory Search:: Searching other directories for source files. +* Phony Targets:: Using a target that is not a real file's name. +* Force Targets:: You can use a target without commands + or dependencies to mark other + targets as phony. +* Empty Targets:: When only the date matters and the + files are empty. +* Special Targets:: Targets with special built-in meanings. +* Multiple Targets:: When to make use of several targets in a rule. +* Multiple Rules:: How to use several rules with the same target. +* Static Pattern:: Static pattern rules apply to multiple targets + and can vary the dependencies according to + the target name. +* Double-Colon:: How to use a special kind of rule to allow + several independent rules for one target. +* Automatic Dependencies:: How to automatically generate rules giving + dependencies from the source files themselves. @end menu @ifinfo -@node Rule Example, Rule Syntax, Rules, Rules -@isection Rule Example +@node Rule Example, Rule Syntax, , Rules +@section Rule Example Here is an example of a rule: @@ -788,13 +1404,14 @@ @node Rule Syntax, Wildcards, Rule Example, Rules @section Rule Syntax +@cindex rule syntax +@cindex syntax of rules In general, a rule looks like this: @example @var{targets} : @var{dependencies} @var{command} - @var{command} - ... + @dots{} @end example @noindent @@ -803,25 +1420,34 @@ @example @var{targets} : @var{dependencies} ; @var{command} @var{command} - @var{command} - ... + @dots{} @end example -The @var{targets} are file names, separated by spaces. Wild card -characters may be used (@pxref{Wildcards}) and a name of the form -@file{@var{a}(@var{m})} represents member @var{m} in archive file -@var{a} (@pxref{Archive Members}). Usually there is only one target -per rule, but occasionally there is a reason to have more; @xref{Multiple -Targets}.@refill +@cindex targets +@cindex rule targets +The @var{targets} are file names, separated by spaces. Wildcard +characters may be used (@pxref{Wildcards, ,Using Wildcard Characters +in File Names}) and a name of the form @file{@var{a}(@var{m})} +represents member @var{m} in archive file @var{a} +(@pxref{Archive Members, ,Archive Members as Targets}). +Usually there is only one +target per rule, but occasionally there is a reason to have more +(@pxref{Multiple Targets, , Multiple Targets in a Rule}).@refill +@cindex commands +@cindex tab character (in commands) The @var{command} lines start with a tab character. The first command may appear on the line after the dependencies, with a tab character, or may appear on the same line, with a semicolon. Either way, the effect is the -same. @xref{Commands}. +same. @xref{Commands, ,Writing the Commands in Rules}. +@cindex dollar sign (@code{$}) in rules +@cindex @code{$}, in rules +@cindex rule, and @code{$} Because dollar signs are used to start variable references, if you really -want a dollar sign in the rule you must write two of them (@samp{$$}). -@xref{Variables}. You may split a long line by inserting a backslash +want a dollar sign in a rule you must write two of them, @samp{$$} +(@pxref{Using Variables, ,How to Use Variables}). +You may split a long line by inserting a backslash followed by a newline, but this is not required, as @code{make} places no limit on the length of a line in a makefile. @@ -828,24 +1454,31 @@ A rule tells @code{make} two things: when the targets are out of date, and how to update them when necessary. +@cindex dependencies +@cindex rule dependencies The criterion for being out of date is specified in terms of the @var{dependencies}, which consist of file names separated by spaces. -(Wildcards and archive members are allowed here too.) A target is out of -date if it does not exist or if it is older than any of the dependencies -(by comparison of last-modification times). The idea is that the contents -of the target file are computed based on information in the dependencies, -so if any of the dependencies changes, the contents of the existing target -file are no longer necessarily valid. +(Wildcards and archive members (@pxref{Archives}) are allowed here too.) +A target is out of date if it does not exist or if it is older than any +of the dependencies (by comparison of last-modification times). The +idea is that the contents of the target file are computed based on +information in the dependencies, so if any of the dependencies changes, +the contents of the existing target file are no longer necessarily +valid. How to update is specified by @var{commands}. These are lines to be executed by the shell (normally @samp{sh}), but with some extra features -(@pxref{Commands}). +(@pxref{Commands, ,Writing the Commands in Rules}). @node Wildcards, Directory Search, Rule Syntax, Rules -@section Using Wildcards Characters in File Names +@section Using Wildcard Characters in File Names @cindex wildcard -@cindex file name +@cindex file name with wildcards +@cindex globbing (wildcards) +@cindex @code{*} (wildcard character) +@cindex @code{?} (wildcard character) +@cindex @code{[@dots{}]} (wildcard characters) A single file name can specify many files using @dfn{wildcard characters}. The wildcard characters in @code{make} are @samp{*}, @samp{?} and @samp{[@dots{}]}, the same as in the Bourne shell. For example, @file{*.c} @@ -852,17 +1485,20 @@ specifies a list of all the files (in the working directory) whose names end in @samp{.c}.@refill -@cindex ~ +@cindex @code{~} (tilde) +@cindex tilde (@code{~}) +@cindex home directory The character @samp{~} at the beginning of a file name also has special significance. If alone, or followed by a slash, it represents your home directory. For example @file{~/bin} expands to @file{/home/you/bin}. If the @samp{~} is followed by a word, the string represents the home -directory of the user named by that word. For example @file{~me/bin} -expands to @file{/home/me/bin}.@refill +directory of the user named by that word. For example @file{~john/bin} +expands to @file{/home/john/bin}.@refill -Wildcard expansion happens automatically in targets, in dependencies, and -in commands. In other contexts, wildcard expansion happens only if you -request it explicitly with the @code{wildcard} function. +Wildcard expansion happens automatically in targets, in dependencies, +and in commands (where the shell does the expansion). In other +contexts, wildcard expansion happens only if you request it explicitly +with the @code{wildcard} function. The special significance of a wildcard character can be turned off by preceding it with a backslash. Thus, @file{foo\*bar} would refer to a @@ -870,23 +1506,25 @@ @samp{bar}.@refill @menu -* Examples: Wildcard Examples. Some simple examples. -* Pitfall: Wildcard Pitfall. @code{*.o} won't do what you want! -* Function: Wildcard Function. - How to do wildcard expansion when defining a variable - using the function @code{wildcard}. +* Wildcard Examples:: Several examples +* Wildcard Pitfall:: Problems to avoid. +* Wildcard Function:: How to cause wildcard expansion where + it does not normally take place. @end menu -@node Wildcard Examples, Wildcard Pitfall, Wildcards, Wildcards +@node Wildcard Examples, Wildcard Pitfall, , Wildcards @subsection Wildcard Examples -Wildcards can be used in the commands of a rule. For example, here is a -rule to delete all the object files: +Wildcards can be used in the commands of a rule, where they are expanded +by the shell. For example, here is a rule to delete all the object files: @example +@group clean: rm -f *.o +@end group @end example +@cindex @code{rm} (shell command) Wildcards are also useful in the dependencies of a rule. With the following rule in the makefile, @samp{make print} will print all the @@ -898,14 +1536,20 @@ touch print @end example -@noindent -This rule uses @file{print} as an empty target file; @pxref{Empty Targets}. +@cindex @code{print} target +@cindex @code{lpr} (shell command) +@cindex @code{touch} (shell command) +@noindent +This rule uses @file{print} as an empty target file; see @ref{Empty +Targets, ,Empty Target Files to Record Events}. (The automatic variable +@samp{$?} is used to print only those files that have changed; see +@ref{Automatic, ,Automatic Variables}.)@refill Wildcard expansion does not happen when you define a variable. Thus, if you write this: @example -objects=*.o +objects = *.o @end example @noindent @@ -912,9 +1556,22 @@ then the value of the variable @code{objects} is the actual string @samp{*.o}. However, if you use the value of @code{objects} in a target, dependency or command, wildcard expansion will take place at that time. +To set @code{objects} to the expansion, instead use: +@example +objects := $(wildcard *.o) +@end example + +@noindent +@xref{Wildcard Function}. + @node Wildcard Pitfall, Wildcard Function, Wildcard Examples, Wildcards @subsection Pitfalls of Using Wildcards +@cindex wildcard pitfalls +@cindex pitfalls of wildcards +@cindex mistakes with wildcards +@cindex errors with wildcards +@cindex problems with wildcards Now here is an example of a naive way of using wildcard expansion, that does not do what you would intend. Suppose you would like to say that the @@ -922,7 +1579,7 @@ directory, and you write this: @example -objects=*.o +objects = *.o foo : $(objects) cc -o foo $(CFLAGS) $(objects) @@ -943,7 +1600,7 @@ expansion, but you need more sophisticated techniques, including the @code{wildcard} function and string substitution. @ifinfo -@xref{Wildcard Function}. +@xref{Wildcard Function, ,The Function @code{wildcard}}. @end ifinfo @iftex These are described in the following section. @@ -974,80 +1631,93 @@ @end example We can change the list of C source files into a list of object files by -substituting @samp{.o} for @samp{.c} in the result, like this: +replacing the @samp{.o} suffix with @samp{.c} in the result, like this: @example -$(subst .c,.o,$(wildcard *.c)) +$(patsubst %.c,%.o,$(wildcard *.c)) @end example @noindent -(Here we have used another function, @code{subst}. -@xref{Text Functions}.)@refill +(Here we have used another function, @code{patsubst}. +@xref{Text Functions, ,Functions for String Substitution and Analysis}.)@refill Thus, a makefile to compile all C source files in the directory and then link them together could be written as follows: @example -objects:=$(subst .c,.o,$(wildcard *.c)) +objects := $(patsubst %.c,%.o,$(wildcard *.c)) foo : $(objects) - cc -o foo $(LDFLAGS) $(objects) + cc -o foo $(objects) @end example @noindent (This takes advantage of the implicit rule for compiling C programs, so there is no need to write explicit rules for compiling the files. -@xref{Flavors}, for an explanation of @samp{:=}, which is a variant of -@samp{=}.) +@xref{Flavors, ,The Two Flavors of Variables}, for an explanation of +@samp{:=}, which is a variant of @samp{=}.) @node Directory Search, Phony Targets, Wildcards, Rules @section Searching Directories for Dependencies @vindex VPATH @findex vpath -@cindex vpath -@cindex search path for dependencies -@cindex directory search +@cindex vpath +@cindex search path for dependencies (@code{VPATH}) +@cindex directory search (@code{VPATH}) For large systems, it is often desirable to put sources in a separate directory from the binaries. The @dfn{directory search} features of -@code{make} facilitate this by searching several directories automatically -to find a dependency. When you redistribute the files among directories, -you do not need to change the individual rules, just the search paths. +@code{make} facilitate this by searching several directories +automatically to find a dependency. When you redistribute the files +among directories, you do not need to change the individual rules, +just the search paths. @menu -* General Search:: The @code{VPATH} variable specifies a search path - that applies to every dependency. -* Selective Search:: The @code{vpath} directive specifies a search path - for a specified class of names. -* Commands/Search:: How to write shell commands that work together - with search paths. -* Implicit/Search:: How search paths affect implicit rules. -* Libraries/Search:: Directory search for link libraries. +* General Search:: Specifying a search path that applies + to every dependency. +* Selective Search:: Specifying a search path + for a specified class of names. +* Commands/Search:: How to write shell commands that work together + with search paths. +* Implicit/Search:: How search paths affect implicit rules. +* Libraries/Search:: Directory search for link libraries. @end menu -@node General Search, Selective Search, Directory Search, Directory Search +@node General Search, Selective Search, , Directory Search @subsection @code{VPATH}: Search Path for All Dependencies +@vindex VPATH The value of the @code{make} variable @code{VPATH} specifies a list of -directories which @code{make} should search (in the order specified) for -dependency files. The directory names are separated by colons. For -example: +directories that @code{make} should search. Most often, the +directories are expected to contain dependency files that are not in the +current directory; however, @code{VPATH} specifies a search list that +@code{make} applies for all files, including files which are targets of +rules. + +Thus, if a file that is listed as a target or dependency does not exist +in the current directory, @code{make} searches the directories listed in +@code{VPATH} for a file with that name. If a file is found in one of +them, that file becomes the dependency. Rules may then specify the +names of source files in the dependencies as if they all existed in the +current directory. @xref{Commands/Search, ,Writing Shell Commands with +Directory Search}. + +In the @code{VPATH} variable, directory names are separated by colons. +The order in which directories are listed is the order followed by +@code{make} in its search. +For example, + @example VPATH = src:../headers @end example @noindent -specifies a path containing two directories, @file{src} and @file{../headers}. +specifies a path containing two directories, @file{src} and +@file{../headers}, which @code{make} searches in that order. -Whenever a file listed as a dependency does not exist in the current -directory, the directories listed in @code{VPATH} are searched for a file -with that name. If a file is found in one of them, that file becomes the -dependency. Rules may then specify the names of source files as if they -all existed in the current directory. +With this value of @code{VPATH}, the following rule, -Using the value of @code{VPATH} set in the previous example, a rule like this: - @example foo.o : foo.c @end example @@ -1065,20 +1735,20 @@ @node Selective Search, Commands/Search, General Search, Directory Search @subsection The @code{vpath} Directive +@findex vpath Similar to the @code{VPATH} variable but more selective is the @code{vpath} -directive, which allows you to specify a search path for a particular class -of filenames, those that match a particular pattern. Thus you can supply -certain search directories for one class of filenames and other directories -(or none) for other filenames. +directive (note lower case), which allows you to specify a search path for a particular class +of file names, those that match a particular pattern. Thus you can supply +certain search directories for one class of file names and other directories +(or none) for other file names. There are three forms of the @code{vpath} directive: @table @code @item vpath @var{pattern} @var{directories} -Specify the search path @var{directories} for filenames that match -@code{pattern}. If another path was previously specified for the same -pattern, the new path is effectively appended to the old path.@refill +Specify the search path @var{directories} for file names that match +@var{pattern}. The search path, @var{directories}, is a colon-separated list of directories to be searched, just like the search path used in the @@ -1087,16 +1757,25 @@ @item vpath @var{pattern} Clear out the search path associated with @var{pattern}. +@c Extra blank line makes sure this gets two lines. @item vpath + Clear all search paths previously specified with @code{vpath} directives. @end table A @code{vpath} pattern is a string containing a @samp{%} character. The -string must match the filename of a dependency that is being searched for, -the @samp{%} character matching any sequence of zero or more characters (as -in pattern rules; @pxref{Pattern Rules}). (If there is no @samp{%}, the -pattern must match the dependency, which is not useful very often.) - +string must match the file name of a dependency that is being searched +for, the @samp{%} character matching any sequence of zero or more +characters (as in pattern rules; @pxref{Pattern Rules, ,Defining and +Redefining Pattern Rules}). For example, @code{%.h} matches files that +end in @code{.h}. (If there is no @samp{%}, the pattern must match the +dependency exactly, which is not useful very often.) + +@cindex @code{%}, quoting in @code{vpath} +@cindex @code{%}, quoting with @code{\} (backslash) +@cindex @code{\} (backslash), to quote @code{%} +@cindex backslash (@code{\}), to quote @code{%} +@cindex quoting @code{%}, in @code{vpath} @samp{%} characters in a @code{vpath} directive's pattern can be quoted with preceding backslashes (@samp{\}). Backslashes that would otherwise quote @samp{%} characters can be quoted with more backslashes. @@ -1107,8 +1786,9 @@ When a dependency fails to exist in the current directory, if the @var{pattern} in a @code{vpath} directive matches the name of the dependency file, then the @var{directories} in that directive are searched -just like (and before) the directories in the @code{VPATH} variable. For -example, +just like (and before) the directories in the @code{VPATH} variable. + +For example, @example vpath %.h ../headers @@ -1121,11 +1801,41 @@ If several @code{vpath} patterns match the dependency file's name, then @code{make} processes each matching @code{vpath} directive one by one, -searching all the directories mentioned in each directive. The @code{vpath} -directives are processed in the order in which they appear in the makefiles. +searching all the directories mentioned in each directive. @code{make} +handles multiple @code{vpath} directives in the order in which they +appear in the makefile; multiple directives with the same pattern are +independent of each other. + +@need 750 +Thus, + +@example +@group +vpath %.c foo +vpath % blish +vpath %.c bar +@end group +@end example + +@noindent +will look for a file ending in @samp{.c} in @file{foo}, then +@file{blish}, then @file{bar}, while + +@example +@group +vpath %.c foo:bar +vpath % blish +@end group +@end example +@noindent +will look for a file ending in @samp{.c} in @file{foo}, then +@file{bar}, then @file{blish}. + @node Commands/Search, Implicit/Search, Selective Search, Directory Search @subsection Writing Shell Commands with Directory Search +@cindex shell command, and directory search +@cindex directory search (@code{VPATH}), and shell commands When a dependency is found in another directory through directory search, this cannot change the commands of the rule; they will execute as written. @@ -1133,7 +1843,8 @@ the dependency in the directory where @code{make} finds it. This is done with the @dfn{automatic variables} such as @samp{$^} -(@pxref{Automatic}). For instance, the value of @samp{$^} is a +(@pxref{Automatic, ,Automatic Variables}). +For instance, the value of @samp{$^} is a list of all the dependencies of the rule, including the names of the directories in which they were found, and the value of @samp{$@@} is the target. Thus:@refill @@ -1144,85 +1855,93 @@ @end example @noindent -The variable @code{CFLAGS} exists so you can specify flags for C -compilation by implicit rule; we use it here for consistency so it will -affect all C compilations uniformly (@pxref{Implicit Variables}). - -Often the dependencies include header files as well, which you don't want -to mention in the commands. The function @code{firstword} can be used to -extract just the first dependency from the entire list, as shown here -(@pxref{Filename Functions}): +(The variable @code{CFLAGS} exists so you can specify flags for C +compilation by implicit rules; we use it here for consistency so it will +affect all C compilations uniformly; +@pxref{Implicit Variables, ,Variables Used by Implicit Rules}.) + +Often the dependencies include header files as well, which you do not +want to mention in the commands. The automatic variable @samp{$<} is +just the first dependency: @example VPATH = src:../headers foo.o : foo.c defs.h hack.h - cc -c $(CFLAGS) $(firstword $^) -o $@@ + cc -c $(CFLAGS) $< -o $@@ @end example -@noindent -Here the value of @samp{$^} would be something like @samp{src/foo.c -../headers/defs.h hack.h}, from which @samp{$(firstword $^)} extracts just -@samp{src/foo.c}.@refill - @node Implicit/Search, Libraries/Search, Commands/Search, Directory Search @subsection Directory Search and Implicit Rules +@cindex @code{VPATH}, and implicit rules +@cindex directory search (@code{VPATH}), and implicit rules +@cindex search path for dependencies (@code{VPATH}), and implicit rules +@cindex implicit rule, and directory search +@cindex implicit rule, and @code{VPATH} +@cindex rule, implicit, and directory search +@cindex rule, implicit, and @code{VPATH} The search through the directories specified in @code{VPATH} or with -@code{vpath} happens also during consideration of implicit rules -(@pxref{Implicit}). +@code{vpath} also happens during consideration of implicit rules +(@pxref{Implicit Rules, ,Using Implicit Rules}). For example, when a file @file{foo.o} has no explicit rule, @code{make} -considers implicit rules, such as to compile @file{foo.c} if that file +considers implicit rules such as to compile @file{foo.c} if that file exists. If such a file is lacking in the current directory, the appropriate directories are searched for it. If @file{foo.c} exists (or is mentioned in the makefile) in any of the directories, the implicit rule for -C compilation is applicable. +C compilation is applied. -The commands of all the built-in implicit rules normally use automatic -variables as a matter of necessity; consequently they will use the file -names found by directory search with no extra effort. +The commands of implicit rules normally use automatic variables as a +matter of necessity; consequently they will use the file names found by +directory search with no extra effort. @node Libraries/Search, , Implicit/Search, Directory Search @subsection Directory Search for Link Libraries +@cindex link libraries, and directory search +@cindex libraries for linking, directory search +@cindex directory search (@code{VPATH}), and link libraries +@cindex @code{VPATH}, and link libraries +@cindex search path for dependencies (@code{VPATH}), and link libraries +@cindex @code{-l} (library search) Directory search applies in a special way to libraries used with the linker. This special feature comes into play when you write a dependency whose name is of the form @samp{-l@var{name}}. (You can tell something -funny is going on here because the dependency is normally the name of a +strange is going on here because the dependency is normally the name of a file, and the @emph{file name} of the library looks like @file{lib@var{name}.a}, not like @samp{-l@var{name}}.)@refill When a dependency's name has the form @samp{-l@var{name}}, @code{make} -handles it specially by searching for the file @samp{lib@var{name}.a} in -the directories @samp{/lib} and @samp{/usr/lib}, and then using matching -@code{vpath} search paths and the @code{VPATH} search path.@refill +handles it specially by searching for the file @file{lib@var{name}.a} in +the current directory, in directories specified by matching @code{vpath} +search paths and the @code{VPATH} search path, and then in the +directories @file{/lib}, @file{/usr/lib}, and @file{@var{prefix}/lib} +(normally @file{/usr/local/lib}). For example, @example +@group foo : foo.c -lcurses cc $^ -o $@@ +@end group @end example @noindent -would cause the command @samp{cc foo.c -lcurses -o foo} to be executed when -@file{foo} is older than @file{foo.c} or than @file{libcurses.a} (which has -probably been found by directory search in the file -@file{/usr/lib/libcurses.a}).@refill - -As shown by the example above, the file name found by directory search is -used only for comparing the file time with the target file's time. It -does not replace the file's name in later usage (such as in automatic -variables like @code{$^}); the name remains unchanged, still starting -with @samp{-l}. This leads to the correct results because the linker -will repeat the appropriate search when it processes this argument.@refill +would cause the command @samp{cc foo.c /usr/lib/libcurses.a -o foo} to +be executed when @file{foo} is older than @file{foo.c} or than +@file{/usr/lib/libcurses.a}.@refill @node Phony Targets, Force Targets, Directory Search, Rules @section Phony Targets @cindex phony targets +@cindex targets, phony +@cindex targets without a file A phony target is one that is not really the name of a file. It is just a name for some commands to be executed when you make an explicit request. +There are two reasons to use a phony target: to avoid a conflict with +a file of the same name, and to improve performance. If you write a rule whose commands will not create the target file, the commands will be executed every time the target comes up for remaking. @@ -1229,8 +1948,10 @@ Here is an example: @example +@group clean: rm *.o temp +@end group @end example @noindent @@ -1237,6 +1958,7 @@ Because the @code{rm} command does not create a file named @file{clean}, probably no such file will ever exist. Therefore, the @code{rm} command will be executed every time you say @samp{make clean}. +@cindex @code{rm} (shell command) @findex .PHONY The phony target will cease to work if anything ever does create a file @@ -1244,7 +1966,7 @@ file @file{clean} would inevitably be considered up to date, and its commands would not be executed. To avoid this problem, you can explicitly declare the target to be phony, using the special target @code{.PHONY} -(@pxref{Special Targets}) as follows: +(@pxref{Special Targets, ,Special Built-in Target Names}) as follows: @example .PHONY : clean @@ -1254,10 +1976,29 @@ Once this is done, @samp{make clean} will run the commands regardless of whether there is a file named @file{clean}. -A phony target should not be a dependency of a real target file; strange -things can result from that. As long as you don't do that, the phony -target commands will be executed only when the phony target is a specified -goal (@pxref{Goals}). +Since it knows that phony targets do not name actual files that could be +remade from other files, @code{make} skips the implicit rule search for +phony targets (@pxref{Implicit Rules}). This is why declaring a target +phony is good for performance, even if you are not worried about the +actual file existing. + +Thus, you first write the line that states that @code{clean} is a +phony target, then you write the rule, like this: + +@example +@group +.PHONY: clean +clean: + rm *.o temp +@end group +@end example + +A phony target should not be a dependency of a real target file; if it +is, its commands are run every time @code{make} goes to update that +file. As long as a phony target is never a dependency of a real +target, the phony target commands will be executed only when the phony +target is a specified goal (@pxref{Goals, ,Arguments to Specify the +Goals}). Phony targets can have dependencies. When one directory contains multiple programs, it is most convenient to describe all of the programs in one @@ -1289,6 +2030,8 @@ object files, the difference files, and the file @file{program}: @example +.PHONY: cleanall cleanobj cleandiff + cleanall : cleanobj cleandiff rm program @@ -1301,6 +2044,10 @@ @node Force Targets, Empty Targets, Phony Targets, Rules @section Rules without Commands or Dependencies +@cindex force targets +@cindex targets, force +@cindex @code{FORCE} +@cindex rule, no commands or dependencies If a rule has no dependencies or commands, and the target of the rule is a nonexistent file, then @code{make} imagines this target to have @@ -1310,9 +2057,11 @@ An example will illustrate this: @example +@group clean: FORCE rm $(objects) FORCE: +@end group @end example Here the target @samp{FORCE} satisfies the special conditions, so the @@ -1321,12 +2070,17 @@ commonly used this way. As you can see, using @samp{FORCE} this way has the same results as using -@samp{.PHONY: clean}. The latter is more explicit, but other versions of -@code{make} do not support it; thus @samp{FORCE} appears in many makefiles. +@samp{.PHONY: clean}. +Using @samp{.PHONY} is more explicit and more efficient. However, +other versions of @code{make} do not support @samp{.PHONY}; thus +@samp{FORCE} appears in many makefiles. @xref{Phony Targets}. + @node Empty Targets, Special Targets, Force Targets, Rules @section Empty Target Files to Record Events @cindex empty targets +@cindex targets, empty +@cindex recording events with empty targets The @dfn{empty target} is a variant of the phony target; it is used to hold commands for an action that you request explicitly from time to time. @@ -1348,47 +2102,72 @@ lpr -p $? touch print @end example +@cindex @code{print} target +@cindex @code{lpr} (shell command) +@cindex @code{touch} (shell command) @noindent With this rule, @samp{make print} will execute the @code{lpr} command if either source file has changed since the last @samp{make print}. The automatic variable @samp{$?} is used to print only those files that have -changed (@pxref{Automatic}). +changed (@pxref{Automatic, ,Automatic Variables}). @node Special Targets, Multiple Targets, Empty Targets, Rules @section Special Built-in Target Names @cindex special targets +@cindex built-in special targets +@cindex targets, built-in special Certain names have special meanings if they appear as targets. @table @code +@findex .PHONY @item .PHONY + The dependencies of the special target @code{.PHONY} are considered to be phony targets. When it is time to consider such a target, @code{make} will run its commands unconditionally, regardless of whether a file with that name exists or what its last-modification -time is. @xref{Phony Targets}. +time is. @xref{Phony Targets, ,Phony Targets}. +@findex .SUFFIXES @item .SUFFIXES + The dependencies of the special target @code{.SUFFIXES} are the list -of suffixes to be used in checking for suffix rules. @xref{Suffix -Rules}. +of suffixes to be used in checking for suffix rules. +@xref{Suffix Rules, , Old-Fashioned Suffix Rules}. +@findex .DEFAULT @item .DEFAULT + The commands specified for @code{.DEFAULT} are used for any target for -which no other commands are known (either explicitly or through an -implicit rule). If @code{.DEFAULT} commands are specified, every -nonexistent file mentioned as a dependency will have these commands -executed on its behalf. @xref{Search Algorithm}. +which no rules are found (either explicit rules or implicit rules). +@xref{Last Resort}. If @code{.DEFAULT} commands are specified, every +file mentioned as a dependency, but not as a target in a rule, will have +these commands executed on its behalf. @xref{Search Algorithm, +,Implicit Rule Search Algorithm}. +@findex .PRECIOUS @item .PRECIOUS @cindex precious targets -The targets which @code{.PRECIOUS} depends on are given this special -treatment: if @code{make} is killed or interrupted during the +@cindex preserving with @code{.PRECIOUS} + +The targets which @code{.PRECIOUS} depends on are given the following +special treatment: if @code{make} is killed or interrupted during the execution of their commands, the target is not deleted. -@xref{Interrupts}. +@xref{Interrupts, ,Interrupting or Killing @code{make}}. +Also, if the target is an intermediate file, it will not be deleted +after it is no longer needed, as is normally done. +@xref{Chained Rules, ,Chains of Implicit Rules}. + +You can also list the target pattern of an implicit rule (such as +@samp{%.o}) as a dependency file of the special target @code{.PRECIOUS} +to preserve intermediate files whose target patterns match that file's +name. +@findex .IGNORE @item .IGNORE + Simply by being mentioned as a target, @code{.IGNORE} says to ignore errors in execution of commands. The dependencies and commands for @code{.IGNORE} are not meaningful. @@ -1396,9 +2175,11 @@ @samp{.IGNORE} exists for historical compatibility. Since @code{.IGNORE} affects every command in the makefile, it is not very useful; we recommend you use the more selective ways to ignore errors -in specific commands. @xref{Errors}. +in specific commands. @xref{Errors, ,Errors in Commands}. +@findex .SILENT @item .SILENT + Simply by being mentioned as a target, @code{.SILENT} says not to print commands before executing them. The dependencies and commands for @code{.SILENT} are not meaningful. @@ -1405,7 +2186,17 @@ @samp{.SILENT} exists for historical compatibility. We recommend you use the more selective ways to silence specific commands. -@xref{Echoing}. +@xref{Echoing, ,Command Echoing}. If you want to silence all commands +for a particular run of @code{make}, use the @samp{-s} or +@w{@samp{--silent}} option (@pxref{Options Summary}). + +@findex .EXPORT_ALL_VARIABLES +@item .EXPORT_ALL_VARIABLES + +Simply by being mentioned as a target, this tells @code{make} to +export all variables to child processes by default. +@xref{Variables/Recursion, ,Communicating Variables to a +Sub-@code{make}}. @end table Any defined implicit rule suffix also counts as a special target if it @@ -1415,10 +2206,14 @@ target name could be special in this way if you break it in two and add both pieces to the suffix list. In practice, suffixes normally begin with @samp{.}, so these special target names also begin with @samp{.}. -@xref{Suffix Rules}. +@xref{Suffix Rules, ,Old-Fashioned Suffix Rules}. -@node Multiple Targets, Static Pattern, Special Targets, Rules +@node Multiple Targets, Multiple Rules, Special Targets, Rules @section Multiple Targets in a Rule +@cindex multiple targets +@cindex several targets in a rule +@cindex targets, multiple +@cindex rule, with multiple targets A rule with multiple targets is equivalent to writing many rules, each with one target, and all identical aside from that. The same commands apply to @@ -1433,7 +2228,7 @@ You want just dependencies, no commands. For example: @example -kbd.o commands.o files.o: command.h +kbd.o command.o files.o: command.h @end example @noindent @@ -1444,7 +2239,7 @@ Similar commands work for all the targets. The commands do not need to be absolutely identical, since the automatic variable @samp{$@@} can be used to substitute the particular target to be remade into the -commands (@pxref{Automatic}). For example: +commands (@pxref{Automatic, ,Automatic Variables}). For example: @example @group @@ -1452,6 +2247,7 @@ generate text.g -$(subst output,,$@@) > $@@ @end group @end example +@findex subst @noindent is equivalent to @@ -1466,48 +2262,116 @@ @noindent Here we assume the hypothetical program @code{generate} makes two types of output, one if given @samp{-big} and one if given -@samp{-little}.@refill +@samp{-little}. +@xref{Text Functions, ,Functions for String Substitution and Analysis}, +for an explanation of the @code{subst} function. @end itemize -@ifinfo Suppose you would like to vary the dependencies according to the target, much as the variable @samp{$@@} allows you to vary the commands. You cannot do this with multiple targets in an ordinary rule, but you can -do it with a @dfn{static pattern rule}. @xref{Static Pattern}. -@end ifinfo +do it with a @dfn{static pattern rule}. +@xref{Static Pattern, ,Static Pattern Rules}. + +@node Multiple Rules, Static Pattern, Multiple Targets, Rules +@section Multiple Rules for One Target +@cindex multiple rules for one target +@cindex several rules for one target +@cindex rule, multiple for one target +@cindex target, multiple rules for one + +One file can be the target of several rules. All the dependencies +mentioned in all the rules are merged into one list of dependencies for +the target. If the target is older than any dependency from any rule, +the commands are executed. + +There can only be one set of commands to be executed for a file. +If more than one rule gives commands for the same file, +@code{make} uses the last set given and prints an error message. +(As a special case, if the file's name begins with a dot, no +error message is printed. This odd behavior is only for +compatibility with other implementations of @code{make}.) +There is no reason to +write your makefiles this way; that is why @code{make} gives you +an error message.@refill + +An extra rule with just dependencies can be used to give a few extra +dependencies to many files at once. For example, one usually has a +variable named @code{objects} containing a list of all the compiler output +files in the system being made. An easy way to say that all of them must +be recompiled if @file{config.h} changes is to write the following: + +@example +objects = foo.o bar.o +foo.o : defs.h +bar.o : defs.h test.h +$(objects) : config.h +@end example -@node Static Pattern, Multiple Rules, Multiple Targets, Rules +This could be inserted or taken out without changing the rules that really +specify how to make the object files, making it a convenient form to use if +you wish to add the additional dependency intermittently. + +Another wrinkle is that the additional dependencies could be specified with +a variable that you set with a command argument to @code{make} +(@pxref{Overriding, ,Overriding Variables}). For example, + +@example +@group +extradeps= +$(objects) : $(extradeps) +@end group +@end example + +@noindent +means that the command @samp{make extradeps=foo.h} will consider +@file{foo.h} as a dependency of each object file, but plain @samp{make} +will not. + +If none of the explicit rules for a target has commands, then @code{make} +searches for an applicable implicit rule to find some commands +@pxref{Implicit Rules, ,Using Implicit Rules}). + +@node Static Pattern, Double-Colon, Multiple Rules, Rules @section Static Pattern Rules -@cindex static pattern rules +@cindex static pattern rule +@cindex rule, static pattern +@cindex pattern rules, static (not implicit) @cindex varying dependencies +@cindex dependencies, varying (static pattern) @dfn{Static pattern rules} are rules which specify multiple targets and construct the dependency names for each target based on the target name. They are more general than ordinary rules with multiple targets because the -targets don't have to have identical dependencies. Their dependencies must +targets do not have to have identical dependencies. Their dependencies must be @emph{analogous}, but not necessarily @emph{identical}. @menu -* Usage: Static Usage. How to use static pattern rules. -* Static vs Implicit:: When are they better than implicit rules? +* Static Usage:: The syntax of static pattern rules. +* Static versus Implicit:: When are they better than implicit rules? @end menu -@node Static Usage, Static vs Implicit, Static Pattern, Static Pattern +@node Static Usage, Static versus Implicit, , Static Pattern @subsection Syntax of Static Pattern Rules +@cindex static pattern rule, syntax of +@cindex pattern rules, static, syntax of Here is the syntax of a static pattern rule: @example -@var{targets}: @var{target-pattern}: @var{dep-patterns} @dots{} +@var{targets} @dots{}: @var{target-pattern}: @var{dep-patterns} @dots{} @var{commands} @dots{} @end example @noindent -The @var{targets} gives the list of targets that the rule applies to. The -targets can contain wildcard characters, just like the targets of ordinary -rules (@pxref{Wildcards}). +The @var{targets} list specifies the targets that the rule applies to. +The targets can contain wildcard characters, just like the targets of +ordinary rules (@pxref{Wildcards, ,Using Wildcard Characters in File +Names}). +@cindex target pattern, static (not implicit) +@cindex stem The @var{target-pattern} and @var{dep-patterns} say how to compute the dependencies of each target. Each target is matched against the @var{target-pattern} to extract a part of the target name, called the @@ -1519,40 +2383,53 @@ the target name; this part is called the @dfn{stem}. The rest of the pattern must match exactly. For example, the target @file{foo.o} matches the pattern @samp{%.o}, with @samp{foo} as the stem. The targets -@file{foo.c} and @file{foo.out} don't match that pattern.@refill +@file{foo.c} and @file{foo.out} do not match that pattern.@refill +@cindex dependency pattern, static (not implicit) The dependency names for each target are made by substituting the stem for the @samp{%} in each dependency pattern. For example, if one dependency pattern is @file{%.c}, then substitution of the stem @samp{foo} gives the dependency name @file{foo.c}. It is legitimate -to write a dependency pattern that doesn't contain @samp{%}; then this +to write a dependency pattern that does not contain @samp{%}; then this dependency is the same for all targets. +@cindex @code{%}, quoting in static pattern +@cindex @code{%}, quoting with @code{\} (backslash) +@cindex @code{\} (backslash), to quote @code{%} +@cindex backslash (@code{\}), to quote @code{%} +@cindex quoting @code{%}, in static pattern @samp{%} characters in pattern rules can be quoted with preceding backslashes (@samp{\}). Backslashes that would otherwise quote @samp{%} characters can be quoted with more backslashes. Backslashes that quote @samp{%} characters or other backslashes are removed from the pattern -before it is compared file names or has a stem substituted into it. +before it is compared to file names or has a stem substituted into it. Backslashes that are not in danger of quoting @samp{%} characters go unmolested. For example, the pattern @file{the\%weird\\%pattern\\} has @samp{the%weird\} preceding the operative @samp{%} character, and @samp{pattern\\} following it. The final two backslashes are left alone -because they can't affect any @samp{%} character.@refill +because they cannot affect any @samp{%} character.@refill Here is an example, which compiles each of @file{foo.o} and @file{bar.o} from the corresponding @file{.c} file: @example +@group objects = foo.o bar.o $(objects): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@@ +@end group @end example +@noindent +Here @samp{$<} is the automatic variable that holds the name of the +dependency and @samp{$@@} is the automatic variable that holds the name +of the target; see @ref{Automatic, , Automatic Variables}. + Each target specified must match the target pattern; a warning is issued for each target that does not. If you have a list of files, only some of which will match the pattern, you can use the @code{filter} function to -remove nonmatching filenames (@pxref{Text Functions}): +remove nonmatching file names (@pxref{Text Functions, ,Functions for String Substitution and Analysis}): @example files = foo.elc bar.o lose.o @@ -1565,18 +2442,35 @@ @noindent Here the result of @samp{$(filter %.o,$(files))} is @file{bar.o lose.o}, -and the first static pattern rule causes each of these object files to be -updated by compiling the corresponding C source file. The result of -@samp{$(filter %.elc,$(files))} is @file{foo.elc}, so that file is made -from @file{foo.el}.@refill +and the first static pattern rule causes each of these object files to +be updated by compiling the corresponding C source file. The result of +@w{@samp{$(filter %.elc,$(files))}} is @file{foo.elc}, so that file is +made from @file{foo.el}.@refill + +Another example shows how to use @code{$*} in static pattern rules: +@vindex $*@r{, and static pattern} + +@example +@group +bigoutput littleoutput : %output : text.g + generate text.g -$* > $@@ +@end group +@end example + +@noindent +When the @code{generate} command is run, @code{$*} will expand to the +stem, either @samp{big} or @samp{little}. -@node Static vs Implicit, , Static Usage, Static Pattern +@node Static versus Implicit, , Static Usage, Static Pattern @subsection Static Pattern Rules versus Implicit Rules +@cindex rule, static pattern versus implicit +@cindex static pattern rule, versus implicit A static pattern rule has much in common with an implicit rule defined as a -pattern rule (@pxref{Pattern Rules}). Both have a pattern for the target -and patterns for constructing the names of dependencies. The difference is -in how @code{make} decides @emph{when} the rule applies. +pattern rule (@pxref{Pattern Rules, ,Defining and Redefining Pattern Rules}). +Both have a pattern for the target and patterns for constructing the +names of dependencies. The difference is in how @code{make} decides +@emph{when} the rule applies. An implicit rule @emph{can} apply to any target that matches its pattern, but it @emph{does} apply only when the target has no commands otherwise @@ -1607,63 +2501,12 @@ to precisely the targets specified. @end itemize -@node Multiple Rules, Double-Colon, Static Pattern, Rules -@section Multiple Rules for One Target - -One file can be the target of several rules. All the dependencies -mentioned in all the rules are merged into one list of dependencies for -the target. If the target is older than any dependency from any rule, -the commands are executed. - -There can only be one set of commands to be executed for a file. -If more than one rule gives commands for the same file, the last -@code{make} uses the last set given and prints an error message. -(As a special case, if the file's name begins with a dot, no -error message is printed. This odd behavior is only for -compatibility with other @code{make}s.) There is no reason to -write your makefiles this way; that is why @code{make} gives you -an error message.@refill - -An extra rule with just dependencies can be used to give a few extra -dependencies to many files at once. For example, one usually has a -variable named @code{objects} containing a list of all the compiler output -files in the system being made. An easy way to say that all of them must -be recompiled if @file{config.h} changes is to write - -@example -objects = foo.o bar.o -foo.o : defs.h -bar.o : defs.h test.h -$(objects) : config.h -@end example - -This could be inserted or taken out without changing the rules that really -say how to make the object files, making it a convenient form to use if -you wish to add the additional dependency intermittently. - -Another wrinkle is that the additional dependencies could be specified with -a variable that you could set with a command argument to @code{make} -(@pxref{Overriding}). For example, - -@example -@group -extradeps= -$(objects) : $(extradeps) -@end group -@end example - -@noindent -means that the command @samp{make extradeps=foo.h} will consider -@file{foo.h} as a dependency of each object file, but plain @samp{make} -will not. - -If none of the explicit rules for a target has commands, then @code{make} -searches for an applicable implicit rule to find some commands. -@xref{Implicit}. - -@node Double-Colon, , Multiple Rules, Rules +@node Double-Colon, Automatic Dependencies, Static Pattern, Rules @section Double-Colon Rules -@cindex double-colon rule +@cindex double-colon rules +@cindex rule, double-colon (@code{::}) +@cindex multiple rules for one target (@code{::}) +@cindex @code{::} rules (double-colon) @dfn{Double-colon} rules are rules written with @samp{::} instead of @samp{:} after the target names. They are handled differently from @@ -1673,7 +2516,7 @@ type: all ordinary, or all double-colon. If they are double-colon, each of them is independent of the others. Each double-colon rule's commands are executed if the target is older than any dependencies of that rule. This -can result in executing none, any or all of the double-colon rules. +can result in executing none, any, or all of the double-colon rules. Double-colon rules with the same target are in fact completely separate from one another. Each double-colon rule is processed individually, just @@ -1689,11 +2532,130 @@ cases are rare. Each double-colon rule should specify commands; if it does not, an -implicit rule will be used if one applies. @xref{Implicit}. +implicit rule will be used if one applies. +@xref{Implicit Rules, ,Using Implicit Rules}. + +@node Automatic Dependencies, , Double-Colon, Rules +@section Generating Dependencies Automatically +@cindex dependencies, automatic generation +@cindex automatic generation of dependencies +@cindex generating dependencies automatically + +In the makefile for a program, many of the rules you need to write often +say only that some object file depends on some header +file. For example, if @file{main.c} uses @file{defs.h} via an +@code{#include}, you would write: + +@example +main.o: defs.h +@end example + +@noindent +You need this rule so that @code{make} knows that it must remake +@file{main.o} whenever @file{defs.h} changes. You can see that for a +large program you would have to write dozens of such rules in your +makefile. And, you must always be very careful to update the makefile +every time you add or remove an @code{#include}. +@cindex @code{#include} + +@cindex @code{-M} (to compiler) +To avoid this hassle, most modern C compilers can write these rules for +you, by looking at the @code{#include} lines in the source files. +Usually this is done with the @samp{-M} option to the compiler. +For example, the command: + +@example +cc -M main.c +@end example + +@noindent +generates the output: + +@example +main.o : main.c defs.h +@end example + +@noindent +Thus you no longer have to write all those rules yourself. +The compiler will do it for you. + +@cindex @code{make depend} +With old @code{make} programs, it was traditional practice to use this +compiler feature to generate dependencies on demand with a command like +@samp{make depend}. That command would create a file @file{depend} +containing all the automatically-generated dependencies; then the +makefile could use @code{include} to read them in (@pxref{Include}). + +In GNU @code{make}, the feature of remaking makefiles makes this +practice obsolete---you need never tell @code{make} explicitly to +regenerate the dependencies, because it always regenerates any makefile +that is out of date. @xref{Remaking Makefiles}. + +The practice we recommend for automatic dependency generation is to have +one makefile corresponding to each source file. For each source file +@file{@var{name}.c} there is a makefile @file{@var{name}.d} which lists +what files the object file @file{@var{name}.o} depends on. That way +only the source files that have changed need to be rescanned to produce +the new dependencies. + +Here is the pattern rule to generate a file of dependencies (i.e., a makefile) +called @file{@var{name}.d} from a C source file called @file{@var{name}.c}: + +@example +@group +%.d: %.c + $(CC) -M $(CPPFLAGS) $< | sed 's/$*.o/& $@@/g' > $@@ +@end group +@end example + +@noindent +@xref{Pattern Rules}, for information on defining pattern rules. +@cindex @code{sed} (shell command) +The purpose of the @code{sed} command is to translate (for example): + +@example +main.o : main.c defs.h +@end example + +@noindent +into: + +@example +main.o main.d : main.c defs.h +@end example + +@noindent +@cindex @code{.d} +This makes each @samp{.d} file depend on all the source and header files +that the corresponding @samp{.o} file depends on. @code{make} then +knows it must regenerate the dependencies whenever any of the source or +header files changes. + +Once you've defined the rule to remake the @samp{.d} files, +you then use the @code{include} directive to read them all in. +@xref{Include}. For example: -@node Commands, Variables, Rules, Top +@example +@group +sources = foo.c bar.c + +include $(sources:.c=.d) +@end group +@end example + +@noindent +(This example uses a substitution variable reference to translate the +list of source files @samp{foo.c bar.c} into a list of dependency +makefiles, @samp{foo.d bar.d}. @xref{Substitution Refs}, for full +information on substitution references.) Since the @samp{.d} files are +makefiles like any others, @code{make} will remake them as necessary +with no further work from you. @xref{Remaking Makefiles}. + +@node Commands, Using Variables, Rules, Top @chapter Writing the Commands in Rules -@cindex commands +@cindex commands, how to write +@cindex rule commands +@cindex writing rule commands The commands of a rule consist of shell command lines to be executed one by one. Each command line must start with a tab, except that the first @@ -1702,33 +2664,37 @@ among the command lines; they are ignored. Users use many different shell programs, but commands in makefiles are -always interpreted by @file{/bin/sh} unless the makefile specifies otherwise. +always interpreted by @file{/bin/sh} unless the makefile specifies +otherwise. @xref{Execution, ,Command Execution}. -Whether comments can be written on command lines, and what syntax they use, -is under the control of the shell that is in use. If it is @file{/bin/sh}, -a @samp{#} at the start of a word starts a comment. +@cindex comments, in commands +@cindex commands, comments in +@cindex @code{#} (comments), in commands +The shell that is in use determines whether comments can be written on +command lines, and what syntax they use. When the shell is +@file{/bin/sh}, a @samp{#} starts a comment that extends to the end of +the line. The @samp{#} does not have to be at the beginning of a line. +Text on a line before a @samp{#} is not part of the comment. @menu -* Echoing:: Normally commands are echoed before execution, - but you can control this in several ways. -* Execution:: How commands are executed. -* Parallel:: Commands of several rules can be executed in parallel, - to reduce total time. -* Errors:: What happens after an error in command execution. - How to ignore errors in certain commands. -* Interrupts:: If a command is interrupted or killed, - the target may be deleted. -* Recursion:: Invoking @code{make} from commands in makefiles. -* Sequences:: Defining canned sequences of commands. -* Empty Commands::Defining commands that do nothing (but are useful). +* Echoing:: How to control when commands are echoed. +* Execution:: How commands are executed. +* Parallel:: How commands can be executed in parallel. +* Errors:: What happens after a command execution error. +* Interrupts:: What happens when a command is interrupted. +* Recursion:: Invoking @code{make} from makefiles. +* Sequences:: Defining canned sequences of commands. +* Empty Commands:: Defining useful, do-nothing commands. @end menu -@node Echoing, Execution, Commands, Commands +@node Echoing, Execution, , Commands @section Command Echoing - -@cindex echoing (of commands) +@cindex echoing of commands @cindex silent operation -@cindex @@ (in commands) +@cindex @code{@@} (in commands) +@cindex commands, echoing +@cindex printing of commands + Normally @code{make} prints each command line before it is executed. We call this @dfn{echoing} because it gives the appearance that you are typing the commands yourself. @@ -1743,34 +2709,47 @@ @@echo About to make distribution files @end example -When @code{make} is given the flag @samp{-n}, echoing is all that happens, -no execution. @xref{Options}. In this case and only this case, even the +@cindex @code{-n} +@cindex @code{--just-print} +@cindex @code{--dry-run} +@cindex @code{--recon} +When @code{make} is given the flag @samp{-n} or @samp{--just-print}, +echoing is all that happens, no execution. @xref{Options Summary, +,Summary of Options}. In this case and only this case, even the commands starting with @samp{@@} are printed. This flag is useful for finding out which commands @code{make} thinks are necessary without actually doing them. @cindex @code{-s} +@cindex @code{--silent} +@cindex @code{--quiet} @findex .SILENT -The @samp{-s} flag to @code{make} prevents all echoing, as if all commands +The @samp{-s} or @samp{--silent} +flag to @code{make} prevents all echoing, as if all commands started with @samp{@@}. A rule in the makefile for the special target -@code{.SILENT} has the same effect (@pxref{Special Targets}). +@code{.SILENT} has the same effect +(@pxref{Special Targets, ,Special Built-in Target Names}). @code{.SILENT} is essentially obsolete since @samp{@@} is more flexible.@refill @node Execution, Parallel, Echoing, Commands @section Command Execution -@cindex execution -@cindex shell +@cindex commands, execution +@cindex execution, of commands +@cindex shell command, execution +@vindex SHELL @r{(command execution)} When it is time to execute commands to update a target, they are executed by making a new subshell for each line. (In practice, @code{make} may take shortcuts that do not affect the results.) -This implies that shell commands such as @code{cd} that set variables local -to each process will not affect the following command lines. If you want -to use @code{cd} to affect the next command, put the two on a single line -with a semicolon between them. Then @code{make} will consider them a -single command and pass them, together, to a shell which will execute them -in sequence. For example: +@cindex @code{cd} (shell command) +@strong{Please note:} this implies that shell commands such as +@code{cd} that set variables local to each process will not affect the +following command lines. If you want to use @code{cd} to affect the +next command, put the two on a single line with a semicolon between +them. Then @code{make} will consider them a single command and pass +them, together, to a shell which will execute them in sequence. For +example: @example foo : bar/lose @@ -1777,6 +2756,12 @@ cd bar; gobble lose > ../foo @end example +@cindex commands, backslash (@code{\}) in +@cindex commands, quoting newlines in +@cindex backslash (@code{\}), in commands +@cindex @code{\} (backslash), in commands +@cindex quoting newline, in commands +@cindex newline, quoting, in commands If you would like to split a single shell command into multiple lines of text, you must use a backslash at the end of all but the last subline. Such a sequence of lines is combined into a single line, by deleting the @@ -1795,23 +2780,28 @@ The program used as the shell is taken from the variable @code{SHELL}. By default, the program @file{/bin/sh} is used. -Unlike most variables, the variable @code{SHELL} will not be set from the -environment, except in a recursive @code{make}. This is because the -environment variable @code{SHELL} is used to specify your personal choice -of shell program for interactive use. It would be very bad for personal -choices like this to affect the functioning of makefiles. -@xref{Environment}. +@cindex environment, @code{SHELL} in +Unlike most variables, the variable @code{SHELL} is never set from the +environment. This is because the @code{SHELL} environment variable is +used to specify your personal choice of shell program for interactive +use. It would be very bad for personal choices like this to affect +the functioning of makefiles. @xref{Environment, ,Variables from the +Environment}. @node Parallel, Errors, Execution, Commands @section Parallel Execution - +@cindex commands, execution in parallel @cindex parallel execution -@cindex execution in parallel +@cindex execution, in parallel @cindex job slots +@cindex @code{-j} +@cindex @code{--jobs} + GNU @code{make} knows how to execute several commands at once. Normally, @code{make} will execute only one command at a time, waiting -for it to finish before executing the next. However, the @samp{-j} -option tells @code{make} to execute many commands simultaneously.@refill +for it to finish before executing the next. However, the @samp{-j} or +@samp{--jobs} option tells @code{make} to execute many commands +simultaneously.@refill If the @samp{-j} option is followed by an integer, this is the number of commands to execute at once; this is called the number of @dfn{job slots}. @@ -1823,12 +2813,15 @@ that output from all of the commands comes when the commands send it, so messages from different commands may be interspersed. -Another problem is that two processes cannot both take input from the same -device; so to make sure that only one command tries to take input from the -terminal at once, @code{make} will invalidate the standard input streams of -all but one running command. This means that attempting to read from -standard input, for most child processes if there are several, will usually -be a fatal error (a @samp{Broken pipe} signal). +Another problem is that two processes cannot both take input from the +same device; so to make sure that only one command tries to take input +from the terminal at once, @code{make} will invalidate the standard +input streams of all but one running command. This means that +attempting to read from standard input will usually be a fatal error (a +@samp{Broken pipe} signal) for most child processes if there are +several. +@cindex broken pipe +@cindex standard input It is unpredictable which command will have a valid standard input stream (which will come from the terminal, or wherever you redirect the standard @@ -1843,17 +2836,27 @@ all commands. If a command fails (is killed by a signal or exits with a nonzero -status), and errors are not ignored for that command (@pxref{Errors}), +status), and errors are not ignored for that command +(@pxref{Errors, ,Errors in Commands}), the remaining command lines to remake the same target will not be run. -If a command fails and the @samp{-k} option was not given -(@pxref{Options}), @code{make} aborts execution. If make terminates for -any reason (including a signal) with child processes running, it waits -for them to finish before actually exiting.@refill - +If a command fails and the @samp{-k} or @samp{--keep-going} +option was not given +(@pxref{Options Summary, ,Summary of Options}), +@code{make} aborts execution. If make +terminates for any reason (including a signal) with child processes +running, it waits for them to finish before actually exiting.@refill + +@cindex load average +@cindex limiting jobs based on load +@cindex jobs, limiting based on load +@cindex @code{-l} (load average) +@cindex @code{--max-load} +@cindex @code{--load-average} When the system is heavily loaded, you will probably want to run fewer jobs than when it is lightly loaded. You can use the @samp{-l} option to tell @code{make} to limit the number of jobs to run at once, based on the load -average. The @samp{-l} option is followed by a floating-point number. For +average. The @samp{-l} or @samp{--max-load} +option is followed by a floating-point number. For example, @example @@ -1874,33 +2877,46 @@ @node Errors, Interrupts, Parallel, Commands @section Errors in Commands +@cindex errors (in commands) +@cindex commands, errors in +@cindex exit status (errors) -@cindex error (in commands) After each shell command returns, @code{make} looks at its exit status. -If the command completed successfully, the next command line is executed in -a new shell, or after the last command line is executed, the rule is finished. +If the command completed successfully, the next command line is executed +in a new shell; after the last command line is finished, the rule is +finished. If there is an error (the exit status is nonzero), @code{make} gives up on the current rule, and perhaps on all rules. Sometimes the failure of a certain command does not indicate a problem. -For example, you may use the @code{mkdir} command to insure that a +For example, you may use the @code{mkdir} command to ensure that a directory exists. If the directory already exists, @code{mkdir} will report an error, but you probably want @code{make} to continue regardless. -@cindex - (in commands) +@cindex @code{-} (in commands) To ignore errors in a command line, write a @samp{-} at the beginning of the line's text (after the initial tab). The @samp{-} is discarded before -the command is passed to the shell for execution. For example, +the command is passed to the shell for execution. + +For example, @example +@group clean: -rm -f *.o +@end group @end example +@cindex @code{rm} (shell command) + +@noindent +This causes @code{rm} to continue even if it is unable to remove a file. @cindex @code{-i} +@cindex @code{--ignore-errors} @findex .IGNORE -When @code{make} is run with the @samp{-i} flag, errors are ignored in +When you run @code{make} with the @samp{-i} or @samp{--ignore-errors} +flag, errors are ignored in all commands of all rules. A rule in the makefile for the special target @code{.IGNORE} has the same effect. These ways of ignoring errors are obsolete because @samp{-} is more flexible. @@ -1907,8 +2923,8 @@ When errors are to be ignored, because of either a @samp{-} or the @samp{-i} flag, @code{make} treats an error return just like success, -except that it prints out a message telling you the status code the -command exited with and saying that the error has been ignored. +except that it prints out a message that tells you the status code +the command exited with, and says that the error has been ignored. When an error happens that @code{make} has not been told to ignore, it implies that the current target cannot be correctly remade, and neither @@ -1916,21 +2932,26 @@ commands will be executed for these targets, since their preconditions have not been achieved. +@cindex @code{-k} +@cindex @code{--keep-going} Normally @code{make} gives up immediately in this circumstance, returning a -nonzero status. However, if the @samp{-k} flag is specified, @code{make} +nonzero status. However, if the @samp{-k} or @samp{--keep-going} +flag is specified, @code{make} continues to consider the other dependencies of the pending targets, remaking them if necessary, before it gives up and returns nonzero status. For example, after an error in compiling one object file, @samp{make -k} will continue compiling other object files even though it already knows -that linking them will be impossible. @xref{Options}. +that linking them will be impossible. @xref{Options Summary, ,Summary of Options}. The usual behavior assumes that your purpose is to get the specified targets up to date; once @code{make} learns that this is impossible, it might as well report the failure immediately. The @samp{-k} option says -that the real purpose is to test as much as possible of the changes made in -the program, perhaps to find several independent problems so that you can -correct them all before the next attempt to compile. This is why Emacs's -@code{compile} command passes the @samp{-k} flag by default. +that the real purpose is to test as many of the changes made in the +program as possible, perhaps to find several independent problems so +that you can correct them all before the next attempt to compile. This +is why Emacs' @code{compile} command passes the @samp{-k} flag by +default. +@cindex Emacs (@code{M-x compile}) @node Interrupts, Recursion, Errors, Commands @section Interrupting or Killing @code{make} @@ -1937,6 +2958,8 @@ @cindex interrupt @cindex signal @cindex deletion of target files +@cindex target, deleting on interrupt +@cindex killing (interruption) If @code{make} gets a fatal signal while a command is executing, it may delete the target file that the command was supposed to update. This is @@ -1967,6 +2990,7 @@ @node Recursion, Sequences, Interrupts, Commands @section Recursive Use of @code{make} @cindex recursion +@cindex subdirectories, recursion for Recursive use of @code{make} means using @code{make} as a command in a makefile. This technique is useful when you want separate makefiles for @@ -1981,12 +3005,14 @@ @end example @noindent -or, equivalently, this (@pxref{Options}): +or, equivalently, this (@pxref{Options Summary, ,Summary of Options}): @example subsystem: $(MAKE) -C subdir @end example +@cindex @code{-C} +@cindex @code{--directory} You can write recursive @code{make} commands just by copying this example, but there are many things to know about how they work and why, and about @@ -1993,23 +3019,26 @@ how the sub-@code{make} relates to the top-level @code{make}. @menu -* MAKE Variable:: Special effects of using @samp{$(MAKE)}. -* Variables/Recursion:: How variables are communicated to a sub-@code{make}. -* Options/Recursion:: How options are communicated to a sub-@code{make}. -* -w Option:: The @samp{-w} option facilitates debugging - makefiles with recursive @code{make} commands. +* MAKE Variable:: The special effects of using @samp{$(MAKE)}. +* Variables/Recursion:: How to communicate variables to a sub-@code{make}. +* Options/Recursion:: How to communicate options to a sub-@code{make}. +* -w Option:: How the @samp{-w} or @samp{--print-directory} option + helps debug use of recursive @code{make} commands. @end menu -@node MAKE Variable, Variables/Recursion, Recursion, Recursion +@node MAKE Variable, Variables/Recursion, , Recursion @subsection How the @code{MAKE} Variable Works @vindex MAKE +@cindex recursion, and @code{MAKE} variable Recursive @code{make} commands should always use the variable @code{MAKE}, not the explicit command name @samp{make}, as shown here: @example +@group subsystem: cd subdir; $(MAKE) +@end group @end example The value of this variable is the file name with which @code{make} was @@ -2017,6 +3046,7 @@ is @samp{cd subdir; /bin/make}. If you use a special version of @code{make} to run the top-level makefile, the same special version will be executed for recursive invocations. +@cindex @code{cd} (shell command) Also, any arguments that define variable values are added to @code{MAKE}, so the sub-@code{make} gets them too. Thus, if you do @samp{make @@ -2023,95 +3053,230 @@ CFLAGS=-O}, so that all C compilations will be optimized, the sub-@code{make} is run with @samp{cd subdir; /bin/make CFLAGS=-O}.@refill -As a special feature, using the variable @code{MAKE} in the commands of a -rule alters the effects of the @samp{-t}, @samp{-n} or @samp{-q} option. -(@xref{Instead of Execution}.)@refill - -Consider the command @samp{make -t} in the above example. Following the -usual definition of @samp{-t}, this would create a file named -@file{subsystem} and do nothing else. What you really want it to do is run -@samp{cd subdir; make -t}; but that would require executing the command, -and @samp{-t} says not to execute commands.@refill - -The special feature makes this do what you want: whenever a rule's commands -use the variable @code{MAKE}, the flags @samp{-t}, @samp{-n} or @samp{-q} -do not apply to that rule. The commands of that rule are executed normally -despite the presence of a flag that causes most commands not to be run. -The usual @code{MAKEFLAGS} mechanism passes the flags to the -sub-@code{make} (@pxref{Options/Recursion}), so your request to touch the -files, or print the commands, is propagated to the subsystem.@refill +As a special feature, using the variable @code{MAKE} in the commands of +a rule alters the effects of the @samp{-t} (@samp{--touch}), @samp{-n} +(@samp{--just-print}), or @samp{-q} (@w{@samp{--question}}) option. +Using the @code{MAKE} variable has the same effect as using a @samp{+} +character at the beginning of the command line. @xref{Instead of +Execution, ,Instead of Executing the Commands}.@refill + +Consider the command @samp{make -t} in the above example. (The +@samp{-t} option marks targets as up to date without actually running +any commands; see @ref{Instead of Execution}.) Following the usual +definition of @samp{-t}, a @samp{make -t} command in the example would +create a file named @file{subsystem} and do nothing else. What you +really want it to do is run @samp{@w{cd subdir;} @w{make -t}}; but that would +require executing the command, and @samp{-t} says not to execute +commands.@refill +@cindex @code{-t}, and recursion +@cindex recursion, and @code{-t} +@cindex @code{--touch}, and recursion + +The special feature makes this do what you want: whenever a command +line of a rule contains the variable @code{MAKE}, the flags @samp{-t}, +@samp{-n} and @samp{-q} do not apply to that line. Command lines +containing @code{MAKE} are executed normally despite the presence of a +flag that causes most commands not to be run. The usual +@code{MAKEFLAGS} mechanism passes the flags to the sub-@code{make} +(@pxref{Options/Recursion, ,Communicating Options to a +Sub-@code{make}}), so your request to touch the files, or print the +commands, is propagated to the subsystem.@refill @node Variables/Recursion, Options/Recursion, MAKE Variable, Recursion @subsection Communicating Variables to a Sub-@code{make} -@cindex environment and recursion +@cindex sub-@code{make} +@cindex environment, and recursion +@cindex exporting variables +@cindex variables, environment +@cindex variables, exporting +@cindex recursion, and environment +@cindex recursion, and variables + +Variable values of the top-level @code{make} can be passed to the +sub-@code{make} through the environment by explicit request. These +variables are defined in the sub-@code{make} as defaults, but do not +override what is specified in the sub-@code{make}'s makefile unless +you use the @samp{-e} switch +(@pxref{Options Summary, ,Summary of Options}).@refill + +To pass down, or @dfn{export}, a variable, @code{make} adds the variable +and its value to the environment for running each command. The +sub-@code{make}, in turn, uses the environment to initialize its table +of variable values. @xref{Environment, ,Variables from the +Environment}. + +Except by explicit request, @code{make} exports a variable only if it +is either defined in the environment initially or set on the command +line, and if its name consists only of letters, numbers, and underscores. +Some shells cannot cope with environment variable names consisting of +characters other than letters, numbers, and underscores. + +Variables are @emph{not} normally passed down if they were created by +default by @code{make} (@pxref{Implicit Variables, ,Variables Used by +Implicit Rules}). The sub-@code{make} will define these for +itself.@refill -Most variable values of the top-level @code{make} are passed to the -sub-@code{make} through the environment. These variables are defined in -the sub-@code{make} as defaults, but do not override what is specified -in the sub-@code{make}'s makefile. - -Variables are passed down if their names consist only of letters, -numbers and underscores. Some shells cannot cope with environment -variable names consisting of characters other than letters, numbers, -and underscores. - -Variable are @emph{not} passed down if they were created by default by -@code{make} (@pxref{Implicit Variables}). The sub-@code{make} will -define these for itself.@refill - -The way this works is that @code{make} adds each variable and its value -to the environment for running each command. The sub-@code{make}, in -turn, uses the environment to initialize its table of variable values. -@xref{Environment}. +@findex export +If you want to export specific variables to a sub-@code{make}, use the +@code{export} directive, like this: +@example +export @var{variable} @dots{} +@end example + +@noindent +@findex unexport +If you want to @emph{prevent} a variable from being exported, use the +@code{unexport} directive, like this: + +@example +unexport @var{variable} @dots{} +@end example + +@noindent +As a convenience, you can define a variable and export it at the same +time by doing: + +@example +export @var{variable} = value +@end example + +@noindent +has the same result as: + +@example +@var{variable} = value +export @var{variable} +@end example + +@noindent +and + +@example +export @var{variable} := value +@end example + +@noindent +has the same result as: + +@example +@var{variable} := value +export @var{variable} +@end example + +You may notice that the @code{export} and @code{unexport} directives +work in @code{make} in the same way they work in the shell, @code{sh}. + +If you want all variables to be exported by default, you can use +@code{export} by itself: + +@example +export +@end example + +@noindent +This tells @code{make} that variables which are not explicitly mentioned +in an @code{export} or @code{unexport} directive should be exported. +Any variable given in an @code{unexport} directive will still @emph{not} +be exported. If you use @code{export} by itself to export variables by +default, variables whose names contain characters other than +alphanumerics and underscores will not be exported unless specifically +mentioned in an @code{export} directive.@refill + +@findex .EXPORT_ALL_VARIABLES +The behavior elicited by an @code{export} directive by itself was the +default in older versions of GNU @code{make}. If your makefiles depend +on this behavior and you want to be compatible with old versions of +@code{make}, you can write a rule for the special target +@code{.EXPORT_ALL_VARIABLES} instead of using the @code{export} directive. +This will be ignored by old @code{make}s, while the @code{export} +directive will cause a syntax error.@refill +@cindex compatibility in exporting + +Likewise, you can use @code{unexport} by itself to tell @code{make} +@emph{not} to export variables by default. Since this is the default +behavior, you would only need to do this if @code{export} had been used +by itself earlier (in an included makefile, perhaps). You +@strong{cannot} use @code{export} and @code{unexport} by themselves to +have variables exported for some commands and not for others. The last +@code{export} or @code{unexport} directive that appears by itself +determines the behavior for the entire run of @code{make}.@refill + @vindex MAKELEVEL -As a special feature, the variable @code{MAKELEVEL} is changed when it is -passed down from level to level. This variable's value is a string which -is the depth of the level as a decimal number. The value is @samp{0} for -the top-level @code{make}; @samp{1} for a sub-@code{make}, @samp{2} for a -sub-sub-@code{make}, and so on. The incrementation happens when -@code{make} sets up the environment for a command.@refill - -The main use of @code{MAKELEVEL} is to test it in a conditional directive -(@pxref{Conditionals}); this way you can write a makefile that behaves one -way if run recursively and another way if run directly by you. +@cindex recursion, level of +As a special feature, the variable @code{MAKELEVEL} is changed when it +is passed down from level to level. This variable's value is a string +which is the depth of the level as a decimal number. The value is +@samp{0} for the top-level @code{make}; @samp{1} for a sub-@code{make}, +@samp{2} for a sub-sub-@code{make}, and so on. The incrementation +happens when @code{make} sets up the environment for a command.@refill + +The main use of @code{MAKELEVEL} is to test it in a conditional +directive (@pxref{Conditionals, ,Conditional Parts of Makefiles}); this +way you can write a makefile that behaves one way if run recursively and +another way if run directly by you.@refill @vindex MAKEFILES You can use the variable @code{MAKEFILES} to cause all sub-@code{make} -commands to use additional makefiles. The value of @code{MAKEFILES} is a -whitespace-separated list of filenames. This variable, if defined in the -outer-level makefile, is passed down through the environment as usual; then +commands to use additional makefiles. The value of @code{MAKEFILES} is +a whitespace-separated list of file names. This variable, if defined in +the outer-level makefile, is passed down through the environment; then it serves as a list of extra makefiles for the sub-@code{make} to read -before the usual or specified ones. @xref{MAKEFILES Variable}. +before the usual or specified ones. @xref{MAKEFILES Variable, ,The +Variable @code{MAKEFILES}}.@refill @node Options/Recursion, -w Option, Variables/Recursion, Recursion @subsection Communicating Options to a Sub-@code{make} -@cindex options and recursion +@cindex options, and recursion +@cindex recursion, and options @vindex MAKEFLAGS Flags such as @samp{-s} and @samp{-k} are passed automatically to the sub-@code{make} through the variable @code{MAKEFLAGS}. This variable is set up automatically by @code{make} to contain the flag letters that -@code{make} received. Thus, if you do @samp{make -ks} then +@code{make} received. Thus, if you do @w{@samp{make -ks}} then @code{MAKEFLAGS} gets the value @samp{ks}.@refill As a consequence, every sub-@code{make} gets a value for @code{MAKEFLAGS} in its environment. In response, it takes the flags from that value and -processes them as if they had been given as arguments. @xref{Options}. +processes them as if they had been given as arguments. +@xref{Options Summary, ,Summary of Options}. +@cindex @code{-C}, and recursion +@cindex @code{-f}, and recursion +@cindex @code{-I}, and recursion +@cindex @code{-o}, and recursion +@cindex @code{-W}, and recursion +@cindex @code{--directory}, and recursion +@cindex @code{--file}, and recursion +@cindex @code{--include-dir}, and recursion +@cindex @code{--old-file}, and recursion +@cindex @code{--assume-old}, and recursion +@cindex @code{--assume-new}, and recursion +@cindex @code{--new-file}, and recursion +@cindex recursion, and @code{-C} +@cindex recursion, and @code{-f} +@cindex recursion, and @code{-I} +@cindex recursion, and @code{-o} +@cindex recursion, and @code{-W} The options @samp{-C}, @samp{-f}, @samp{-I}, @samp{-o}, and @samp{-W} are not put into @code{MAKEFLAGS}; these options are not passed down.@refill -The @samp{-j} (@pxref{Parallel}) option is a special case. If you set +@cindex @code{-j}, and recursion +@cindex @code{--jobs}, and recursion +@cindex recursion, and @code{-j} +@cindex job slots, and recursion +The @samp{-j} option is a special case +(@pxref{Parallel, ,Parallel Execution}). If you set it to some numeric value, @samp{-j 1} is always put into @code{MAKEFLAGS} instead of the value you specified. This is because if -the @samp{-j} option were passed down to sub-@code{make}s, you would get +the @w{@samp{-j}} option were passed down to sub-@code{make}s, you would get many more jobs running in parallel than you asked for. If you give @samp{-j} with no numeric argument, meaning to run as many jobs as possible in parallel, this is passed down, since multiple infinities are no more than one.@refill -If you don't want to pass the other flags down, you must change the +If you do not want to pass the other flags down, you must change the value of @code{MAKEFLAGS}, like this: @example @@ -2141,16 +3306,17 @@ @noindent but now @code{MAKEFLAGS} makes this usage redundant. -@cindex setting options from the environment -@cindex options, setting from the environment +@cindex setting options from environment +@cindex options, setting from environment @cindex setting options in makefiles @cindex options, setting in makefiles The @code{MAKEFLAGS} and @code{MFLAGS} variables can also be useful if you -want to have certain options, such as @samp{-k} (@pxref{Options}) set each -time you run @code{make}. Just put @samp{MAKEFLAGS=k} or @samp{MFLAGS=-k} -in your environment. These variables may also be set in makefiles, so a -makefile can specify additional flags that should also be in effect for -that makefile.@refill +want to have certain options, such as @samp{-k} +(@pxref{Options Summary, ,Summary of Options}) +set each time you run @code{make}. Just put @samp{MAKEFLAGS=k} or +@w{@samp{MFLAGS=-k}} in your environment. These variables may also be +set in makefiles, so a makefile can specify additional flags that should +also be in effect for that makefile.@refill If you do put @code{MAKEFLAGS} or @code{MFLAGS} in your environment, you should be sure not to include any options that will drastically affect @@ -2161,14 +3327,17 @@ probably annoying effects.@refill @node -w Option, , Options/Recursion, Recursion -@subsection The @samp{-w} Option +@subsection The @samp{--print-directory} Option +@cindex directories, printing them +@cindex printing directories +@cindex recursion, and printing directories If you use several levels of recursive @code{make} invocations, the -@samp{-w} option can make the output a lot easier to understand by showing -each directory as @code{make} starts processing it and as @code{make} -finishes processing it. For example, if @samp{make -w} is run in the -directory @file{/u/gnu/make}, @code{make} will print a line of the -form:@refill +@samp{-w} or @w{@samp{--print-directory}} option can make the output a +lot easier to understand by showing each directory as @code{make} +starts processing it and as @code{make} finishes processing it. For +example, if @samp{make -w} is run in the directory @file{/u/gnu/make}, +@code{make} will print a line of the form:@refill @example make: Entering directory `/u/gnu/make'. @@ -2184,9 +3353,22 @@ @noindent when processing is completed. +@cindex @code{-C}, and @code{-w} +@cindex @code{--directory}, and @code{--print-directory} +@cindex recursion, and @code{-w} +@cindex @code{-w}, and @code{-C} +@cindex @code{-w}, and recursion +@cindex @code{--print-directory}, and @code{--directory} +@cindex @code{--print-directory}, and recursion +Normally, you do not need to specify this option because @samp{make} +does it for you: @samp{-w} is turned on automatically when you use the +@samp{-C} option, and in sub-@code{make}s (unless you also use +@samp{-s}, which says to be silent). + @node Sequences, Empty Commands, Recursion, Commands @section Defining Canned Command Sequences @cindex sequences of commands +@cindex commands, sequences of When the same sequence of commands is useful in making various targets, you can define it as a canned sequence with the @code{define} directive, and @@ -2202,6 +3384,7 @@ mv y.tab.c $@@ endef @end example +@cindex @code{yacc} @noindent Here @code{run-yacc} is the name of the variable being defined; @@ -2209,16 +3392,18 @@ commands. The @code{define} directive does not expand variable references and function calls in the canned sequence; the @samp{$} characters, parentheses, variable names, and so on, all become part of the value of the -variable you are defining. @xref{Defining}, for a complete explanation of -@code{define}. +variable you are defining. +@xref{Defining, ,Defining Variables Verbatim}, +for a complete explanation of @code{define}. -The first command in this example runs Yacc on the first dependency (of -whichever rule uses the canned sequence). The output file from Yacc is +The first command in this example runs Yacc on the first dependency of +whichever rule uses the canned sequence. The output file from Yacc is always named @file{y.tab.c}. The second command moves the output to the rule's target file name. To use the canned sequence, substitute the variable into the commands of a -rule. You can substitute it like any other variable (@pxref{Reference}). +rule. You can substitute it like any other variable +(@pxref{Reference, ,Basics of Variable References}). Because variables defined by @code{define} are recursively expanded variables, all the variable references you wrote inside the @code{define} are expanded now. For example: @@ -2229,16 +3414,18 @@ @end example @noindent -@samp{foo.y} will substituted for the variable @samp{$^} when it occurs in +@samp{foo.y} will be substituted for the variable @samp{$^} when it occurs in @code{run-yacc}'s value, and @samp{foo.c} for @samp{$@@}.@refill This is a realistic example, but this particular one is not needed in practice because @code{make} has an implicit rule to figure out these -commands based on the file names involved. @xref{Implicit}. +commands based on the file names involved +(@pxref{Implicit Rules, ,Using Implicit Rules}). @node Empty Commands, , Sequences, Commands -@section Defining Empty Commands +@section Using Empty Commands @cindex empty commands +@cindex commands, empty It is sometimes useful to define commands which do nothing. This is done simply by giving a command that consists of nothing but whitespace. For @@ -2245,7 +3432,7 @@ example: @example -target:; +target: ; @end example @noindent @@ -2253,18 +3440,20 @@ line beginning with a tab character to define an empty command string, but this would be confusing because such a line looks empty. +@findex .DEFAULT@r{, and empty commands} You may be wondering why you would want to define a command string that does nothing. The only reason this is useful is to prevent a target from getting implicit commands (from implicit rules or the -@code{.DEFAULT} special target; @pxref{Implicit} and @pxref{Last Resort}). +@code{.DEFAULT} special target; @pxref{Implicit Rules} and +@pxref{Last Resort, ,Defining Last-Resort Default Rules}).@refill You may be inclined to define empty command strings for targets that are not actual files, but only exist so that their dependencies can be -remade. However, this is not the best way to do that, because if the -target file actually does exist, its dependencies may not be remade. -@xref{Phony Targets}, for a better way to do this. +remade. However, this is not the best way to do that, because the +dependencies may not be remade properly if the target file actually does exist. +@xref{Phony Targets, ,Phony Targets}, for a better way to do this. -@node Variables, Conditionals, Commands, Top +@node Using Variables, Conditionals, Commands, Top @chapter How to Use Variables @cindex variable @cindex value @@ -2271,42 +3460,55 @@ @cindex recursive variable expansion @cindex simple variable expansion -A @dfn{variable} is a name defined within @code{make} to represent a string -of text, called the variable's @dfn{value}. These values can be -substituted by explicit request into targets, dependencies, commands and -other parts of the makefile. +A @dfn{variable} is a name defined in a makefile to represent a string +of text, called the variable's @dfn{value}. These values are +substituted by explicit request into targets, dependencies, commands, +and other parts of the makefile. (In some other versions of @code{make}, +variables are called @dfn{macros}.) +@cindex macro + +Variables and functions in all parts of a makefile are expanded when +read, except for the shell commands in rules, the right-hand sides of +variable definitions using @samp{=}, and the bodies of variable +definitions using the @code{define} directive.@refill Variables can represent lists of file names, options to pass to compilers, programs to run, directories to look in for source files, directories to write output in, or anything else you can imagine. -A variable name may be any sequence characters not containing @samp{:}, +A variable name may be any sequence of characters not containing @samp{:}, @samp{#}, @samp{=}, or leading or trailing whitespace. However, -variable names containing characters other than letters, numbers and +variable names containing characters other than letters, numbers, and underscores should be avoided, as they may be given special meanings in the -future, and they are not passed through the environment to a -sub-@code{make} (@pxref{Variables/Recursion}). +future, and with some shells they cannot be passed through the environment to a +sub-@code{make} +(@pxref{Variables/Recursion, ,Communicating Variables to a Sub-@code{make}}). It is traditional to use upper case letters in variable names, but we recommend using lower case letters for variable names that serve internal purposes in the makefile, and reserving upper case for parameters that control implicit rules or for parameters that the user should override with -command options (@pxref{Overriding}). +command options (@pxref{Overriding, ,Overriding Variables}). @menu -* Reference:: How to use the value of a variable. -* Flavors:: Variables come in two flavors. -* Advanced:: Advanced features for referencing a variable. -* Values:: All the ways variables get their values. -* Setting:: How to set a variable in the makefile. -* Override Directive:: Setting a variable in the makefile - even if the user has set it with a command argument. -* Defining:: An alternate way to set a variable to a verbatim string. -* Environment:: Variable values can come from the environment. +* Reference:: How to use the value of a variable. +* Flavors:: Variables come in two flavors. +* Advanced:: Advanced features for referencing a variable. +* Values:: All the ways variables get their values. +* Setting:: How to set a variable in the makefile. +* Override Directive:: How to set a variable in the makefile even if + the user has set it with a command argument. +* Defining:: An alternate way to set a variable + to a verbatim string. +* Environment:: Variable values can come from the environment. @end menu -@node Reference, Flavors, Variables, Variables +@node Reference, Flavors, , Using Variables @section Basics of Variable References +@cindex variables, how to reference +@cindex reference to variables +@cindex @code{$}, in variable reference +@cindex dollar sign (@code{$}), in variable reference To substitute a variable's value, write a dollar sign followed by the name of the variable in parentheses or braces: either @samp{$(foo)} or @@ -2315,28 +3517,32 @@ the effect of a single dollar sign in a file name or command. Variable references can be used in any context: targets, dependencies, -commands, most directives, and new variable values. Here is a common kind -of example, where a variable holds the names of all the object files in a -program: +commands, most directives, and new variable values. Here is an +example of a common case, where a variable holds the names of all the +object files in a program: @example +@group objects = program.o foo.o utils.o program : $(objects) cc -o program $(objects) $(objects) : defs.h +@end group @end example Variable references work by strict textual substitution. Thus, the rule @example +@group foo = c -prog.o : prog.c - $(foo)$(foo) prog.c +prog.o : prog.$(foo) + $(foo)$(foo) -$(foo) prog.$(foo) +@end group @end example @noindent -could be used to compile a C program @file{prog.c}. Since spaces around +could be used to compile a C program @file{prog.c}. Since spaces before the variable value are ignored in variable assignments, the value of @code{foo} is precisely @samp{c}. (Don't actually write your makefiles this way!) @@ -2345,24 +3551,29 @@ open-parenthesis or open-brace treats that single character as the variable name. Thus, you could reference the variable @code{x} with @samp{$x}. However, this practice is strongly discouraged, except in -the case of the automatic variables (@pxref{Automatic}). +the case of the automatic variables (@pxref{Automatic, ,Automatic Variables}). -@node Flavors, Advanced, Reference, Variables +@node Flavors, Advanced, Reference, Using Variables @section The Two Flavors of Variables -@cindex flavors (of variables) +@cindex flavors of variables @cindex recursive variable expansion +@cindex variables, flavors +@cindex recursively expanded variables +@cindex variables, recursively expanded -There are two ways that a variables in GNU @code{make} can have a value; -we call them two @dfn{flavors} of variables. The two flavors are +There are two ways that a variable in GNU @code{make} can have a value; +we call them the two @dfn{flavors} of variables. The two flavors are distinguished in how they are defined and in what they do when expanded. +@cindex = The first flavor of variable is a @dfn{recursively expanded} variable. Variables of this sort are defined by lines using @samp{=} -(@pxref{Setting}). The value you specify is installed verbatim; if it -contains references to other variables, these references are expanded -whenever this variable is substituted (in the course of expanding some -other string). When this happens, it is called @dfn{recursive -expansion}. +(@pxref{Setting, ,Setting Variables}) or by the @code{define} directive +(@pxref{Defining, ,Defining Variables Verbatim}). The value you specify +is installed verbatim; if it contains references to other variables, +these references are expanded whenever this variable is substituted (in +the course of expanding some other string). When this happens, it is +called @dfn{recursive expansion}.@refill For example, @@ -2390,7 +3601,7 @@ @noindent will do what was intended: when @samp{CFLAGS} is expanded in a command, it will expand to @samp{-Ifoo -Ibar -O}. A major disadvantage is that you -can't append something on the end of a variable, as in +cannot append something on the end of a variable, as in @example CFLAGS = $(CFLAGS) -O @@ -2399,8 +3610,11 @@ @noindent because it will cause an infinite loop in the variable expansion. (Actually @code{make} detects the infinite loop and reports an error.) +@cindex loops in variable expansion +@cindex variables, loops in expansion -Another disadvantage is that any functions (@pxref{Functions}) +Another disadvantage is that any functions +(@pxref{Functions, ,Functions for Transforming Text}) referenced in the definition will be executed every time the variable is expanded. This makes @code{make} run slower; worse, it causes the @code{wildcard} and @code{shell} functions to give unpredictable results @@ -2408,10 +3622,14 @@ times. To avoid all the problems and inconveniences of recursively expanded -variables, there is another flavor: @dfn{simply expanded} variables. +variables, there is another flavor: simply expanded variables. -Simply expanded variables are defined by lines using @samp{:=} -(@pxref{Setting}). The value of a simply expanded variable is scanned +@cindex simply expanded variables +@cindex variables, simply expanded +@cindex := +@dfn{Simply expanded variables} are defined by lines using @samp{:=} +(@pxref{Setting, ,Setting Variables}). +The value of a simply expanded variable is scanned once and for all, expanding any references to other variables and functions, when the variable is defined. The actual value of the simply expanded variable is the result of expanding the text that you write. @@ -2435,12 +3653,47 @@ When a simply expanded variable is referenced, its value is substituted verbatim. +Here is a somewhat more complicated example, illustrating the use of +@samp{:=} in conjunction with the @code{shell} function. +(@xref{Shell Function, , The @code{shell} Function}.) This example +also shows use of the variable @code{MAKELEVEL}, which is changed +when it is passed down from level to level. +(@xref{Variables/Recursion, , Communicating Variables to a +Sub-@code{make}}, for information about @code{MAKELEVEL}.) + +@vindex MAKELEVEL +@vindex MAKE +@example +@group +ifeq (0,$@{MAKELEVEL@}) +cur-dir := $(shell pwd) +whoami := $(shell whoami) +host-type := $(shell arch) +MAKE := $@{MAKE@} host-type=$@{host-type@} whoami=$@{whoami@} +endif +@end group +@end example + +@noindent +An advantage of this use of @samp{:=} is that a typical +`descend into a directory' command then looks like this: + +@example +@group +$@{subdirs@}: + $@{MAKE@} cur-dir=$@{cur-dir@}/$@@ -C $@@ all +@end group +@end example + Simply expanded variables generally make complicated makefile programming more predictable because they work like variables in most programming languages. They allow you to redefine a variable using its own value (or its value processed in some way by one of the expansion functions) and to -use the expansion functions much more efficiently (@pxref{Functions}). +use the expansion functions much more efficiently +(@pxref{Functions, ,Functions for Transforming Text}). +@cindex spaces, in variable values +@cindex variables, spaces in values You can also use them to introduce controlled leading or trailing spaces into variable values. Such spaces are discarded from your input before substitution of variable references and function calls; this means you can @@ -2455,7 +3708,7 @@ @noindent Here the value of the variable @code{space} is precisely one space. -@node Advanced, Values, Flavors, Variables +@node Advanced, Values, Flavors, Using Variables @section Advanced Features for Reference to Variables @cindex reference to variables @@ -2463,15 +3716,20 @@ variables in more flexible ways. @menu -* Substitution Refs:: Referencing a variable with substitutions on the value. -* Computed Names:: Computing the name of the variable to refer to. +* Substitution Refs:: Referencing a variable with + substitutions on the value. +* Computed Names:: Computing the name of the variable to refer to. @end menu -@node Substitution Refs, Computed Names, Advanced, Advanced +@node Substitution Refs, Computed Names, , Advanced @subsection Substitution References @cindex modified variable reference @cindex substitution variable reference +@cindex variables, modified reference +@cindex variables, substitution reference +@cindex variables, substituting suffix in +@cindex suffix, substituting in variables A @dfn{substitution reference} substitutes the value of a variable with alterations that you specify. It has the form @samp{$(@var{var}:@var{a}=@var{b})} (or @@ -2490,24 +3748,29 @@ @end example @noindent -sets @samp{bar} to @samp{a.c b.c c.c}. @xref{Setting}. +sets @samp{bar} to @samp{a.c b.c c.c}. @xref{Setting, ,Setting Variables}. A substitution reference is actually an abbreviation for use of the -@code{patsubst} expansion function (@pxref{Text Functions}). We provide +@code{patsubst} expansion function (@pxref{Text Functions, ,Functions for String Substitution and Analysis}). We provide substitution references as well as @code{patsubst} for compatibility with other implementations of @code{make}. -Another type of substitution reference lets you use the full power of the -@code{patsubst} function. It has the same form +@findex patsubst +Another type of substitution reference lets you use the full power of +the @code{patsubst} function. It has the same form @samp{$(@var{var}:@var{a}=@var{b})} described above, except that now -@var{a} must contain a single @samp{%} character. This case is equivalent -to @samp{$(patsubst @var{a},@var{b},$(@var{var}))}. -@xref{Text Functions}, for a description of the @code{patsubst} function. -For example:@refill +@var{a} must contain a single @samp{%} character. This case is +equivalent to @samp{$(patsubst @var{a},@var{b},$(@var{var}))}. +@xref{Text Functions, ,Functions for String Substitution and Analysis}, +for a description of the @code{patsubst} function.@refill @example +@group +@exdent For example: + foo := a.o b.o c.o bar := $(foo:%.o=%.c) +@end group @end example @noindent @@ -2517,14 +3780,18 @@ @subsection Computed Variable Names @cindex nested variable reference @cindex computed variable name -@cindex variable reference, nested +@cindex variables, computed names +@cindex variables, nested references +@cindex variables, @samp{$} in name +@cindex @code{$}, in variable name +@cindex dollar sign (@code{$}), in variable name Computed variable names are a complicated concept needed only for sophisticated makefile programming. For most purposes you need not -consider about them, except to know that making a variable with a dollar -sign in its name might have strange results. However, if you are the -type that wants to understand everything, or you are actually interested -in what they do, read on. +consider them, except to know that making a variable with a dollar sign +in its name might have strange results. However, if you are the type +that wants to understand everything, or you are actually interested in +what they do, read on. Variables may be referenced inside the name of a variable. This is called a @dfn{computed variable name} or a @dfn{nested variable @@ -2573,15 +3840,17 @@ which becomes @samp{$(z)} which becomes @samp{Hello}. Nested variable references can also contain modified references and -function invocations (@pxref{Functions}), just like any other reference. -For example, using the @code{subst} function (@pxref{Text Functions}): +function invocations (@pxref{Functions, ,Functions for Transforming Text}), just like any other reference. +For example, using the @code{subst} function (@pxref{Text Functions, ,Functions for String Substitution and Analysis}): @example +@group x = variable1 variable2 := Hello y = $(subst 1,2,$(x)) z = y a := $($($(z))) +@end group @end example @noindent @@ -2598,18 +3867,25 @@ invariant text. For example, @example +@group a_dirs := dira dirb 1_dirs := dir1 dir2 +@end group +@group a_files := filea fileb 1_files := file1 file2 +@end group +@group ifeq "$(use_a)" "yes" a1 := a else a1 := 1 endif +@end group +@group ifeq "$(use_dirs)" "yes" df := dirs else @@ -2617,6 +3893,7 @@ endif dirs := $($(a1)_$(df)) +@end group @end example @noindent @@ -2627,10 +3904,12 @@ Computed variable names can also be used in substitution references: @example +@group a_objects := a.o b.o c.o 1_objects := 1.o 2.o 3.o -sources := $($(a1)_object:.o=.c) +sources := $($(a1)_objects:.o=.c) +@end group @end example @noindent @@ -2643,15 +3922,21 @@ the expansion of nested references. For example, @example +@group ifdef do_sort func := sort else func := strip endif +@end group +@group bar := a d b g q c +@end group +@group foo := $($(func) $(bar)) +@end group @end example @noindent @@ -2661,12 +3946,30 @@ This restriction could be removed in the future if that change is shown to be a good idea. +You can also use computed variable names in the left-hand side of a +variable assignment, or in a @code{define} directive, as in: + +@example +dir = foo +$(dir)_sources := $(wildcard $(dir)/*.c) +define $(dir)_print +lpr $($(dir)_sources) +endef +@end example + +@noindent +This example defines the variables @samp{dir}, @samp{foo_sources}, and +@samp{foo_print}. + Note that @dfn{nested variable references} are quite different from -@dfn{recursively expanded variables} (@pxref{Flavors}), though both are +@dfn{recursively expanded variables} +(@pxref{Flavors, ,The Two Flavors of Variables}), though both are used together in complex ways when doing makefile programming.@refill -@node Values, Setting, Advanced, Variables +@node Values, Setting, Advanced, Using Variables @section How Variables Get Their Values +@cindex variables, how they get their values +@cindex value, how a variable gets it Variables can get values in several different ways: @@ -2673,26 +3976,28 @@ @itemize @bullet @item You can specify an overriding value when you run @code{make}. -@xref{Overriding}. +@xref{Overriding, ,Overriding Variables}. @item You can specify a value in the makefile, either -with an assignment (@pxref{Setting}) or with a -verbatim definition (@pxref{Defining}).@refill +with an assignment (@pxref{Setting, ,Setting Variables}) or with a +verbatim definition (@pxref{Defining, ,Defining Variables Verbatim}).@refill @item -Values are inherited from the environment. @xref{Environment}. +Variables in the environment become @code{make} variables. +@xref{Environment, ,Variables from the Environment}. @item Several @dfn{automatic} variables are given new values for each rule. -Each of these has a single conventional use. @xref{Automatic}. +Each of these has a single conventional use. +@xref{Automatic, ,Automatic Variables}. @item Several variables have constant initial values. -@xref{Implicit Variables}. +@xref{Implicit Variables, ,Variables Used by Implicit Rules}. @end itemize -@node Setting, Override Directive, Values, Variables +@node Setting, Override Directive, Values, Using Variables @section Setting Variables @cindex setting variables @cindex = @@ -2713,7 +4018,10 @@ Variables defined with @samp{=} are @dfn{recursively expanded} variables. Variables defined with @samp{:=} are @dfn{simply expanded} variables; these definitions can contain variable references which will be expanded before -the definition is made. @xref{Flavors}. +the definition is made. @xref{Flavors, ,The Two Flavors of Variables}. + +The variable name may contain function and variable references, which +are expanded when the line is read to find the actual variable name to use. There is no limit on the length of the value of a variable except the amount of swapping space on the computer. When a variable definition is @@ -2724,17 +4032,19 @@ Most variable names are considered to have the empty string as a value if you have never set them. Several variables have built-in initial values -that are not empty, but can be set by you in the usual ways -(@pxref{Implicit Variables}). Several special variables are set +that are not empty, but you can set them in the usual ways +(@pxref{Implicit Variables, ,Variables Used by Implicit Rules}). +Several special variables are set automatically to a new value for each rule; these are called the -@dfn{automatic} variables (@pxref{Automatic}). +@dfn{automatic} variables (@pxref{Automatic, ,Automatic Variables}). -@node Override Directive, Defining, Setting, Variables +@node Override Directive, Defining, Setting, Using Variables @section The @code{override} Directive @findex override @cindex overriding with @code{override} +@cindex variable, overriding -If a variable has been set with a command argument (@pxref{Overriding}), +If a variable has been set with a command argument (@pxref{Overriding, ,Overriding Variables}), then ordinary assignments in the makefile are ignored. If you want to set the variable in the makefile even though it was set with a command argument, you can use an @code{override} directive, which is a line that @@ -2774,28 +4084,35 @@ @noindent @iftex -See the next section. +See the next section for information about @code{define}. @end iftex @ifinfo -@xref{Defining}. +@xref{Defining, ,Defining Variables Verbatim}. @end ifinfo -@node Defining, Environment, Override Directive, Variables +@node Defining, Environment, Override Directive, Using Variables @section Defining Variables Verbatim @findex define @findex endef +@cindex verbatim variable definition +@cindex defining variables verbatim +@cindex variable, defining verbatim Another way to set the value of a variable is to use the @code{define} -directive. This directive has a different syntax which allows newline +directive. This directive has an unusual syntax which allows newline characters to be included in the value, which is convenient for defining -canned sequences of commands (@pxref{Sequences}). +canned sequences of commands +(@pxref{Sequences, ,Defining Canned Command Sequences}). The @code{define} directive is followed on the same line by the name of the variable and nothing more. The value to give the variable appears on the following lines. The end of the value is marked by a line containing just the word @code{endef}. Aside from this difference in syntax, @code{define} -works just like @samp{=}; it creates a recursively-expanded variable -(@pxref{Flavors}). +works just like @samp{=}: it creates a recursively-expanded variable +(@pxref{Flavors, ,The Two Flavors of Variables}). +The variable name may contain function and variable references, which +are expanded when the directive is read to find the actual variable name +to use. @example define two-lines @@ -2809,6 +4126,7 @@ part of the variable's value (except for the final newline which precedes the @code{endef} and is not considered part of the value).@refill +@need 800 The previous example is functionally equivalent to this: @example @@ -2818,9 +4136,9 @@ @noindent since the shell will interpret the semicolon and the newline identically. -If you want variable definitions made with @code{define} to take precedence -over command-line variable definitions, the @code{override} directive can -be used together with @code{define}: +If you want variable definitions made with @code{define} to take +precedence over command-line variable definitions, you can use the +@code{override} directive together with @code{define}: @example override define two-lines @@ -2830,19 +4148,21 @@ @end example @noindent -@xref{Override Directive}. +@xref{Override Directive, ,The @code{override} Directive}. -@node Environment, , Defining, Variables +@node Environment, , Defining, Using Variables @section Variables from the Environment +@cindex variable, environment @cindex environment -Variables in @code{make} can come from the environment with which +Variables in @code{make} can come from the environment in which @code{make} is run. Every environment variable that @code{make} sees when it starts up is transformed into a @code{make} variable with the same name and value. But an explicit assignment in the makefile, or with a command argument, overrides the environment. (If the @samp{-e} flag is specified, then values from the environment override assignments in the makefile. -@xref{Options}. But this is not recommended practice.) +@xref{Options Summary, ,Summary of Options}. +But this is not recommended practice.) Thus, by setting the variable @code{CFLAGS} in your environment, you can cause all C compilations in most makefiles to use the compiler switches you @@ -2851,11 +4171,14 @@ this is not totally reliable; some makefiles set @code{CFLAGS} explicitly and therefore are not affected by the value in the environment.) -When @code{make} is invoked recursively, variables defined in the outer -invocation are automatically passed to inner invocations through the -environment (@pxref{Recursion}). This is the main purpose of turning -environment variables into @code{make} variables, and it requires no -attention from you.@refill +When @code{make} is invoked recursively, variables defined in the +outer invocation can be passed to inner invocations through the +environment (@pxref{Recursion, ,Recursive Use of @code{make}}). By +default, only variables that came from the environment or the command +line are passed to recursive invocations. You can use the +@code{export} directive to pass other variables. +@xref{Variables/Recursion, , Communicating Variables to a +Sub-@code{make}}, for full details. Other use of variables from the environment is not recommended. It is not wise for makefiles to depend for their functioning on environment variables @@ -2867,35 +4190,34 @@ which is normally present in the environment to specify the user's choice of interactive shell. It would be very undesirable for this choice to affect @code{make}. So @code{make} ignores the environment value of -@code{SHELL} if the value of @code{MAKELEVEL} is zero (which is normally -true except in recursive invocations of @code{make}).@refill +@code{SHELL}.@refill -@node Conditionals, Functions, Variables, Top +@node Conditionals, Functions, Using Variables, Top @chapter Conditional Parts of Makefiles @cindex conditionals A @dfn{conditional} causes part of a makefile to be obeyed or ignored -depending on the values of variables. Conditionals can compare the value -of one variable with another, or the value of a variable with a constant -string. Conditionals control what @code{make} actually ``sees'' in the -makefile, so they @emph{cannot} be used to control shell commands at the -time of execution.@refill +depending on the values of variables. Conditionals can compare the +value of one variable to another, or the value of a variable to +a constant string. Conditionals control what @code{make} actually +``sees'' in the makefile, so they @emph{cannot} be used to control shell +commands at the time of execution.@refill @menu -* Example: Conditional Example. An annotated example. -* Syntax: Conditional Syntax. Precise rules for syntax of conditionals. -* Flags: Testing Flags. Conditionals testing flags such as @samp{-t}. +* Conditional Example:: Example of a conditional +* Conditional Syntax:: The syntax of conditionals. +* Testing Flags:: Conditionals that test flags. @end menu -@node Conditional Example, Conditional Syntax, Conditionals, Conditionals +@node Conditional Example, Conditional Syntax, , Conditionals @section Example of a Conditional -This conditional tells @code{make} to use one set of libraries if the -@code{CC} variable is @samp{gcc}, and a different set of libraries -otherwise. It works by controlling which of two command lines will be used -as the command for a rule. The result is that @samp{CC=gcc} as an argument -to @code{make} changes not only which compiler is used but also which -libraries are linked. +The following example of a conditional tells @code{make} to use one set +of libraries if the @code{CC} variable is @samp{gcc}, and a different +set of libraries otherwise. It works by controlling which of two +command lines will be used as the command for a rule. The result is +that @samp{CC=gcc} as an argument to @code{make} changes not only which +compiler is used but also which libraries are linked. @example libs_for_gcc = -lgnu @@ -2927,10 +4249,11 @@ The @code{endif} directive ends the conditional. Every conditional must end with an @code{endif}. Unconditional makefile text follows. -Conditionals work at the textual level: the lines of the conditional are -treated as part of the makefile, or ignored, according to the condition. -This is why the larger syntactic units of the makefile, such as rules, may -cross the beginning or the end of the conditional. +As this example illustrates, conditionals work at the textual level: +the lines of the conditional are treated as part of the makefile, or +ignored, according to the condition. This is why the larger syntactic +units of the makefile, such as rules, may cross the beginning or the +end of the conditional. When the variable @code{CC} has the value @samp{gcc}, the above example has this effect: @@ -3016,6 +4339,25 @@ compare them. If they are identical, the @var{text-if-true} is effective; otherwise, the @var{text-if-false}, if any, is effective. +Often you want to test if a variable has a non-empty value. When the +value results from complex expansions of variables and functions, +expansions you would consider empty may actually contain whitespace +characters and thus are not seen as empty. However, you can use the +@code{strip} function (@pxref{Text Functions}) to avoid interpreting +whitespace as a non-empty value. For example: + +@example +@group +ifeq ($(strip $(foo)),) +@var{text-if-empty} +endif +@end group +@end example + +@noindent +will evaluate @var{text-if-empty} even if the expansion of +@code{$(foo)} contains whitespace characters. + @item ifneq (@var{arg1}, @var{arg2}) @itemx ifneq '@var{arg1}' '@var{arg2}' @itemx ifneq "@var{arg1}" "@var{arg2}" @@ -3031,6 +4373,37 @@ if any, is effective. Variables that have never been defined have an empty value. +Note that @code{ifdef} only tests whether a variable has a value. It +does not expand the variable to see if that value is nonempty. +Consequently, tests using @code{ifdef} return true for all definitions +except those like @code{foo =}. To test for an empty value, use +@w{@code{ifeq ($(foo),)}}. For example, + +@example +bar = +foo = $(bar) +ifdef foo +frobozz = yes +else +frobozz = no +endif +@end example + +@noindent +sets @samp{frobozz} to @samp{yes}, while: + +@example +foo = +ifdef foo +frobozz = yes +else +frobozz = no +endif +@end example + +@noindent +sets @samp{frobozz} to @samp{no}. + @item ifndef @var{variable-name} If the variable @var{variable-name} has an empty value, the @var{text-if-true} is effective; otherwise, the @var{text-if-false}, @@ -3050,11 +4423,17 @@ line, and spaces or tabs at the end. A comment starting with @samp{#} may appear at the end of the line. -Conditionals work at the textual level. The lines of the -@var{text-if-true} are read as part of the makefile if the condition is -true; if the condition is false, those lines are ignored completely. It -follows that syntactic units of the makefile, such as rules, may safely be -split across the beginning or the end of the conditional.@refill +Conditionals affect which lines of the makefile @code{make} uses. If +the condition is true, @code{make} reads the lines of the +@var{text-if-true} as part of the makefile; if the condition is false, +@code{make} ignores those lines completely. It follows that syntactic +units of the makefile, such as rules, may safely be split across the +beginning or the end of the conditional.@refill + +@code{make} evaluates conditionals when it reads a makefile. +Consequently, you cannot use automatic variables in the tests of +conditionals because they are not defined until commands are run +(@pxref{Automatic, , Automatic Variables}). To prevent intolerable confusion, it is not permitted to start a conditional in one makefile and end it in another. However, you may @@ -3066,8 +4445,10 @@ You can write a conditional that tests @code{make} command flags such as @samp{-t} by using the variable @code{MAKEFLAGS} together with the -@code{findstring} function. This is useful when @code{touch} is not -enough to make a file appear up to date. +@code{findstring} function +(@pxref{Text Functions, , Functions for String Substitution and Analysis}). +This is useful when @code{touch} is not enough to make a file appear up +to date. The @code{findstring} function determines whether one string appears as a substring of another. If you want to test for the @samp{-t} flag, @@ -3080,9 +4461,8 @@ @example archive.a: @dots{} ifneq (,$(findstring t,$(MAKEFLAGS))) - @@echo $(MAKE) > /dev/null - touch archive.a - ranlib -t archive.a + +touch archive.a + +ranlib -t archive.a else ranlib archive.a endif @@ -3089,10 +4469,9 @@ @end example @noindent -The @code{echo} command does nothing when executed; but its presence, with -a reference to the variable @code{MAKE}, marks the rule as ``recursive'' so -that its commands will be executed despite use of the @samp{-t} flag. -@xref{Recursion}. +The @samp{+} prefix marks those command lines as ``recursive'' so +that they will be executed despite use of the @samp{-t} flag. +@xref{Recursion, ,Recursive Use of @code{make}}. @node Functions, Running, Conditionals, Top @chapter Functions for Transforming Text @@ -3106,18 +4485,20 @@ call, just as a variable might be substituted. @menu -* Syntax of Functions:: How to write a function call. -* Text Functions:: General-purpose text manipulation functions. -* Filename Functions:: Functions for manipulating file names. -* Foreach Function:: Repeat some text with controlled variation. -* Origin Function:: Find where a variable got its value. -* Shell Function:: Substitute the output of a shell command. +* Syntax of Functions:: How to write a function call. +* Text Functions:: General-purpose text manipulation functions. +* Filename Functions:: Functions for manipulating file names. +* Foreach Function:: Repeat some text with controlled variation. +* Origin Function:: Find where a variable got its value. +* Shell Function:: Substitute the output of a shell command. @end menu -@node Syntax of Functions, Text Functions, Functions, Functions +@node Syntax of Functions, Text Functions, , Functions @section Function Call Syntax -@cindex $ (function call) -@cindex arguments +@cindex @code{$}, in function call +@cindex dollar sign (@code{$}), in function call +@cindex arguments of functions +@cindex functions, syntax of A function call resembles a variable reference. It looks like this: @@ -3135,20 +4516,18 @@ Here @var{function} is a function name; one of a short list of names that are part of @code{make}. There is no provision for defining new functions. -The @var{arguments} are the arguments of the function. They are separated -from the function name by one or more spaces and/or tabs, and if there is -more than one argument they are separated by commas. Such whitespace and -commas are not part of any argument's value. The delimiters which you use -to surround the function call, whether parentheses or braces, can appear in -an argument only in matching pairs; the other kind of delimiters may appear -singly. If the arguments themselves contain other function calls or -variable references, it is wisest to use the same kind of delimiters for -all the references; in other words, write @w{@samp{$(subst a,b,$(x))}}, not -@w{@samp{$(subst a,b,$@{x@})}}. This is both because it is clearer, and -because only one type of delimiters is matched to find the end of the -reference. Thus in @w{@samp{$(subst a,b,$@{subst c,d,$@{x@}@})}} -doesn't work because the second @code{subst} function invocation ends at -the first @samp{@}}, not the second. +The @var{arguments} are the arguments of the function. They are +separated from the function name by one or more spaces or tabs, and if +there is more than one argument, then they are separated by commas. +Such whitespace and commas are not part of an argument's value. The +delimiters which you use to surround the function call, whether +parentheses or braces, can appear in an argument only in matching pairs; +the other kind of delimiters may appear singly. If the arguments +themselves contain other function calls or variable references, it is +wisest to use the same kind of delimiters for all the references; write +@w{@samp{$(subst a,b,$(x))}}, not @w{@samp{$(subst a,b,$@{x@})}}. This +is because it is clearer, and because only one type of delimiter is +matched to find the end of the reference. The text written for each argument is processed by substitution of variables and function calls to produce the argument value, which @@ -3160,14 +4539,17 @@ argument as written. These characters can be put into the argument value by variable substitution. First define variables @code{comma} and @code{space} whose values are isolated comma and space characters, then -substitute those variables where such characters are wanted, like this: +substitute these variables where such characters are wanted, like this: @example +@group comma:= , +empty:= space:= $(empty) $(empty) foo:= a b c bar:= $(subst $(space),$(comma),$(foo)) # @r{bar is now `a,b,c'.} +@end group @end example @noindent @@ -3176,6 +4558,7 @@ @node Text Functions, Filename Functions, Syntax of Functions, Functions @section Functions for String Substitution and Analysis +@cindex functions, for text Here are some functions that operate on strings: @@ -3201,6 +4584,11 @@ @var{replacement} also contains a @samp{%}, the @samp{%} is replaced by the text that matched the @samp{%} in @var{pattern}.@refill +@cindex @code{%}, quoting in @code{patsubst} +@cindex @code{%}, quoting with @code{\} (backslash) +@cindex @code{\} (backslash), to quote @code{%} +@cindex backslash (@code{\}), to quote @code{%} +@cindex quoting @code{%}, in @code{patsubst} @samp{%} characters in @code{patsubst} function invocations can be quoted with preceding backslashes (@samp{\}). Backslashes that would otherwise quote @samp{%} characters can be quoted with more backslashes. @@ -3210,10 +4598,9 @@ @samp{%} characters go unmolested. For example, the pattern @file{the\%weird\\%pattern\\} has @samp{the%weird\} preceding the operative @samp{%} character, and @samp{pattern\\} following it. The -final two backslashes are left alone because they can't affect any +final two backslashes are left alone because they cannot affect any @samp{%} character.@refill - Whitespace between words is folded into single space characters; leading and trailing whitespace is discarded. @@ -3226,14 +4613,91 @@ @noindent produces the value @samp{x.c.o bar.o}. +Substitution references (@pxref{Substitution Refs, ,Substitution +References}) are a simpler way to get the effect of the @code{patsubst} +function: + +@example +$(@var{var}:@var{pattern}=@var{replacement}) +@end example + +@noindent +is equivalent to + +@example +$(patsubst @var{pattern},@var{replacement},$(@var{var})) +@end example + +The second shorthand simplifies one of the most common uses of +@code{patsubst}: replacing the suffix at the end of file names. + +@example +$(@var{var}:@var{suffix}=@var{replacement}) +@end example + +@noindent +is equivalent to + +@example +$(patsubst %@var{suffix},%@var{replacement},$(@var{var})) +@end example + +@noindent +For example, you might have a list of object files: + +@example +objects = foo.o bar.o baz.o +@end example + +@noindent +To get the list of corresponding source files, you could simply write: + +@example +$(objects:.o=.c) +@end example + +@noindent +instead of using the general form: + +@example +$(patsubst %.o,%.c,$(objects)) +@end example + @item $(strip @var{string}) +@cindex stripping whitespace +@cindex whitespace, stripping +@cindex spaces, stripping @findex strip Removes leading and trailing whitespace from @var{string} and replaces each internal sequence of one or more whitespace characters with a -single space. Thus, @samp{$(strip a b c )} results in @samp{a b c}. +single space. Thus, @samp{$(strip a b c )} results in @w{@samp{a b c}}. + +The function @code{strip} can be very useful when used in conjunction +with conditionals. When comparing something with the null string +@samp{""} using @code{ifeq} or @code{ifneq}, you usually want a string +of just whitespace to match the null string (@pxref{Conditionals}). + +Thus, the following may fail to have the desired results: + +@example +.PHONY: all +ifneq "$(needs_made)" "" +all: $(needs_made) +else +all:;@@echo 'Nothing to make!' +endif +@end example +@noindent +Replacing the variable reference @w{@samp{$(needs_made)}} with the +function call @w{@samp{$(strip $(needs_made))}} in the @code{ifneq} +directive would make it more robust.@refill + @item $(findstring @var{find},@var{in}) @findex findstring +@cindex searching for strings +@cindex finding strings +@cindex strings, searching for Searches @var{in} for an occurrence of @var{find}. If it occurs, the value is @var{find}; otherwise, the value is empty. You can use this function in a conditional to test for the presence of a specific @@ -3245,38 +4709,65 @@ @end example @noindent -produce the values @samp{a} and @samp{}, respectively. @xref{Testing -Flags}, for a practical application of @code{findstring}.@refill +produce the values @samp{a} and @samp{} (the empty string), +respectively. @xref{Testing Flags}, for a practical application of +@code{findstring}.@refill -@item $(filter @var{pattern},@var{text}) +@need 750 @findex filter +@cindex filtering words +@cindex words, filtering +@item $(filter @var{pattern}@dots{},@var{text}) Removes all whitespace-separated words in @var{text} that do -@emph{not} match @var{pattern}, returning only matching words. The -pattern is written using @samp{%}, just like the patterns used in -@code{patsubst} function above.@refill +@emph{not} match any of the @var{pattern} words, returning only +matching words. The patterns are written using @samp{%}, just like +the patterns used in the @code{patsubst} function above.@refill The @code{filter} function can be used to separate out different types -of strings (such as filenames) in a variable. For example: +of strings (such as file names) in a variable. For example: @example -sources := foo.c bar.c ugh.h +sources := foo.c bar.c baz.s ugh.h foo: $(sources) - cc $(filter %.c,$(sources)) -o foo + cc $(filter %.c %.s,$(sources)) -o foo @end example @noindent -says that @file{foo} depends of @file{foo.c}, @file{bar.c} and -@file{ugh.h} but only @file{foo.c} and @file{bar.c} should be specified -in the command to the compiler.@refill +says that @file{foo} depends of @file{foo.c}, @file{bar.c}, +@file{baz.s} and @file{ugh.h} but only @file{foo.c}, @file{bar.c} and +@file{baz.s} should be specified in the command to the +compiler.@refill -@item $(filter-out @var{pattern},@var{text}) +@item $(filter-out @var{pattern}@dots{},@var{text}) @findex filter-out +@cindex filtering out words +@cindex words, filtering out Removes all whitespace-separated words in @var{text} that @emph{do} -match @var{pattern}, returning only the words that match. This is the -exact opposite of the @code{filter} function.@refill +match the @var{pattern} words, returning only the words that @emph{do +not} match. This is the exact opposite of the @code{filter} +function.@refill -@item $(sort @var{list}) +For example, given: + +@example +@group +objects=main1.o foo.o main2.o bar.o +mains=main1.o main2.o +@end group +@end example + +@noindent +the following generates a list which contains all the object files not +in @samp{mains}: + +@example +$(filter-out $(mains),$(objects)) +@end example + +@need 1500 @findex sort +@cindex sorting words +@item $(sort @var{list}) Sorts the words of @var{list} in lexical order, removing duplicate words. The output is a list of words separated by single spaces. Thus, @@ -3287,13 +4778,22 @@ @noindent returns the value @samp{bar foo lose}. + +@cindex removing duplicate words +@cindex duplicate words, removing +@cindex words, removing duplicates +Incidentally, since @code{sort} removes duplicate words, you can use +it for this purpose even if you don't care about the sort order. @end table -Here is a realistic example of the use of @code{subst} and @code{patsubst}. -Suppose that a makefile uses the @code{VPATH} variable to specify a list of -directories that @code{make} should search for dependency files. This -example shows how to tell the C compiler to search for header files in the -same list of directories. +Here is a realistic example of the use of @code{subst} and +@code{patsubst}. Suppose that a makefile uses the @code{VPATH} variable +to specify a list of directories that @code{make} should search for +dependency files +(@pxref{General Search, , @code{VPATH} Search Path for All Dependencies}). +This example shows how to +tell the C compiler to search for header files in the same list of +directories.@refill The value of @code{VPATH} is a list of directories separated by colons, such as @samp{src:../headers}. First, the @code{subst} function is used to @@ -3310,7 +4810,8 @@ compiler, like this: @example -override CFLAGS:= $(CFLAGS) $(patsubst %,-I%,$(subst :, ,$(VPATH))) +override CFLAGS := $(CFLAGS) \ + $(patsubst %,-I%,$(subst :, ,$(VPATH))) @end example @noindent @@ -3318,29 +4819,12 @@ previously given value of @code{CFLAGS}. The @code{override} directive is used so that the new value is assigned even if the previous value of @code{CFLAGS} was specified with a command argument (@pxref{Override -Directive}). - -The function @code{strip} can be very useful when used in conjunction -with conditionals. When comparing something with the null string -@samp{""} using @code{ifeq} or @code{ifneq}, you usually want a string -of just whitespace to match the null string. Thus, - -@example -.PHONY: all -ifneq "$(needs_made)" "" -all: $(needs_made) -else -all:;@@echo 'Nothing to make!' -endif -@end example +Directive, , The @code{override} Directive}). -@noindent -might fail to have the desired results. Replacing the variable reference -@samp{"$(needs_made)"} with the function call @samp{"$(strip -$(needs_made))"} in the @code{ifneq} directive would make it more robust. - @node Filename Functions, Foreach Function, Text Functions, Functions @section Functions for File Names +@cindex functions, for file names +@cindex file name functions Several of the built-in expansion functions relate specifically to taking apart file names or lists of file names. @@ -3352,8 +4836,10 @@ the results are concatenated with single spaces between them. @table @code -@item $(dir @var{names}) +@item $(dir @var{names}@dots{}) @findex dir +@cindex directory part +@cindex file name, directory part Extracts the directory-part of each file name in @var{names}. The directory-part of the file name is everything up through (and including) the last slash in it. If the file name contains no slash, @@ -3366,8 +4852,10 @@ @noindent produces the result @samp{src/ ./}. -@item $(notdir @var{names}) +@item $(notdir @var{names}@dots{}) @findex notdir +@cindex file name, nondirectory part +@cindex nondirectory part Extracts all but the directory-part of each file name in @var{names}. If the file name contains no slash, it is left unchanged. Otherwise, everything through the last slash is removed from it. @@ -3386,8 +4874,10 @@ @noindent produces the result @samp{foo.c hacks}. -@item $(suffix @var{names}) +@item $(suffix @var{names}@dots{}) @findex suffix +@cindex suffix, function to find +@cindex file name suffix Extracts the suffix of each file name in @var{names}. If the file name contains a period, the suffix is everything starting with the last period. Otherwise, the suffix is the empty string. This frequently @@ -3404,8 +4894,10 @@ @noindent produces the result @samp{.c}. -@item $(basename @var{names}) +@item $(basename @var{names}@dots{}) @findex basename +@cindex basename +@cindex file name, basename of Extracts all but the suffix of each file name in @var{names}. If the file name contains a period, the basename is everything starting up to (and not including) the last period. Otherwise, the basename is the @@ -3418,8 +4910,11 @@ @noindent produces the result @samp{src/foo hacks}. -@item $(addsuffix @var{suffix},@var{names}) +@c plural convention with dots (be consistent) +@item $(addsuffix @var{suffix},@var{names}@dots{}) @findex addsuffix +@cindex suffix, adding +@cindex file name suffix, adding The argument @var{names} is regarded as a series of names, separated by whitespace; @var{suffix} is used as a unit. The value of @var{suffix} is appended to the end of each individual name and the @@ -3433,11 +4928,13 @@ @noindent produces the result @samp{foo.c bar.c}. -@item $(addprefix @var{prefix},@var{names}) +@item $(addprefix @var{prefix},@var{names}@dots{}) @findex addprefix +@cindex prefix, adding +@cindex file name prefix, adding The argument @var{names} is regarded as a series of names, separated by whitespace; @var{prefix} is used as a unit. The value of -@var{prefix} is appended to the front of each individual name and the +@var{prefix} is prepended to the front of each individual name and the resulting larger names are concatenated with single spaces between them. For example, @@ -3450,6 +4947,8 @@ @item $(join @var{list1},@var{list2}) @findex join +@cindex joining lists of words +@cindex words, joining lists Concatenates the two arguments word by word: the two first words (one from each argument) concatenated form the first word of the result, the two second words form the second word of the result, and so on. So the @@ -3468,6 +4967,8 @@ @item $(word @var{n},@var{text}) @findex word +@cindex words, selecting +@cindex selecting words Returns the @var{n}th word of @var{text}. The legitimate values of @var{n} start from 1. If @var{n} is bigger than the number of words in @var{text}, the value is empty. For example, @@ -3479,16 +4980,22 @@ @noindent returns @samp{bar}. +@c Following item phrased to prevent overfull hbox. --RJC 17 Jul 92 @item $(words @var{text}) @findex words -Returns the number of words in @var{text}. Thus, @code{$(word -$(words @var{text}),@var{text})} is the last word of @var{text}.@refill +@cindex words, finding number +Returns the number of words in @var{text}. +Thus, the last word of @var{text} is +@w{@code{$(word $(words @var{text}),@var{text})}}.@refill -@item $(firstword @var{names}) +@item $(firstword @var{names}@dots{}) @findex firstword +@cindex words, extracting first The argument @var{names} is regarded as a series of names, separated by whitespace. The value is the first name in the series. The rest -of the names are ignored. For example, +of the names are ignored. + +For example, @example $(firstword foo bar) @@ -3501,19 +5008,18 @@ @item $(wildcard @var{pattern}) @findex wildcard +@cindex wildcard, function The argument @var{pattern} is a file name pattern, typically containing -wildcard characters. The result of @code{wildcard} is a space-separated -list of the names of existing files that match the pattern. - -Wildcards are expanded automatically in rules. @xref{Wildcards}. -But they are not normally expanded when a variable is set, or inside the -arguments of other functions. Those occasions are when the @code{wildcard} -function is useful.@refill +wildcard characters (as in shell file name patterns). The result of +@code{wildcard} is a space-separated list of the names of existing files +that match the pattern. +@xref{Wildcards, ,Using Wildcard Characters in File Names}. @end table @node Foreach Function, Origin Function, Filename Functions, Functions @section The @code{foreach} Function @findex foreach +@cindex words, iterating over The @code{foreach} function is very different from other functions. It causes one piece of text to be used repeatedly, each time with a different @@ -3529,7 +5035,7 @@ @noindent The first two arguments, @var{var} and @var{list}, are expanded before anything else is done; note that the last argument, @var{text}, is -@emph{not} expanded at the same time. Then for each word of the expanded +@strong{not} expanded at the same time. Then for each word of the expanded value of @var{list}, the variable named by the expanded value of @var{var} is set to that word, and @var{text} is expanded. Presumably @var{text} contains references to that variable, so its expansion will be different @@ -3553,8 +5059,8 @@ as @samp{$(wildcard a/*)}; the second repetition produces the result of @samp{$(wildcard b/*)}; and the third, that of @samp{$(wildcard c/*)}. -This example has the same result (except for setting @samp{find_files}, -@samp{dirs} and @samp{dir}) as the following example: +This example has the same result (except for setting @samp{dirs}) as +the following example: @example files := $(wildcard a/* b/* c/* d/*) @@ -3583,24 +5089,26 @@ @code{foreach}. The variable @var{var} is a simply-expanded variable during the execution of @code{foreach}. If @var{var} was undefined before the @code{foreach} function call, it is undefined after the call. -@xref{Flavors}.@refill +@xref{Flavors, ,The Two Flavors of Variables}.@refill You must take care when using complex variable expressions that result in variable names because many strange things are valid variable names, but are probably not what you intended. For example, -@example +@smallexample files := $(foreach Es escrito en espanol!,b c ch,$(find_files)) -@end example +@end smallexample @noindent might be useful if the value of @code{find_files} references the variable whose name is @samp{Es escrito en espanol!} (es un nombre bastante largo, -que no?), but it is more likely to be a mistake. +no?), but it is more likely to be a mistake. @node Origin Function, Shell Function, Foreach Function, Functions @section The @code{origin} Function @findex origin +@cindex variable, origin of +@cindex origin of variable The @code{origin} function is unlike most other functions in that it does not operate on the values of variables; it tells you something @emph{about} @@ -3622,35 +5130,45 @@ @table @samp @item undefined + if @var{variable} was never defined. @item default + if @var{variable} has a default definition, as is usual with @code{CC} -and so on. @xref{Implicit Variables}. Note that if you have -redefined a default variable, the @code{origin} function will return -the origin of the later definition. +and so on. @xref{Implicit Variables, ,Variables Used by Implicit Rules}. +Note that if you have redefined a default variable, the @code{origin} +function will return the origin of the later definition. @item environment + if @var{variable} was defined as an environment variable and the -@samp{-e} option is @emph{not} turned on (@pxref{Options}). +@samp{-e} option is @emph{not} turned on (@pxref{Options Summary, ,Summary of Options}). @item environment override + if @var{variable} was defined as an environment variable and the -@samp{-e} option @emph{is} turned on (@pxref{Options}). +@w{@samp{-e}} option @emph{is} turned on (@pxref{Options Summary, +,Summary of Options}).@refill @item file + if @var{variable} was defined in a makefile. @item command line + if @var{variable} was defined on the command line. @item override + if @var{variable} was defined with an @code{override} directive in a -makefile (@pxref{Override Directive}). +makefile (@pxref{Override Directive, ,The @code{override} Directive}). @item automatic + if @var{variable} is an automatic variable defined for the -execution of the commands for each rule. +execution of the commands for each rule +(@pxref{Automatic, , Automatic Variables}). @end table This information is primarily useful (other than for your curiosity) to @@ -3657,9 +5175,9 @@ determine if you want to believe the value of a variable. For example, suppose you have a makefile @file{foo} that includes another makefile @file{bar}. You want a variable @code{bletch} to be defined in @file{bar} -if you run the command @samp{make -f bar}, even if the environment contains +if you run the command @w{@samp{make -f bar}}, even if the environment contains a definition of @code{bletch}. However, if @file{foo} defined -@code{bletch} before including @file{bar}, you don't want to override that +@code{bletch} before including @file{bar}, you do not want to override that definition. This could be done by using an @code{override} directive in @file{foo}, giving that definition precedence over the later definition in @file{bar}; unfortunately, the @code{override} directive would also @@ -3667,11 +5185,13 @@ include:@refill @example +@group ifdef bletch ifeq "$(origin bletch)" "environment" bletch = barf, gag, etc. endif endif +@end group @end example @noindent @@ -3682,22 +5202,27 @@ from the environment, even under @samp{-e}, you could instead write: @example +@group ifneq "$(findstring environment,$(origin bletch))" "" bletch = barf, gag, etc. endif +@end group @end example Here the redefinition takes place if @samp{$(origin bletch)} returns either @samp{environment} or @samp{environment override}. +@xref{Text Functions, , Functions for String Substitution and Analysis}. @node Shell Function, , Origin Function, Functions @section The @code{shell} Function @findex shell -@cindex command expansion +@cindex commands, expansion @cindex backquotes +@cindex shell command, function for The @code{shell} function is unlike any other function except the -@code{wildcard} function (@pxref{Wildcard Function}) in that it +@code{wildcard} function +(@pxref{Wildcard Function, ,The Function @code{wildcard}}) in that it communicates with the world outside of @code{make}. The @code{shell} function performs the same function that backquotes @@ -3732,59 +5257,59 @@ using a very strange shell, this has the same result as @samp{$(wildcard *.c)}.@refill -@node Running, Implicit, Functions, Top +@node Running, Implicit Rules, Functions, Top @chapter How to Run @code{make} -A makefile that says how to recompile a program can be used in more than -one way. The simplest use is to recompile every file that is out of date. -This is what @code{make} will do if run with no arguments. +A makefile that says how to recompile a program can be used in more +than one way. The simplest use is to recompile every file that is out +of date. Usually, makefiles are written so that if you run +@code{make} with no arguments, it does just that. But you might want to update only some of the files; you might want to use a different compiler or different compiler options; you might want just to find out which files are out of date without changing them. -By specifying arguments when you run @code{make}, you can do any of these -things or many others. +By giving arguments when you run @code{make}, you can do any of these +things and many others. @menu -* Makefile Arguments:: Arguments to specify which makefile to use. - -* Goals:: Goal arguments specify which parts of the makefile - should be used. - -* Instead of Execution:: Mode flags specify what kind of thing to do - with the commands in the makefile - other than simply execute them. - -* Avoiding Compilation:: How to avoid recompiling certain files. - -* Overriding:: Overriding a variable can specify an alternate - compiler, or alternate flags for the compiler, - or whatever else you program into the makefile. - -* Testing:: How to proceed past some errors, to test compilation. - -* Options:: Summary of all options @code{make} accepts. +* Makefile Arguments:: How to specify which makefile to use. +* Goals:: How to use goal arguments to specify which + parts of the makefile to use. +* Instead of Execution:: How to use mode flags to specify what + kind of thing to do with the commands + in the makefile other than simply + execute them. +* Avoiding Compilation:: How to avoid recompiling certain files. +* Overriding:: How to override a variable to specify + an alternate compiler and other things. +* Testing:: How to proceed past some errors, to + test compilation. +* Options Summary:: Summary of Options @end menu -@node Makefile Arguments, Goals, Running, Running +@node Makefile Arguments, Goals, , Running @section Arguments to Specify the Makefile +@cindex @code{--file} +@cindex @code{--makefile} +@cindex @code{-f} -The way to specify the name of the makefile is with the @samp{-f} option. -For example, @samp{-f altmake} says to use the file @file{altmake} as -the makefile. +The way to specify the name of the makefile is with the @samp{-f} or +@samp{--file} option (@samp{--makefile} also works). For example, +@samp{-f altmake} says to use the file @file{altmake} as the makefile. -If you use the @samp{-f} flag several times (each time with a -following argument), all the specified files are used jointly as +If you use the @samp{-f} flag several times and follow each @samp{-f} +with an argument, all the specified files are used jointly as makefiles. -If you do not use the @samp{-f} flag, the default is to try -@file{GNUmakefile}, @file{makefile}, or @file{Makefile}, in that order, and -use the first of these three which exists. @xref{Makefiles}.@refill +If you do not use the @samp{-f} or @samp{--file} flag, the default is +to try @file{GNUmakefile}, @file{makefile}, and @file{Makefile}, in +that order, and use the first of these three which exists or can be made +(@pxref{Makefiles, ,Writing Makefiles}).@refill @node Goals, Instead of Execution, Makefile Arguments, Running @section Arguments to Specify the Goals -@cindex goal +@cindex goal, how to specify The @dfn{goals} are the targets that @code{make} should strive ultimately to update. Other targets are updated as well if they appear as @@ -3799,10 +5324,11 @@ Use the name of the goal as an argument. If you specify several goals, @code{make} processes each of them in turn, in the order you name them. -Any target in the makefile may be specified as a goal (unless it starts -with @samp{-} or contains an @samp{=}). Even targets not in the makefile -may be specified, if @code{make} can find implicit rules that say how to -make them. +Any target in the makefile may be specified as a goal (unless it +starts with @samp{-} or contains an @samp{=}, in which case it will be +parsed as a switch or variable definition, respectively). Even +targets not in the makefile may be specified, if @code{make} can find +implicit rules that say how to make them. One use of specifying a goal is if you want to compile only a part of the program, or only one of several programs. Specify as a goal each @@ -3815,30 +5341,43 @@ @end example If you are working on the program @code{size}, you might want to say -@samp{make size} so that only the files of that program are recompiled. +@w{@samp{make size}} so that only the files of that program are recompiled. -Another use of specifying a goal is to make files that aren't normally -made. For example, there may be a file of debugging output, or a version -of the program that is compiled specially for testing, which has a rule -in the makefile but isn't a dependency of the default goal. - -Another use of specifying a goal is to run the commands associated with a -phony target (@pxref{Phony Targets}) or empty target (@pxref{Empty Targets}). -Many makefiles contain a phony target named @file{clean} which deletes -everything except source files. Naturally, this is done only if you -request it explicitly with @samp{make clean}. Here is a list of typical -phony and empty target names: +Another use of specifying a goal is to make files that are not normally +made. For example, there may be a file of debugging output, or a +version of the program that is compiled specially for testing, which has +a rule in the makefile but is not a dependency of the default goal. + +Another use of specifying a goal is to run the commands associated with +a phony target (@pxref{Phony Targets}) or empty target (@pxref{Empty +Targets, ,Empty Target Files to Record Events}). Many makefiles contain +a phony target named @file{clean} which deletes everything except source +files. Naturally, this is done only if you request it explicitly with +@w{@samp{make clean}}. Here is a list of typical phony and empty target +names:@refill @table @file @item all +@cindex @code{all} @r{(standard target)} Make all the top-level targets the makefile knows about. @item clean +@cindex @code{clean} @r{(standard target)} Delete all files that are normally created by running @code{make}. +@item mostlyclean +@cindex @code{mostlyclean} @r{(standard target)} +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 distclean +@cindex @code{distclean} @r{(standard target)} @itemx realclean +@cindex @code{realclean} @r{(standard target)} @itemx clobber +@cindex @code{clobber} @r{(standard target)} Any of these three might be defined to delete everything that would not be part of a standard distribution. For example, this would delete configuration files or links that you would normally create as @@ -3846,27 +5385,44 @@ these files. @item install +@cindex @code{install} @r{(standard target)} Copy the executable file into a directory that users typically search for commands; copy any auxiliary files that the executable uses into the directories where it will look for them. @item print +@cindex @code{print} @r{(standard target)} Print listings of the source files that have changed. @item tar +@cindex @code{tar} @r{(standard target)} Create a tar file of the source files. @item shar +@cindex @code{shar} @r{(standard target)} Create a shell archive (shar file) of the source files. @item dist +@cindex @code{dist} @r{(standard target)} Create a distribution file of the source files. This might be a tar file, or a shar file, or a compressed version of one of the above, or even more than one of the above. + +@item TAGS +@cindex @code{TAGS} @r{(standard target)} +Update a tags table for this program. + +@item check +@cindex @code{check} @r{(standard target)} +@itemx test +@cindex @code{test} @r{(standard target)} +Perform self tests on the program this makefile builds. @end table @node Instead of Execution, Avoiding Compilation, Goals, Running @section Instead of Executing the Commands +@cindex execution, instead of +@cindex commands, instead of executing The makefile tells @code{make} how to tell whether a target is up to date, and how to update each target. But updating the targets is not always @@ -3873,19 +5429,30 @@ what you want. Certain options specify other activities for @code{make}. @table @samp +@item -n +@itemx --just-print +@itemx --dry-run +@itemx --recon +@cindex @code{--just-print} +@cindex @code{--dry-run} +@cindex @code{--recon} +@cindex @code{-n} +``No-op''. The activity is to print what commands would be used to make +the targets up to date, but not actually execute them. + @item -t +@itemx --touch +@cindex @code{--touch} @cindex touching files +@cindex target, touching @cindex @code{-t} ``Touch''. The activity is to mark the targets as up to date without actually changing them. In other words, @code{make} pretends to compile the targets but does not really change their contents. -@item -n -@cindex @code{-n} -``No-op''. The activity is to print what commands would be used to make -the targets up to date, but not actually execute them. - @item -q +@itemx --question +@cindex @code{--question} @cindex @code{-q} @cindex question mode ``Question''. The activity is to find out silently whether the targets @@ -3893,17 +5460,24 @@ words, neither compilation nor output will occur. @item -W +@itemx --what-if +@itemx --assume-new +@itemx --new-file +@cindex @code{--what-if} @cindex @code{-W} +@cindex @code{--assume-new} +@cindex @code{--new-file} @cindex what if +@cindex files, assuming new ``What if''. Each @samp{-W} flag is followed by a file name. The given files' modification times are recorded by @code{make} as being the present -time, although the actual modification times remain the same. When used in -conjunction with the @samp{-n} flag, the @samp{-W} flag provides a way to -see what would happen if you were to modify specific files.@refill +time, although the actual modification times remain the same. +You can use the @samp{-W} flag in conjunction with the @samp{-n} flag +to see what would happen if you were to modify specific files.@refill @end table -With the @samp{-n} flag, @code{make} prints without execution the commands -that it would normally execute. +With the @samp{-n} flag, @code{make} prints the commands that it would +normally execute but does not execute them. With the @samp{-t} flag, @code{make} ignores the commands in the rules and uses (in effect) the command @code{touch} for each target that needs to @@ -3924,7 +5498,7 @@ the @samp{+} character or the strings @samp{$(MAKE)} or @samp{$@{MAKE@}} is run regardless of these options. Other lines in the same rule are not run unless they too begin with @samp{+} or contain @samp{$(MAKE)} or -@samp{$@{MAKE@}}.@refill +@samp{$@{MAKE@}} (@xref{MAKE Variable, ,How the @code{MAKE} Variable Works}.) The @samp{-W} flag provides two features: @@ -3941,18 +5515,23 @@ @end itemize Note that the options @samp{-p} and @samp{-v} allow you to obtain other -information about @code{make} or about the makefiles in use. -@xref{Options}.@refill +information about @code{make} or about the makefiles in use +(@pxref{Options Summary, ,Summary of Options}).@refill @node Avoiding Compilation, Overriding, Instead of Execution, Running @section Avoiding Recompilation of Some Files @cindex @code{-o} +@cindex @code{--old-file} +@cindex @code{--assume-old} +@cindex files, assuming old +@cindex files, avoiding recompilation of +@cindex recompilation, avoiding -Sometimes you may have changed a source file but you don't want to +Sometimes you may have changed a source file but you do not want to recompile all the files that depend on it. For example, suppose you add a macro or a declaration to a header file that many other files depend on. Being conservative, @code{make} assumes that any change in the header file -requires recompilation of all dependent files, but you know that they don't +requires recompilation of all dependent files, but you know that they do not need to be recompiled and you would rather not waste the time waiting for them to compile. @@ -3975,11 +5554,12 @@ header files will not cause any recompilation. @end enumerate -If you have already changed the header file at a time when some files do -need recompilation, it is too late to do this. Instead, you can use the -@samp{-o @var{file}} flag, which marks a specified file as ``old'' -(@pxref{Options}). This means that the file itself won't be remade, -and nothing else will be remade on its account. Follow this procedure: +If you have already changed the header file at a time when some files +do need recompilation, it is too late to do this. Instead, you can +use the @w{@samp{-o @var{file}}} flag, which marks a specified file as +``old'' (@pxref{Options Summary, ,Summary of Options}). This means +that the file itself will not be remade, and nothing else will be +remade on its account. Follow this procedure: @enumerate @item @@ -3995,6 +5575,9 @@ @node Overriding, Testing, Avoiding Compilation, Running @section Overriding Variables @cindex overriding variables with arguments +@cindex variable, overriding with arguments +@cindex command line variables +@cindex variable, command line An argument that contains @samp{=} specifies the value of a variable: @samp{@var{v}=@var{x}} sets the value of the variable @var{v} to @var{x}. @@ -4019,15 +5602,15 @@ CFLAGS=-g @end example -Each time you run @code{make}, you can override this value if you wish. -For example, if you say @samp{make CFLAGS='-g -O'}, each C compilation will -be done with @samp{cc -c -g -O}. (This illustrates how you can enclose -spaces and other special characters in the value of a variable when you -override it.) +Each time you run @code{make}, you can override this value if you +wish. For example, if you say @samp{make CFLAGS='-g -O'}, each C +compilation will be done with @samp{cc -c -g -O}. (This illustrates +how you can use quoting in the shell to enclose spaces and other +special characters in the value of a variable when you override it.) The variable @code{CFLAGS} is only one of many standard variables that exist just so that you can change them this way. @xref{Implicit -Variables}, for a complete list. +Variables, , Variables Used by Implicit Rules}, for a complete list. You can also program the makefile to look at additional variables of your own, giving the user the ability to control other aspects of how the @@ -4043,12 +5626,13 @@ There is one way that the makefile can change a variable that you have overridden. This is to use the @code{override} directive, which is a line -that looks like this: @samp{override @var{variable} = @var{value}}. -@xref{Override Directive}. +that looks like this: @samp{override @var{variable} = @var{value}} +(@pxref{Override Directive, ,The @code{override} Directive}). -@node Testing, Options, Overriding, Running +@node Testing, Options Summary, Overriding, Running @section Testing the Compilation of a Program @cindex testing compilation +@cindex compilation, testing Normally, when an error happens in executing a shell command, @code{make} gives up immediately, returning a nonzero status. No further commands are @@ -4061,16 +5645,19 @@ as possible. @cindex @code{-k} -On these occasions, you should use the @samp{-k} flag. This tells -@code{make} to continue to consider the other dependencies of the pending -targets, remaking them if necessary, before it gives up and returns nonzero -status. For example, after an error in compiling one object file, -@samp{make -k} will continue compiling other object files even though it -already knows that linking them will be impossible. In addition to -continuing after failed shell commands, @samp{make -k} will continue as much -as possible after discovering that it doesn't know how to make a target or -dependency file. This will always cause an error message, but without -@samp{-k}, it is a fatal error. @xref{Options}. +@cindex @code{--keep-going} +On these occasions, you should use the @samp{-k} or +@samp{--keep-going} flag. This tells @code{make} to continue to +consider the other dependencies of the pending targets, remaking them +if necessary, before it gives up and returns nonzero status. For +example, after an error in compiling one object file, @samp{make -k} +will continue compiling other object files even though it already +knows that linking them will be impossible. In addition to continuing +after failed shell commands, @samp{make -k} will continue as much as +possible after discovering that it does not know how to make a target +or dependency file. This will always cause an error message, but +without @samp{-k}, it is a fatal error (@pxref{Options Summary, +,Summary of Options}).@refill The usual behavior of @code{make} assumes that your purpose is to get the goals up to date; once @code{make} learns that this is impossible, it might @@ -4077,29 +5664,40 @@ as well report the failure immediately. The @samp{-k} flag says that the real purpose is to test as much as possible of the changes made in the program, perhaps to find several independent problems so that you can -correct them all before the next attempt to compile. This is why Emacs's +correct them all before the next attempt to compile. This is why Emacs' @kbd{M-x compile} command passes the @samp{-k} flag by default. -@node Options, , Testing, Running +@node Options Summary, , Testing, Running @section Summary of Options @cindex options @cindex flags +@cindex switches Here is a table of all the options @code{make} understands: @table @samp @item -b +@cindex @code{-b} @itemx -m +@cindex @code{-m} These options are ignored for compatibility with other versions of @code{make}. @item -C @var{dir} +@cindex @code{-C} +@itemx --directory @var{dir} +@cindex @code{--directory} Change to directory @var{dir} before reading the makefiles. If multiple @samp{-C} options are specified, each is interpreted relative to the previous one: @samp{-C / -C etc} is equivalent to @samp{-C /etc}. This is typically used with recursive invocations of @code{make} -(@pxref{Recursion}). +(@pxref{Recursion, ,Recursive Use of @code{make}}). @item -d +@cindex @code{-d} +@itemx --debug +@cindex @code{--debug} +@c Extra blank line here makes the table look better. + 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, @@ -4108,111 +5706,209 @@ @code{make} decides what to do. @item -e +@cindex @code{-e} +@itemx --environment-overrides +@cindex @code{--environment-overrides} Give variables taken from the environment precedence -over variables from makefiles. @xref{Environment}. +over variables from makefiles. +@xref{Environment, ,Variables from the Environment}. @item -f @var{file} -Use file @var{file} as a makefile. @xref{Makefiles}. +@cindex @code{-f} +@itemx --file @var{file} +@cindex @code{--file} +@itemx --makefile @var{file} +@cindex @code{--makefile} +Read the file named @var{file} as a makefile. +@xref{Makefiles, ,Writing Makefiles}. + +@item -h +@cindex @code{-h} +@itemx --help +@cindex @code{--help} +@c Extra blank line here makes the table look better. + +Remind you of the options that @code{make} understands and then exit. @item -i +@cindex @code{-i} +@itemx --ignore-errors +@cindex @code{--ignore-errors} Ignore all errors in commands executed to remake files. -@xref{Errors}. +@xref{Errors, ,Errors in Commands}. @item -I @var{dir} +@cindex @code{-I} +@itemx --include-dir @var{dir} +@cindex @code{--include-dir} Specifies a directory @var{dir} to search for included makefiles. -@xref{Include}. If several @samp{-I} options are used to specify several -directories, the directories are searched in the order specified. Unlike -the arguments to other flags of @code{make}, directories given with -@samp{-I} flags may come directly after the flag: @samp{-I@var{dir}} is -allowed, as well as @samp{-I @var{dir}}. This syntax is allowed for -compatibility with the C preprocessor's @samp{-I} flag.@refill - -@item -j @var{jobs} -Specifies the number of jobs (commands) to run simultaneously. If +@xref{Include, ,Including Other Makefiles}. If several @samp{-I} +options are used to specify several directories, the directories are +searched in the order specified. + +@item -j [@var{jobs}] +@cindex @code{-j} +@itemx --jobs [@var{jobs}] +@cindex @code{--jobs} +Specifies the number of jobs (commands) to run simultaneously. With no +argument, @code{make} runs as many jobs simultaneously as possible. If there is more than one @samp{-j} option, the last one is effective. -@xref{Execution}, for more information on how commands are run. +@xref{Parallel, ,Parallel Execution}, +for more information on how commands are run. @item -k +@cindex @code{-k} +@itemx --keep-going +@cindex @code{--keep-going} 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. -@xref{Testing}. +@xref{Testing, ,Testing the Compilation of a Program}. -@item -l @var{load} -@item -l +@item -l [@var{load}] +@cindex @code{-l} +@itemx --load-average [@var{load}] +@cindex @code{--load-average} +@itemx --max-load [@var{load}] +@cindex @code{--max-load} Specifies that no new jobs (commands) should be started if there are others jobs running and the load average is at least @var{load} (a floating-point number). With no argument, removes a previous load -limit. @xref{Parallel}. +limit. @xref{Parallel, ,Parallel Execution}. @item -n +@cindex @code{-n} +@itemx --just-print +@cindex @code{--just-print} +@itemx --dry-run +@cindex @code{--dry-run} +@itemx --recon +@cindex @code{--recon} +@c Extra blank line here makes the table look better. + Print the commands that would be executed, but do not execute them. -@xref{Instead of Execution}. +@xref{Instead of Execution, ,Instead of Executing the Commands}. @item -o @var{file} +@cindex @code{-o} +@itemx --old-file @var{file} +@cindex @code{--old-file} +@itemx --assume-old @var{file} +@cindex @code{--assume-old} Do not remake the file @var{file} even if it is older than its dependencies, and do not remake anything on account of changes in @var{file}. Essentially the file is treated as very old and its rules -are ignored. @xref{Avoiding Compilation}. +are ignored. @xref{Avoiding Compilation, ,Avoiding Recompilation of +Some Files}.@refill @item -p +@cindex @code{-p} +@itemx --print-data-base +@cindex @code{--print-data-base} 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 @samp{-v} switch (see below). To print the data base without -trying to remake any files, use @samp{make -p -f /dev/null}. +trying to remake any files, use @w{@samp{make -p -f /dev/null}}. @item -q +@cindex @code{-q} +@itemx --question +@cindex @code{--question} ``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. @xref{Instead of Execution}. +return an exit status that is zero if the specified targets are already +up to date, nonzero otherwise. @xref{Instead of Execution, ,Instead of +Executing the Commands}.@refill @item -r -Eliminate use of the built-in implicit rules (@pxref{Implicit}). -Also clear out the default list of suffixes for suffix rules -(@pxref{Suffix Rules}). +@cindex @code{-r} +@itemx --no-builtin-rules +@cindex @code{--no-builtin-rules} +Eliminate use of the built-in implicit rules (@pxref{Implicit Rules, +,Using Implicit Rules}). You can still define your own by writing +pattern rules (@pxref{Pattern Rules, ,Defining and Redefining Pattern +Rules}). The @samp{-r} option also clears out the default list of +suffixes for suffix rules (@pxref{Suffix Rules, ,Old-Fashioned Suffix +Rules}). But you can still define your own suffixes with a rule for +@code{.SUFFIXES}, and then define your own suffix rules. @item -s +@cindex @code{-s} +@itemx --silent +@cindex @code{--silent} +@itemx --quiet +@cindex @code{--quiet} +@c Extra blank line here makes the table look better. + Silent operation; do not print the commands as they are executed. -@xref{Echoing}. +@xref{Echoing, ,Command Echoing}. @item -S +@cindex @code{-S} +@itemx --no-keep-going +@cindex @code{--no-keep-going} +@itemx --stop +@cindex @code{--stop} +@c Extra blank line here makes the table look better. + Cancel the effect of the @samp{-k} option. This is never necessary except in a recursive @code{make} where @samp{-k} might be inherited -from the top-level @code{make} via @code{MAKEFLAGS} (@pxref{Recursion}) +from the top-level @code{make} via @code{MAKEFLAGS} (@pxref{Recursion, ,Recursive Use of @code{make}}) or if you set @samp{-k} in @code{MAKEFLAGS} in your environment.@refill @item -t +@cindex @code{-t} +@itemx --touch +@cindex @code{--touch} +@c Extra blank line here makes the table look better. + 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 -@code{make}. @xref{Instead of Execution}. +@code{make}. @xref{Instead of Execution, ,Instead of Executing the Commands}. @item -v +@cindex @code{-v} +@itemx --version +@cindex @code{--version} Print the version of the @code{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 @samp{make -v -f -/dev/null}. +of authors, and a notice that there is no warranty. After this +information is printed, continue processing normally. To get this +information without doing anything else, use +@w{@samp{make --version -f /dev/null}}. @item -w +@cindex @code{-w} +@itemx --print-directory +@cindex @code{--print-directory} Print a message containing the working directory both before and after executing the makefile. This may be useful for tracking down errors from complicated nests of recursive @code{make} commands. -@xref{Recursion}. +@xref{Recursion, ,Recursive Use of @code{make}}. (In practice, you +rarely need to specify this option since @samp{make} does it for you; +see @ref{-w Option, ,The @samp{--print-directory} Option}.) @item -W @var{file} +@cindex @code{-W} +@itemx --what-if @var{file} +@cindex @code{--what-if} +@itemx --new-file @var{file} +@cindex @code{--new-file} +@itemx --assume-new @var{file} +@cindex @code{--assume-new} Pretend that the target @var{file} has just been modified. When used with the @samp{-n} flag, this shows you what would happen if you were to modify that file. Without @samp{-n}, it is almost the same as running a @code{touch} command on the given file before running @code{make}, except that the modification time is changed only in the -imagination of @code{make}.@refill +imagination of @code{make}. +@xref{Instead of Execution, ,Instead of Executing the Commands}. @end table -@node Implicit, Archives, Running, Top +@node Implicit Rules, Archives, Running, Top @chapter Using Implicit Rules @cindex implicit rule +@cindex rule, implicit Certain standard ways of remaking target files are used very often. For example, one customary way to make an object file is from a C source file @@ -4219,17 +5915,17 @@ using the C compiler, @code{cc}. @dfn{Implicit rules} tell @code{make} how to use customary techniques so -that you don't have to specify them in detail when you want to use them. -For example, there is an implicit rule for C compilation. Implicit rules -work based on file names. For example, C compilation typically takes a -@file{.c} file and makes a @file{.o} file. So @code{make} applies the -implicit rule for C compilation when it sees this combination of file-name -endings. +that you do not have to specify them in detail when you want to use +them. For example, there is an implicit rule for C compilation. File +names determine which implicit rules are run. For example, C +compilation typically takes a @file{.c} file and makes a @file{.o} file. +So @code{make} applies the implicit rule for C compilation when it sees +this combination of file name endings.@refill A chain of implicit rules can apply in sequence; for example, @code{make} will remake a @file{.o} file from a @file{.y} file by way of a @file{.c} file. @iftex -@xref{Chained Rules}. +@xref{Chained Rules, ,Chains of Implicit Rules}. @end iftex The built-in implicit rules use several variables in their commands so @@ -4237,42 +5933,45 @@ implicit rule works. For example, the variable @code{CFLAGS} controls the flags given to the C compiler by the implicit rule for C compilation. @iftex -@xref{Implicit Variables}. +@xref{Implicit Variables, ,Variables Used by Implicit Rules}. @end iftex You can define your own implicit rules by writing @dfn{pattern rules}. @iftex -@xref{Pattern Rules}. +@xref{Pattern Rules, ,Defining and Redefining Pattern Rules}. @end iftex -@menu -* Using Implicit:: How to use an existing implicit rule - to get the commands for updating a file. - -* Catalogue of Rules:: Catalogue of built-in implicit rules. - -* Implicit Variables:: By changing certain variables, you can - change what the predefined implicit rules do. - -* Chained Rules:: Using a chain of implicit rules. - -* Pattern Rules:: Defining new implicit rules. - -* Last Resort:: Defining commands for rules which can't find any. - -* Suffix Rules:: The old-fashioned style of implicit rule. +@dfn{Suffix rules} are a more limited way to define implicit rules. +Pattern rules are more general and clearer, but suffix rules are +retained for compatibility. +@iftex +@xref{Suffix Rules, ,Old-Fashioned Suffix Rules}. +@end iftex -* Search Algorithm:: Precise algorithm for applying implicit rules. +@menu +* Using Implicit:: How to use an existing implicit rule + to get the commands for updating a file. +* Catalogue of Rules:: A list of built-in implicit rules. +* Implicit Variables:: How to change what predefined rules do. +* Chained Rules:: How to use a chain of implicit rules. +* Pattern Rules:: How to define new implicit rules. +* Last Resort:: How to defining commands for rules + which cannot find any. +* Suffix Rules:: The old-fashioned style of implicit rule. +* Search Algorithm:: The precise algorithm for applying + implicit rules. @end menu -@node Using Implicit, Catalogue of Rules, Implicit, Implicit +@node Using Implicit, Catalogue of Rules, , Implicit Rules @section Using Implicit Rules +@cindex implicit rule, how to use +@cindex rule, implicit, how to use To allow @code{make} to find a customary method for updating a target file, all you have to do is refrain from specifying commands yourself. Either write a rule with no command lines, or don't write a rule at all. Then @code{make} will figure out which implicit rule to use based on which -kind of source file exists. +kind of source file exists or can be made. For example, suppose the makefile looks like this: @@ -4286,10 +5985,11 @@ will automatically look for an implicit rule that tells how to update it. This happens whether or not the file @file{foo.o} currently exists. -If an implicit rule is found, it supplies both commands and one or more -dependencies (the source files). You would want to write a rule for -@file{foo.o} with no command lines if you need to specify additional -dependencies, such as header files, that the implicit rule cannot supply. +If an implicit rule is found, it can supply both commands and one or +more dependencies (the source files). You would want to write a rule +for @file{foo.o} with no command lines if you need to specify additional +dependencies, such as header files, that the implicit rule cannot +supply. Each implicit rule has a target pattern and dependency patterns. There may be many implicit rules with the same target pattern. For example, numerous @@ -4303,8 +6003,8 @@ Of course, when you write the makefile, you know which implicit rule you want @code{make} to use, and you know it will choose that one because you know which possible dependency files are supposed to exist. -@xref{Catalogue of Rules}, for a catalogue of all the predefined implicit -rules. +@xref{Catalogue of Rules, ,Catalogue of Implicit Rules}, +for a catalogue of all the predefined implicit rules. Above, we said an implicit rule applies if the required dependencies ``exist or can be made''. A file ``can be made'' if it is mentioned explicitly in @@ -4311,59 +6011,91 @@ the makefile as a target or a dependency, or if an implicit rule can be recursively found for how to make it. When an implicit dependency is the result of another implicit rule, we say that @dfn{chaining} is occurring. -@xref{Chained Rules}. +@xref{Chained Rules, ,Chains of Implicit Rules}. In general, @code{make} searches for an implicit rule for each target, and for each double-colon rule, that has no commands. A file that is mentioned only as a dependency is considered a target whose rule specifies nothing, -so implicit rule search happens for it. @xref{Search Algorithm}, for the +so implicit rule search happens for it. @xref{Search Algorithm, ,Implicit Rule Search Algorithm}, for the details of how the search is done. -If you don't want an implicit rule to be used for a target that has no -commands, you can give that target empty commands by writing a semicolon. -@xref{Empty Commands}. +Note that explicit dependencies do not influence implicit rule search. +For example, consider this explicit rule: + +@example +foo.o: foo.p +@end example + +@noindent +The dependency on @file{foo.p} does not necessarily mean that +@code{make} will remake @file{foo.o} according to the implicit rule to +make an object file, a @file{.o} file, from a Pascal source file, a +@file{.p} file. For example, if @file{foo.c} also exists, the implicit +rule to make an object file from a C source file is used instead, +because it appears before the Pascal rule in the list of predefined +implicit rules (@pxref{Catalogue of Rules, , Catalogue of Implicit +Rules}). + +If you do not want an implicit rule to be used for a target that has no +commands, you can give that target empty commands by writing a semicolon +(@pxref{Empty Commands, ,Defining Empty Commands}). -@node Catalogue of Rules, Implicit Variables, Using Implicit, Implicit +@node Catalogue of Rules, Implicit Variables, Using Implicit, Implicit Rules @section Catalogue of Implicit Rules +@cindex implicit rule, predefined +@cindex rule, implicit, predefined -Here is a catalogue of predefined implicit rules which are always available -unless the makefile explicitly overrides or cancels them. -@xref{Canceling Rules}, for information on canceling or overriding an -implicit rule. The @samp{-r} option cancels all predefined rules. +Here is a catalogue of predefined implicit rules which are always +available unless the makefile explicitly overrides or cancels them. +@xref{Canceling Rules, ,Canceling Implicit Rules}, for information on +canceling or overriding an implicit rule. The @samp{-r} or +@samp{--no-builtin-rules} option cancels all predefined rules. Not all of these rules will always be defined, even when the @samp{-r} option is not given. Many of the predefined implicit rules are implemented in @code{make} as suffix rules, so which ones will be defined depends on the @dfn{suffix list} (the list of dependencies of -the special target @code{.SUFFIXES}). @xref{Suffix Rules}. -The default suffix list is: @samp{.out}, @samp{.a}, @samp{.o}, -@samp{.c}, @samp{.cc}, @samp{.C}, @samp{.p}, @samp{.f}, @samp{.F}, @samp{.r}, -@samp{.e}, @samp{.y}, @samp{.ye}, @samp{.yr}, @samp{.l}, @samp{.s}, -@samp{.S}, @samp{.h}, @samp{.info}, @samp{.dvi}, @samp{.tex}, -@samp{.texinfo}, @samp{.cweb}, @samp{.web}, @samp{.sh}, @samp{.elc}, -@samp{.el}. All of the implicit rules described below whose dependencies -have one of these suffixes are actually suffix rules. If you modify -the suffix list, the only predefined suffix rules in effect will be those -named by one or two of the suffixes that are on the list you specify; -rules whose suffixes fail to be on the list are disabled.@refill +the special target @code{.SUFFIXES}). The default suffix list is: +@code{.out}, @code{.a}, @code{.ln}, @code{.o}, @code{.c}, @code{.cc}, +@code{.C}, @code{.p}, @code{.f}, @code{.F}, @code{.r}, @code{.y}, +@code{.l}, @code{.s}, @code{.S}, @code{.mod}, @code{.sym}, +@code{.def}, @code{.h}, @code{.info}, @code{.dvi}, @code{.tex}, +@code{.texinfo}, @code{.texi}, @code{.cweb}, @code{.web}, @code{.sh}, +@code{.elc}, @code{.el}. All of the implicit rules described below +whose dependencies have one of these suffixes are actually suffix +rules. If you modify the suffix list, the only predefined suffix +rules in effect will be those named by one or two of the suffixes that +are on the list you specify; rules whose suffixes fail to be on the +list are disabled. @xref{Suffix Rules, ,Old-Fashioned Suffix Rules}, +for full details on suffix rules. @table @asis @item Compiling C programs -@file{@var{n}.o} will be made automatically from @file{@var{n}.c} with +@cindex C, rule to compile +@pindex cc +@pindex gcc +@file{@var{n}.o} is made automatically from @file{@var{n}.c} with a command of the form @samp{$(CC) -c $(CPPFLAGS) $(CFLAGS)}.@refill @item Compiling C++ programs -@file{@var{n}.o} will be made automatically from @file{@var{n}.cc} or -@file{@var{n}.C} with a command of the form @samp{$(C++) -c $(CPPFLAGS) -$(C++FLAGS)}. We encourage you to use the suffix @samp{.cc} for C++ +@cindex C++, rule to compile +@pindex g++ +@file{@var{n}.o} is made automatically from @file{@var{n}.cc} or +@file{@var{n}.C} with a command of the form @samp{$(CXX) -c $(CPPFLAGS) +$(CXXFLAGS)}. We encourage you to use the suffix @samp{.cc} for C++ source files instead of @samp{.C}.@refill @item Compiling Pascal programs -@file{@var{n}.o} will be made automatically from @file{@var{n}.p} +@cindex Pascal, rule to compile +@pindex pc +@file{@var{n}.o} is made automatically from @file{@var{n}.p} with the command @samp{$(PC) -c $(PFLAGS)}.@refill @item Compiling Fortran and Ratfor programs -@file{@var{n}.o} will be made automatically from @file{@var{n}.r}, +@cindex Fortran, rule to compile +@cindex Ratfor, rule to compile +@pindex f77 +@file{@var{n}.o} is made automatically from @file{@var{n}.r}, @file{@var{n}.F} or @file{@var{n}.f} by running the Fortran compiler. The precise command used is as follows:@refill @@ -4377,7 +6109,7 @@ @end table @item Preprocessing Fortran and Ratfor programs -@file{@var{n}.f} will be made automatically from @file{@var{n}.r} or +@file{@var{n}.f} is made automatically from @file{@var{n}.r} or @file{@var{n}.F}. This rule runs just the preprocessor to convert a Ratfor or preprocessable Fortran program into a strict Fortran program. The precise command used is as follows:@refill @@ -4390,29 +6122,35 @@ @end table @item Compiling Modula-2 programs -@file{@var{n}.sym} will be made from @file{@var{n}.def} with a command +@cindex Modula-2, rule to compile +@pindex m2c +@file{@var{n}.sym} is made from @file{@var{n}.def} with a command of the form @samp{$(M2C) $(M2FLAGS) $(DEFFLAGS)}. @file{@var{n}.o} -will be made from @file{@var{n}.mod} with a command of the form -@samp{$(M2C) $(M2FLAGS) $(MODFLAGS)}.@refill +is made from @file{@var{n}.mod}; the form is: +@w{@samp{$(M2C) $(M2FLAGS) $(MODFLAGS)}}.@refill +@need 1200 @item Assembling and preprocessing assembler programs -@file{@var{n}.o} will be made automatically from @file{@var{n}.s} by -running the assembler @code{as}. The precise command used is +@cindex assembly, rule to compile +@pindex as +@file{@var{n}.o} is made automatically from @file{@var{n}.s} by +running the assembler, @code{as}. The precise command is @samp{$(AS) $(ASFLAGS)}.@refill -@file{@var{n}.s} will be made automatically from @file{@var{n}.S} by -running the C preprocessor @code{cpp}. The precise command used is -@samp{$(CPP) $(CPPFLAGS)}.@refill +@file{@var{n}.s} is made automatically from @file{@var{n}.S} by +running the C preprocessor, @code{cpp}. The precise command is +@w{@samp{$(CPP) $(CPPFLAGS)}}. @item Linking a single object file -@file{@var{n}} will be made automatically from @file{@var{n}.o} by +@cindex linking, predefined rule for +@file{@var{n}} is made automatically from @file{@var{n}.o} by running the linker @code{ld} via the C compiler. The precise command -used is @samp{$(CC) $(LDFLAGS) @var{n}.o $(LOADLIBES)}.@refill +used is @w{@samp{$(CC) $(LDFLAGS) @var{n}.o $(LOADLIBES)}}.@refill This rule does the right thing for a simple program with only one source file. It will also do the right thing if there are multiple -object files (presumably coming from various other source files), the -first of which has a name matching that of the executable file. Thus, +object files (presumably coming from various other source files), one +of which has a name matching that of the executable file. Thus, @example x: y.o z.o @@ -4422,6 +6160,7 @@ when @file{x.c}, @file{y.c} and @file{z.c} all exist will execute: @example +@group cc -c x.c -o x.o cc -c y.c -o y.o cc -c z.c -o z.o @@ -4429,6 +6168,7 @@ rm -f x.o rm -f y.o rm -f z.o +@end group @end example @noindent @@ -4436,24 +6176,28 @@ name derives from the executable file name, you must write an explicit command for linking. -Each kind of file automatically made into @code{.o} object files will +Each kind of file automatically made into @samp{.o} object files will be automatically linked by using the compiler (@samp{$(CC)}, @samp{$(FC)} or @samp{$(PC)}; the C compiler @samp{$(CC)} is used to -assemble @code{.s} files) without the @samp{-c} option. This could be -done by using the @code{.o} object files as intermediates, but it is +assemble @samp{.s} files) without the @samp{-c} option. This could be +done by using the @samp{.o} object files as intermediates, but it is faster to do the compiling and linking in one step, so that's how it's done.@refill @item Yacc for C programs -@file{@var{n}.c} will be made automatically from @file{@var{n}.y} by +@pindex yacc +@cindex Yacc, rule to run +@file{@var{n}.c} is made automatically from @file{@var{n}.y} by running Yacc with the command @samp{$(YACC) $(YFLAGS)}. @item Lex for C programs -@file{@var{n}.c} will be made automatically from @file{@var{n}.l} by +@pindex lex +@cindex Lex, rule to run +@file{@var{n}.c} is made automatically from @file{@var{n}.l} by by running Lex. The actual command is @samp{$(LEX) $(LFLAGS)}. @item Lex for Ratfor programs -@file{@var{n}.r} will be made automatically from @file{@var{n}.l} by +@file{@var{n}.r} is made automatically from @file{@var{n}.l} by by running Lex. The actual command is @samp{$(LEX) $(LFLAGS)}. The convention of using the same suffix @samp{.l} for all Lex files @@ -4464,75 +6208,124 @@ guess which compiler to use. It will guess the C compiler, because that is more common. If you are using Ratfor, make sure @code{make} knows this by mentioning @file{@var{n}.r} in the makefile. Or, if you -are using Ratfor exclusively, with no C files, remove @code{.c} from +are using Ratfor exclusively, with no C files, remove @samp{.c} from the list of implicit rule suffixes with:@refill @example +@group .SUFFIXES: -.SUFFIXES: .r .f .l @dots{} +.SUFFIXES: .o .r .f .l @dots{} +@end group @end example @item Making Lint Libraries from C, Yacc, or Lex programs -@file{@var{n}.ln} will be made from @file{@var{n}.c} with a command of -the form @samp{$(LINT) $(LINTFLAGS) $(CPPFLAGS) -i}. The same command -will be used on the C code produced from @file{@var{n}.y} or -@file{@var{n}.l}.@refill +@pindex lint +@cindex @code{lint}, rule to run +@file{@var{n}.ln} is made from @file{@var{n}.c} with a command of +the form @w{@samp{$(LINT) $(LINTFLAGS) $(CPPFLAGS) -i}}. +The same command is used on the C code produced from +@file{@var{n}.y} or @file{@var{n}.l}.@refill @item @TeX{} and Web -@file{@var{n}.dvi} will be made from @file{@var{n}.tex} with the -command @samp{$(TEX)}. @file{@var{n}.tex} will be made from +@cindex @TeX{}, rule to run +@cindex Web, rule to run +@pindex tex +@pindex cweave +@pindex weave +@pindex tangle +@pindex ctangle +@file{@var{n}.dvi} is made from @file{@var{n}.tex} with the +command @samp{$(TEX)}. @file{@var{n}.tex} is made from @file{@var{n}.web} with @samp{$(WEAVE)}, or from @file{@var{n}.cweb} -with @samp{$(CWEAVE)}. @file{@var{n}.p} will be made from -@file{@var{n}.web} with @samp{$(TANGLE)} and @file{@var{n}.c} will be +with @samp{$(CWEAVE)}. @file{@var{n}.p} is made from +@file{@var{n}.web} with @samp{$(TANGLE)} and @file{@var{n}.c} is made from @file{@var{n}.cweb} with @samp{$(CTANGLE)}.@refill @item Texinfo and Info -@file{@var{n}.dvi} will be made from @file{@var{n}.texinfo} using the -@samp{$(TEX)} and @samp{$(TEXINDEX)} commands. The actual command -sequence contains many shell conditionals to avoid unnecessarily -running @TeX{} twice and to create the proper sorted index files. -@file{@var{n}.info} will be made from @file{@var{n}.texinfo} with the -command @samp{$(MAKEINFO)}.@refill +@cindex Texinfo, rule to format +@cindex Info, rule to format +@pindex texi2dvi +@pindex makeinfo +@file{@var{n}.dvi} is made from @file{@var{n}.texinfo} or +@file{@var{n}.texi} with the @samp{$(TEXI2DVI)} command. +@file{@var{n}.info} is made from @file{@var{n}.texinfo} or +@file{@var{n}.texi} with the @samp{$(MAKEINFO)} command .@refill @item RCS -Any file @file{@var{n}} will be extracted if necessary from an RCS file +@cindex RCS, rule to extract from +@pindex co +Any file @file{@var{n}} is extracted if necessary from an RCS file named either @file{@var{n},v} or @file{RCS/@var{n},v}. The precise -command used is @samp{$(CO) $(COFLAGS)}. @file{@var{n}} will not be +command used is @w{@samp{$(CO) $(COFLAGS)}}. @file{@var{n}} will not be extracted from RCS if it already exists, even if the RCS file is -newer.@refill +newer. The rules for RCS are terminal +(@pxref{Match-Anything Rules, ,Match-Anything Pattern Rules}), +so RCS files cannot be generated from another source; they must +actually exist.@refill @item SCCS -Any file @file{@var{n}} will be extracted if necessary from an SCCS -file named either @file{s.@var{n}} or @file{SCCS/s.@var{n}}. The -precise command used is @samp{$(GET) $(GFLAGS)}.@refill +@cindex SCCS, rule to extract from +@pindex get +Any file @file{@var{n}} is extracted if necessary from an SCCS file +named either @file{s.@var{n}} or @file{SCCS/s.@var{n}}. The precise +command used is @w{@samp{$(GET) $(GFLAGS)}}. The rules for SCCS are +terminal (@pxref{Match-Anything Rules, ,Match-Anything Pattern Rules}), +so SCCS files cannot be generated from another source; they must +actually exist.@refill -For the benefit of SCCS, a file @file{@var{n}} will be copied from +For the benefit of SCCS, a file @file{@var{n}} is copied from @file{@var{n}.sh} and made executable (by everyone). This is for shell scripts that are checked into SCCS. Since RCS preserves the -execution permission of a file, you don't need to use this feature +execution permission of a file, you do not need to use this feature with RCS.@refill -We recommend that you avoid the use of SCCS. RCS is widely held to be +We recommend that you avoid using of SCCS. RCS is widely held to be superior, and is also free. By choosing free software in place of comparable (or inferior) proprietary software, you support the free software movement. @end table -@node Implicit Variables, Chained Rules, Catalogue of Rules, Implicit +Usually, you want to change only the variables listed in the table +above, which are documented in the following section. + +However, the commands in built-in implicit rules actually use +variables such as @code{COMPILE.c}, @code{LINK.p}, and +@code{PREPROCESS.S}, whose values contain the commands listed above. + +@code{make} follows the convention that the rule to compile a +@file{.@var{x}} source file uses the variable @code{COMPILE.@var{x}}. +Similarly, the rule to produce an executable from a @file{.@var{x}} +file uses @code{LINK.@var{x}}; and the rule to preprocess a +@file{.@var{x}} file uses @code{PREPROCESS.@var{x}}. + +@vindex OUTPUT_OPTION +Every rule that produces an object file uses the variable +@code{OUTPUT_OPTION}. @code{make} defines this variable either to +contain @samp{-o $@@}, or to be empty, depending on a compile-time +option. You need the @samp{-o} option to ensure that the output goes +into the right file when the source file is in a different directory, +as when using @code{VPATH} (@pxref{Directory Search}). However, +compilers on some systems do not accept a @samp{-o} switch for object +files. If you use such a system, and use @code{VPATH}, some +compilations will put their output in the wrong place. +A possible workaround for this problem is to give @code{OUTPUT_OPTION} +the value @w{@samp{; mv $*.o $@@}}. + +@node Implicit Variables, Chained Rules, Catalogue of Rules, Implicit Rules @section Variables Used by Implicit Rules @cindex flags for compilers The commands in built-in implicit rules make liberal use of certain -predefined variables. You can alter these variables, either in the -makefile or with arguments to @code{make}, to alter how the implicit rules -work without redefining the rules themselves. +predefined variables. You can alter these variables in the makefile, +with arguments to @code{make}, or in the environment to alter how the +implicit rules work without redefining the rules themselves. For example, the command used to compile a C source file actually says @samp{$(CC) -c $(CFLAGS) $(CPPFLAGS)}. The default values of the variables used are @samp{cc} and nothing, resulting in the command @samp{cc -c}. By -redefining @samp{$(CC)} to @samp{ncc}, you could cause @samp{ncc} to be +redefining @samp{CC} to @samp{ncc}, you could cause @samp{ncc} to be used for all C compilations performed by the implicit rule. By redefining -@samp{$(CFLAGS)} to be @samp{-g}, you could pass the @samp{-g} option to +@samp{CFLAGS} to be @samp{-g}, you could pass the @samp{-g} option to each compilation. @emph{All} implicit rules that do C compilation use @samp{$(CC)} to get the program name for the compiler and @emph{all} include @samp{$(CFLAGS)} among the arguments given to the compiler.@refill @@ -4544,28 +6337,33 @@ name.) If a variable value contains more than one argument, separate them with spaces. -Here is a table of variables used as names of programs: +Here is a table of variables used as names of programs in built-in rules: @table @code @item AR @vindex AR -Archive-maintaing program; default @samp{ar}. +Archive-maintaining program; default @samp{ar}. +@pindex ar @item AS @vindex AS Program for doing assembly; default @samp{as}. +@pindex as @item CC @vindex CC Program for compiling C programs; default @samp{cc}. +@pindex cc -@item C++ -@vindex C++ +@item CXX +@vindex CXX Program for compiling C++ programs; default @samp{g++}. +@pindex g++ @item CO @vindex CO Program for extracting a file from RCS; default @samp{co}. +@pindex co @item CPP @vindex CPP @@ -4574,34 +6372,30 @@ @item FC @vindex FC -Program for compiling or preprocessing Fortran, Ratfor, -and EFL programs; default @samp{f77}. +Program for compiling or preprocessing Fortran and Ratfor programs; +default @samp{f77}. +@pindex f77 @item GET @vindex GET Program for extracting a file from SCCS; default @samp{get}. +@pindex get @item LEX @vindex LEX Program to use to turn Lex grammars into C programs or Ratfor programs; default @samp{lex}. +@pindex lex @item PC @vindex PC Program for compiling Pascal programs; default @samp{pc}. - -@item FC -@itemx EC -@itemx RC -@vindex FC -@vindex EC -@vindex RC -Programs for compiling Fortran, EFL, and Ratfor programs, -respectively; these all default to @samp{f77}. +@pindex pc @item YACC @vindex YACC Program to use to turn Yacc grammars into C programs; default @samp{yacc}. +@pindex yacc @item YACCR @vindex YACCR @@ -4608,44 +6402,48 @@ Program to use to turn Yacc grammars into Ratfor programs; default @samp{yacc -r}. -@item YACCE -@vindex YACCE -Program to use to turn Yacc grammars into EFL -programs; default @samp{yacc -e}. - @item MAKEINFO @vindex MAKEINFO -Program to make Info files from Texinfo source; default @samp{makeinfo}. +Program to convert a Texinfo source file into an Info file; default +@samp{makeinfo}. +@pindex makeinfo @item TEX @vindex TEX -Program to make @TeX{} DVI files from @TeX{} or Texinfo source; +Program to make @TeX{} @sc{dvi} files from @TeX{} source; default @samp{tex}. +@pindex tex -@item TEXINDEX -@vindex TEXINDEX -The @code{texindex} program distributed with Emacs. -This is used in the process to make @TeX{} DVI files from Texinfo source. +@item TEXI2DVI +@vindex TEXI2DVI +Program to make @TeX{} @sc{dvi} files from Texinfo source; +default @samp{texi2dvi}. +@pindex texi2dvi @item WEAVE @vindex WEAVE Program to translate Web into @TeX{}; default @samp{weave}. +@pindex weave @item CWEAVE @vindex CWEAVE Program to translate C Web into @TeX{}; default @samp{cweave}. +@pindex cweave @item TANGLE @vindex TANGLE Program to translate Web into Pascal; default @samp{tangle}. +@pindex tangle @item CTANGLE @vindex CTANGLE Program to translate C Web into C; default @samp{ctangle}. +@pindex ctangle @item RM @vindex RM Command to remove a file; default @samp{rm -f}. +@pindex rm @end table Here is a table of variables whose values are additional arguments for the @@ -4655,19 +6453,19 @@ @table @code @item ARFLAGS @vindex ARFLAGS -Flags to give the archive- maintaining program; default @samp{rv}. +Flags to give the archive-maintaining program; default @samp{rv}. @item ASFLAGS @vindex ASFLAGS Extra flags to give to the assembler (when explicitly -invoked on a @samp{.s} file). +invoked on a @samp{.s} or @samp{.S} file). @item CFLAGS @vindex CFLAGS Extra flags to give to the C compiler. -@item C++FLAGS -@vindex C++FLAGS +@item CXXFLAGS +@vindex CXXFLAGS Extra flags to give to the C++ compiler. @item COFLAGS @@ -4679,10 +6477,6 @@ Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers). -@item EFLAGS -@vindex EFLAGS -Extra flags to give to the Fortran compiler for EFL programs. - @item FFLAGS @vindex FFLAGS Extra flags to give to the Fortran compiler. @@ -4713,10 +6507,11 @@ Extra flags to give to Yacc. @end table -@node Chained Rules, Pattern Rules, Implicit Variables, Implicit +@node Chained Rules, Pattern Rules, Implicit Variables, Implicit Rules @section Chains of Implicit Rules @cindex chains of rules +@cindex rule, implicit, chains of Sometimes a file can be made by a sequence of implicit rules. For example, a file @file{@var{n}.o} could be made from @file{@var{n}.y} by running first Yacc and then @code{cc}. Such a sequence is called a @dfn{chain}. @@ -4724,11 +6519,12 @@ If the file @file{@var{n}.c} exists, or is mentioned in the makefile, no special searching is required: @code{make} finds that the object file can be made by C compilation from @file{@var{n}.c}; later on, when considering -how to make @file{@var{n}.c}, the rule for running Yacc will be +how to make @file{@var{n}.c}, the rule for running Yacc is used. Ultimately both @file{@var{n}.c} and @file{@var{n}.o} are updated.@refill @cindex intermediate file +@cindex files, intermediate However, even if @file{@var{n}.c} does not exist and is not mentioned, @code{make} knows how to envision it as the missing link between @file{@var{n}.o} and @file{@var{n}.y}! In this case, @file{@var{n}.c} is @@ -4739,15 +6535,18 @@ Intermediate files are remade using their rules just like all other files. The difference is that the intermediate file is deleted when -@code{make} is finished. Therefore, the intermediate file which did -not exist before @code{make} also does not exist after @code{make}. -The deletion is reported to you by printing a @samp{rm -f} command -that shows what @code{make} is doing. (You can optionally define an -implicit rule so as to preserve certain intermediate files. You can also -list the target pattern of an implicit rule (such as @samp{%.o}) as a -dependency file of the special target @code{.PRECIOUS} to preserve intermediate -files whose target patterns match that file's name.)@refill -@cindex preserving intermediate files with .PRECIOUS +@code{make} is finished. Therefore, the intermediate file which did not +exist before @code{make} also does not exist after @code{make}. The +deletion is reported to you by printing a @samp{rm -f} command that +shows what @code{make} is doing. (You can list the target pattern of an +implicit rule (such as @samp{%.o}) as a dependency of the special +target @code{.PRECIOUS} to preserve intermediate files made by implicit +rules whose target patterns match that file's name; +see @ref{Interrupts}.)@refill +@cindex intermediate files, preserving +@cindex preserving intermediate files +@cindex preserving with .PRECIOUS +@cindex @code{.PRECIOUS} intermediate files A chain can involve more than two implicit rules. For example, it is possible to make a file @file{foo} from @file{RCS/foo.y,v} by running RCS, @@ -4769,7 +6568,7 @@ preference to the step-by-step chain because it comes earlier in the ordering of rules. -@node Pattern Rules, Last Resort, Chained Rules, Implicit +@node Pattern Rules, Last Resort, Chained Rules, Implicit Rules @section Defining and Redefining Pattern Rules You define an implicit rule by writing a @dfn{pattern rule}. A pattern @@ -4782,37 +6581,35 @@ Thus, a pattern rule @samp{%.o : %.c} says how to make any file @file{@var{stem}.o} from another file @file{@var{stem}.c}.@refill -@menu -* Intro: Pattern Intro. Basics of writing pattern rules. -* Examples: Pattern Examples. Real examples of pattern rule definitions. - -* Vars: Automatic. The automatic variables enable the commands - in pattern rules to act on the right files. - -* Matching: Pattern Match. Details of how patterns match. - -* Match-Anything Rules:: Precautions in defining a rules that can - match any target file whatever. - -* Canceling Rules:: Overriding or canceling built-in rules. +Note that expansion using @samp{%} in pattern rules occurs +@strong{after} any variable or function expansions, which take place +when the makefile is read. @xref{Using Variables, , How to Use +Variables}, and @ref{Functions, ,Functions for Transforming Text}. -* Last Resort:: How to define a last-resort rule - that applies to any target that no other - rule applies to. - -* Suffix Rules:: The old-fashioned way to define implicit rules. +@menu +* Pattern Intro:: An introduction to pattern rules. +* Pattern Examples:: Examples of pattern rules. +* Automatic:: How to use automatic variables in the + commands of implicit rules. +* Pattern Match:: How patterns match. +* Match-Anything Rules:: Precautions you should take prior to + defining rules that can match any + target file whatever. +* Canceling Rules:: How to override or cancel built-in rules. @end menu -@node Pattern Intro, Pattern Examples, Pattern Rules, Pattern Rules +@node Pattern Intro, Pattern Examples, , Pattern Rules @subsection Introduction to Pattern Rules - @cindex pattern rule -You define an implicit rule by writing a @dfn{pattern rule}. A pattern -rule looks like an ordinary rule, except that its target contains the -character @samp{%} (exactly one of them). The target is considered a -pattern for matching file names; the @samp{%} can match any nonempty -substring, while other characters match only themselves. +@cindex rule, pattern +A pattern rule contains the character @samp{%} (exactly one of them) +in the target; otherwise, it looks exactly like an ordinary rule. The +target is a pattern for matching file names; the @samp{%} matches any +nonempty substring, while other characters match only themselves. +@cindex target pattern, implicit +@cindex @code{%}, in pattern rules + For example, @samp{%.c} as a pattern matches any file name that ends in @samp{.c}. @samp{s.%.c} as a pattern matches any file name that starts with @samp{s.}, ends in @samp{.c} and is at least five characters long. @@ -4824,43 +6621,53 @@ the pattern rule to apply, its target pattern must match the file name under consideration, and its dependency patterns must name files that exist or can be made. These files become dependencies of the target. +@cindex dependency pattern, implicit Thus, a rule of the form @example -%.o : %.c +%.o : %.c ; @var{command}@dots{} @end example @noindent -would specify how to make any file @file{@var{n}.o}, with another file -@file{@var{n}.c} as its dependency, provided that the other file exists or -can be made. +specifies how to make a file @file{@var{n}.o}, with another file +@file{@var{n}.c} as its dependency, provided that @file{@var{n}.c} +exists or can be made. There may also be dependencies that do not use @samp{%}; such a dependency attaches to every file made by this pattern rule. These unvarying dependencies are useful occasionally. -It is allowed for a pattern rule to have no dependencies that contain -@samp{%} or to have no dependencies at all. This is effectively a general -wildcard. It provides a way to make any file that matches the target pattern. +@c !!! The following sentence should be rewritten. --bob +@c rewritten by roland; does it win now? +A pattern rule need not have any dependencies that contain @samp{%}, or +in fact any dependencies at all. Such a rule is effectively a general +wildcard. It provides a way to make any file that matches the target +pattern. @xref{Last Resort}. +@c !!! The end of of this paragraph should be rewritten. --bob Pattern rules may have more than one target. Unlike normal rules, this does not act as many different rules with the same dependencies and commands. If a pattern rule has multiple targets, @code{make} knows that the rule's commands are responsible for making all of the targets. The -commands are executed only once to make all of the targets. When searching +commands are executed only once to make all the targets. When searching for a pattern rule to match a target, the target patterns of a rule other than the one that matches the target in need of a rule are incidental: @code{make} worries only about giving commands and dependencies to the file presently in question. However, when this file's commands are run, the other targets are marked as having been updated themselves. +@cindex multiple targets, in pattern rule +@cindex target, multiple in pattern rule The order in which pattern rules appear in the makefile is important -because the rules are considered in that order. Of equally applicable -rules, the first one found is used. The rules you write take precedence -over those that are built in. Note, however, that a rule whose +since this is the order in which they are considered. +Of equally applicable +rules, only the first one found is used. The rules you write take precedence +over those that are built in. Note however, that a rule whose dependencies actually exist or are mentioned always takes priority over a rule with dependencies that must be made by chaining other implicit rules. +@cindex pattern rules, order of +@cindex order of pattern rules @node Pattern Examples, Automatic, Pattern Intro, Pattern Rules @subsection Pattern Rule Examples @@ -4878,7 +6685,7 @@ defines a rule that can make any file @file{@var{x}.o} from @file{@var{x}.c}. The command uses the automatic variables @samp{$@@} and @samp{$<} to substitute the names of the target file and the source file -in each case where the rule applies (@pxref{Automatic}).@refill +in each case where the rule applies (@pxref{Automatic, ,Automatic Variables}).@refill Here is a second built-in rule: @@ -4888,39 +6695,46 @@ @end example @noindent -defines a rule that can make any file @file{@var{x}} whatever from a +defines a rule that can make any file @file{@var{x}} whatsoever from a corresponding file @file{@var{x},v} in the subdirectory @file{RCS}. Since the target is @samp{%}, this rule will apply to any file whatever, provided the appropriate dependency file exists. The double colon makes the rule @dfn{terminal}, which means that its dependency may not be an intermediate -file (@pxref{Match-Anything Rules}).@refill +file (@pxref{Match-Anything Rules, ,Match-Anything Pattern Rules}).@refill +@need 500 This pattern rule has two targets: @example +@group %.tab.c %.tab.h: %.y bison -d $< +@end group @end example @noindent -This tells @code{make} that the command @samp{bison -d @var{x}.y} -will make both @file{@var{x}.tab.c} and @file{@var{x}.tab.h}. If the file -@file{foo} depends on the files @file{parse.tab.o} and @file{scan.o} and -@file{scan.o} depends on @file{parse.tab.h}, when @file{parse.y} is -changed, the command @samp{bison -d parse.y} will be executed only once, -and the dependencies of both @file{parse.tab.o} and @file{scan.o} will be -satisfied. (Presumably, @file{parse.tab.o} will be recompiled from -@file{parse.tab.c} and @file{scan.o} from @file{scan.c}, and @file{foo} -will be linked from @file{parse.tab.o}, @file{scan.o}, and its other +@c The following paragraph is rewritten to avoid overfull hboxes +This tells @code{make} that the command @samp{bison -d @var{x}.y} will +make both @file{@var{x}.tab.c} and @file{@var{x}.tab.h}. If the file +@file{foo} depends on the files @file{parse.tab.o} and @file{scan.o} +and the file @file{scan.o} depends on the file @file{parse.tab.h}, +when @file{parse.y} is changed, the command @samp{bison -d parse.y} +will be executed only once, and the dependencies of both +@file{parse.tab.o} and @file{scan.o} will be satisfied. (Presumably +the file @file{parse.tab.o} will be recompiled from @file{parse.tab.c} +and the file @file{scan.o} from @file{scan.c}, while @file{foo} is +linked from @file{parse.tab.o}, @file{scan.o}, and its other dependencies, and it will execute happily ever after.)@refill @node Automatic, Pattern Match, Pattern Examples, Pattern Rules @subsection Automatic Variables @cindex automatic variables +@cindex variable, automatic +@cindex variable, and implicit rule Suppose you are writing a pattern rule to compile a @samp{.c} file into a @samp{.o} file: how do you write the @samp{cc} command so that it operates -on the right source file name? You can't write the name in the command, +on the right source file name? You cannot write the name in the command, because the name is different each time the implicit rule is applied. What you do is use a special feature of @code{make}, the @dfn{automatic @@ -4932,38 +6746,68 @@ Here is a table of automatic variables: @table @code +@vindex $@@ +@vindex @@ @r{(automatic variable)} @item $@@ The file name of the target of the rule. If the target is an archive -member, then @samp{$@@} is the name of the archive file. +member, then @samp{$@@} is the name of the archive file. In a pattern +rule that has multiple targets (@pxref{Pattern Intro, ,Introduction to +Pattern Rules}), @samp{$@@} is the name of whichever target caused the +rule's commands to be run. +@vindex $% +@vindex % @r{(automatic variable)} @item $% -The target member name, when the target is an archive member. For -example, if the target is @file{foo.a(bar.o)} then @samp{$%} is -@file{bar.o} and @samp{$@@} is @file{foo.a}. @samp{$%} is empty -when the target is not an archive member. +The target member name, when the target is an archive member. +@xref{Archives}. For example, if the target is @file{foo.a(bar.o)} then +@samp{$%} is @file{bar.o} and @samp{$@@} is @file{foo.a}. @samp{$%} is +empty when the target is not an archive member. +@vindex $< +@vindex < @r{(automatic variable)} @item $< -The name of the first dependency. +The name of the first dependency. If the target got its commands from +an implicit rule, this will be the first dependency added by the +implicit rule (@pxref{Implicit Rules}). +@vindex $? +@vindex ? @r{(automatic variable)} @item $? -The names of all the dependencies that are -newer than the target, with spaces between them. +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 (@pxref{Archives}). +@cindex dependencies, list of changed +@cindex list of changed dependencies +@vindex $^ +@vindex ^ @r{(automatic variable)} @item $^ -The names of all the dependencies, with spaces between them. +The names of all the dependencies, with spaces between them. For +dependencies which are archive members, only the member named is used +(@pxref{Archives}). +@cindex dependencies, list of all +@cindex list of all dependencies +@vindex $* +@vindex * @r{(automatic variable)} @item $* -The stem with which an implicit rule matches (@pxref{Pattern Match}). -If the target is @file{dir/a.foo.b} and the target pattern is -@file{a.%.b} then the stem is @file{dir/foo}. The stem is useful for -constructing names of related files.@refill - -In an explicit rule, there is no stem; so @samp{$*} cannot be -determined in that way. Instead, if the target name ends with a -recognized suffix (@pxref{Suffix Rules}), @samp{$*} is set to the -target name minus the suffix. For example, if the target name is -@samp{foo.c}, then @samp{$*} is set to @samp{foo}, since @samp{.c} is -a suffix.@refill +The stem with which an implicit rule matches (@pxref{Pattern Match, ,How +Patterns Match}). If the target is @file{dir/a.foo.b} and the target +pattern is @file{a.%.b} then the stem is @file{dir/foo}. The stem is +useful for constructing names of related files.@refill +@cindex stem, variable for + +In a static pattern rule, the stem is part of the file name that matched +the @samp{%} in the target pattern. + +In an explicit rule, there is no stem; so @samp{$*} cannot be determined +in that way. Instead, if the target name ends with a recognized suffix +(@pxref{Suffix Rules, ,Old-Fashioned Suffix Rules}), @samp{$*} is set to +the target name minus the suffix. For example, if the target name is +@samp{foo.c}, then @samp{$*} is set to @samp{foo}, since @samp{.c} is a +suffix. GNU @code{make} does this bizarre thing only for compatibility +with other implementations of @code{make}. You should generally never use +@samp{$*} except in implicit rules or static pattern rules.@refill If the target name in an explicit rule does not end with a recognized suffix, @samp{$*} is set to the empty string for that rule. @@ -4975,68 +6819,95 @@ This rule copies just the changed object files into the archive: @example +@group lib: foo.o bar.o lose.o win.o ar r lib $? +@end group @end example Of the variables listed above, four have values that are single file -names, and two have values that are lists of file names. These six have -variants that get just the file's directory name or just the file name -within the directory. The variant variables' names are formed by +names, and two have values that are lists of file names. These six +have variants that get just the file's directory name or just the file +name within the directory. The variant variables' names are formed by appending @samp{D} or @samp{F}, respectively. These variants are semi-obsolete in GNU @code{make} since the functions @code{dir} and @code{notdir} can be used to get an equivalent effect (@pxref{Filename -Functions}). Here is a table of the variants:@refill +Functions, , Functions for File Names}). Here is a table of the +variants:@refill @table @samp +@vindex $(@@D) +@vindex @@D @r{(automatic variable)} @item $(@@D) The directory part of the file name of the target. If the value of @samp{$@@} is @file{dir/foo.o} then @samp{$(@@D)} is @file{dir/}. This value is @file{./} if @samp{$@@} does not contain a slash. -@samp{$(@@D)} is equivalent to @samp{$(dir $@@)}.@refill +@samp{$(@@D)} is equivalent to @w{@samp{$(dir $@@)}}.@refill +@vindex $(@@F) +@vindex @@F @r{(automatic variable)} @item $(@@F) The file-within-directory part of the file name of the target. If the value of @samp{$@@} is @file{dir/foo.o} then @samp{$(@@F)} is @file{foo.o}. @samp{$(@@F)} is equivalent to @samp{$(notdir $@@)}. +@vindex $(*D) +@vindex *D @r{(automatic variable)} @item $(*D) +@vindex $(*F) +@vindex *F @r{(automatic variable)} @itemx $(*F) The directory part and the file-within-directory part of the stem; @file{dir/} and @file{foo} in this example. +@vindex $(%D) +@vindex %D @r{(automatic variable)} @item $(%D) +@vindex $(%F) +@vindex %F @r{(automatic variable)} @itemx $(%F) The directory part and the file-within-directory part of the target -archive member name. This makes sense only for archive member -targets of the form @file{@var{archive}(@var{member})} -and useful only when @var{member} may contain a directory name. -(@xref{Archive Members}.) +archive member name. This makes sense only for archive member targets +of the form @file{@var{archive}(@var{member})} and is useful only when +@var{member} may contain a directory name. (@xref{Archive Members, +,Archive Members as Targets}.) +@vindex $( tar-`sed -e '/version_string/!d' \ + -e 's/[^0-9.]*\([0-9.]*\).*/\1/' \ + -e q + version.c`.shar.Z +@end group + +@group +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` +@end group + +@group +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 +@end group +@end example + +@node Concept Index, Name Index, Complex Makefile, Top @unnumbered Index of Concepts @printindex cp @node Name Index, , Concept Index, Top -@unnumbered Index of Functions, Variables, and Directives +@unnumbered Index of Functions, Variables, & Directives @printindex fn diff -ruN make-3.62/misc.c make-3.63/misc.c --- make-3.62/misc.c Mon Oct 7 18:04:20 1991 +++ make-3.63/misc.c Fri Jan 22 16:32:00 1993 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988-1991 Free Software Foundation, Inc. +/* 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 @@ -216,9 +216,9 @@ char *s1, *s2, *s3, *s4, *s5, *s6; { if (makelevel == 0) - fprintf (stderr, "%s: ", program); + fprintf (stderr, "%s: *** ", program); else - fprintf (stderr, "%s[%u]: ", program, makelevel); + fprintf (stderr, "%s[%u]: *** ", program, makelevel); fprintf (stderr, s1, s2, s3, s4, s5, s6); fputs (". Stop.\n", stderr); @@ -260,7 +260,7 @@ unsigned int lineno; char *s1, *s2, *s3, *s4, *s5, *s6; { - fprintf (stderr, "%s:%u: ", file, lineno); + fprintf (stderr, "%s:%u: *** ", file, lineno); fprintf (stderr, s1, s2, s3, s4, s5, s6); fputs (". Stop.\n", stderr); @@ -308,7 +308,7 @@ xmalloc (size) unsigned int size; { - char *result = malloc (size); + char *result = (char *) malloc (size); if (result == 0) fatal ("virtual memory exhausted"); return result; @@ -320,7 +320,7 @@ char *ptr; unsigned int size; { - char *result = realloc (ptr, size); + char *result = (char *) realloc (ptr, size); if (result == 0) fatal ("virtual memory exhausted"); return result; @@ -481,14 +481,18 @@ } #endif -#if !defined(POSIX) && !defined(__GNU_LIBRARY__) +#ifdef GETLOADAVG_PRIVILEGED + +#ifndef HAVE_UNISTD_H extern int getuid (), getgid (), geteuid (), getegid (); -#ifdef USG extern int setuid (), setgid (); -#else -extern int setreuid (), setregid (); -#endif /* USG. */ -#endif /* Not POSIX and not GNU C library. */ +#ifdef HAVE_SETREUID +extern int setreuid (); +#endif /* Have setreuid. */ +#ifdef HAVE_SETREGID +extern int setregid (); +#endif /* Have setregid. */ +#endif /* No . */ /* 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; @@ -511,11 +515,15 @@ 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 (); @@ -527,7 +535,8 @@ 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. */ -#if defined (USG) || defined (POSIX) +#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 @@ -535,11 +544,12 @@ 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 ("setuid"); - if (setgid (user_gid) < 0) - pfatal_with_name ("setgid"); + pfatal_with_name ("user_access: setuid"); + #else + /* 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 @@ -546,13 +556,23 @@ 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 ("setreuid"); + pfatal_with_name ("user_access: setreuid"); + +#endif + +#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 ("setregid"); + pfatal_with_name ("user_access: setregid"); #endif current_access = user; + +#endif /* GETLOADAVG_PRIVILEGED */ } /* Give the process appropriate permissions for access to @@ -560,6 +580,8 @@ void make_access () { +#ifdef GETLOADAVG_PRIVILEGED + if (!access_inited) init_access (); @@ -568,19 +590,25 @@ /* See comments in user_access, above. */ -#if defined (USG) || defined (POSIX) +#ifndef HAVE_SETREUID if (setuid (make_uid) < 0) - pfatal_with_name ("setuid"); - if (setgid (make_gid) < 0) - pfatal_with_name ("setgid"); + pfatal_with_name ("make_access: setuid"); #else if (setreuid (user_uid, make_uid) < 0) - pfatal_with_name ("setreuid"); + pfatal_with_name ("make_access: setreuid"); +#endif + +#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 ("setregid"); + pfatal_with_name ("make_access: setregid"); #endif current_access = make; + +#endif /* GETLOADAVG_PRIVILEGED */ } /* Give the process appropriate permissions for a child process. @@ -588,11 +616,45 @@ void child_access () { +#ifdef GETLOADAVG_PRIVILEGED + /* 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 ("setuid"); + 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 ("setgid"); + pfatal_with_name ("child_access: setgid"); +#else + if (setregid (user_gid, user_gid) < 0) + pfatal_with_name ("child_access: setregid"); +#endif + +#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 diff -ruN make-3.62/read.c make-3.63/read.c --- make-3.62/read.c Thu Oct 10 16:20:54 1991 +++ make-3.63/read.c Mon Jan 18 19:14:29 1993 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. +/* 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 @@ -22,7 +22,7 @@ #include "variable.h" /* This is POSIX.2, but most systems using -DPOSIX probably don't have it. */ -#ifdef __GNU_LIBRARY__ +#ifdef HAVE_GLOB_H #include #else #include "glob/glob.h" @@ -66,9 +66,10 @@ struct conditionals { - unsigned int if_cmds; - unsigned int max_ignoring; - char *ignoring; + unsigned int if_cmds; /* Depth of conditional nesting. */ + unsigned int allocated; /* Elts allocated in following arrays. */ + char *ignoring; /* Are we ignoring or interepreting? */ + char *seen_else; /* Have we already seen an `else'? */ }; static struct conditionals toplevel_conditionals; @@ -79,6 +80,7 @@ static char *default_include_directories[] = { + INCLUDEDIR, "/usr/gnu/include", "/usr/local/include", "/usr/include", @@ -127,7 +129,11 @@ MAKEFILES is updated for finding remaining tokens. */ p = value; while ((name = find_next_token (&p, &length)) != 0) - read_makefile (name, 1); + { + if (*p != '\0') + *p++ = '\0'; + read_makefile (name, 1); + } free (value); } @@ -220,7 +226,8 @@ unsigned int commands_started; register char *p; char *p2; - int ignoring = 0; + int ignoring = 0, in_ignored_define = 0; + int no_targets = 0; /* Set when reading a rule without targets. */ struct nameseq *filenames = 0; struct dep *deps; @@ -229,12 +236,15 @@ int two_colon; char *pattern = 0, *pattern_percent; + int makefile_errno; + #define record_waiting_files() \ do \ { \ - record_files (filenames, pattern, pattern_percent, deps, \ - commands_started, commands, commands_idx, \ - two_colon, filename, lineno, type != 1); \ + if (filenames != 0) \ + record_files (filenames, pattern, pattern_percent, deps, \ + commands_started, commands, commands_idx, \ + two_colon, filename, lineno, type != 1); \ filenames = 0; \ commands_idx = 0; \ pattern = 0; \ @@ -247,6 +257,8 @@ /* First, get a stream to read. */ infile = fopen (filename, "r"); + /* Save the error code so we print the right message later. */ + makefile_errno = errno; /* If the makefile wasn't found and it's either a makefile from the `MAKEFILES' variable (type 1) or an included makefile (type 2), @@ -259,13 +271,13 @@ { char *name = concat (include_directories[i], "/", filename); infile = fopen (name, "r"); - if (infile != 0) + if (infile == 0) + free (name); + else { filename = name; break; } - else - free (name); } } @@ -292,7 +304,12 @@ if (infile == 0) { if (type != 1) - perror_with_name ("fopen: ", filename); + { + /* If we did some searching, errno has the error + from the last attempt, rather from FILENAME itself. */ + errno = makefile_errno; + perror_with_name ("fopen: ", filename); + } return; } @@ -300,9 +317,8 @@ reading_lineno_ptr = &lineno; /* Loop over lines in the file. - The strategy is to accumulate target names in FILENAMES, - dependencies in DEPS and commands in COMMANDS. - These are used to define a rule + The strategy is to accumulate target names in FILENAMES, dependencies + in DEPS and commands in COMMANDS. These are used to define a rule when the start of the next rule (or eof) is encountered. */ initbuffer (&lb); @@ -310,11 +326,8 @@ while (!feof (infile)) { lineno += nlines; - nlines = readline (&lb, infile, filename); + nlines = readline (&lb, infile, filename, lineno); - /* Collapse continuation lines. */ - collapse_continuations (lb.buffer); - if (collapsed_length < lb.size) { collapsed_length = lb.size; @@ -323,6 +336,8 @@ collapsed = (char *) xmalloc (collapsed_length); } strcpy (collapsed, lb.buffer); + /* Collapse continuation lines. */ + collapse_continuations (collapsed); remove_comments (collapsed); p = collapsed; @@ -331,23 +346,71 @@ if (*p == '\0' && lb.buffer[0] != '\t') continue; -#define word1eq(s, l) ((p[l] == '\0' || isblank (p[l])) && \ - !strncmp (s, p, l)) - if (word1eq ("ifdef", 5) || word1eq ("ifndef", 6) - || word1eq ("ifeq", 4) || word1eq ("ifneq", 5) - || word1eq ("else", 4) || word1eq ("endif", 5)) + /* strncmp is first to avoid dereferencing out into space. */ +#define word1eq(s, l) (!strncmp (s, p, l) \ + && (p[l] == '\0' || isblank (p[l]))) + if (!in_ignored_define + && (word1eq ("ifdef", 5) || word1eq ("ifndef", 6) + || word1eq ("ifeq", 4) || word1eq ("ifneq", 5) + || word1eq ("else", 4) || word1eq ("endif", 5))) { int i = conditional_line (p, filename, lineno); if (i >= 0) - { - ignoring = i; - continue; - } + ignoring = i; else makefile_fatal (filename, lineno, "invalid syntax in conditional"); + continue; + } + else if (word1eq ("endef", 5)) + { + if (in_ignored_define) + in_ignored_define = 0; + else + makefile_fatal (filename, lineno, "extraneous `endef'"); + continue; + } + else if (word1eq ("define", 6)) + { + if (ignoring) + in_ignored_define = 1; + else + { + p2 = next_token (p + 6); + p = end_of_token (p2); + lineno = do_define (p2, p - p2, o_file, + lineno, infile, filename); + } + continue; + } + else if (word1eq ("override", 8)) + { + p2 = next_token (p + 8); + if (p2 == 0) + makefile_error (filename, lineno, "empty `override' directive"); + if (!strncmp (p2, "define", 6) && (isblank (p2[6]) || p2[6] == '\0')) + { + if (ignoring) + in_ignored_define = 1; + else + { + unsigned int len; + p2 = end_of_token (p2); + p = find_next_token (&p2, &len); + lineno = do_define (p, len, o_override, + lineno, infile, filename); + } + } + else if (!ignoring && !try_variable_definition (p2, o_override)) + makefile_error (filename, lineno, "empty `override' directive"); + + continue; } + + if (ignoring) + /* Ignore the line. We continue here so conditionals + can appear in the middle of a rule. */ continue; else if (lb.buffer[0] == '\t') { @@ -354,9 +417,16 @@ /* This line is a shell command. */ unsigned int len; + if (no_targets) + { + /* Ignore the commands in a rule with no targets. */ + no_targets = 0; + continue; + } + if (filenames == 0) makefile_fatal (filename, lineno, - "commands commence before first target"); + "commands with no associated target"); /* Add this command line to end of the line being accumulated. */ p = lb.buffer; @@ -371,65 +441,93 @@ bcopy (p, &commands[commands_idx], len); commands_idx += len; commands[commands_idx++] = '\n'; + + continue; } - else if (word1eq ("define", 6)) + else if (word1eq ("export", 6)) { + struct variable *v; p2 = next_token (p + 6); - p = end_of_token (p2); - lineno = do_define (p2, p - p2, o_file, lineno, infile, filename); - continue; + if (*p2 == '\0') + export_all_variables = 1; + v = try_variable_definition (p2, o_file); + if (v != 0) + v->export = v_export; + else + { + unsigned int len; + for (p = find_next_token (&p2, &len); p != 0; + p = find_next_token (&p2, &len)) + { + v = lookup_variable (p, len); + if (v == 0) + v = define_variable (p, len, "", o_file, 0); + v->export = v_export; + } + } } - else if (word1eq ("endef", 5)) - makefile_fatal (filename, lineno, "extraneous `endef'"); - else if (word1eq ("override", 8)) + else if (word1eq ("unexport", 8)) { + unsigned int len; + struct variable *v; p2 = next_token (p + 8); - if (p2 == 0) - makefile_error (filename, lineno, "empty `override' directive"); - if (!strncmp (p2, "define", 6)) - { - unsigned int len; - p2 = end_of_token (p2); - p = find_next_token (&p2, &len); - lineno = do_define (p, len, o_override, - lineno, infile, filename); + if (*p2 == '\0') + export_all_variables = 0; + for (p = find_next_token (&p2, &len); p != 0; + p = find_next_token (&p2, &len)) + { + v = lookup_variable (p, len); + if (v == 0) + v = define_variable (p, len, "", o_file, 0); + v->export = v_noexport; } - else if (!try_variable_definition (p2, o_override)) - makefile_error (filename, lineno, - "Empty `override' directive"); - continue; } else if (word1eq ("include", 7)) { /* We have found an `include' line specifying a nested makefile to be read at this point. */ - struct conditionals *save = conditionals; - struct conditionals new_conditionals; + struct conditionals *save, new_conditionals; + struct nameseq *files; + p = allocated_variable_expand (next_token (p + 8)); if (*p == '\0') { - makefile_error (filename, lineno, "no filename for `include'"); + makefile_error (filename, lineno, "no file name for `include'"); continue; } - p2 = end_of_token (p); - if (*p2 != '\0') - { - *p2++ = '\0'; - if (*next_token (p2) != '\0') - makefile_error (filename, lineno, - "extraneous text after `include'"); - } + + /* Parse the list of file names. */ + p2 = p; + files = multi_glob (parse_file_seq (&p2, '\0', + sizeof (struct nameseq)), + sizeof (struct nameseq)); + free (p); + + /* Save the state of conditionals and start + the included makefile with a clean slate. */ + save = conditionals; bzero ((char *) &new_conditionals, sizeof new_conditionals); conditionals = &new_conditionals; + /* Record the rules that are waiting so they will determine the default goal before those in the included makefile. */ record_waiting_files (); - read_makefile (p, 2); - free (p); + + /* Read each included makefile. */ + while (files != 0) + { + struct nameseq *next = files->next; + char *name = files->name; + free (files); + files = next; + + read_makefile (name, 2); + } + + /* Restore state. */ conditionals = save; reading_filename = filename; reading_lineno_ptr = &lineno; - continue; } else if (word1eq ("vpath", 5)) { @@ -442,12 +540,7 @@ pattern = savestring (p, len); p = find_next_token (&p2, &len); if (p != 0) - { - p = savestring (p, len); - if (find_next_token (&p2, (unsigned int *) 0) != 0) - makefile_error (filename, lineno, - "extraneous text after `vpath' directive"); - } + p = savestring (p, len); /* No searchpath means remove all previous selective VPATH's with the same pattern. */ } @@ -459,11 +552,11 @@ free (pattern); if (p != 0) free (p); - continue; } #undef word1eq else if (try_variable_definition (p, o_file)) - continue; + /* This line has been dealt with. */ + ; else { /* This line describes some target files. */ @@ -480,6 +573,8 @@ /* Found one. Cut the line short there before expanding it. */ *cmdleft = '\0'; + collapse_continuations (lb.buffer); + /* Expand variable and function references before doing anything else so that special characters can be inside variables. */ p = variable_expand (lb.buffer); @@ -497,14 +592,25 @@ p2 = next_token (p); if (*p2 == '\0') - /* This line contained a variable reference that - expanded to nothing but whitespace. */ - continue; + { + if (cmdleft != 0) + makefile_fatal (filename, lineno, + "missing rule before commands"); + else + /* This line contained a variable reference that + expanded to nothing but whitespace. */ + continue; + } else if (*p2 == ':') - makefile_fatal (filename, lineno, "missing target name"); + { + /* We accept and ignore rules without targets for + compatibility with SunOS 4 make. */ + no_targets = 1; + continue; + } filenames = multi_glob (parse_file_seq (&p2, ':', - sizeof (struct nameseq)), + sizeof (struct nameseq), 1), sizeof (struct nameseq)); if (*p2++ == '\0') makefile_fatal (filename, lineno, "missing separator"); @@ -529,7 +635,7 @@ if (p != 0) { struct nameseq *target; - target = parse_file_seq (&p2, ':', sizeof (struct nameseq)); + target = parse_file_seq (&p2, ':', sizeof (struct nameseq), 1); ++p2; if (target == 0) makefile_fatal (filename, lineno, "missing target pattern"); @@ -546,13 +652,13 @@ /* Parse the dependencies. */ deps = (struct dep *) - multi_glob (parse_file_seq (&p2, '\0', sizeof (struct dep)), + multi_glob (parse_file_seq (&p2, '\0', sizeof (struct dep), 1), sizeof (struct dep)); commands_idx = 0; if (cmdleft != 0) { - /* Semicolon means rest of line is a command */ + /* Semicolon means rest of line is a command. */ unsigned int len = strlen (cmdleft + 1); commands_started = lineno; @@ -567,10 +673,18 @@ commands_idx += len; commands[commands_idx++] = '\n'; } + + continue; } + + /* We get here except in the case that we just read a rule line. + Record now the last rule we read, so following spurious + commands are properly diagnosed. */ + record_waiting_files (); + no_targets = 0; } - if (ignoring) + if (conditionals->if_cmds) makefile_fatal (filename, lineno, "missing `endif'"); /* At eof, record the last rule. */ @@ -606,11 +720,17 @@ register unsigned int idx = 0; register char *p; + /* Expand the variable name. */ + char *var = (char *) alloca (namelen + 1); + bcopy (name, var, namelen); + var[namelen] = '\0'; + var = variable_expand (var); + initbuffer (&lb); while (!feof (infile)) { lineno += nlines; - nlines = readline (&lb, infile, filename); + nlines = readline (&lb, infile, filename, lineno); p = next_token (lb.buffer); if ((p[5] == '\0' || isblank (p[5])) && !strncmp (p, "endef", 5)) @@ -626,8 +746,9 @@ definition[0] = '\0'; else definition[idx - 1] = '\0'; - (void) define_variable (name, namelen, definition, origin, 1); + (void) define_variable (var, strlen (var), definition, origin, 1); free (definition); + freebuffer (&lb); return lineno; } else @@ -650,6 +771,8 @@ /* No `endef'!! */ makefile_fatal (filename, lineno, "missing `endef', unterminated `define'"); + + /* NOTREACHED */ return 0; } @@ -711,9 +834,17 @@ /* NOTDEF indicates an `endif' command. */ if (notdef) --conditionals->if_cmds; + else if (conditionals->seen_else[conditionals->if_cmds - 1]) + makefile_fatal (filename, lineno, "only one `else' per conditional"); else - conditionals->ignoring[conditionals->if_cmds - 1] - = !conditionals->ignoring[conditionals->if_cmds - 1]; + { + /* Toggle the state of ignorance. */ + conditionals->ignoring[conditionals->if_cmds - 1] + = !conditionals->ignoring[conditionals->if_cmds - 1]; + /* Record that we have seen an `else' in this conditional. + A second `else' will be erroneous. */ + conditionals->seen_else[conditionals->if_cmds - 1] = 1; + } for (i = 0; i < conditionals->if_cmds; ++i) if (conditionals->ignoring[i]) return 1; @@ -720,26 +851,38 @@ return 0; } - if (conditionals->max_ignoring == 0) + if (conditionals->allocated == 0) { - conditionals->max_ignoring = 5; - conditionals->ignoring = (char *) xmalloc (conditionals->max_ignoring); + conditionals->allocated = 5; + conditionals->ignoring = (char *) xmalloc (conditionals->allocated); + conditionals->seen_else = (char *) xmalloc (conditionals->allocated); } ++conditionals->if_cmds; - if (conditionals->if_cmds > conditionals->max_ignoring) + if (conditionals->if_cmds > conditionals->allocated) { - conditionals->max_ignoring += 5; + conditionals->allocated += 5; conditionals->ignoring = (char *) - xrealloc (conditionals->ignoring, conditionals->max_ignoring); + xrealloc (conditionals->ignoring, conditionals->allocated); + conditionals->seen_else = (char *) + xrealloc (conditionals->seen_else, conditionals->allocated); } - if (conditionals->if_cmds > 1 && - conditionals->ignoring[conditionals->if_cmds - 2]) - /* We are already ignoring, so just push a level - to match the next "else" or "endif", and keep ignoring. */ - conditionals->ignoring[conditionals->if_cmds - 1] = 1; - else if (cmdname[notdef ? 3 : 2] == 'd') + /* Record that we have seen an `if...' but no `else' so far. */ + conditionals->seen_else[conditionals->if_cmds - 1] = 0; + + /* Search through the stack to see if we're already ignoring. */ + for (i = 0; i < conditionals->if_cmds - 1; ++i) + if (conditionals->ignoring[i]) + { + /* We are already ignoring, so just push a level + to match the next "else" or "endif", and keep ignoring. + We don't want to expand variables in the condition. */ + conditionals->ignoring[conditionals->if_cmds - 1] = 1; + return 1; + } + + if (cmdname[notdef ? 3 : 2] == 'd') { /* "Ifdef" or "ifndef". */ struct variable *v; @@ -983,7 +1126,8 @@ { /* Give a warning if the rule is meaningless. */ makefile_error (filename, lineno, - "target `%s' doesn't match the target pattern"); + "target `%s' doesn't match the target pattern", + name); this = 0; } else @@ -1048,19 +1192,53 @@ /* Defining .SUFFIXES with no dependencies clears out the list of suffixes. */ if (f == suffix_file && this == 0) - f->deps = 0; - else if (f->deps != 0) { d = f->deps; - while (d->next != 0) - d = d->next; - d->next = this; + while (d != 0) + { + struct dep *nextd = d->next; + free (d->name); + free (d); + d = nextd; + } + f->deps = 0; + } + else if (f->deps != 0) + { + /* Add the file's old deps and the new ones in THIS together. */ + + struct dep *firstdeps, *moredeps; + if (cmds != 0) + { + /* This is the rule with commands, so put its deps first. + The rationale behind this is that $< expands to the + first dep in the chain, and commands use $< expecting + to get the dep that rule specifies. */ + firstdeps = this; + moredeps = f->deps; + } + else + { + /* Append the new deps to the old ones. */ + firstdeps = f->deps; + moredeps = this; + } + + if (firstdeps == 0) + firstdeps = moredeps; + else + { + d = firstdeps; + while (d->next != 0) + d = d->next; + d->next = moredeps; + } + + f->deps = firstdeps; } else f->deps = this; - uniquize_deps (f->deps); - /* If this is a static pattern rule, set the file's stem to the part of its name that matched the `%' in the pattern, so you can use $* in the commands. */ @@ -1096,7 +1274,7 @@ /* Free name if not needed further. */ if (f != 0 && name != f->name - && !(f->name == name + 2 && name[0] == '.' && name[1] == '/')) + && (name < f->name || name > f->name + strlen (f->name))) { free (name); name = f->name; @@ -1217,9 +1395,8 @@ if (i % 2 == 0) /* All the backslashes quoted each other; the % was unquoted. */ return p; - else - /* The % was quoted by a backslash. Look for another. */ - ++p; + + /* The % was quoted by a backslash. Look for another. */ } else /* No backslash in sight. */ @@ -1276,9 +1453,23 @@ } p--; + /* Skip leading `./'s. */ + while (p - q > 2 && q[0] == '.' && q[1] == '/') + { + q += 2; /* Skip "./". */ + while (q < p && *q == '/') + /* Skip following slashes: ".//foo" is "foo", not "/foo". */ + ++q; + } + /* Extract the filename just found, and skip it. */ - name = savestring (q, p - q); + if (q == p) + /* ".///" was stripped to "". */ + name = savestring ("./", 2); + else + name = savestring (q, p - q); + /* Add it to the front of the chain. */ new1 = (struct nameseq *) xmalloc (size); new1->name = name; @@ -1296,10 +1487,11 @@ */ static unsigned int -readline (linebuffer, stream, filename) +readline (linebuffer, stream, filename, lineno) struct linebuffer *linebuffer; FILE *stream; char *filename; + unsigned int lineno; { char *buffer = linebuffer->buffer; register char *p = linebuffer->buffer; @@ -1315,12 +1507,17 @@ { if (fgets (p, end - p, stream) == 0) if (feof (stream)) - return nlines; + break; else pfatal_with_name (filename); len = strlen (p); - if (len == 0 || (p += len)[-1] != '\n') + if (len == 0) + /* This only happens when the first thing on the line is a '\0'. */ + makefile_fatal (filename, lineno, "NUL not allowed in makefile"); + + p += len; + if (p[-1] != '\n') { /* Probably ran out of buffer space. */ register unsigned int p_off = p - buffer; @@ -1358,7 +1555,7 @@ if (!backslash) { p[-1] = '\0'; - return nlines; + break; } if (end - p <= 1) @@ -1372,6 +1569,8 @@ linebuffer->buffer = buffer; } } + + return nlines; } /* Construct the list of include directories @@ -1527,8 +1726,8 @@ { case 0: /* Success. */ { - register int i; - for (i = 0; i < gl.gl_pathc; ++i) + register int i = gl.gl_pathc; + while (i-- > 0) { struct nameseq *elt = (struct nameseq *) xmalloc (size); elt->name = savestring (gl.gl_pathv[i], @@ -1537,6 +1736,8 @@ new = elt; } globfree (&gl); + free (old->name); + free (old); break; } @@ -1547,6 +1748,7 @@ default: old->next = new; new = old; + break; } } diff -ruN make-3.62/remake.c make-3.63/remake.c --- make-3.62/remake.c Tue Oct 29 20:57:32 1991 +++ make-3.63/remake.c Fri Jan 22 17:02:48 1993 @@ -1,4 +1,5 @@ -/* Copyright (C) 1988-1991 Free Software Foundation, Inc. +/* 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 @@ -29,21 +30,16 @@ #include #endif - -#if !defined(__GNU_LIBRARY__) && !defined(POSIX) -extern int fstat (); -extern time_t time (); -#endif - extern int try_implicit_rule (); /* Incremented when a file has been remade. */ -static unsigned int files_remade = 0; +unsigned int files_remade = 0; -static int update_file (), update_file_1 (), check_dep (); +static int update_file (), update_file_1 (), check_dep (), touch_file (); static void remake_file (); -static time_t name_mtime (), library_file_mtime (); +static time_t name_mtime (); +static int library_search (); extern time_t f_mtime (); /* Remake all the goals in the `struct dep' chain GOALS. Return -1 if nothing @@ -79,9 +75,13 @@ { register struct dep *g, *lastgoal; + /* Start jobs that are waiting for the load to go down. */ + + start_waiting_jobs (); + /* Wait for a child to die. */ - wait_for_children (1, 0); + reap_children (1, 0); lastgoal = 0; g = goals; @@ -192,34 +192,47 @@ register int status = 0; register struct file *f; unsigned int ofiles_remade = files_remade; - int commands_finished = 0; for (f = file; f != 0; f = f->prev) { - register struct dep *d; - char not_started = f->command_state == cs_not_started; - status |= update_file_1 (f, depth); check_renamed (f); - for (d = f->also_make; d != 0; d = d->next) - { - d->file->command_state = f->command_state; - d->file->update_status = f->update_status; - d->file->updated = f->updated; - } - if (status != 0 && !keep_going_flag) return status; - commands_finished |= not_started && f->command_state == cs_finished; + switch (f->command_state) + { + case cs_finished: + /* The file is done being remade. */ + break; + + case cs_running: + case cs_deps_running: + /* Don't run the other :: rules for this + file until this rule is finished. */ + return 0; + + default: + error ("internal error: `%s' command_state == %d in update_file", + f->name, (int) f->command_state); + abort (); + break; + } } /* For a top level target, if we have found nothing whatever to do for it, print a message saying nothing needs doing. */ - if (status == 0 && files_remade == ofiles_remade - && commands_finished && depth == 0 && !silent_flag && !question_flag) + /* Give a message iff updated successfully, and never under -s or -q. */ + if (status == 0 && !silent_flag && !question_flag + /* files_remade will have been incremented iff we actually + ran any commands (under -n, if we would have). */ + && files_remade == ofiles_remade + /* Only give the diagnostic for top-level targets. + The makefile chain run is done with DEPTH==1 precisely + to avoid this message. */ + && depth == 0) { if (file->phony || file->cmds == 0) message ("Nothing to be done for `%s'.", file->name); @@ -242,7 +255,7 @@ int noexist, must_make, deps_changed; int dep_status = 0; register struct dep *d, *lastd; - char running = 0; + int running = 0; DEBUGPR ("Considering target file `%s'.\n"); @@ -302,7 +315,8 @@ else { DEBUGPR ("No implicit rule found for `%s'.\n"); - if (default_file != 0 && default_file->cmds != 0) + if (!file->is_target + && default_file != 0 && default_file->cmds != 0) { DEBUGPR ("Using default commands for `%s'.\n"); file->cmds = default_file->cmds; @@ -320,6 +334,8 @@ { time_t mtime; + check_renamed (d->file); + mtime = file_mtime (d->file); check_renamed (d->file); @@ -526,8 +542,9 @@ return file->update_status; } -/* Set FILE's `updated' flag and re-check its mtime and the mtime's - of all files listed in its `also_make' member. */ +/* Set FILE's `updated' flag and re-check its mtime and the mtime's of all + files listed in its `also_make' member. Under -t, this function also + touches FILE. */ void notice_finished_file (file) @@ -538,7 +555,34 @@ file->command_state = cs_finished; file->updated = 1; - ++files_remade; + if (touch_flag + /* The update status will be: + -1 if no commands were run; + 0 if some commands (+ or ${MAKE}) were run and won; + 1 if some commands were run and lost. + The only time we don't want to touch the target is if + it had some recursive commands, and they lost. */ + && file->update_status != 1) + { + if (file->cmds != 0 && file->cmds->any_recurse) + { + /* If all the command lines were recursive, + we don't want to do the touching. */ + unsigned int i; + for (i = 0; i < file->cmds->ncommand_lines; ++i) + if (!file->cmds->lines_recurse[i]) + goto have_nonrecursing; + } + else + { + have_nonrecursing: + if (file->phony) + file->update_status = 0; + else + /* Should set file's modification date and do nothing else. */ + file->update_status = touch_file (file); + } + } if (!file->phony) { @@ -549,16 +593,24 @@ file->last_mtime = 0; } - for (d = file->also_make; d != 0; d = d->next) - { - d->file->command_state = cs_finished; - d->file->updated = 1; - d->file->update_status = file->update_status; - if (just_print_flag || question_flag) - d->file->last_mtime = file->last_mtime; - else - d->file->last_mtime = 0; - } + if (file->update_status != -1) + /* We actually tried to update FILE, which has + updated its also_make's as well (if it worked). + If it didn't work, it wouldn't work again for them. + So mark them as updated with the same status. */ + for (d = file->also_make; d != 0; d = d->next) + { + d->file->command_state = cs_finished; + d->file->updated = 1; + d->file->update_status = file->update_status; + + if (!d->file->phony) + /* Fetch the new modification time. + We do this instead of just invalidating the cached time + so that a vpath_search can happen. Otherwise, it would + never be done because the target is already updated. */ + (void) f_mtime (d->file); + } } /* Check whether another file (whose mtime is THIS_MTIME) @@ -629,6 +681,13 @@ if (dep_status != 0 && !keep_going_flag) break; + if (d->file->command_state == cs_running + || d->file->command_state == cs_deps_running) + /* Record that some of FILE's dependencies are still being made. + This tells the upper levels to wait on processing it until + the commands are finished. */ + file->command_state = cs_deps_running; + lastd = d; d = d->next; } @@ -638,7 +697,7 @@ return dep_status; } -/* Touch FILE. Return zero if successful, nonzero if not. */ +/* Touch FILE. Return zero if successful, one if not. */ #define TOUCH_ERROR(call) return (perror_with_name (call, file->name), 1) @@ -712,11 +771,11 @@ else { /* This is a dependency file we cannot remake. Fail. */ - static char noway[] = "*** No way to make target"; + static char noway[] = "No rule to make target"; if (keep_going_flag || file->dontcare) { if (!file->dontcare) - error ("%s `%s'.", noway, file->name); + error ("*** %s `%s'.", noway, file->name); file->update_status = 1; } else @@ -727,15 +786,7 @@ { chop_commands (file->cmds); - if (touch_flag && !file->cmds->any_recurse) - { - if (file->phony) - file->update_status = 0; - else - /* Should set file's modification date and do nothing else. */ - file->update_status = touch_file (file); - } - else + if (!touch_flag || file->cmds->any_recurse) { execute_file_commands (file); return; @@ -742,15 +793,18 @@ } } + /* This does the touching under -t. */ notice_finished_file (file); } /* Return the mtime of a file, given a `struct file'. - Caches the time in the struct file to avoid excess stat calls. If the file - is not found, and SEARCH is nonzero, VPATH searching and replacement is - done. If that fails, a library (-lLIBNAME) is tried but the library's - actual name (/lib/libLIBNAME.a, etc.) is not substituted into FILE. */ + Caches the time in the struct file to avoid excess stat calls. + If the file is not found, and SEARCH is nonzero, VPATH searching and + replacement is done. If that fails, a library (-lLIBNAME) is tried and + the library's actual name (/lib/libLIBNAME.a, etc.) is substituted into + FILE. */ + time_t f_mtime (file, search) register struct file *file; @@ -828,26 +882,24 @@ { /* If name_mtime failed, search VPATH. */ char *name = file->name; - if (vpath_search (&name)) + if (vpath_search (&name) + /* Last resort, is it a library (-lxxx)? */ + || (name[0] == '-' && name[1] == 'l' + && library_search (&name))) { rename_file (file, name); check_renamed (file); return file_mtime (file); } - else - /* Last resort, is it a library (-lxxx)? */ - if (name[0] == '-' && name[1] == 'l') - mtime = library_file_mtime (&name[2]); } } /* Store the mtime into all the entries for this file. */ - - while (file != 0) + do { file->last_mtime = mtime; file = file->prev; - } + } while (file != 0); return mtime; } @@ -868,40 +920,59 @@ } -/* Return the mtime of a library file specified as -lLIBNAME, - searching for a suitable library file in the system library directories - and the VPATH directories. */ +/* Search for a library file specified as -lLIBNAME, searching for a + suitable library file in the system library directories and the VPATH + directories. */ -static time_t -library_file_mtime (lib) - char *lib; +static int +library_search (lib) + char **lib; { - time_t mtime; - char *name; + static char *dirs[] = + { + "/lib", + "/usr/lib", + LIBDIR, /* Defined by configuration. */ + 0 + }; + + char *libname = &(*lib)[2]; /* Name without the `-l'. */ + + /* Buffer to construct possible names in. */ + char *buf = xmalloc (sizeof (LIBDIR) + 8 + strlen (libname) + 4 + 2 + 1); + char *file, **dp; + + /* Look first for `libNAME.a' in the current directory. */ + + sprintf (buf, "lib%s.a", libname); + if (name_mtime (buf) != (time_t) -1) + { + *lib = buf; + return 1; + } + + /* Now try VPATH search on that. */ - name = concat ("/usr/lib/lib", lib, ".a"); - mtime = name_mtime (name); - if (mtime == (time_t) -1) - mtime = name_mtime (name + 4); - if (mtime == (time_t) -1) + file = buf; + if (vpath_search (&file)) { - char *local = concat ("/usr/local/lib/lib", lib, ".a"); - mtime = name_mtime (local); - free (local); + free (buf); + *lib = file; + return 1; } - if (mtime == (time_t) -1) - mtime = name_mtime (name + 9); - if (mtime == (time_t) -1) + + /* Now try the standard set of directories. */ + + for (dp = dirs; *dp != 0; ++dp) { - char *newname = name + 9; - if (vpath_search (&newname)) + sprintf (buf, "%s/lib%s.a", *dp, libname); + if (name_mtime (buf) != (time_t) -1) { - mtime = name_mtime (newname); - free (newname); + *lib = buf; + return 1; } } - free (name); - - return mtime; + free (buf); + return 0; } diff -ruN make-3.62/remote-cstms.c make-3.63/remote-cstms.c --- make-3.62/remote-cstms.c Wed Jul 3 18:27:54 1991 +++ make-3.63/remote-cstms.c Sat Jul 4 20:52:45 1992 @@ -1,9 +1,15 @@ -/* Copyright (C) 1988, 1989 Free Software Foundation, Inc. +/* This file implements an interface to the Customs daemon to do + remote execution of commands under GNU make. + 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 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 1, or (at your option) +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, @@ -38,23 +44,21 @@ return !CUSTOMS_FAIL (&permit.addr); } -/* Start a remote job running the command in ARGV. - 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). */ +/* 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, stdin_fd, is_remote, id_ptr, used_stdin) - char **argv; +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 char **environ; extern int vfork (), execve (); PATH_VAR (cwd); char waybill[MAX_DATA_SIZE], msg[128]; @@ -66,9 +70,13 @@ int pid; /* Find the current directory. */ - if (getwd (cwd) == 0) + if (getcwd (cwd, GET_PATH_MAX) == 0) { +#ifdef HAVE_GETCWD + perror_with_name ("exporting: getcwd: ", ""); +#else error ("exporting: getwd: %s", cwd); +#endif return 1; } @@ -95,7 +103,7 @@ /* Create a WayBill to give to the server. */ len = Customs_MakeWayBill (&permit, cwd, argv[0], argv, - environ, retport, waybill); + envp, retport, waybill); /* Send the request to the server, timing out in 20 seconds. */ timeout.tv_usec = 0; diff -ruN make-3.62/remote-stub.c make-3.63/remote-stub.c --- make-3.62/remote-stub.c Wed May 10 18:57:31 1989 +++ make-3.63/remote-stub.c Tue Mar 10 17:15:46 1992 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988, 1989 Free Software Foundation, Inc. +/* Copyright (C) 1988, 1989, 1992 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify @@ -30,17 +30,16 @@ return 0; } -/* Start a remote job running the command in ARGV. - 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). */ +/* 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, stdin_fd, is_remote, id_ptr, used_stdin) - char **argv; +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; diff -ruN make-3.62/rule.c make-3.63/rule.c --- make-3.62/rule.c Wed Aug 7 17:32:00 1991 +++ make-3.63/rule.c Fri Nov 13 18:14:36 1992 @@ -1,5 +1,5 @@ /* Pattern and suffix rule internals for GNU Make. -Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. +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 @@ -24,7 +24,6 @@ #include "rule.h" static void freerule (); -static int new_pattern_rule (); /* Chain of all pattern rules. */ @@ -71,12 +70,14 @@ name = 0; namelen = 0; - rule = lastrule = pattern_rules; + rule = pattern_rules; + lastrule = 0; while (rule != 0) { unsigned int ndeps = 0; register struct dep *dep; - + struct rule *next = rule->next; + ++num_pattern_rules; for (dep = rule->deps; dep != 0; dep = dep->next) @@ -92,6 +93,8 @@ 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 (p - dep->name > namelen) @@ -106,13 +109,16 @@ if (!dir_file_exists_p (name, ".")) { + /* The name is absolute and the directory does not exist. */ if (*name == '/') { freerule (rule, lastrule); - rule = lastrule; + --num_pattern_rules; goto end_main_loop; } else + /* The directory does not exist, but + it might be found in a VPATH directory. */ rule->subdir = 1; } } @@ -121,9 +127,9 @@ if (ndeps > max_pattern_deps) max_pattern_deps = ndeps; - end_main_loop:; lastrule = rule; - rule = rule->next; + end_main_loop: + rule = next; } if (name != 0) @@ -231,12 +237,12 @@ /* 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 dependents), the old one is replaced + (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. */ -static int +int new_pattern_rule (rule, override) register struct rule *rule; int override; @@ -251,11 +257,15 @@ rule->next = 0; /* Search for an identical rule. */ - lastrule = pattern_rules; + 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])) + { + 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; @@ -274,7 +284,7 @@ else last_pattern_rule->next = rule; last_pattern_rule = rule; - + /* We got one. Stop looking. */ goto matched; } @@ -285,6 +295,7 @@ return 0; } } + } matched:; @@ -386,15 +397,12 @@ free ((char *) rule); - if (lastrule == 0) - return; - if (pattern_rules == rule) - if (lastrule != pattern_rules) + if (lastrule != 0) abort (); else pattern_rules = next; - else + else if (lastrule != 0) lastrule->next = next; if (last_pattern_rule == rule) last_pattern_rule = lastrule; @@ -521,4 +529,8 @@ #endif puts (" reference nonexistent subdirectories."); } + + if (num_pattern_rules != rules) + fatal ("BUG: num_pattern_rules wrong! %u != %u", + num_pattern_rules, rules); } diff -ruN make-3.62/rule.h make-3.63/rule.h --- make-3.62/rule.h Mon Jun 3 16:37:28 1991 +++ make-3.63/rule.h Sun Aug 2 06:11:29 1992 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. +/* Copyright (C) 1988, 1989, 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 @@ -49,3 +49,4 @@ extern void install_pattern_rule (); +int new_pattern_rule (); diff -ruN make-3.62/signame.c make-3.63/signame.c --- make-3.62/signame.c +++ make-3.63/signame.c Wed Jan 6 20:47:18 1993 @@ -0,0 +1,267 @@ +/* Convert between signal names and numbers. + Copyright (C) 1990, 1992, 1993 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. */ + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Some systems do not define NSIG in . */ +#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]; +#endif /* !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 +} + +/* 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_SYS_SIGLIST +/* 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 diff -ruN make-3.62/signame.h make-3.63/signame.h --- make-3.62/signame.h +++ make-3.63/signame.h Fri Jan 22 14:46:32 1993 @@ -0,0 +1,57 @@ +/* Convert between signal names and numbers. + Copyright (C) 1990, 1992, 1993 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 two. */ + +#if !defined (HAVE_SYS_SIGLIST) && !defined (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 + +#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 +#if !defined (HAVE_SYS_SIGLIST) +extern char *sys_siglist[]; +#endif + +#endif diff -ruN make-3.62/texinfo.tex make-3.63/texinfo.tex --- make-3.62/texinfo.tex Wed Oct 23 23:04:50 1991 +++ make-3.63/texinfo.tex Thu Jan 14 17:56:26 1993 @@ -1,6 +1,6 @@ %% TeX macros to handle texinfo files -% Copyright (C) 1985, 1986, 1988, 1990, 1991 Free Software Foundation, Inc. +% Copyright (C) 1985, 86, 88, 90, 91, 92, 1993 Free Software Foundation, Inc. %This texinfo.tex file is free software; you can redistribute it and/or %modify it under the terms of the GNU General Public License as @@ -22,7 +22,7 @@ %You are forbidden to forbid anyone else to use, share and improve %what you give them. Help stamp out software-hoarding! -\def\texinfoversion{2.55} +\def\texinfoversion{2.93} \message{Loading texinfo package [Version \texinfoversion]:} \message{} @@ -50,6 +50,14 @@ \message{Basics,} \chardef\other=12 +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Ignore a token. +% +\def\gobble#1{} + \hyphenation{ap-pen-dix} \hyphenation{mini-buf-fer mini-buf-fers} \hyphenation{eshell} @@ -60,8 +68,20 @@ \newdimen\pagewidth \newdimen\pageheight \pagewidth=\hsize \pageheight=\vsize +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\def\loggingall{\tracingcommands2 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \showboxbreadth\maxdimen\showboxdepth\maxdimen +}% + %---------------------Begin change----------------------- % +%%%% For @cropmarks command. % Dimensions to add cropmarks at corners Added by P. A. MacKay, 12 Nov. 1986 % \newdimen\cornerlong \newdimen\cornerthick @@ -69,7 +89,9 @@ \newdimen \outerhsize \newdimen \outervsize \cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks \outerhsize=7in -\outervsize=9.5in +%\outervsize=9.5in +% Alternative @smallbook page size is 9.25in +\outervsize=9.25in \topandbottommargin=.75in % %---------------------End change----------------------- @@ -85,6 +107,7 @@ {\let\hsize=\pagewidth \makefootline}}}% \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi} +%%%% For @cropmarks command %%%% % Here is a modification of the main output routine for Near East Publications % This provides right-angle cropmarks at all four corners. @@ -93,6 +116,7 @@ % site of the centerlined box. (P. A. MacKay, 12 November, 1986) % \def\croppageout#1{\hoffset=0pt % make sure this doesn't mess things up +{\escapechar=`\\\relax % makes sure backslash is used in output files. \shipout \vbox to \outervsize{\hsize=\outerhsize \vbox{\line{\ewtop\hfill\ewtop}} @@ -114,7 +138,7 @@ \vbox{\moveright\cornerthick\nsbot}} \nointerlineskip \vbox{\line{\ewbot\hfill\ewbot}} - } + }} \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi} % @@ -141,28 +165,84 @@ \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} -% Parse an argument, then pass it to #1. -% The argument can be delimited with [...] or with "..." or braces -% or it can be a whole line. -% #1 should be a macro which expects -% an ordinary undelimited TeX argument. - -\def\parsearg #1{\let\next=#1\begingroup\obeylines\futurelet\temp\parseargx} +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% +\def\parsearg#1{% + \let\next = #1% + \begingroup + \obeylines + \futurelet\temp\parseargx +} +% If the next token is an obeyed space (from an @example environment or +% the like), remove it and recurse. Otherwise, we're done. \def\parseargx{% -\ifx \obeyedspace\temp \aftergroup\parseargdiscardspace \else% -\aftergroup \parseargline % -\fi \endgroup} + \ifx\obeyedspace\temp + \expandafter\parseargdiscardspace + \else + \expandafter\parseargline + \fi +} +% Remove a single space (as the delimiter token to the macro call). {\obeyspaces % -\gdef\parseargdiscardspace {\begingroup\obeylines\futurelet\temp\parseargx}} + \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} -\gdef\obeyedspace{\ } +\def\obeyedspace{\ } -\def\parseargline{\begingroup \obeylines \parsearglinex} {\obeylines % -\gdef\parsearglinex #1^^M{\endgroup \next {#1}}} + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + % + % First remove any @c comment, then any @comment. + % Result of each macro is put in \toks0. + \argremovec #1\c\relax % + \expandafter\argremovecomment \the\toks0 \comment\relax % + % + % Call the caller's macro, saved as \next in \parsearg. + \expandafter\next\expandafter{\the\toks0}% + }% +} +% Since all \c{,omment} does is throw away the argument, we can let TeX +% do that for us. The \relax here is matched by the \relax in the call +% in \parseargline; it could be more or less anything, its purpose is +% just to delimit the argument to the \c. +\def\argremovec#1\c#2\relax{\toks0 = {#1}} +\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} + +% \argremovec{,omment} might leave us with trailing spaces, though; e.g., +% @end itemize @c foo +% will have two active spaces as part of the argument with the +% `itemize'. Here we remove all active spaces from #1, and assign the +% result to \toks0. +% +% This loses if there are any *other* active characters besides spaces +% in the argument -- _ ^ +, for example -- since they get expanded. +% Fortunately, Texinfo does not define any such commands. (If it ever +% does, the catcode of the characters in questionwill have to be changed +% here.) But this means we cannot call \removeactivespaces as part of +% \argremovec{,omment}, since @c uses \parsearg, and thus the argument +% that \parsearg gets might well have any character at all in it. +% +\def\removeactivespaces#1{% + \begingroup + \ignoreactivespaces + \edef\temp{#1}% + \global\toks0 = \expandafter{\temp}% + \endgroup +} + +% Change the active space to expand to nothing. +% +\begingroup + \obeyspaces + \gdef\ignoreactivespaces{\obeyspaces\let =\empty} +\endgroup + + \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} %% These are used to keep @begin/@end levels from running away @@ -173,7 +253,7 @@ \endgroup\fi} % This is not perfect, but it should reduce lossage % @begin foo is the same as @foo, for now. -\newhelp\EMsimple{Type to continue} +\newhelp\EMsimple{Type to continue.} \outer\def\begin{\parsearg\beginxxx} @@ -182,19 +262,40 @@ {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else \csname #1\endcsname\fi} -%% @end foo executes the definition of \Efoo. -%% foo can be delimited by doublequotes or brackets. - +% @end foo executes the definition of \Efoo. +% \def\end{\parsearg\endxxx} - \def\endxxx #1{% -\expandafter\ifx\csname E#1\endcsname\relax -\expandafter\ifx\csname #1\endcsname\relax -\errmessage{Undefined command @end #1}\else -\errorE{#1}\fi\fi -\csname E#1\endcsname} -\def\errorE#1{ -{\errhelp=\EMsimple \errmessage{@end #1 not within #1 environment}}} + \removeactivespaces{#1}% + \edef\endthing{\the\toks0}% + % + \expandafter\ifx\csname E\endthing\endcsname\relax + \expandafter\ifx\csname \endthing\endcsname\relax + % There's no \foo, i.e., no ``environment'' foo. + \errhelp = \EMsimple + \errmessage{Undefined command `@end \endthing'}% + \else + \unmatchedenderror\endthing + \fi + \else + % Everything's ok; the right environment has been started. + \csname E\endthing\endcsname + \fi +} + +% There is an environment #1, but it hasn't been started. Give an error. +% +\def\unmatchedenderror#1{% + \errhelp = \EMsimple + \errmessage{This `@end #1' doesn't have a matching `@#1'}% +} + +% Define the control sequence \E#1 to give an unmatched @end error. +% +\def\defineunmatchedend#1{% + \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% +} + % Single-spacing is done by various environments. @@ -211,10 +312,12 @@ % Kludge this until the fonts are right (grr). \def\@{{\tt \char '100}} -% Define @` and @' to be the same as ` and ' -% but suppressing ligatures. -\def\`{{`}} -\def\'{{'}} +% This is turned off because it was never documented +% and you can use @w{...} around a quote to suppress ligatures. +%% Define @` and @' to be the same as ` and ' +%% but suppressing ligatures. +%\def\`{{`}} +%\def\'{{'}} % Used to generate quoted braces. @@ -232,16 +335,51 @@ % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } -% @w prevents a word break -\def\w #1{\hbox{#1}} - -% @group ... @end group forces ... to be all on one page. - -\def\group{\begingroup% \inENV ??? -\ifnum\catcode13=\active \else -\errmessage{@group invalid in context where filling is enabled}\fi -\def \Egroup{\egroup\endgroup} -\vbox\bgroup} +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +\def\group{\begingroup + \ifnum\catcode13=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + % + % The \vtop we start below produces a box with large depth; thus, TeX + % puts \baselineskip glue before it, and (when the next line of text + % is done) \lineskip glue after it. (See p.82 of the TeXbook.) But + % the next line of text also gets us \parskip glue. Final result: + % space below is slightly more than space above. + \def\Egroup{% + \egroup % End the \vtop. + \endgroup % End the \group. + }% + % + \vtop\bgroup + % We do @comment here in case we are called inside an environment, + % such as @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} % @need space-in-mils % forces a page break if there is not space-in-mils remaining. @@ -250,13 +388,47 @@ \def\need{\parsearg\needx} -\def\needx #1{\par % -% This method tries to make TeX break the page naturally -% if the depth of the box does not fit. -{\baselineskip=0pt% -\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000 -\prevdepth=-1000pt -}} +% Old definition--didn't work. +%\def\needx #1{\par % +%% This method tries to make TeX break the page naturally +%% if the depth of the box does not fit. +%{\baselineskip=0pt% +%\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000 +%\prevdepth=-1000pt +%}} + +\def\needx#1{% + % Go into vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % Don't add any leading before our big empty box, but allow a page + % break, since the best break might be right here. + \allowbreak + \nointerlineskip + \vtop to #1\mil{\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak +} % @br forces paragraph break @@ -273,17 +445,21 @@ % @exdent text.... % outputs text on separate line in roman font, starting at standard page margin -\def\exdent{\errmessage{@exdent in filled text}} - % @lisp, etc, define \exdent locally from \internalexdent +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\def\exdent{\parsearg\exdentyyy} +\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} + +% This defn is used inside nofill environments such as @example. +\def\nofillexdent{\parsearg\nofillexdentyyy} +\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount +\leftline{\hskip\leftskip{\rm#1}}}} -{\obeyspaces -\gdef\internalexdent{\parsearg\exdentzzz}} +%\hbox{{\rm#1}}\hfil\break}} -\def\exdentzzz #1{{\advance \leftskip by -\lispnarrowing -\advance \hsize by -\leftskip -\advance \hsize by -\rightskip -\leftline{{\rm#1}}}} - % @include file insert text of that file as input. \def\include{\parsearg\includezzz} @@ -344,55 +520,203 @@ \let\titlepage=\relax } -\def\ignore{\begingroup\ignoresections -% Make sure that spaces turn into tokens that match what \ignorexxx wants. -\catcode32=10 -\ignorexxx} -\long\def\ignorexxx #1\end ignore{\endgroup\ignorespaces} - -\def\direntry{\begingroup\direntryxxx} -\long\def\direntryxxx #1\end direntry{\endgroup\ignorespaces} - -% Conditionals to test whether a flag is set. - -\def\ifset{\begingroup\ignoresections\parsearg\ifsetxxx} - -\def\ifsetxxx #1{\endgroup -\expandafter\ifx\csname IF#1\endcsname\relax \let\temp=\ifsetfail -\else \let\temp=\relax \fi -\temp} -\def\Eifset{} -\def\ifsetfail{\begingroup\ignoresections\ifsetfailxxx} -\long\def\ifsetfailxxx #1\end ifset{\endgroup\ignorespaces} - -\def\ifclear{\begingroup\ignoresections\parsearg\ifclearxxx} - -\def\ifclearxxx #1{\endgroup -\expandafter\ifx\csname IF#1\endcsname\relax \let\temp=\relax -\else \let\temp=\ifclearfail \fi -\temp} -\def\Eifclear{} -\def\ifclearfail{\begingroup\ignoresections\ifclearfailxxx} -\long\def\ifclearfailxxx #1\end ifclear{\endgroup\ignorespaces} +% Used in nested conditionals, where we have to parse the Texinfo source +% and so want to turn off most commands, in case they are used +% incorrectly. +% +\def\ignoremorecommands{% + \let\defcv = \relax + \let\deffn = \relax + \let\deffnx = \relax + \let\defindex = \relax + \let\defivar = \relax + \let\defmac = \relax + \let\defmethod = \relax + \let\defop = \relax + \let\defopt = \relax + \let\defspec = \relax + \let\deftp = \relax + \let\deftypefn = \relax + \let\deftypefun = \relax + \let\deftypevar = \relax + \let\deftypevr = \relax + \let\defun = \relax + \let\defvar = \relax + \let\defvr = \relax +} + +% Ignore @ignore ... @end ignore. +% +\def\ignore{\doignore{ignore}} + +% Also ignore @ifinfo, @menu, and @direntry text. +% +\def\ifinfo{\doignore{ifinfo}} +\def\menu{\doignore{menu}} +\def\direntry{\doignore{direntry}} + +% Ignore text until a line `@end #1'. +% +\def\doignore#1{\begingroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define a command to swallow text until we reach `@end #1'. + \long\def\doignoretext##1\end #1{\enddoignore}% + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \catcode32 = 10 + % + % And now expand that command. + \doignoretext +} + +% What we do to finish off ignored text. +% +\def\enddoignore{\endgroup\ignorespaces}% + +% Ignore text, except that we keep track of conditional commands for +% purposes of nesting, up to an `@end #1' command. +% +\def\nestedignore#1{% + % We must actually expand the ignored text to look for the @end + % command, so that nested ignore constructs work. Thus, we put the + % text into a \vbox and then do nothing with the result. To minimize + % the change of memory overflow, we follow the approach outlined on + % page 401 of the TeXbook: make the current font be a dummy font. + % + \setbox0 = \vbox\bgroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define `@end #1' to end the box, which will in turn undefine the + % @end command again. + \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% + % + % We are going to be parsing Texinfo commands. Most cause no + % trouble when they are used incorrectly, but some commands do + % complicated argument parsing or otherwise get confused, so we + % undefine them. + % + % We can't do anything about stray @-signs, unfortunately; + % they'll produce `undefined control sequence' errors. + \ignoremorecommands + % + % Set the current font to be \nullfont, a TeX primitive, and define + % all the font commands to also use \nullfont. We don't use + % dummy.tfm, as suggested in the TeXbook, because not all sites + % might have that installed. Therefore, math mode will still + % produce output, but that should be an extremely small amount of + % stuff compared to the main input. + \nullfont + \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont + \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont + \let\tensf = \nullfont + % + % Don't complain when characters are missing from the fonts. + \tracinglostchars = 0 + % + % Don't bother to do space factor calculations. + \frenchspacing + % + % Don't report underfull hboxes. + \hbadness = 10000 + % + % Do minimal line-breaking. + \pretolerance = 10000 +} -% @set foo to set the flag named foo. -% @clear foo to clear the flag named foo. +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. +% \def\set{\parsearg\setxxx} -\def\setxxx #1{ -\expandafter\let\csname IF#1\endcsname=\set} +\def\setxxx#1{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + \def\temp{#2}% + \ifx\temp\empty \expandafter\let\csname SET#1\endcsname = \empty + \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. + \fi +} +\def\setzzz#1#2 \endsetzzz{\expandafter\edef\csname SET#1\endcsname{#2}} +% @clear VAR clears (i.e., unsets) the variable VAR. +% \def\clear{\parsearg\clearxxx} -\def\clearxxx #1{ -\expandafter\let\csname IF#1\endcsname=\relax} +\def\clearxxx#1{\expandafter\let\csname SET#1\endcsname=\relax} + +% @value{foo} gets the text saved in variable foo. +% +\def\value#1{\expandafter + \ifx\csname SET#1\endcsname\relax + {\{No value for ``#1''\}} + \else \csname SET#1\endcsname \fi} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +\def\ifset{\parsearg\ifsetxxx} +\def\ifsetxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifsetfail + \else + \expandafter\ifsetsucceed + \fi +} +\def\ifsetsucceed{\conditionalsucceed{ifset}} +\def\ifsetfail{\nestedignore{ifset}} +\defineunmatchedend{ifset} + +% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +\def\ifclear{\parsearg\ifclearxxx} +\def\ifclearxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifclearsucceed + \else + \expandafter\ifclearfail + \fi +} +\def\ifclearsucceed{\conditionalsucceed{ifclear}} +\def\ifclearfail{\nestedignore{ifclear}} +\defineunmatchedend{ifclear} + +% @iftex always succeeds; we read the text following, through @end +% iftex). But `@end iftex' should be valid only after an @iftex. +% +\def\iftex{\conditionalsucceed{iftex}} +\defineunmatchedend{iftex} -% Some texinfo constructs that are trivial in tex +% We can't just want to start a group at @iftex (for example) and end it +% at @end iftex, since then @set commands inside the conditional have no +% effect (they'd get reverted at the end of the group). So we must +% define \Eiftex to redefine itself to be its previous value. (We can't +% just define it to fail again with an ``unmatched end'' error, since +% the @ifset might be nested.) +% +\def\conditionalsucceed#1{% + \edef\temp{% + % Remember the current value of \E#1. + \let\nece{prevE#1} = \nece{E#1}% + % + % At the `@end #1', redefine \E#1 to be its previous value. + \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% + }% + \temp +} -\def\iftex{} -\def\Eiftex{} -\def\ifinfo{\begingroup\ignoresections\ifinfoxxx} -\long\def\ifinfoxxx #1\end ifinfo{\endgroup\ignorespaces} +% We need to expand lots of \csname's, but we don't want to expand the +% control sequences after we've constructed them. +% +\def\nece#1{\expandafter\noexpand\csname#1\endcsname} -\long\def\menu #1\end menu{} +% @asis just yields its argument. Used with @table, for example. +% \def\asis#1{#1} % @math means output in math mode. @@ -408,6 +732,10 @@ \let\implicitmath = $ \def\math#1{\implicitmath #1\implicitmath} +% @bullet and @minus need the same treatment as @math, just above. +\def\bullet{\implicitmath\ptexbullet\implicitmath} +\def\minus{\implicitmath-\implicitmath} + \def\node{\ENVcheck\parsearg\nodezzz} \def\nodezzz#1{\nodexxx [#1,]} \def\nodexxx[#1,#2]{\gdef\lastnode{#1}} @@ -442,9 +770,8 @@ \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} \def\inforef #1{\inforefzzz #1,,,,**} -\def\inforefzzz #1,#2,#3,#4**{See Info file \file{\losespace#3{}}, - node \samp{\losespace#1{}}} -\def\losespace #1{#1} +\def\inforefzzz #1,#2,#3,#4**{See Info file \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} \message{fonts,} @@ -624,11 +951,21 @@ \def\b#1{{\bf #1}} \let\strong=\b -\def\t#1{{\tt \exhyphenpenalty=10000\rawbackslash \frenchspacing #1}\null} +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +\def\t#1{% + {\tt \nohyphenation \rawbackslash \frenchspacing #1}% + \null +} \let\ttfont = \t %\def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null} \def\samp #1{`\tclose{#1}'\null} -\def\key #1{{\tt \exhyphenpenalty=10000\uppercase{#1}}\null} +\def\key #1{{\tt \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} \let\file=\samp @@ -635,14 +972,26 @@ % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. -\newdimen\tclosesave -\newdimen\tcloserm -\def\tclose#1{{\rm \tcloserm=\fontdimen2\font \tt \tclosesave=\fontdimen2\font -\fontdimen2\font=\tcloserm -% prevent breaking lines at hyphens. -\exhyphenpenalty=10000 -\def\ {{\fontdimen2\font=\tclosesave{} }}% - \rawbackslash \frenchspacing #1\fontdimen2\font=\tclosesave}\null} +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \frenchspacing + #1% + }% + \null +} \let\code=\tclose %\let\exp=\tclose %Was temporary @@ -682,6 +1031,10 @@ \newif\ifseenauthor \newif\iffinishedtitlepage +\def\shorttitlepage{\parsearg\shorttitlepagezzz} +\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + \def\titlepage{\begingroup \parindent=0pt \textfonts \let\subtitlerm=\tenrm % I deinstalled the following change because \cmr12 is undefined. @@ -896,7 +1249,7 @@ %\def\tablinezzz #1{\+#1\cr} %\def\&{&} -% Tables -- @table, @ftable, @item(x), @kitem(x), @xitem(x). +% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). % default indentation of table text \newdimen\tableindent \tableindent=.8in @@ -908,7 +1261,8 @@ % used internally for \itemindent minus \itemmargin \newdimen\itemmax -% Note @table and @ftable define @item, @itemx, etc., with these defs. +% Note @table, @vtable, and @vtable define @item, @itemx, etc., with +% these defs. % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). @@ -928,19 +1282,33 @@ \itemzzz {#1}} \def\itemzzz #1{\begingroup % -\advance \hsize by -\rightskip % -\advance \hsize by -\leftskip % -\setbox0=\hbox{\itemfont{#1}}% -\itemindex{#1}% -\parskip=0in % -\noindent % -\ifdim \wd0>\itemmax % -\vadjust{\penalty 10000}% -\hbox to \hsize{\hskip -\tableindent\box0\hss}\ % -\else % -\hbox to 0pt{\hskip -\tableindent\box0\hss}% -\fi % -\endgroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemfont{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % Be sure we are not still in the middle of a paragraph. + \parskip=0in + \par + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + \setbox0=\hbox{\hskip \leftskip \hskip -\tableindent \unhbox0}\box0 + \nobreak + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. Since that + % text will be indented by \tableindent, we make the item text be in + % a zero-width box. + \noindent + \rlap{\hskip -\tableindent\box0}% + \fi + \endgroup } \def\item{\errmessage{@item while not in a table}} @@ -965,8 +1333,16 @@ \def\Eftable{\endgraf\endgroup\afterenvbreak}% \let\Etable=\relax}} +\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} +{\obeylines\obeyspaces% +\gdef\vtablex #1^^M{% +\tabley\vritemindex#1 \endtabley +\def\Evtable{\endgraf\endgroup\afterenvbreak}% +\let\Etable=\relax}} + \def\dontindex #1{} \def\fnitemindex #1{\doind {fn}{\code{#1}}}% +\def\vritemindex #1{\doind {vr}{\code{#1}}}% {\obeyspaces % \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% @@ -984,6 +1360,7 @@ \itemmax=\tableindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \tableindent % +\exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% @@ -1002,51 +1379,127 @@ \def\itemize{\parsearg\itemizezzz} -\def\itemizezzz #1{\itemizey {#1}{\Eitemize}} +\def\itemizezzz #1{% + \begingroup % ended by the @end itemsize + \itemizey {#1}{\Eitemize} +} \def\itemizey #1#2{% \aboveenvbreak % -\begingroup % -\itemno = 0 % \itemmax=\itemindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \itemindent % -\parindent = 0pt -\parskip = \smallskipamount +\exdentamount=\itemindent +\parindent = 0pt % +\parskip = \smallskipamount % \ifdim \parskip=0pt \parskip=2pt \fi% \def#2{\endgraf\endgroup\afterenvbreak}% \def\itemcontents{#1}% \let\item=\itemizeitem} -\def\bullet{$\ptexbullet$} -\def\minus{$-$} - % Set sfcode to normal for the chars that usually have another value. % These are `.?!:;,' \def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } -% Allow argument of `a', `A' or `1' to specify type of enumeration. +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} -\def\enumeratey #1 #2\endenumeratey{ -\if#1a \alphaenumerate\else\if#1A \capsenumerate\else -\itemizey{\the\itemno.}\Eenumerate\flushcr -\fi\fi} - -\def\alphaenumerate{\itemizey{\ifcase\itemno\or -a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m\or n\or o\or -p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z\else -\errmessage{More than 26 items in @alphaenumerate; get a bigger alphabet.}\fi.}% -\Eenumerate\flushcr} - -\def\capsenumerate{\itemizey{\ifcase\itemno\or -A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M\or N\or O\or -P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z\else -\errmessage{More than 26 items in @capsenumerate; get a bigger alphabet.}\fi.}% -\Eenumerate\flushcr} +\def\enumeratey #1 #2\endenumeratey{% + \begingroup % ended by the @end enumerate + % + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call itemizey, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \itemizey{#1.}\Eenumerate\flushcr +} -% Allow all natural ways of terminating enumerates to work. +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} \def\Ealphaenumerate{\Eenumerate} \def\Ecapsenumerate{\Eenumerate} @@ -1058,7 +1511,7 @@ \ifhmode \errmessage{\in hmode at itemizeitem}\fi {\parskip=0in \hskip 0pt \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% -\vadjust{\penalty 300}}% +\vadjust{\penalty 1200}}% \flushcr} \message{indexing,} @@ -1282,33 +1735,51 @@ \def\printindex{\parsearg\doprintindex} -\def\doprintindex#1{\tex % -\dobreak \chapheadingskip {10000} -\catcode`\%=\other\catcode`\&=\other\catcode`\#=\other -\catcode`\$=\other\catcode`\_=\other -\catcode`\~=\other -% The following don't help, since the chars were translated -% when the raw index was written, and their fonts were discarded -% due to \indexnofonts. -%\catcode`\"=\active -%\catcode`\^=\active -%\catcode`\_=\active -%\catcode`\|=\active -%\catcode`\<=\active -%\catcode`\>=\active -\def\indexbackslash{\rawbackslashxx} -\indexfonts\rm \tolerance=9500 \advance\baselineskip -1pt -\begindoublecolumns -\openin 1 \jobname.#1s -\ifeof 1 -% \enddoublecolumns gets confused if there is no text in the index, -% and it loses the chapter title and the aux file entries for the index. -% The easiest way to prevent this problem is to make sure there is some text. -(Index is empty) -\else \closein 1 \input \jobname.#1s -\fi -\enddoublecolumns -\Etex} +\def\doprintindex#1{% + \tex + \dobreak \chapheadingskip {10000} + \catcode`\%=\other\catcode`\&=\other\catcode`\#=\other + \catcode`\$=\other\catcode`\_=\other + \catcode`\~=\other + % + % The following don't help, since the chars were translated + % when the raw index was written, and their fonts were discarded + % due to \indexnofonts. + %\catcode`\"=\active + %\catcode`\^=\active + %\catcode`\_=\active + %\catcode`\|=\active + %\catcode`\<=\active + %\catcode`\>=\active + % % + \def\indexbackslash{\rawbackslashxx} + \indexfonts\rm \tolerance=9500 \advance\baselineskip -1pt + \begindoublecolumns + % + % See if the index file exists and is nonempty. + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + (Index is nonexistent) + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + (Index is empty) + \else + \input \jobname.#1s + \fi + \fi + \closein 1 + \enddoublecolumns + \Etex +} % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. @@ -1317,17 +1788,64 @@ % \balancecolumns gets confused if there is any shrink. \newskip\initialskipamount \initialskipamount 12pt plus4pt -\outer\def\initial #1{% +\def\initial #1{% {\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt \ifdim\lastskip<\initialskipamount \removelastskip \penalty-200 \vskip \initialskipamount\fi \line{\secbf#1\hfill}\kern 2pt\penalty10000}} -\outer\def\entry #1#2{ -{\parfillskip=0in \parskip=0in \parindent=0in -\hangindent=1in \hangafter=1% -\noindent\hbox{#1}\indexdotfill #2\par -}} +% This typesets a paragraph consisting of #1, dot leaders, and then #2 +% flush to the right margin. It is used for index and table of contents +% entries. The paragraph is indented by \leftskip. +% +\def\entry #1#2{\begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent=2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % Start a ``paragraph'' for the index entry so the line breaking + % parameters we've set above will have an effect. + \noindent + % + % Insert the text of the index entry. TeX will do line-breaking on it. + #1% + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ #2% The page number ends the paragraph. + \par +\endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders @@ -1344,59 +1862,89 @@ }} %% Define two-column mode, which is used in indexes. -%% Adapted from the TeXBook, page 416 +%% Adapted from the TeXbook, page 416. \catcode `\@=11 \newbox\partialpage -\newdimen\doublecolumnhsize \doublecolumnhsize = 3.11in -\newdimen\doublecolumnvsize \doublecolumnvsize = 19.1in -\newdimen\availdimen@ +\newdimen\doublecolumnhsize \def\begindoublecolumns{\begingroup - \output={\global\setbox\partialpage= - \vbox{\unvbox255\kern -\topskip \kern \baselineskip}}\eject + % Grab any single-column material above us. + \output = {\global\setbox\partialpage + =\vbox{\unvbox255\kern -\topskip \kern \baselineskip}}% + \eject + % + % Now switch to the double-column output routine. \output={\doublecolumnout}% - \hsize=\doublecolumnhsize \vsize=\doublecolumnvsize} -\def\enddoublecolumns{\output={\balancecolumns}\eject - \endgroup \pagegoal=\vsize} - -\def\doublecolumnout{\splittopskip=\topskip \splitmaxdepth=\maxdepth - \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage - \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ - \onepageout\pagesofar \unvbox255 \penalty\outputpenalty} + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it once. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +- < + % 1pt) as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \vsize = 2\vsize + \doublecolumnpagegoal +} + +\def\enddoublecolumns{\eject \endgroup \pagegoal=\vsize \unvbox\partialpage} + +\def\doublecolumnsplit{\splittopskip=\topskip \splitmaxdepth=\maxdepth + \global\dimen@=\pageheight \global\advance\dimen@ by-\ht\partialpage + \global\setbox1=\vsplit255 to\dimen@ \global\setbox0=\vbox{\unvbox1} + \global\setbox3=\vsplit255 to\dimen@ \global\setbox2=\vbox{\unvbox3} + \ifdim\ht0>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi + \ifdim\ht2>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi +} +\def\doublecolumnpagegoal{% + \dimen@=\vsize \advance\dimen@ by-2\ht\partialpage \global\pagegoal=\dimen@ +} \def\pagesofar{\unvbox\partialpage % \hsize=\doublecolumnhsize % have to restore this since output routine -% changes it to set cropmarks (P. A. MacKay, 12 Nov. 1986) \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}} -\def\balancecolumns{% -% Unset the glue. - \setbox255=\vbox{\unvbox255} - \dimen@=\ht255 - \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip - \divide\dimen@ by2 - \availdimen@=\pageheight \advance\availdimen@ by-\ht\partialpage -% If the remaining data is too big for one page, -% output one page normally, then work with what remains. - \ifdim \dimen@>\availdimen@ - { - \splittopskip=\topskip \splitmaxdepth=\maxdepth - \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage - \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ - \onepageout\pagesofar - } -% Recompute size of what remains, in case we just output some of it. - \dimen@=\ht255 - \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip - \divide\dimen@ by2 +\def\doublecolumnout{% + \setbox5=\copy255 + {\vbadness=10000 \doublecolumnsplit} + \ifvbox255 + \setbox0=\vtop to\dimen@{\unvbox0} + \setbox2=\vtop to\dimen@{\unvbox2} + \onepageout\pagesofar \unvbox255 \penalty\outputpenalty + \else + \setbox0=\vbox{\unvbox5} + \ifvbox0 + \dimen@=\ht0 \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip + \divide\dimen@ by2 \splittopskip=\topskip \splitmaxdepth=\maxdepth + {\vbadness=10000 + \loop \global\setbox5=\copy0 + \setbox1=\vsplit5 to\dimen@ + \setbox3=\vsplit5 to\dimen@ + \ifvbox5 \global\advance\dimen@ by1pt \repeat + \setbox0=\vbox to\dimen@{\unvbox1} + \setbox2=\vbox to\dimen@{\unvbox3} + \global\setbox\partialpage=\vbox{\pagesofar} + \doublecolumnpagegoal + } + \fi \fi - \setbox0=\vbox{\unvbox255} - \splittopskip=\topskip - {\vbadness=10000 \loop \global\setbox3=\copy0 - \global\setbox1=\vsplit3 to\dimen@ - \ifdim\ht3>\dimen@ \global\advance\dimen@ by1pt \repeat} - \setbox0=\vbox to\dimen@{\unvbox1} \setbox2=\vbox to\dimen@{\unvbox3} - \pagesofar} +} \catcode `\@=\other \message{sectioning,} @@ -1427,6 +1975,10 @@ \def\chapternofonts{% \let\rawbackslash=\relax% \let\frenchspacing=\relax% +\def\result{\realbackslash result} +\def\equiv{\realbackslash equiv} +\def\expansion{\realbackslash expansion} +\def\print{\realbackslash print} \def\TeX{\realbackslash TeX} \def\dots{\realbackslash dots} \def\copyright{\realbackslash copyright} @@ -1453,6 +2005,7 @@ \def\dfn##1{\realbackslash dfn {##1}} } +\def\thischaptername{No Chapter Title} \outer\def\chapter{\parsearg\chapterzzz} \def\chapterzzz #1{\seccheck{chapter}% \secno=0 \subsecno=0 \subsubsecno=0 @@ -1495,7 +2048,20 @@ \outer\def\top{\parsearg\unnumberedzzz} \outer\def\unnumbered{\parsearg\unnumberedzzz} \def\unnumberedzzz #1{\seccheck{unnumbered}% -\secno=0 \subsecno=0 \subsubsecno=0 \message{(#1)} +\secno=0 \subsecno=0 \subsubsecno=0 +% +% This used to be simply \message{#1}, but TeX fully expands the +% argument to \message. Therefore, if #1 contained @-commands, TeX +% expanded them. For example, in `@unnumbered The @cite{Book}', TeX +% expanded @cite (which turns out to cause errors because \cite is meant +% to be executed, not expanded). +% +% Anyway, we don't want the fully-expanded definition of @cite to appear +% as a result of the \message, we just want `@cite' itself. We use +% \the to achieve this: TeX expands \the only once, +% simply yielding the contents of the . +\toks0 = {#1}\message{(\the\toks0)}% +% \unnumbchapmacro {#1}% \gdef\thischapter{#1}\gdef\thissection{#1}% {\chapternofonts% @@ -1763,6 +2329,8 @@ \newskip \secheadingskip \secheadingskip = 21pt plus 8pt minus 4pt \def\secheadingbreak{\dobreak \secheadingskip {-1000}} +% @paragraphindent is defined for the Info formatting commands only. +\let\paragraphindent=\comment % Section fonts are the base font at magstep2, which produces % a size a bit more than 14 points in the default situation. @@ -1807,9 +2375,9 @@ \newskip\contentsrightmargin \contentsrightmargin=1in \def\startcontents#1{% + \pagealignmacro + \immediate\closeout \contentsfile \ifnum \pageno>0 - \pagealignmacro - \immediate\closeout \contentsfile \pageno = -1 % Request roman numbered pages. \fi % Don't need to put `Contents' or `Short Contents' in the headline. @@ -1863,18 +2431,34 @@ % See comments in \dochapentry re vbox and related settings \def\shortchapentry#1#2#3{% - \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\strut\raggedright - {#2\labelspace #1}\dotfill\doshortpageno{#3}}% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}% } -\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} -\def\shortunnumberedentry#1#2{% - \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\strut\raggedright - #1\dotfill\doshortpageno{#2}}% +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. +% We could simplify the code here by writing out an \appendixentry +% command in the toc file for appendices, instead of using \chapentry +% for both, but it doesn't seem worth it. +\setbox0 = \hbox{\shortcontrm Appendix } +\newdimen\shortappendixwidth \shortappendixwidth = \wd0 + +\def\shortchaplabel#1{% + % We typeset #1 in a box of constant width, regardless of the text of + % #1, so the chapter titles will come out aligned. + \setbox0 = \hbox{#1}% + \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi + % + % This space should be plenty, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in in \shortchapentry above.) + \advance\dimen0 by 1.1em + \hbox to \dimen0{#1\hfil}% } +\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} +\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}} + % Sections. \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} \def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} @@ -1899,39 +2483,37 @@ % if at all possible; hence the \penalty. \def\dochapentry#1#2{% \penalty-300 \vskip\baselineskip - % This \vbox (and similar ones in dosecentry etc.) used to be a - % \line; changed to permit linebreaks for long headings. See - % comments above \majorheading. Here we also use \strut to - % keep the top end of the vbox from jamming up against the previous - % entry in the table of contents. - \vbox{\chapentryfonts - \hyphenpenalty=10000\tolerance=5000 % this line and next introduced - \parindent=0pt\strut\raggedright % with \line -> \vbox change - #1\dotfill - \dopageno{#2}}% + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno{#2}}% + \endgroup \nobreak\vskip .25\baselineskip } -\def\dosecentry#1#2{% - \vbox{\secentryfonts \leftskip=\tocindent - \hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\strut\raggedright #1\dotfill - \dopageno{#2}}% -} - -\def\dosubsecentry#1#2{% - \vbox{\subsecentryfonts \leftskip=2\tocindent - \hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\strut\raggedright #1\dotfill - \dopageno{#2}}% -} - -\def\dosubsubsecentry#1#2{% - \vbox{\subsubsecentryfonts \leftskip=3\tocindent - \hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\strut\raggedright #1\dotfill - \dopageno{#2}}% -} +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno{#2}}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno{#2}}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno{#2}}% +\endgroup} + +% Final typesetting of a toc entry; we use the same \entry macro as for +% the index entries, but we want to suppress hyphenation here. (We +% can't do that in the \entry macro, since index entries might consist +% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) +% +\def\tocentry#1#2{\begingroup + \hyphenpenalty = 10000 + \entry{#1}{#2}% +\endgroup} % Space between chapter (or whatever) number and the title. \def\labelspace{\hskip1em \relax} @@ -1956,26 +2538,23 @@ \let\ptexequiv = \equiv -{\tentt -\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} -\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} -\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} -\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} +%{\tentt +%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} +%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} +%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} +%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} % Adapted from the manmac format (p.420 of TeXbook) -\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex - depth .1ex\hfil} -} +%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex +% depth .1ex\hfil} +%} \def\point{$\star$} -\def\result{\leavevmode\raise.15ex\copy\dblarrowbox} -\def\expansion{\leavevmode\raise.1ex\copy\longdblarrowbox} -\def\print{\leavevmode\lower.1ex\copy\pushcharbox} - -\def\equiv{\leavevmode\lower.1ex\copy\equivbox} +\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} -% Does anyone really want this? -% \def\bull{\leavevmode\copy\bullbox} +\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} % Adapted from the TeXbook's \boxit. {\tentt \global\dimen0 = 3em}% Width of the box. @@ -2044,14 +2623,19 @@ {\obeyspaces % \gdef\sepspaces{\def {\ }}} -\newskip\aboveenvskipamount \aboveenvskipamount= 0pt -\def\aboveenvbreak{{\advance\aboveenvskipamount by \parskip -\endgraf \ifdim\lastskip<\aboveenvskipamount -\removelastskip \penalty-50 \vskip\aboveenvskipamount \fi}} +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt -\def\afterenvbreak{\endgraf \ifdim\lastskip<\aboveenvskipamount -\removelastskip \penalty-50 \vskip\aboveenvskipamount \fi} +% Make spacing and below environment symmetrical. +\def\aboveenvbreak{{\advance\envskipamount by \parskip +\endgraf \ifdim\lastskip<\envskipamount +\removelastskip \penalty-50 \vskip\envskipamount \fi}} +\let\afterenvbreak = \aboveenvbreak + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. +\let\nonarrowing=\relax + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \cartouche: draw rectangle w/rounded corners around argument \font\circle=lcircle10 @@ -2084,6 +2668,8 @@ % side, and for 6pt waste from % each corner char \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing=\comment \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop @@ -2122,18 +2708,27 @@ \let\par=\lisppar \def\Elisp{\endgroup\afterenvbreak}% \parskip=0pt +% @cartouche defines \nonarrowing to inhibit narrowing +% at next level down. +\ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing +\exdentamount=\lispnarrowing +\let\exdent=\nofillexdent +\let\nonarrowing=\relax +\fi \parindent=0pt -\let\exdent=\internalexdent \obeyspaces \obeylines \tt \rawbackslash -\def\next##1{}\next} - - -\let\example=\lisp -\def\Eexample{\Elisp} +\gobble +} -\let\smallexample=\lisp -\def\Esmallexample{\Elisp} +% Define the \E... control sequence only if we are inside the +% environment, so the error checking in \end will work. +% +% We must call \lisp last in the definition, since it reads the +% return following the @example (or whatever) command. +% +\def\example{\begingroup \def\Eexample{\Elisp\endgroup}\lisp} +\def\smallexample{\begingroup \def\Esmallexample{\Elisp\endgroup}\lisp} % Macro for 9 pt. examples, necessary to print with 5" lines. % From Pavel@xerox. This is not really used unless the @@ -2150,10 +2745,18 @@ % by adding a space to the end of each line. \let\par=\lisppar \def\Esmalllisp{\endgroup\afterenvbreak}% +%%%% Smaller baseline skip for small examples. +\baselineskip 10pt \parskip=0pt +% @cartouche defines \nonarrowing to inhibit narrowing +% at next level down. +\ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing +\exdentamount=\lispnarrowing +\let\exdent=\nofillexdent +\let\nonarrowing=\relax +\fi \parindent=0pt -\let\exdent=\internalexdent \obeyspaces \obeylines \ninett \indexfonts \rawbackslash \def\next##1{}\next} @@ -2170,9 +2773,15 @@ \let\par=\lisppar \def\Edisplay{\endgroup\afterenvbreak}% \parskip=0pt +% @cartouche defines \nonarrowing to inhibit narrowing +% at next level down. +\ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing +\exdentamount=\lispnarrowing +\let\exdent=\nofillexdent +\let\nonarrowing=\relax +\fi \parindent=0pt -\let\exdent=\internalexdent \obeyspaces \obeylines \def\next##1{}\next} @@ -2233,8 +2842,14 @@ \singlespace \parindent=0pt \def\Equotation{\par\endgroup\afterenvbreak}% -\advance \rightskip by \lispnarrowing -\advance \leftskip by \lispnarrowing} +% @cartouche defines \nonarrowing to inhibit narrowing +% at next level down. +\ifx\nonarrowing\relax +\advance \leftskip by \lispnarrowing +\advance \rightskip by \lispnarrowing +\exdentamount=\lispnarrowing +\let\nonarrowing=\relax +\fi} \message{defuns,} % Define formatter for defuns @@ -2252,7 +2867,18 @@ \def\activeparens{% \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active \catcode`\[=\active \catcode`\]=\active} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +\global\let(=\lparen \global\let)=\rparen +\global\let[=\lbrack \global\let]=\rbrack + \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} @@ -2304,6 +2930,7 @@ % Make all lines underfull and no complaints: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent +\exdentamount=\defbodyindent {\df #1}\enskip % Generate function name } @@ -2321,6 +2948,7 @@ \def#2{\begingroup\obeylines\activeparens\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent \begingroup % \catcode 61=\active % \obeylines\activeparens\spacesplit#3} @@ -2333,6 +2961,7 @@ \def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#4}}} \def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % @@ -2344,6 +2973,7 @@ \begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#5}}} % These parsing functions are similar to the preceding ones @@ -2358,6 +2988,7 @@ \def#2{\begingroup\obeylines\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent \begingroup % \catcode 61=\active % \obeylines\spacesplit#3} @@ -2370,8 +3001,48 @@ \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent \begingroup\obeylines\spacesplit{#3{#4}}} +% This seems to work right in all cases. +\let\deftpparsebody=\defvrparsebody +% This fails to work. When given `@deftp {Data Type} foo_t', +% it thinks the type name is just `f'. +%%% This is the same as all the others except for the last line. We need +%%% to parse the arguments differently for @deftp, since the ``attributes'' +%%% there are optional. +%%% +%%\def\deftpparsebody #1#2#3#4 {\begingroup\inENV % +%%\medbreak % +%%% Define the end token that this defining construct specifies +%%% so that it will exit this group. +%%\def#1{\endgraf\endgroup\medbreak}% +%%\def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% +%%\parindent=0in +%%\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +%%\exdentamount=\defbodyindent +%%\begingroup\obeylines\parsetpheaderline{#3{#4}}} + +%%{\obeylines % +%% % Parse the type name and any attributes (field names, etc.). +%% % #1 is the beginning of the macro call that will produce the output, +%% % i.e., \deftpheader{CLASS}; this is passed from \deftpparsebody. +%% % #2 is the type name, e.g., `struct termios'. +%% % #3 is the (possibly empty) attribute list. +%% % +%% \gdef\parsetpheaderline#1#2#3^^M{% +%% \endgroup % Started in \deftpparsebody. +%% % +%% % If the attribute list is in fact empty, there will be no space after +%% % #2; so we can't put a space in our TeX parameter list. But if it +%% % isn't empty, then #3 will begin with an unwanted space. +%% \def\theargs{\ignorespaces #3}% +%% % +%% % Call the macro to produce the output. +%% #1{#2}\theargs % +%% }% +%%} + \def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies @@ -2381,6 +3052,7 @@ \begingroup\obeylines\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent \begingroup\obeylines\spacesplit{#3{#5}}} % Split up #2 at the first space token. @@ -2628,7 +3300,7 @@ % @deftp Class window height width ... -\def\deftp{\defvrparsebody\Edeftp\deftpx\deftpheader} +\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} @@ -2804,7 +3476,7 @@ \catcode `\=\other \catcode `\=\other \catcode `\=\other -\catcode `\=\other +\catcode 26=\other \catcode `\^^[=\other \catcode `\^^\=\other \catcode `\^^]=\other @@ -2823,6 +3495,8 @@ \catcode `\$=\other \catcode `\#=\other \catcode `\&=\other +% `\+ does not work, so use 43. +\catcode 43=\other % the aux file uses ' as the escape. % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. @@ -2845,6 +3519,10 @@ \newcount \footnoteno +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. \def\supereject{\par\penalty -20000\footnoteno =0 } % @footnotestyle is meaningful for info output only.. @@ -2870,6 +3548,60 @@ }%end \catcode `\@=11 +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.1} +\def\strutheightpercent{.71} +\def\strutdepthpercent{.29} +% +\def\setleading#1{% + \baselineskip = #1\relax + \normalbaselineskip = \baselineskip + \lineskip = \lineskipfactor\baselineskip + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt} + + % End of control word definitions. \message{and turning on texinfo input format.} @@ -2889,12 +3621,16 @@ \newdimen\defaultparindent \defaultparindent = 15pt \parindent = \defaultparindent \parskip 18pt plus 1pt -\baselineskip 15pt +\setleading{15pt} \advance\topskip by 1.2cm % Prevent underfull vbox error messages. \vbadness=10000 +% Following George Bush, just get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + % Use TeX 3.0's \emergencystretch to help line breaking, but if we're % using an old version of TeX, don't do anything. We want the amount of % stretch added to depend on the line length, hence the dependence on @@ -2905,13 +3641,19 @@ \divide\emergencystretch by 45 \fi -% Use @smallbook to reset parameters for 7x9.5 format +% Use @smallbook to reset parameters for 7x9.5 format (or else 7x9.25) \def\smallbook{ + +% These values for secheadingskip and subsecheadingskip are +% experiments. RJC 7 Aug 1992 +\global\secheadingskip = 17pt plus 6pt minus 3pt +\global\subsecheadingskip = 14pt plus 6pt minus 3pt + \global\lispnarrowing = 0.3in -\global\baselineskip 12pt +\setleading{12pt} +\advance\topskip by -1cm \global\parskip 3pt plus 1pt \global\hsize = 5in -\global\doublecolumnhsize=2.4in \global\doublecolumnvsize=15.0in \global\vsize=7.5in \global\tolerance=700 \global\hfuzz=1pt @@ -2929,32 +3671,21 @@ \def\afourpaper{ \global\tolerance=700 \global\hfuzz=1pt -\global\baselineskip=12pt +\setleading{12pt} \global\parskip 15pt plus 1pt \global\vsize= 53\baselineskip \advance\vsize by \topskip %\global\hsize= 5.85in % A4 wide 10pt -\global\hsize= 6.5 +\global\hsize= 6.5in \global\outerhsize=\hsize \global\advance\outerhsize by 0.5in \global\outervsize=\vsize \global\advance\outervsize by 0.6in -\global\doublecolumnhsize=\hsize -\global\divide\doublecolumnhsize by 2 -\global\advance\doublecolumnhsize by -0.1in -\global\doublecolumnvsize=\vsize -\global\multiply\doublecolumnvsize by 2 -\global\advance\doublecolumnvsize by 0.1in \global\pagewidth=\hsize \global\pageheight=\vsize } - -%% For a final copy, take out the rectangles -%% that mark overfull boxes (in case you have decided -%% that the text looks ok even though it passes the margin). -\def\finalout{\overfullrule=0pt} % Define macros to output various characters with catcode for normal text. \catcode`\"=\other diff -ruN make-3.62/variable.c make-3.63/variable.c --- make-3.62/variable.c Mon Oct 7 18:06:26 1991 +++ make-3.63/variable.c Wed Jan 13 16:09:20 1993 @@ -1,5 +1,5 @@ /* Internals of variables for GNU Make. -Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. +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 @@ -22,14 +22,6 @@ #include "dep.h" #include "file.h" -#ifdef __GNUC__ -#define max(a, b) \ - ({ register int __a = (a), __b = (b); __a > __b ? __a : __b; }) -#else -#define max(a, b) ((a) > (b) ? (a) : (b)) -#endif - - /* Hash table of all global variable definitions. */ #ifndef VARIABLE_BUCKETS @@ -47,15 +39,6 @@ static struct variable_set_list global_setlist = { 0, &global_variable_set }; struct variable_set_list *current_variable_set_list = &global_setlist; - -/* 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; /* Implement variables. */ @@ -105,6 +88,8 @@ 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; @@ -120,6 +105,7 @@ v->origin = origin; v->recursive = recursive; v->expanding = 0; + v->export = v_default; v->next = set->table[hashval]; set->table[hashval] = v; return v; @@ -369,59 +355,23 @@ /* 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; - /* Don't let SHELL come from the environment - if MAKELEVEL is 0. Also, SHELL must not be empty. */ - if (*v->value == '\0' || (v->origin == o_env && makelevel == 0)) + /* 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 ("/bin/sh", 7); - } -} - -/* 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 = max (2 * variable_buffer_length, newlen + 100); - 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. */ - -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); + v->value = savestring (default_shell, 7); } - return variable_buffer; + /* Make sure MAKEFILES gets exported if it is set. */ + v = define_variable ("MAKEFILES", 9, "", o_default, 0); + v->export = v_ifset; } +int export_all_variables; + /* Create a new environment for FILE's commands. The child's MAKELEVEL variable is incremented. */ @@ -440,9 +390,8 @@ register unsigned int i; register unsigned nvariables; char **result; + unsigned int mklev_hash; - int noexport = enter_file (".NOEXPORT")->is_target; - /* Find the lowest number of buckets in any set in the list. */ s = file->variables; buckets = s->set->buckets; @@ -450,6 +399,14 @@ if (s->set->buckets < buckets) buckets = s->set->buckets; + /* Find the hash value of `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 *)); @@ -471,28 +428,42 @@ register struct variable_bucket *ov; register char *p = v->name; - /* If `.NOEXPORT' was specified, only export command-line and - environment variables. This is a temporary (very ugly) hack - until I fix this problem the right way in version 4. Ick. */ - if (noexport - && (v->origin != o_command - && v->origin != o_env && v->origin != o_env_override - && !(v->origin == o_file && getenv (p) != 0))) + if (i == mklev_hash % set->buckets + && streq (v->name, "MAKELEVEL")) + /* Don't include MAKELEVEL because it will be + added specially at the end. */ continue; - if (v->origin == o_default - || streq (p, "MAKELEVEL")) - continue; + switch (v->export) + { + case v_default: + if (!export_all_variables + && v->origin != o_command + && v->origin != o_env && v->origin != o_env_override + && !(v->origin == o_file && getenv (p) != 0)) + 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')) + 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; - if (*p != '\0') - continue; + + 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)) @@ -519,7 +490,11 @@ for (b = table[i]; b != 0; b = b->next) { register struct variable *v = b->variable; - result[nvariables++] = concat (v->name, "=", v->value); + /* If V is recursively expanded, expand its value. */ + char *value = v->recursive ? recursively_expand (v) : v->value; + result[nvariables++] = concat (v->name, "=", value); + if (v->recursive) + free (value); } } result[nvariables] = (char *) xmalloc (100); @@ -529,9 +504,7 @@ return result; } -/* Try to interpret LINE (a null-terminated string) - as a variable definition. If it is one, define the - variable and return 1. Otherwise return 0. +/* 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 @@ -542,9 +515,12 @@ 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. */ + definition and then is evaluated only once at the time of expansion. -int + If a variable was defined, a pointer to its `struct variable' is returned. + If not, NULL is returned. */ + +struct variable * try_variable_definition (line, origin) char *line; enum variable_origin origin; @@ -554,9 +530,9 @@ register char *beg; register char *end; register int recursive; + char *name, *expanded_name; + struct variable *v; - if (*p == '\t') - return 0; while (1) { c = *p++; @@ -586,10 +562,18 @@ --end; p = next_token (p); - (void) define_variable (beg, end - beg, recursive ? p : variable_expand (p), - origin, recursive); + /* Expand the name, so "$(foo)bar = baz" works. */ + name = savestring (beg, end - beg); + expanded_name = allocated_variable_expand (name); + free (name); + + v = define_variable (expanded_name, strlen (expanded_name), + recursive ? p : variable_expand (p), + origin, recursive); - return 1; + free (expanded_name); + + return v; } /* Print information for variable V, prefixing it with PREFIX. */ @@ -724,45 +708,4 @@ { if (file->variables != 0) print_variable_set (file->variables->set, "# "); -} - -struct output_state - { - char *buffer; - unsigned int length; - }; - -/* Save the current variable output state and return a pointer - to storage describing it. Then reset the output state. */ - -char * -save_variable_output () -{ - struct output_state *state; - - state = (struct output_state *) xmalloc (sizeof (struct output_state)); - state->buffer = variable_buffer; - state->length = variable_buffer_length; - - variable_buffer = 0; - variable_buffer_length = 0; - - return (char *) state; -} - -/* Restore the variable output state saved in SAVE. */ - -void -restore_variable_output (save) - char *save; -{ - register struct output_state *state = (struct output_state *) save; - - if (variable_buffer != 0) - free (variable_buffer); - - variable_buffer = state->buffer; - variable_buffer_length = state->length; - - free ((char *) state); } diff -ruN make-3.62/variable.h make-3.63/variable.h --- make-3.62/variable.h Mon Jun 3 16:37:27 1991 +++ make-3.63/variable.h Tue Dec 22 18:44:09 1992 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. +/* 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 @@ -42,6 +42,13 @@ 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. */ @@ -63,18 +70,15 @@ extern struct variable_set_list *current_variable_set_list; -extern char *variable_buffer_output (); -extern char *initialize_variable_output (); -extern char *save_variable_output (); -extern void restore_variable_output (); - extern void push_new_variable_scope (), pop_variable_scope (); extern int handle_function (); -extern char *variable_expand (), *allocated_variable_expand (); -extern char *variable_expand_for_file (); +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 (); @@ -83,12 +87,13 @@ extern void merge_variable_set_lists (); -extern int try_variable_definition (); +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 (); +extern char *subst_expand (), *patsubst_expand (), *recursively_expand (); extern char **target_environment (); +extern int export_all_variables; diff -ruN make-3.62/version.c make-3.63/version.c --- make-3.62/version.c Mon Oct 28 20:23:21 1991 +++ make-3.63/version.c Fri Jan 22 19:08:41 1993 @@ -1,4 +1,4 @@ -char *version_string = "3.62"; +char *version_string = "3.63"; /* Local variables: diff -ruN make-3.62/vpath.c make-3.63/vpath.c --- make-3.62/vpath.c Mon Jun 3 16:37:37 1991 +++ make-3.63/vpath.c Mon Jan 11 17:46:31 1993 @@ -1,4 +1,4 @@ -/* Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. +/* 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 @@ -124,62 +124,65 @@ /* Remove matching listings. */ register struct vpath *path, *lastpath; - lastpath = vpaths; - for (path = vpaths; path != 0; lastpath = path, path = 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 == vpaths) - vpaths = path->next; - else - lastpath->next = path->next; - - /* Free its unused storage. */ - free (path->pattern); - free ((char *) path->searchpath); - free ((char *) path); - } + 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); + } + + lastpath = next; + path = next; + } + if (pattern != 0) free (pattern); return; } - /* Skip over any initial colons. */ - p = dirpath; - while (*p == ':') - ++p; - /* 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 we find. */ + increment our estimated number for each colon or blank we find. */ maxelem = 2; + p = dirpath; while (*p != '\0') - if (*p++ == ':') + if (*p++ == ':' || isblank (*p)) ++maxelem; vpath = (char **) xmalloc (maxelem * sizeof (char *)); maxvpath = 0; - elem = 0; + /* Skip over any initial colons and blanks. */ p = dirpath; + while (*p == ':' || isblank (*p)) + ++p; + + elem = 0; while (*p != '\0') { char *v; unsigned int len; - /* Find the next entry. */ - while (*p != '\0' && *p == ':') - ++p; - if (*p == '\0') - break; - /* Find the end of this entry. */ v = p; - while (*p != '\0' && *p != ':') + while (*p != '\0' && *p != ':' && !isblank (*p)) ++p; len = p - v; @@ -192,8 +195,12 @@ continue; 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) @@ -200,7 +207,12 @@ maxvpath = len; } else + /* The directory does not exist. Omit from the list. */ free (v); + + /* Skip over colons and blanks between entries. */ + while (*p == ':' || isblank (*p)) + ++p; } if (elem > 0) @@ -344,11 +356,6 @@ /* Clobber a null into the name at the last slash. Now NAME is the name of the directory to look in. */ *n = '\0'; - - /* Make sure the directory exists and we know its contents. */ - if (name_dplen > 0 && !dir_file_exists_p (name, "")) - /* It doesn't exist. */ - continue; /* We know the directory is in the hash table now because either construct_vpath_list or the code just above put it there.