Changeset 503 for trunk/src/gmake/main.c
- Timestamp:
- Sep 15, 2006, 7:09:38 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gmake/main.c
r386 r503 1 1 /* Argument parsing and main program of GNU Make. 2 Copyright (C) 1988, 1989, 1990, 1991, 1994, 1995, 1996, 1997, 1998, 1999, 3 2002, 2003, 2005 Free Software Foundation, Inc. 2 Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software 4 Foundation, Inc. 4 5 This file is part of GNU Make. 5 6 6 GNU Make is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Make is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Make; see the file COPYING. If not, write to 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 19 MA 02111-1307, USA. */ 7 GNU Make is free software; you can redistribute it and/or modify it under the 8 terms of the GNU General Public License as published by the Free Software 9 Foundation; either version 2, or (at your option) any later version. 10 11 GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 13 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License along with 16 GNU Make; see the file COPYING. If not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ 20 18 21 19 #include "make.h" … … 84 82 #endif 85 83 84 static void clean_jobserver PARAMS ((int status)); 86 85 static void print_data_base PARAMS ((void)); 87 86 static void print_version PARAMS ((void)); … … 273 272 they appear out of date or not. */ 274 273 274 static int always_make_set = 0; 275 275 int always_make_flag = 0; 276 276 … … 365 365 { 366 366 { 'b', ignore, 0, 0, 0, 0, 0, 0, 0 }, 367 { 'B', flag, (char *) &always_make_ flag, 1, 1, 0, 0, 0, "always-make" },367 { 'B', flag, (char *) &always_make_set, 1, 1, 0, 0, 0, "always-make" }, 368 368 { 'C', string, (char *) &directories, 0, 0, 0, 0, 0, "directory" }, 369 369 { 'd', flag, (char *) &debug_flag, 1, 1, 0, 0, 0, 0 }, … … 419 419 { CHAR_MAX+4, flag, (char *) &warn_undefined_variables_flag, 1, 1, 0, 0, 0, 420 420 "warn-undefined-variables" }, 421 { 0 }421 { 0, 0, 0, 0, 0, 0, 0, 0, 0 } 422 422 }; 423 423 … … 488 488 489 489 int posix_pedantic; 490 491 /* Nonzero if we have seen the '.SECONDEXPANSION' target. 492 This turns on secondary expansion of prerequisites. */ 493 494 int second_expansion; 490 495 491 496 /* Negative if we have seen the `.NOTPARALLEL' target with empty dependency list. … … 538 543 { 539 544 init_hash_global_variable_set (); 545 strcache_init (); 540 546 init_hash_files (); 541 547 hash_init_directories (); … … 671 677 { 672 678 sprintf(errmsg, 673 _("%s: Interrupt/Exception caught (code = 0x% x, addr = 0x%x)\n"),674 prg, exrec->ExceptionCode, exrec->ExceptionAddress);679 _("%s: Interrupt/Exception caught (code = 0x%lx, addr = 0x%lx)\n"), 680 prg, exrec->ExceptionCode, (DWORD)exrec->ExceptionAddress); 675 681 fprintf(stderr, errmsg); 676 682 exit(255); … … 678 684 679 685 sprintf(errmsg, 680 _("\nUnhandled exception filter called from program %s\nExceptionCode = % x\nExceptionFlags = %x\nExceptionAddress = %x\n"),686 _("\nUnhandled exception filter called from program %s\nExceptionCode = %lx\nExceptionFlags = %lx\nExceptionAddress = %lx\n"), 681 687 prg, exrec->ExceptionCode, exrec->ExceptionFlags, 682 exrec->ExceptionAddress);688 (DWORD)exrec->ExceptionAddress); 683 689 684 690 if (exrec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION … … 686 692 sprintf(&errmsg[strlen(errmsg)], 687 693 (exrec->ExceptionInformation[0] 688 ? _("Access violation: write operation at address % x\n")689 : _("Access violation: read operation at address % x\n")),694 ? _("Access violation: write operation at address %lx\n") 695 : _("Access violation: read operation at address %lx\n")), 690 696 exrec->ExceptionInformation[1]); 691 697 … … 760 766 batch_mode_shell = 1; 761 767 unixy_shell = 0; 762 sh_found = 0; 768 sprintf (sh_path, "%s", search_token); 769 default_shell = xstrdup (w32ify (sh_path, 0)); 770 DB (DB_VERBOSE, 771 (_("find_and_set_shell setting default_shell = %s\n"), default_shell)); 772 sh_found = 1; 763 773 } else if (!no_default_sh_exe && 764 774 (token == NULL || !strcmp (search_token, default_shell))) { … … 774 784 } else { 775 785 char *p; 776 struct variable *v = lookup_variable ( "PATH", 4);786 struct variable *v = lookup_variable (STRING_SIZE_TUPLE ("PATH")); 777 787 778 788 /* Search Path for shell */ … … 847 857 open_tmpfile(char **name, const char *template) 848 858 { 859 #ifdef HAVE_FDOPEN 849 860 int fd; 861 #endif 850 862 851 863 #if defined HAVE_MKSTEMP || defined HAVE_MKTEMP … … 899 911 struct dep *read_makefiles; 900 912 PATH_VAR (current_directory); 913 unsigned int restarts = 0; 901 914 #ifdef WINDOWS32 902 915 char *unix_path = NULL; … … 922 935 } 923 936 } 937 #endif 938 939 #ifdef HAVE_ATEXIT 940 atexit (close_stdout); 924 941 #endif 925 942 … … 1052 1069 /* Extract program from full path */ 1053 1070 int argv0_len; 1054 char *p = strrchr (argv[0], '\\'); 1055 if (!p) 1056 p = argv[0]; 1057 argv0_len = strlen(p); 1058 if (argv0_len > 4 1059 && streq (&p[argv0_len - 4], ".exe")) 1071 program = strrchr (argv[0], '\\'); 1072 if (program) 1060 1073 { 1061 /* Remove .exe extension */1062 p[argv0_len - 4] = '\0';1063 /* Increment past the initial '\'*/1064 program = p + 1;1074 argv0_len = strlen(program); 1075 if (argv0_len > 4 && streq (&program[argv0_len - 4], ".exe")) 1076 /* Remove .exe extension */ 1077 program[argv0_len - 4] = '\0'; 1065 1078 } 1066 1079 } … … 1106 1119 /* Set up .FEATURES */ 1107 1120 define_variable (".FEATURES", 9, 1108 "target-specific order-only second-expansion ",1121 "target-specific order-only second-expansion else-if", 1109 1122 o_default, 0); 1123 #ifndef NO_ARCHIVES 1124 do_variable_definition (NILF, ".FEATURES", "archives", 1125 o_default, f_append, 0); 1126 #endif 1110 1127 #ifdef MAKE_JOBSERVER 1111 1128 do_variable_definition (NILF, ".FEATURES", "jobserver", … … 1155 1172 1156 1173 /* Another wrinkle is that POSIX says the value of SHELL set in the 1157 makefile should not change the value of SHELL given to 1158 subprocesses, which seems silly to me but... */ 1159 if (strncmp (envp[i], "SHELL=", 6) == 0) 1174 makefile won't change the value of SHELL given to subprocesses */ 1175 if (streq (v->name, "SHELL")) 1160 1176 { 1161 1177 #ifndef __MSDOS__ … … 1164 1180 shell_var.name = "SHELL"; 1165 1181 shell_var.value = xstrdup (ep + 1); 1182 } 1183 1184 /* If MAKE_RESTARTS is set, remember it but don't export it. */ 1185 if (streq (v->name, "MAKE_RESTARTS")) 1186 { 1187 v->export = v_noexport; 1188 restarts = (unsigned int) atoi (ep + 1); 1166 1189 } 1167 1190 } … … 1209 1232 /* Decode the switches. */ 1210 1233 1211 decode_env_switches ( "MAKEFLAGS", 9);1234 decode_env_switches (STRING_SIZE_TUPLE ("MAKEFLAGS")); 1212 1235 #if 0 1213 1236 /* People write things like: 1214 1237 MFLAGS="CC=gcc -pipe" "CFLAGS=-g" 1215 1238 and we set the -p, -i and -e switches. Doesn't seem quite right. */ 1216 decode_env_switches ( "MFLAGS", 6);1239 decode_env_switches (STRING_SIZE_TUPLE ("MFLAGS")); 1217 1240 #endif 1218 1241 decode_switches (argc, argv, 0); 1219 1242 #ifdef WINDOWS32 1220 1243 if (suspend_flag) { 1221 fprintf(stderr, "%s (pid = % d)\n", argv[0], GetCurrentProcessId());1244 fprintf(stderr, "%s (pid = %ld)\n", argv[0], GetCurrentProcessId()); 1222 1245 fprintf(stderr, _("%s is suspending for 30 seconds..."), argv[0]); 1223 1246 Sleep(30 * 1000); … … 1228 1251 decode_debug_flags (); 1229 1252 1253 /* Set always_make_flag if -B was given and we've not restarted already. */ 1254 always_make_flag = always_make_set && (restarts == 0); 1255 1230 1256 /* Print version information. */ 1231 1232 1257 if (print_version_flag || print_data_base_flag || db_level) 1233 print_version (); 1234 1235 /* `make --version' is supposed to just print the version and exit. */ 1236 if (print_version_flag) 1237 die (0); 1258 { 1259 print_version (); 1260 1261 /* `make --version' is supposed to just print the version and exit. */ 1262 if (print_version_flag) 1263 die (0); 1264 } 1238 1265 1239 1266 #ifndef VMS … … 1382 1409 /* Figure out the level of recursion. */ 1383 1410 { 1384 struct variable *v = lookup_variable ( MAKELEVEL_NAME, MAKELEVEL_LENGTH);1411 struct variable *v = lookup_variable (STRING_SIZE_TUPLE (MAKELEVEL_NAME)); 1385 1412 if (v != 0 && v->value[0] != '\0' && v->value[0] != '-') 1386 1413 makelevel = (unsigned int) atoi (v->value); … … 1429 1456 } 1430 1457 1431 (void) define_variable ("CURDIR", 6, current_directory, o_ default, 0);1458 (void) define_variable ("CURDIR", 6, current_directory, o_file, 0); 1432 1459 1433 1460 /* Read any stdin makefiles into temporary files. */ … … 1582 1609 if (no_default_sh_exe) 1583 1610 no_default_sh_exe = !find_and_set_default_shell(NULL); 1584 1585 if (no_default_sh_exe && job_slots != 1) {1586 error (NILF, _("Do not specify -j or --jobs if sh.exe is not available."));1587 error (NILF, _("Resetting make for single job mode."));1588 job_slots = 1;1589 }1590 1611 #endif /* WINDOWS32 */ 1591 1612 … … 1594 1615 { 1595 1616 extern int _is_unixy_shell (const char *_path); 1596 struct variable *shv = lookup_variable ( "SHELL", 5);1617 struct variable *shv = lookup_variable (STRING_SIZE_TUPLE ("SHELL")); 1597 1618 extern int unixy_shell; 1598 1619 extern char *default_shell; … … 1613 1634 1614 1635 /* Decode switches again, in case the variables were set by the makefile. */ 1615 decode_env_switches ( "MAKEFLAGS", 9);1636 decode_env_switches (STRING_SIZE_TUPLE ("MAKEFLAGS")); 1616 1637 #if 0 1617 decode_env_switches ( "MFLAGS", 6);1638 decode_env_switches (STRING_SIZE_TUPLE ("MFLAGS")); 1618 1639 #endif 1619 1640 … … 1766 1787 build_vpath_lists (); 1767 1788 1768 /* Mark files given with -o flags as very old 1769 a nd as having been updated already, and files given with -W flags as1770 brand new (time-stamp as far as possible into the future). */1789 /* Mark files given with -o flags as very old and as having been updated 1790 already, and files given with -W flags as brand new (time-stamp as far 1791 as possible into the future). If restarts is set we'll do -W later. */ 1771 1792 1772 1793 if (old_files != 0) … … 1780 1801 } 1781 1802 1782 if ( new_files != 0)1803 if (!restarts && new_files != 0) 1783 1804 { 1784 1805 for (p = new_files->list; *p != 0; ++p) … … 1840 1861 1841 1862 /* Free the storage. */ 1842 free ((char *)d);1863 free_dep (d); 1843 1864 1844 1865 d = last == 0 ? read_makefiles : last->next; … … 1959 1980 log_working_directory (0); 1960 1981 1982 clean_jobserver (0); 1983 1961 1984 if (makefiles != 0) 1962 1985 { … … 2003 2026 } 2004 2027 2005 #ifndef _AMIGA 2006 for (p = environ; *p != 0; ++p) 2007 if (strneq (*p, MAKELEVEL_NAME, MAKELEVEL_LENGTH) 2008 && (*p)[MAKELEVEL_LENGTH] == '=') 2009 { 2010 /* The SGI compiler apparently can't understand 2011 the concept of storing the result of a function 2012 in something other than a local variable. */ 2013 char *sgi_loses; 2014 sgi_loses = (char *) alloca (40); 2015 *p = sgi_loses; 2016 sprintf (*p, "%s=%u", MAKELEVEL_NAME, makelevel); 2017 break; 2018 } 2019 #else /* AMIGA */ 2020 { 2021 char buffer[256]; 2022 int len; 2023 2024 len = GetVar (MAKELEVEL_NAME, buffer, sizeof (buffer), GVF_GLOBAL_ONLY); 2025 2026 if (len != -1) 2027 { 2028 sprintf (buffer, "%u", makelevel); 2029 SetVar (MAKELEVEL_NAME, buffer, -1, GVF_GLOBAL_ONLY); 2030 } 2031 } 2032 #endif 2028 ++restarts; 2033 2029 2034 2030 if (ISDB (DB_BASIC)) 2035 2031 { 2036 2032 char **p; 2037 fputs (_("Re-executing:"), stdout);2033 printf (_("Re-executing[%u]:"), restarts); 2038 2034 for (p = nargv; *p != 0; ++p) 2039 2035 printf (" %s", *p); 2040 2036 putchar ('\n'); 2041 2037 } 2038 2039 #ifndef _AMIGA 2040 for (p = environ; *p != 0; ++p) 2041 { 2042 if (strneq (*p, MAKELEVEL_NAME, MAKELEVEL_LENGTH) 2043 && (*p)[MAKELEVEL_LENGTH] == '=') 2044 { 2045 /* The SGI compiler apparently can't understand 2046 the concept of storing the result of a function 2047 in something other than a local variable. */ 2048 char *sgi_loses; 2049 sgi_loses = (char *) alloca (40); 2050 *p = sgi_loses; 2051 sprintf (*p, "%s=%u", MAKELEVEL_NAME, makelevel); 2052 } 2053 if (strneq (*p, "MAKE_RESTARTS=", 14)) 2054 { 2055 char *sgi_loses; 2056 sgi_loses = (char *) alloca (40); 2057 *p = sgi_loses; 2058 sprintf (*p, "MAKE_RESTARTS=%u", restarts); 2059 restarts = 0; 2060 } 2061 } 2062 #else /* AMIGA */ 2063 { 2064 char buffer[256]; 2065 2066 sprintf (buffer, "%u", makelevel); 2067 SetVar (MAKELEVEL_NAME, buffer, -1, GVF_GLOBAL_ONLY); 2068 2069 sprintf (buffer, "%u", restarts); 2070 SetVar ("MAKE_RESTARTS", buffer, -1, GVF_GLOBAL_ONLY); 2071 restarts = 0; 2072 } 2073 #endif 2074 2075 /* If we didn't set the restarts variable yet, add it. */ 2076 if (restarts) 2077 { 2078 char *b = alloca (40); 2079 sprintf (b, "MAKE_RESTARTS=%u", restarts); 2080 putenv (b); 2081 } 2042 2082 2043 2083 fflush (stdout); … … 2091 2131 define_makeflags (1, 0); 2092 2132 2133 /* Set always_make_flag if -B was given. */ 2134 always_make_flag = always_make_set; 2135 2136 /* If restarts is set we haven't set up -W files yet, so do that now. */ 2137 if (restarts && new_files != 0) 2138 { 2139 for (p = new_files->list; *p != 0; ++p) 2140 { 2141 f = enter_command_line_file (*p); 2142 f->last_mtime = f->mtime_before_update = NEW_MTIME; 2143 } 2144 } 2145 2093 2146 /* If there is a temp file from reading a makefile from stdin, get rid of 2094 2147 it now. */ … … 2132 2185 } 2133 2186 2134 goals = (struct dep *) xmalloc (sizeof (struct dep)); 2135 goals->next = 0; 2136 goals->name = 0; 2137 goals->ignore_mtime = 0; 2138 goals->need_2nd_expansion = 0; 2187 goals = alloc_dep (); 2139 2188 goals->file = default_goal_file; 2140 2189 } … … 2186 2235 } 2187 2236 2237 /* NOTREACHED */ 2188 2238 return 0; 2189 2239 } … … 2292 2342 if (goals == 0) 2293 2343 { 2294 goals = (struct dep *) xmalloc (sizeof (struct dep));2344 goals = alloc_dep (); 2295 2345 lastgoal = goals; 2296 2346 } 2297 2347 else 2298 2348 { 2299 lastgoal->next = (struct dep *) xmalloc (sizeof (struct dep));2349 lastgoal->next = alloc_dep (); 2300 2350 lastgoal = lastgoal->next; 2301 2351 } 2302 lastgoal->name = 0; 2352 2303 2353 lastgoal->file = f; 2304 lastgoal->ignore_mtime = 0;2305 lastgoal->need_2nd_expansion = 0;2306 2354 2307 2355 { … … 2310 2358 char *value; 2311 2359 2312 v = lookup_variable ( "MAKECMDGOALS", 12);2360 v = lookup_variable (STRING_SIZE_TUPLE ("MAKECMDGOALS")); 2313 2361 if (v == 0) 2314 2362 value = f->name; … … 2903 2951 2904 2952 printf ("%sGNU Make %s\n\ 2905 %sCopyright (C) 200 3Free Software Foundation, Inc.\n",2953 %sCopyright (C) 2006 Free Software Foundation, Inc.\n", 2906 2954 precede, version_string, precede); 2907 2955 … … 2927 2975 2928 2976 static void 2929 print_data_base ( void)2977 print_data_base () 2930 2978 { 2931 2979 time_t when; … … 2939 2987 print_file_data_base (); 2940 2988 print_vpath_data_base (); 2989 strcache_print_stats ("#"); 2941 2990 2942 2991 when = time ((time_t *) 0); 2943 2992 printf (_("\n# Finished Make data base on %s\n"), ctime (&when)); 2993 } 2994 2995 static void 2996 clean_jobserver (int status) 2997 { 2998 char token = '+'; 2999 3000 /* Sanity: have we written all our jobserver tokens back? If our 3001 exit status is 2 that means some kind of syntax error; we might not 3002 have written all our tokens so do that now. If tokens are left 3003 after any other error code, that's bad. */ 3004 3005 if (job_fds[0] != -1 && jobserver_tokens) 3006 { 3007 if (status != 2) 3008 error (NILF, 3009 "INTERNAL: Exiting with %u jobserver tokens (should be 0)!", 3010 jobserver_tokens); 3011 else 3012 while (jobserver_tokens--) 3013 { 3014 int r; 3015 3016 EINTRLOOP (r, write (job_fds[1], &token, 1)); 3017 if (r != 1) 3018 perror_with_name ("write", ""); 3019 } 3020 } 3021 3022 3023 /* Sanity: If we're the master, were all the tokens written back? */ 3024 3025 if (master_job_slots) 3026 { 3027 /* We didn't write one for ourself, so start at 1. */ 3028 unsigned int tcnt = 1; 3029 3030 /* Close the write side, so the read() won't hang. */ 3031 close (job_fds[1]); 3032 3033 while (read (job_fds[0], &token, 1) == 1) 3034 ++tcnt; 3035 3036 if (tcnt != master_job_slots) 3037 error (NILF, 3038 "INTERNAL: Exiting with %u jobserver tokens available; should be %u!", 3039 tcnt, master_job_slots); 3040 3041 close (job_fds[0]); 3042 } 2944 3043 } 2945 3044 … … 2954 3053 if (!dying) 2955 3054 { 2956 char token = '+';2957 3055 int err; 2958 3056 … … 2963 3061 2964 3062 /* Wait for children to die. */ 2965 for (err = (status != 0); job_slots_used > 0; err = 0) 3063 err = (status != 0); 3064 while (job_slots_used > 0) 2966 3065 reap_children (1, err); 2967 3066 … … 2975 3074 print_data_base (); 2976 3075 2977 /* Sanity: have we written all our jobserver tokens back? If our 2978 exit status is 2 that means some kind of syntax error; we might not 2979 have written all our tokens so do that now. If tokens are left 2980 after any other error code, that's bad. */ 2981 2982 if (job_fds[0] != -1 && jobserver_tokens) 2983 { 2984 if (status != 2) 2985 error (NILF, 2986 "INTERNAL: Exiting with %u jobserver tokens (should be 0)!", 2987 jobserver_tokens); 2988 else 2989 while (jobserver_tokens--) 2990 { 2991 int r; 2992 2993 EINTRLOOP (r, write (job_fds[1], &token, 1)); 2994 if (r != 1) 2995 perror_with_name ("write", ""); 2996 } 2997 } 2998 2999 3000 /* Sanity: If we're the master, were all the tokens written back? */ 3001 3002 if (master_job_slots) 3003 { 3004 /* We didn't write one for ourself, so start at 1. */ 3005 unsigned int tcnt = 1; 3006 3007 /* Close the write side, so the read() won't hang. */ 3008 close (job_fds[1]); 3009 3010 while ((err = read (job_fds[0], &token, 1)) == 1) 3011 ++tcnt; 3012 3013 if (tcnt != master_job_slots) 3014 error (NILF, 3015 "INTERNAL: Exiting with %u jobserver tokens available; should be %u!", 3016 tcnt, master_job_slots); 3017 } 3076 clean_jobserver (status); 3018 3077 3019 3078 /* Try to move back to the original directory. This is essential on
Note:
See TracChangeset
for help on using the changeset viewer.