Print this page
make: remove SCCS ident stuff
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/bin/make/common/main.cc
+++ new/usr/src/cmd/make/bin/make/common/main.cc
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 -/*
26 - * @(#)main.cc 1.158 06/12/12
27 - */
28 -
29 -#pragma ident "@(#)main.cc 1.158 06/12/12"
30 25
31 26 /*
32 27 * main.cc
33 28 *
34 29 * make program main routine plus some helper routines
35 30 */
36 31
37 32 /*
38 33 * Included files
39 34 */
40 35 #if defined(TEAMWARE_MAKE_CMN)
41 36 # include <avo/intl.h>
42 37 # include <avo/libcli.h> /* libcli_init() */
43 38 # include <avo/cli_license.h> /* avo_cli_get_license() */
44 39 # include <avo/find_dir.h> /* avo_find_run_dir() */
45 40 # include <avo/version_string.h>
46 41 # include <avo/util.h> /* avo_init() */
47 42 #ifdef USE_DMS_CCR
48 43 # include <avo/usage_tracking.h>
49 44 #else
50 45 # include <avo/cleanup.h>
51 46 #endif
52 47 #endif
53 48
54 49 #if defined(TEAMWARE_MAKE_CMN)
55 50 /* This is for dmake only (not for Solaris make).
56 51 * Include code to check updates (dmake patches)
57 52 */
58 53 #ifdef _CHECK_UPDATE_H
59 54 #include <libAU.h>
60 55 #endif
61 56 #endif
62 57
63 58 #include <bsd/bsd.h> /* bsd_signal() */
64 59
65 60 #ifdef DISTRIBUTED
66 61 # include <dm/Avo_AcknowledgeMsg.h>
67 62 # include <rw/xdrstrea.h>
68 63 # include <dmrc/dmrc.h> /* dmakerc file processing */
69 64 #endif
70 65
71 66 #include <locale.h> /* setlocale() */
72 67 #include <mk/copyright.h>
73 68 #include <mk/defs.h>
74 69 #include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
75 70 #include <mksh/macro.h> /* getvar() */
76 71 #include <mksh/misc.h> /* getmem(), setup_char_semantics() */
77 72
78 73 #if defined(TEAMWARE_MAKE_CMN)
79 74 #ifdef USE_DMS_CCR
80 75 # include <pubdmsi18n/pubdmsi18n.h> /* libpubdmsi18n_init() */
81 76 #endif
82 77 #endif
83 78
84 79 #include <pwd.h> /* getpwnam() */
85 80 #include <setjmp.h>
86 81 #include <signal.h>
87 82 #include <stdlib.h>
88 83 #include <sys/errno.h> /* ENOENT */
89 84 #include <sys/stat.h> /* fstat() */
90 85 #include <fcntl.h> /* open() */
91 86
92 87 #ifdef SUN5_0
93 88 # include <sys/systeminfo.h> /* sysinfo() */
94 89 #endif
95 90
96 91 #include <sys/types.h> /* stat() */
97 92 #include <sys/wait.h> /* wait() */
98 93 #include <unistd.h> /* execv(), unlink(), access() */
99 94 #include <vroot/report.h> /* report_dependency(), get_report_file() */
100 95
101 96 // From read2.cc
102 97 extern Name normalize_name(register wchar_t *name_string, register int length);
103 98
104 99 // From parallel.cc
105 100 #if defined(TEAMWARE_MAKE_CMN)
106 101 #define MAXJOBS_ADJUST_RFE4694000
107 102
108 103 #ifdef MAXJOBS_ADJUST_RFE4694000
109 104 extern void job_adjust_fini();
110 105 #endif /* MAXJOBS_ADJUST_RFE4694000 */
111 106 #endif /* TEAMWARE_MAKE_CMN */
112 107
113 108 #if defined(linux)
114 109 #include <ctype.h>
115 110 #endif
116 111
117 112 /*
118 113 * Defined macros
119 114 */
120 115 #define LD_SUPPORT_ENV_VAR NOCATGETS("SGS_SUPPORT")
121 116 #define LD_SUPPORT_MAKE_LIB NOCATGETS("libmakestate.so.1")
122 117
123 118 /*
124 119 * typedefs & structs
125 120 */
126 121
127 122 /*
128 123 * Static variables
129 124 */
130 125 static char *argv_zero_string;
131 126 static Boolean build_failed_ever_seen;
132 127 static Boolean continue_after_error_ever_seen; /* `-k' */
133 128 static Boolean dmake_group_specified; /* `-g' */
134 129 static Boolean dmake_max_jobs_specified; /* `-j' */
135 130 static Boolean dmake_mode_specified; /* `-m' */
136 131 static Boolean dmake_add_mode_specified; /* `-x' */
137 132 static Boolean dmake_output_mode_specified; /* `-x DMAKE_OUTPUT_MODE=' */
138 133 static Boolean dmake_compat_mode_specified; /* `-x SUN_MAKE_COMPAT_MODE=' */
139 134 static Boolean dmake_odir_specified; /* `-o' */
140 135 static Boolean dmake_rcfile_specified; /* `-c' */
141 136 static Boolean env_wins; /* `-e' */
142 137 static Boolean ignore_default_mk; /* `-r' */
143 138 static Boolean list_all_targets; /* `-T' */
144 139 static int mf_argc;
145 140 static char **mf_argv;
146 141 static Dependency_rec not_auto_depen_struct;
147 142 static Dependency not_auto_depen = ¬_auto_depen_struct;
148 143 static Boolean pmake_cap_r_specified; /* `-R' */
149 144 static Boolean pmake_machinesfile_specified; /* `-M' */
150 145 static Boolean stop_after_error_ever_seen; /* `-S' */
151 146 static Boolean trace_status; /* `-p' */
152 147
153 148 #ifdef DMAKE_STATISTICS
154 149 static Boolean getname_stat = false;
155 150 #endif
156 151
157 152 #if defined(TEAMWARE_MAKE_CMN)
158 153 static time_t start_time;
159 154 static int g_argc;
160 155 static char **g_argv;
161 156 #ifdef USE_DMS_CCR
162 157 static Avo_usage_tracking *usageTracking = NULL;
163 158 #else
164 159 static Avo_cleanup *cleanup = NULL;
165 160 #endif
166 161 #endif
167 162
168 163 /*
169 164 * File table of contents
170 165 */
171 166 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
172 167 extern "C" void cleanup_after_exit(void);
173 168 #else
174 169 extern void cleanup_after_exit(int, ...);
175 170 #endif
176 171
177 172 #ifdef TEAMWARE_MAKE_CMN
178 173 extern "C" {
179 174 extern void dmake_exit_callback(void);
180 175 extern void dmake_message_callback(char *);
181 176 }
182 177 #endif
183 178
184 179 extern Name normalize_name(register wchar_t *name_string, register int length);
185 180
186 181 extern int main(int, char * []);
187 182
188 183 static void append_makeflags_string(Name, String);
189 184 static void doalarm(int);
190 185 static void enter_argv_values(int , char **, ASCII_Dyn_Array *);
191 186 static void make_targets(int, char **, Boolean);
192 187 static int parse_command_option(char);
193 188 static void read_command_options(int, char **);
194 189 static void read_environment(Boolean);
195 190 static void read_files_and_state(int, char **);
196 191 static Boolean read_makefile(Name, Boolean, Boolean, Boolean);
197 192 static void report_recursion(Name);
198 193 static void set_sgs_support(void);
199 194 static void setup_for_projectdir(void);
200 195 static void setup_makeflags_argv(void);
201 196 static void report_dir_enter_leave(Boolean entering);
202 197
203 198 extern void expand_value(Name, register String , Boolean);
204 199
205 200 #ifdef DISTRIBUTED
206 201 extern int dmake_ofd;
207 202 extern FILE* dmake_ofp;
208 203 extern int rxmPid;
209 204 extern XDR xdrs_out;
210 205 #endif
211 206 #ifdef TEAMWARE_MAKE_CMN
212 207 extern char verstring[];
213 208 #endif
214 209
215 210 jmp_buf jmpbuffer;
216 211 #if !defined(linux)
217 212 nl_catd catd;
218 213 #endif
219 214
220 215 /*
221 216 * main(argc, argv)
222 217 *
223 218 * Parameters:
224 219 * argc You know what this is
225 220 * argv You know what this is
226 221 *
227 222 * Static variables used:
228 223 * list_all_targets make -T seen
229 224 * trace_status make -p seen
230 225 *
231 226 * Global variables used:
232 227 * debug_level Should we trace make actions?
233 228 * keep_state Set if .KEEP_STATE seen
234 229 * makeflags The Name "MAKEFLAGS", used to get macro
235 230 * remote_command_name Name of remote invocation cmd ("on")
236 231 * running_list List of parallel running processes
237 232 * stdout_stderr_same true if stdout and stderr are the same
238 233 * auto_dependencies The Name "SUNPRO_DEPENDENCIES"
239 234 * temp_file_directory Set to the dir where we create tmp file
240 235 * trace_reader Set to reflect tracing status
241 236 * working_on_targets Set when building user targets
242 237 */
243 238 int
244 239 main(int argc, char *argv[])
245 240 {
246 241 /*
247 242 * cp is a -> to the value of the MAKEFLAGS env var,
248 243 * which has to be regular chars.
249 244 */
250 245 register char *cp;
251 246 char make_state_dir[MAXPATHLEN];
252 247 Boolean parallel_flag = false;
253 248 char *prognameptr;
254 249 char *slash_ptr;
255 250 mode_t um;
256 251 int i;
257 252 #ifdef TEAMWARE_MAKE_CMN
258 253 struct itimerval value;
259 254 char def_dmakerc_path[MAXPATHLEN];
260 255 Name dmake_name, dmake_name2;
261 256 Name dmake_value, dmake_value2;
262 257 Property prop, prop2;
263 258 struct stat statbuf;
264 259 int statval;
265 260 #endif
266 261
267 262 #ifndef PARALLEL
268 263 struct stat out_stat, err_stat;
269 264 #endif
270 265 hostid = gethostid();
271 266 #ifdef TEAMWARE_MAKE_CMN
272 267 avo_get_user(NULL, NULL); // Initialize user name
273 268 #endif
274 269 bsd_signals();
275 270
276 271 (void) setlocale(LC_ALL, "");
277 272
278 273 #if defined (HP_UX) || defined(linux)
279 274 /* HP-UX users typically will not have NLSPATH set, and this binary
280 275 * requires that it be set. On HP-UX 9.0x, /usr/lib/nls/%L/%N.cat is
281 276 * the path to set it to.
282 277 */
283 278
284 279 if (getenv(NOCATGETS("NLSPATH")) == NULL) {
285 280 putenv(NOCATGETS("NLSPATH=/usr/lib/nls/%L/%N.cat"));
286 281 }
287 282 #endif
288 283
289 284 #ifdef DMAKE_STATISTICS
290 285 if (getenv(NOCATGETS("DMAKE_STATISTICS"))) {
291 286 getname_stat = true;
292 287 }
293 288 #endif
294 289
295 290
296 291 /*
297 292 * avo_init() sets the umask to 0. Save it here and restore
298 293 * it after the avo_init() call.
299 294 */
300 295 #if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL)
301 296 um = umask(0);
302 297 avo_init(argv[0]);
303 298 umask(um);
304 299
305 300 #ifdef USE_DMS_CCR
306 301 usageTracking = new Avo_usage_tracking(NOCATGETS("dmake"), argc, argv);
307 302 #else
308 303 cleanup = new Avo_cleanup(NOCATGETS("dmake"), argc, argv);
309 304 #endif
310 305 #endif
311 306
312 307 #if defined(TEAMWARE_MAKE_CMN)
313 308 catd = catopen(AVO_DOMAIN_DMAKE, NL_CAT_LOCALE);
314 309 libcli_init();
315 310
316 311 #ifdef _CHECK_UPDATE_H
317 312 /* This is for dmake only (not for Solaris make).
318 313 * Check (in background) if there is an update (dmake patch)
319 314 * and inform user
320 315 */
321 316 {
322 317 Avo_err *err;
323 318 char *dir;
324 319 err = avo_find_run_dir(&dir);
325 320 if (AVO_OK == err) {
326 321 AU_check_update_service(NOCATGETS("Dmake"), dir);
327 322 }
328 323 }
329 324 #endif /* _CHECK_UPDATE_H */
330 325 #endif
331 326
332 327 // ---> fprintf(stderr, catgets(catd, 15, 666, "--- SUN make ---\n"));
333 328
334 329
335 330 #if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL)
336 331 /*
337 332 * I put libmksdmsi18n_init() under #ifdef because it requires avo_i18n_init()
338 333 * from avo_util library.
339 334 */
340 335 libmksdmsi18n_init();
341 336 #ifdef USE_DMS_CCR
342 337 libpubdmsi18n_init();
343 338 #endif
344 339 #endif
345 340
346 341
347 342 #ifndef TEAMWARE_MAKE_CMN
348 343 textdomain(NOCATGETS("SUNW_SPRO_MAKE"));
349 344 #endif /* TEAMWARE_MAKE_CMN */
350 345
351 346 #ifdef TEAMWARE_MAKE_CMN
352 347 g_argc = argc;
353 348 g_argv = (char **) malloc((g_argc + 1) * sizeof(char *));
354 349 for (i = 0; i < argc; i++) {
355 350 g_argv[i] = argv[i];
356 351 }
357 352 g_argv[i] = NULL;
358 353 #endif /* TEAMWARE_MAKE_CMN */
359 354
360 355 /*
361 356 * Set argv_zero_string to some form of argv[0] for
362 357 * recursive MAKE builds.
363 358 */
364 359
365 360 if (*argv[0] == (int) slash_char) {
366 361 /* argv[0] starts with a slash */
367 362 argv_zero_string = strdup(argv[0]);
368 363 } else if (strchr(argv[0], (int) slash_char) == NULL) {
369 364 /* argv[0] contains no slashes */
370 365 argv_zero_string = strdup(argv[0]);
371 366 } else {
372 367 /*
373 368 * argv[0] contains at least one slash,
374 369 * but doesn't start with a slash
375 370 */
376 371 char *tmp_current_path;
377 372 char *tmp_string;
378 373
379 374 tmp_current_path = get_current_path();
380 375 tmp_string = getmem(strlen(tmp_current_path) + 1 +
381 376 strlen(argv[0]) + 1);
382 377 (void) sprintf(tmp_string,
383 378 "%s/%s",
384 379 tmp_current_path,
385 380 argv[0]);
386 381 argv_zero_string = strdup(tmp_string);
387 382 retmem_mb(tmp_string);
388 383 }
389 384
390 385 /*
391 386 * The following flags are reset if we don't have the
392 387 * (.nse_depinfo or .make.state) files locked and only set
393 388 * AFTER the file has been locked. This ensures that if the user
394 389 * interrupts the program while file_lock() is waiting to lock
395 390 * the file, the interrupt handler doesn't remove a lock
396 391 * that doesn't belong to us.
397 392 */
398 393 make_state_lockfile = NULL;
399 394 make_state_locked = false;
400 395
401 396 #ifdef NSE
402 397 nse_depinfo_lockfile[0] = '\0';
403 398 nse_depinfo_locked = false;
404 399 #endif
405 400
406 401 /*
407 402 * look for last slash char in the path to look at the binary
408 403 * name. This is to resolve the hard link and invoke make
409 404 * in svr4 mode.
410 405 */
411 406
412 407 /* Sun OS make standart */
413 408 svr4 = false;
414 409 posix = false;
415 410 if(!strcmp(argv_zero_string, NOCATGETS("/usr/xpg4/bin/make"))) {
416 411 svr4 = false;
417 412 posix = true;
418 413 } else {
419 414 prognameptr = strrchr(argv[0], '/');
420 415 if(prognameptr) {
421 416 prognameptr++;
422 417 } else {
423 418 prognameptr = argv[0];
424 419 }
425 420 if(!strcmp(prognameptr, NOCATGETS("svr4.make"))) {
426 421 svr4 = true;
427 422 posix = false;
428 423 }
429 424 }
430 425 #if !defined(HP_UX) && !defined(linux)
431 426 if (getenv(USE_SVR4_MAKE) || getenv(NOCATGETS("USE_SVID"))){
432 427 svr4 = true;
433 428 posix = false;
434 429 }
435 430 #endif
436 431
437 432 /*
438 433 * Find the dmake_compat_mode: posix, sun, svr4, or gnu_style, .
439 434 */
440 435 char * dmake_compat_mode_var = getenv(NOCATGETS("SUN_MAKE_COMPAT_MODE"));
441 436 if (dmake_compat_mode_var != NULL) {
442 437 if (0 == strcasecmp(dmake_compat_mode_var, NOCATGETS("GNU"))) {
443 438 gnu_style = true;
444 439 }
445 440 //svr4 = false;
446 441 //posix = false;
447 442 }
448 443
449 444 /*
450 445 * Temporary directory set up.
451 446 */
452 447 char * tmpdir_var = getenv(NOCATGETS("TMPDIR"));
453 448 if (tmpdir_var != NULL && *tmpdir_var == '/' && strlen(tmpdir_var) < MAXPATHLEN) {
454 449 strcpy(mbs_buffer, tmpdir_var);
455 450 for (tmpdir_var = mbs_buffer+strlen(mbs_buffer);
456 451 *(--tmpdir_var) == '/' && tmpdir_var > mbs_buffer;
457 452 *tmpdir_var = '\0');
458 453 if (strlen(mbs_buffer) + 32 < MAXPATHLEN) { /* 32 = strlen("/dmake.stdout.%d.%d.XXXXXX") */
459 454 sprintf(mbs_buffer2, NOCATGETS("%s/dmake.tst.%d.XXXXXX"),
460 455 mbs_buffer, getpid());
461 456 int fd = mkstemp(mbs_buffer2);
462 457 if (fd >= 0) {
463 458 close(fd);
464 459 unlink(mbs_buffer2);
465 460 tmpdir = strdup(mbs_buffer);
466 461 }
467 462 }
468 463 }
469 464
470 465 #ifndef PARALLEL
471 466 /* find out if stdout and stderr point to the same place */
472 467 if (fstat(1, &out_stat) < 0) {
473 468 fatal(catgets(catd, 1, 165, "fstat of standard out failed: %s"), errmsg(errno));
474 469 }
475 470 if (fstat(2, &err_stat) < 0) {
476 471 fatal(catgets(catd, 1, 166, "fstat of standard error failed: %s"), errmsg(errno));
477 472 }
478 473 if ((out_stat.st_dev == err_stat.st_dev) &&
479 474 (out_stat.st_ino == err_stat.st_ino)) {
480 475 stdout_stderr_same = true;
481 476 } else {
482 477 stdout_stderr_same = false;
483 478 }
484 479 #else
485 480 stdout_stderr_same = false;
486 481 #endif
487 482 /* Make the vroot package scan the path using shell semantics */
488 483 set_path_style(0);
489 484
490 485 setup_char_semantics();
491 486
492 487 setup_for_projectdir();
493 488
494 489 /*
495 490 * If running with .KEEP_STATE, curdir will be set with
496 491 * the connected directory.
497 492 */
498 493 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
499 494 (void) atexit(cleanup_after_exit);
500 495 #else
501 496 (void) on_exit(cleanup_after_exit, (char *) NULL);
502 497 #endif
503 498
504 499 load_cached_names();
505 500
506 501 /*
507 502 * Set command line flags
508 503 */
509 504 setup_makeflags_argv();
510 505 read_command_options(mf_argc, mf_argv);
511 506 read_command_options(argc, argv);
512 507 if (debug_level > 0) {
513 508 cp = getenv(makeflags->string_mb);
514 509 (void) printf(catgets(catd, 1, 167, "MAKEFLAGS value: %s\n"), cp == NULL ? "" : cp);
515 510 }
516 511
517 512 setup_interrupt(handle_interrupt);
518 513
519 514 read_files_and_state(argc, argv);
520 515
521 516 #ifdef TEAMWARE_MAKE_CMN
522 517 /*
523 518 * Find the dmake_output_mode: TXT1, TXT2 or HTML1.
524 519 */
525 520 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
526 521 dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
527 522 prop2 = get_prop(dmake_name2->prop, macro_prop);
528 523 if (prop2 == NULL) {
529 524 /* DMAKE_OUTPUT_MODE not defined, default to TXT1 mode */
530 525 output_mode = txt1_mode;
531 526 } else {
532 527 dmake_value2 = prop2->body.macro.value;
533 528 if ((dmake_value2 == NULL) ||
534 529 (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("TXT1")))) {
535 530 output_mode = txt1_mode;
536 531 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("TXT2"))) {
537 532 output_mode = txt2_mode;
538 533 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("HTML1"))) {
539 534 output_mode = html1_mode;
540 535 } else {
541 536 warning(catgets(catd, 1, 352, "Unsupported value `%s' for DMAKE_OUTPUT_MODE after -x flag (ignored)"),
542 537 dmake_value2->string_mb);
543 538 }
544 539 }
545 540 /*
546 541 * Find the dmake_mode: distributed, parallel, or serial.
547 542 */
548 543 if ((!pmake_cap_r_specified) &&
549 544 (!pmake_machinesfile_specified)) {
550 545 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
551 546 dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
552 547 prop2 = get_prop(dmake_name2->prop, macro_prop);
553 548 if (prop2 == NULL) {
554 549 /* DMAKE_MODE not defined, default to distributed mode */
555 550 dmake_mode_type = distributed_mode;
556 551 no_parallel = false;
557 552 } else {
558 553 dmake_value2 = prop2->body.macro.value;
559 554 if ((dmake_value2 == NULL) ||
560 555 (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("distributed")))) {
561 556 dmake_mode_type = distributed_mode;
562 557 no_parallel = false;
563 558 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("parallel"))) {
564 559 dmake_mode_type = parallel_mode;
565 560 no_parallel = false;
566 561 #ifdef SGE_SUPPORT
567 562 grid = false;
568 563 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("grid"))) {
569 564 dmake_mode_type = parallel_mode;
570 565 no_parallel = false;
571 566 grid = true;
572 567 #endif
573 568 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("serial"))) {
574 569 dmake_mode_type = serial_mode;
575 570 no_parallel = true;
576 571 } else {
577 572 fatal(catgets(catd, 1, 307, "Unknown dmake mode argument `%s' after -m flag"), dmake_value2->string_mb);
578 573 }
579 574 }
580 575
581 576 if ((!list_all_targets) &&
582 577 (report_dependencies_level == 0)) {
583 578 /*
584 579 * Check to see if either DMAKE_RCFILE or DMAKE_MODE is defined.
585 580 * They could be defined in the env, in the makefile, or on the
586 581 * command line.
587 582 * If neither is defined, and $(HOME)/.dmakerc does not exists,
588 583 * then print a message, and default to parallel mode.
589 584 */
590 585 #ifdef DISTRIBUTED
591 586 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
592 587 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
593 588 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
594 589 dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
595 590 if ((((prop = get_prop(dmake_name->prop, macro_prop)) == NULL) ||
596 591 ((dmake_value = prop->body.macro.value) == NULL)) &&
597 592 (((prop2 = get_prop(dmake_name2->prop, macro_prop)) == NULL) ||
598 593 ((dmake_value2 = prop2->body.macro.value) == NULL))) {
599 594 Boolean empty_dmakerc = true;
600 595 char *homedir = getenv(NOCATGETS("HOME"));
601 596 if ((homedir != NULL) && (strlen(homedir) < (sizeof(def_dmakerc_path) - 16))) {
602 597 sprintf(def_dmakerc_path, NOCATGETS("%s/.dmakerc"), homedir);
603 598 if ((((statval = stat(def_dmakerc_path, &statbuf)) != 0) && (errno == ENOENT)) ||
604 599 ((statval == 0) && (statbuf.st_size == 0))) {
605 600 } else {
606 601 Avo_dmakerc *rcfile = new Avo_dmakerc();
607 602 Avo_err *err = rcfile->read(def_dmakerc_path, NULL, TRUE);
608 603 if (err) {
609 604 fatal(err->str);
610 605 }
611 606 empty_dmakerc = rcfile->was_empty();
612 607 delete rcfile;
613 608 }
614 609 }
615 610 if (empty_dmakerc) {
616 611 if (getenv(NOCATGETS("DMAKE_DEF_PRINTED")) == NULL) {
617 612 putenv(NOCATGETS("DMAKE_DEF_PRINTED=TRUE"));
618 613 (void) fprintf(stdout, catgets(catd, 1, 302, "dmake: defaulting to parallel mode.\n"));
619 614 (void) fprintf(stdout, catgets(catd, 1, 303, "See the man page dmake(1) for more information on setting up the .dmakerc file.\n"));
620 615 }
621 616 dmake_mode_type = parallel_mode;
622 617 no_parallel = false;
623 618 }
624 619 }
625 620 #else
626 621 if(dmake_mode_type == distributed_mode) {
627 622 (void) fprintf(stdout, NOCATGETS("dmake: Distributed mode not implemented.\n"));
628 623 (void) fprintf(stdout, NOCATGETS(" Defaulting to parallel mode.\n"));
629 624 dmake_mode_type = parallel_mode;
630 625 no_parallel = false;
631 626 }
632 627 #endif /* DISTRIBUTED */
633 628 }
634 629 }
635 630 #endif
636 631
637 632 #ifdef TEAMWARE_MAKE_CMN
638 633 parallel_flag = true;
639 634 /* XXX - This is a major hack for DMake/Licensing. */
640 635 if (getenv(NOCATGETS("DMAKE_CHILD")) == NULL) {
641 636 if (!avo_cli_search_license(argv[0], dmake_exit_callback, TRUE, dmake_message_callback)) {
642 637 /*
643 638 * If the user can not get a TeamWare license,
644 639 * default to serial mode.
645 640 */
646 641 dmake_mode_type = serial_mode;
647 642 no_parallel = true;
648 643 } else {
649 644 putenv(NOCATGETS("DMAKE_CHILD=TRUE"));
650 645 }
651 646 start_time = time(NULL);
652 647 /*
653 648 * XXX - Hack to disable SIGALRM's from licensing library's
654 649 * setitimer().
655 650 */
656 651 value.it_interval.tv_sec = 0;
657 652 value.it_interval.tv_usec = 0;
658 653 value.it_value.tv_sec = 0;
659 654 value.it_value.tv_usec = 0;
660 655 (void) setitimer(ITIMER_REAL, &value, NULL);
661 656 }
662 657
663 658 //
664 659 // If dmake is running with -t option, set dmake_mode_type to serial.
665 660 // This is done because doname() calls touch_command() that runs serially.
666 661 // If we do not do that, maketool will have problems.
667 662 //
668 663 if(touch) {
669 664 dmake_mode_type = serial_mode;
670 665 no_parallel = true;
671 666 }
672 667 #else
673 668 parallel_flag = false;
674 669 #endif
675 670
676 671 #if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
677 672 /*
678 673 * Check whether stdout and stderr are physically same.
679 674 * This is in order to decide whether we need to redirect
680 675 * stderr separately from stdout.
681 676 * This check is performed only if __DMAKE_SEPARATE_STDERR
682 677 * is not set. This variable may be used in order to preserve
683 678 * the 'old' behaviour.
684 679 */
685 680 out_err_same = true;
686 681 char * dmake_sep_var = getenv(NOCATGETS("__DMAKE_SEPARATE_STDERR"));
687 682 if (dmake_sep_var == NULL || (0 != strcasecmp(dmake_sep_var, NOCATGETS("NO")))) {
688 683 struct stat stdout_stat;
689 684 struct stat stderr_stat;
690 685 if( (fstat(1, &stdout_stat) == 0)
691 686 && (fstat(2, &stderr_stat) == 0) )
692 687 {
693 688 if( (stdout_stat.st_dev != stderr_stat.st_dev)
694 689 || (stdout_stat.st_ino != stderr_stat.st_ino) )
695 690 {
696 691 out_err_same = false;
697 692 }
698 693 }
699 694 }
700 695 #endif
701 696
702 697 #ifdef DISTRIBUTED
703 698 /*
704 699 * At this point, DMake should startup an rxm with any and all
705 700 * DMake command line options. Rxm will, among other things,
706 701 * read the rc file.
707 702 */
708 703 if ((!list_all_targets) &&
709 704 (report_dependencies_level == 0) &&
710 705 (dmake_mode_type == distributed_mode)) {
711 706 startup_rxm();
712 707 }
713 708 #endif
714 709
715 710 /*
716 711 * Enable interrupt handler for alarms
717 712 */
718 713 (void) bsd_signal(SIGALRM, (SIG_PF)doalarm);
719 714
720 715 /*
721 716 * Check if make should report
722 717 */
723 718 if (getenv(sunpro_dependencies->string_mb) != NULL) {
724 719 FILE *report_file;
725 720
726 721 report_dependency("");
727 722 report_file = get_report_file();
728 723 if ((report_file != NULL) && (report_file != (FILE*)-1)) {
729 724 (void) fprintf(report_file, "\n");
730 725 }
731 726 }
732 727
733 728 /*
734 729 * Make sure SUNPRO_DEPENDENCIES is exported (or not) properly
735 730 * and NSE_DEP.
736 731 */
737 732 if (keep_state) {
738 733 maybe_append_prop(sunpro_dependencies, macro_prop)->
739 734 body.macro.exported = true;
740 735 #ifdef NSE
741 736 (void) setenv(NOCATGETS("NSE_DEP"), get_current_path());
742 737 #endif
743 738 } else {
744 739 maybe_append_prop(sunpro_dependencies, macro_prop)->
745 740 body.macro.exported = false;
746 741 }
747 742
748 743 working_on_targets = true;
749 744 if (trace_status) {
750 745 dump_make_state();
751 746 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
752 747 fclose(stdout);
753 748 fclose(stderr);
754 749 exit_status = 0;
755 750 #endif
756 751 exit(0);
757 752 }
758 753 if (list_all_targets) {
759 754 dump_target_list();
760 755 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
761 756 fclose(stdout);
762 757 fclose(stderr);
763 758 exit_status = 0;
764 759 #endif
765 760 exit(0);
766 761 }
767 762 trace_reader = false;
768 763
769 764 /*
770 765 * Set temp_file_directory to the directory the .make.state
771 766 * file is written to.
772 767 */
773 768 if ((slash_ptr = strrchr(make_state->string_mb, (int) slash_char)) == NULL) {
774 769 temp_file_directory = strdup(get_current_path());
775 770 } else {
776 771 *slash_ptr = (int) nul_char;
777 772 (void) strcpy(make_state_dir, make_state->string_mb);
778 773 *slash_ptr = (int) slash_char;
779 774 /* when there is only one slash and it's the first
780 775 ** character, make_state_dir should point to '/'.
781 776 */
782 777 if(make_state_dir[0] == '\0') {
783 778 make_state_dir[0] = '/';
784 779 make_state_dir[1] = '\0';
785 780 }
786 781 if (make_state_dir[0] == (int) slash_char) {
787 782 temp_file_directory = strdup(make_state_dir);
788 783 } else {
789 784 char tmp_current_path2[MAXPATHLEN];
790 785
791 786 (void) sprintf(tmp_current_path2,
792 787 "%s/%s",
793 788 get_current_path(),
794 789 make_state_dir);
795 790 temp_file_directory = strdup(tmp_current_path2);
796 791 }
797 792 }
798 793
799 794 #ifdef DISTRIBUTED
800 795 building_serial = false;
801 796 #endif
802 797
803 798 report_dir_enter_leave(true);
804 799
805 800 make_targets(argc, argv, parallel_flag);
806 801
807 802 report_dir_enter_leave(false);
808 803
809 804 #ifdef NSE
810 805 exit(nse_exit_status());
811 806 #else
812 807 if (build_failed_ever_seen) {
813 808 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
814 809 if (posix) {
815 810 exit_status = 1;
816 811 }
817 812 #endif
818 813 exit(1);
819 814 }
820 815 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
821 816 exit_status = 0;
822 817 #endif
823 818 exit(0);
824 819 #endif
825 820 /* NOTREACHED */
826 821 }
827 822
828 823 /*
829 824 * cleanup_after_exit()
830 825 *
831 826 * Called from exit(), performs cleanup actions.
832 827 *
833 828 * Parameters:
834 829 * status The argument exit() was called with
835 830 * arg Address of an argument vector to
836 831 * cleanup_after_exit()
837 832 *
838 833 * Global variables used:
839 834 * command_changed Set if we think .make.state should be rewritten
840 835 * current_line Is set we set commands_changed
841 836 * do_not_exec_rule
842 837 * True if -n flag on
843 838 * done The Name ".DONE", rule we run
844 839 * keep_state Set if .KEEP_STATE seen
845 840 * parallel True if building in parallel
846 841 * quest If -q is on we do not run .DONE
847 842 * report_dependencies
848 843 * True if -P flag on
849 844 * running_list List of parallel running processes
850 845 * temp_file_name The temp file is removed, if any
851 846 * catd the message catalog file
852 847 * usage_tracking Should have been constructed in main()
853 848 * should destroyed just before exiting
854 849 */
855 850 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
856 851 extern "C" void
857 852 cleanup_after_exit(void)
858 853 #else
859 854 void cleanup_after_exit(int status, ...)
860 855 #endif
861 856 {
862 857 Running rp;
863 858 #ifdef NSE
864 859 char push_cmd[NSE_TFS_PUSH_LEN + 3 +
865 860 (MAXPATHLEN * MB_LEN_MAX) + 12];
866 861 char *active;
867 862 #endif
868 863
869 864 extern long getname_bytes_count;
870 865 extern long getname_names_count;
871 866 extern long getname_struct_count;
872 867 extern long freename_bytes_count;
873 868 extern long freename_names_count;
874 869 extern long freename_struct_count;
875 870 extern long other_alloc;
876 871
877 872 extern long env_alloc_num;
878 873 extern long env_alloc_bytes;
879 874
880 875
881 876 #ifdef DMAKE_STATISTICS
882 877 if(getname_stat) {
883 878 printf(NOCATGETS(">>> Getname statistics:\n"));
884 879 printf(NOCATGETS(" Allocated:\n"));
885 880 printf(NOCATGETS(" Names: %ld\n"), getname_names_count);
886 881 printf(NOCATGETS(" Strings: %ld Kb (%ld bytes)\n"), getname_bytes_count/1000, getname_bytes_count);
887 882 printf(NOCATGETS(" Structs: %ld Kb (%ld bytes)\n"), getname_struct_count/1000, getname_struct_count);
888 883 printf(NOCATGETS(" Total bytes: %ld Kb (%ld bytes)\n"), getname_struct_count/1000 + getname_bytes_count/1000, getname_struct_count + getname_bytes_count);
889 884
890 885 printf(NOCATGETS("\n Unallocated: %ld\n"), freename_names_count);
891 886 printf(NOCATGETS(" Names: %ld\n"), freename_names_count);
892 887 printf(NOCATGETS(" Strings: %ld Kb (%ld bytes)\n"), freename_bytes_count/1000, freename_bytes_count);
893 888 printf(NOCATGETS(" Structs: %ld Kb (%ld bytes)\n"), freename_struct_count/1000, freename_struct_count);
894 889 printf(NOCATGETS(" Total bytes: %ld Kb (%ld bytes)\n"), freename_struct_count/1000 + freename_bytes_count/1000, freename_struct_count + freename_bytes_count);
895 890
896 891 printf(NOCATGETS("\n Total used: %ld Kb (%ld bytes)\n"), (getname_struct_count/1000 + getname_bytes_count/1000) - (freename_struct_count/1000 + freename_bytes_count/1000), (getname_struct_count + getname_bytes_count) - (freename_struct_count + freename_bytes_count));
897 892
898 893 printf(NOCATGETS("\n>>> Other:\n"));
899 894 printf(
900 895 NOCATGETS(" Env (%ld): %ld Kb (%ld bytes)\n"),
901 896 env_alloc_num,
902 897 env_alloc_bytes/1000,
903 898 env_alloc_bytes
904 899 );
905 900
906 901 }
907 902 #endif
908 903
909 904 /*
910 905 #ifdef DISTRIBUTED
911 906 if (get_parent() == TRUE) {
912 907 #endif
913 908 */
914 909
915 910 parallel = false;
916 911 #ifdef SUN5_0
917 912 /* If we used the SVR4_MAKE, don't build .DONE or .FAILED */
918 913 if (!getenv(USE_SVR4_MAKE)){
919 914 #endif
920 915 /* Build the target .DONE or .FAILED if we caught an error */
921 916 if (!quest && !list_all_targets) {
922 917 Name failed_name;
923 918
924 919 MBSTOWCS(wcs_buffer, NOCATGETS(".FAILED"));
925 920 failed_name = GETNAME(wcs_buffer, FIND_LENGTH);
926 921 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
927 922 if ((exit_status != 0) && (failed_name->prop != NULL)) {
928 923 #else
929 924 if ((status != 0) && (failed_name->prop != NULL)) {
930 925 #endif
931 926 #ifdef TEAMWARE_MAKE_CMN
932 927 /*
933 928 * [tolik] switch DMake to serial mode
934 929 */
935 930 dmake_mode_type = serial_mode;
936 931 no_parallel = true;
937 932 #endif
938 933 (void) doname(failed_name, false, true);
939 934 } else {
940 935 if (!trace_status) {
941 936 #ifdef TEAMWARE_MAKE_CMN
942 937 /*
943 938 * Switch DMake to serial mode
944 939 */
945 940 dmake_mode_type = serial_mode;
946 941 no_parallel = true;
947 942 #endif
948 943 (void) doname(done, false, true);
949 944 }
950 945 }
951 946 }
952 947 #ifdef SUN5_0
953 948 }
954 949 #endif
955 950 /*
956 951 * Remove the temp file utilities report dependencies thru if it
957 952 * is still around
958 953 */
959 954 if (temp_file_name != NULL) {
960 955 (void) unlink(temp_file_name->string_mb);
961 956 }
962 957 /*
963 958 * Do not save the current command in .make.state if make
964 959 * was interrupted.
965 960 */
966 961 if (current_line != NULL) {
967 962 command_changed = true;
968 963 current_line->body.line.command_used = NULL;
969 964 }
970 965 /*
971 966 * For each parallel build process running, remove the temp files
972 967 * and zap the command line so it won't be put in .make.state
973 968 */
974 969 for (rp = running_list; rp != NULL; rp = rp->next) {
975 970 if (rp->temp_file != NULL) {
976 971 (void) unlink(rp->temp_file->string_mb);
977 972 }
978 973 if (rp->stdout_file != NULL) {
979 974 (void) unlink(rp->stdout_file);
980 975 retmem_mb(rp->stdout_file);
981 976 rp->stdout_file = NULL;
982 977 }
983 978 if (rp->stderr_file != NULL) {
984 979 (void) unlink(rp->stderr_file);
985 980 retmem_mb(rp->stderr_file);
986 981 rp->stderr_file = NULL;
987 982 }
988 983 command_changed = true;
989 984 /*
990 985 line = get_prop(rp->target->prop, line_prop);
991 986 if (line != NULL) {
992 987 line->body.line.command_used = NULL;
993 988 }
994 989 */
995 990 }
996 991 /* Remove the statefile lock file if the file has been locked */
997 992 if ((make_state_lockfile != NULL) && (make_state_locked)) {
998 993 (void) unlink(make_state_lockfile);
999 994 make_state_lockfile = NULL;
1000 995 make_state_locked = false;
1001 996 }
1002 997 /* Write .make.state */
1003 998 write_state_file(1, (Boolean) 1);
1004 999
1005 1000 #ifdef TEAMWARE_MAKE_CMN
1006 1001 // Deleting the usage tracking object sends the usage mail
1007 1002 #ifdef USE_DMS_CCR
1008 1003 //usageTracking->setExitStatus(exit_status, NULL);
1009 1004 //delete usageTracking;
1010 1005 #else
1011 1006 cleanup->set_exit_status(exit_status);
1012 1007 delete cleanup;
1013 1008 #endif
1014 1009 #endif
1015 1010
1016 1011 #ifdef NSE
1017 1012 /* If running inside an activated environment, push the */
1018 1013 /* .nse_depinfo file (if written) */
1019 1014 active = getenv(NSE_VARIANT_ENV);
1020 1015 if (keep_state &&
1021 1016 (active != NULL) &&
1022 1017 !IS_EQUAL(active, NSE_RT_SOURCE_NAME) &&
1023 1018 !do_not_exec_rule &&
1024 1019 (report_dependencies_level == 0)) {
1025 1020 (void) sprintf(push_cmd,
1026 1021 "%s %s/%s",
1027 1022 NSE_TFS_PUSH,
1028 1023 get_current_path(),
1029 1024 NSE_DEPINFO);
1030 1025 (void) system(push_cmd);
1031 1026 }
1032 1027 #endif
1033 1028
1034 1029 /*
1035 1030 #ifdef DISTRIBUTED
1036 1031 }
1037 1032 #endif
1038 1033 */
1039 1034
1040 1035 #if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
1041 1036 job_adjust_fini();
1042 1037 #endif
1043 1038
1044 1039 #ifdef TEAMWARE_MAKE_CMN
1045 1040 catclose(catd);
1046 1041 #endif
1047 1042 #ifdef DISTRIBUTED
1048 1043 if (rxmPid > 0) {
1049 1044 // Tell rxm to exit by sending it an Avo_AcknowledgeMsg
1050 1045 Avo_AcknowledgeMsg acknowledgeMsg;
1051 1046 RWCollectable *msg = (RWCollectable *)&acknowledgeMsg;
1052 1047
1053 1048 int xdrResult = xdr(&xdrs_out, msg);
1054 1049
1055 1050 if (xdrResult) {
1056 1051 fflush(dmake_ofp);
1057 1052 } else {
1058 1053 /*
1059 1054 fatal(catgets(catd, 1, 266, "couldn't tell rxm to exit"));
1060 1055 */
1061 1056 kill(rxmPid, SIGTERM);
1062 1057 }
1063 1058
1064 1059 waitpid(rxmPid, NULL, 0);
1065 1060 rxmPid = 0;
1066 1061 }
1067 1062 #endif
1068 1063 }
1069 1064
1070 1065 /*
1071 1066 * handle_interrupt()
1072 1067 *
1073 1068 * This is where C-C traps are caught.
1074 1069 *
1075 1070 * Parameters:
1076 1071 *
1077 1072 * Global variables used (except DMake 1.0):
1078 1073 * current_target Sometimes the current target is removed
1079 1074 * do_not_exec_rule But not if -n is on
1080 1075 * quest or -q
1081 1076 * running_list List of parallel running processes
1082 1077 * touch Current target is not removed if -t on
1083 1078 */
1084 1079 void
1085 1080 handle_interrupt(int)
1086 1081 {
1087 1082 Property member;
1088 1083 Running rp;
1089 1084
1090 1085 (void) fflush(stdout);
1091 1086 #ifdef DISTRIBUTED
1092 1087 if (rxmPid > 0) {
1093 1088 // Tell rxm to exit by sending it an Avo_AcknowledgeMsg
1094 1089 Avo_AcknowledgeMsg acknowledgeMsg;
1095 1090 RWCollectable *msg = (RWCollectable *)&acknowledgeMsg;
1096 1091
1097 1092 int xdrResult = xdr(&xdrs_out, msg);
1098 1093
1099 1094 if (xdrResult) {
1100 1095 fflush(dmake_ofp);
1101 1096 } else {
1102 1097 kill(rxmPid, SIGTERM);
1103 1098 rxmPid = 0;
1104 1099 }
1105 1100 }
1106 1101 #endif
1107 1102 if (childPid > 0) {
1108 1103 kill(childPid, SIGTERM);
1109 1104 childPid = -1;
1110 1105 }
1111 1106 for (rp = running_list; rp != NULL; rp = rp->next) {
1112 1107 if (rp->state != build_running) {
1113 1108 continue;
1114 1109 }
1115 1110 if (rp->pid > 0) {
1116 1111 kill(rp->pid, SIGTERM);
1117 1112 rp->pid = -1;
1118 1113 }
1119 1114 }
1120 1115 if (getpid() == getpgrp()) {
1121 1116 bsd_signal(SIGTERM, SIG_IGN);
1122 1117 kill (-getpid(), SIGTERM);
1123 1118 }
1124 1119 #ifdef TEAMWARE_MAKE_CMN
1125 1120 /* Clean up all parallel/distributed children already finished */
1126 1121 finish_children(false);
1127 1122 #endif
1128 1123
1129 1124 /* Make sure the processes running under us terminate first */
1130 1125
1131 1126 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
1132 1127 while (wait((int *) NULL) != -1);
1133 1128 #else
1134 1129 while (wait((union wait*) NULL) != -1);
1135 1130 #endif
1136 1131 /* Delete the current targets unless they are precious */
1137 1132 if ((current_target != NULL) &&
1138 1133 current_target->is_member &&
1139 1134 ((member = get_prop(current_target->prop, member_prop)) != NULL)) {
1140 1135 current_target = member->body.member.library;
1141 1136 }
1142 1137 if (!do_not_exec_rule &&
1143 1138 !touch &&
1144 1139 !quest &&
1145 1140 (current_target != NULL) &&
1146 1141 !(current_target->stat.is_precious || all_precious)) {
1147 1142
1148 1143 /* BID_1030811 */
1149 1144 /* azv 16 Oct 95 */
1150 1145 current_target->stat.time = file_no_time;
1151 1146
1152 1147 if (exists(current_target) != file_doesnt_exist) {
1153 1148 (void) fprintf(stderr,
1154 1149 "\n*** %s ",
1155 1150 current_target->string_mb);
1156 1151 if (current_target->stat.is_dir) {
1157 1152 (void) fprintf(stderr,
1158 1153 catgets(catd, 1, 168, "not removed.\n"),
1159 1154 current_target->string_mb);
1160 1155 } else if (unlink(current_target->string_mb) == 0) {
1161 1156 (void) fprintf(stderr,
1162 1157 catgets(catd, 1, 169, "removed.\n"),
1163 1158 current_target->string_mb);
1164 1159 } else {
1165 1160 (void) fprintf(stderr,
1166 1161 catgets(catd, 1, 170, "could not be removed: %s.\n"),
1167 1162 current_target->string_mb,
1168 1163 errmsg(errno));
1169 1164 }
1170 1165 }
1171 1166 }
1172 1167 for (rp = running_list; rp != NULL; rp = rp->next) {
1173 1168 if (rp->state != build_running) {
1174 1169 continue;
1175 1170 }
1176 1171 if (rp->target->is_member &&
1177 1172 ((member = get_prop(rp->target->prop, member_prop)) !=
1178 1173 NULL)) {
1179 1174 rp->target = member->body.member.library;
1180 1175 }
1181 1176 if (!do_not_exec_rule &&
1182 1177 !touch &&
1183 1178 !quest &&
1184 1179 !(rp->target->stat.is_precious || all_precious)) {
1185 1180
1186 1181 rp->target->stat.time = file_no_time;
1187 1182 if (exists(rp->target) != file_doesnt_exist) {
1188 1183 (void) fprintf(stderr,
1189 1184 "\n*** %s ",
1190 1185 rp->target->string_mb);
1191 1186 if (rp->target->stat.is_dir) {
1192 1187 (void) fprintf(stderr,
1193 1188 catgets(catd, 1, 171, "not removed.\n"),
1194 1189 rp->target->string_mb);
1195 1190 } else if (unlink(rp->target->string_mb) == 0) {
1196 1191 (void) fprintf(stderr,
1197 1192 catgets(catd, 1, 172, "removed.\n"),
1198 1193 rp->target->string_mb);
1199 1194 } else {
1200 1195 (void) fprintf(stderr,
1201 1196 catgets(catd, 1, 173, "could not be removed: %s.\n"),
1202 1197 rp->target->string_mb,
1203 1198 errmsg(errno));
1204 1199 }
1205 1200 }
1206 1201 }
1207 1202 }
1208 1203
1209 1204 #ifdef SGE_SUPPORT
1210 1205 /* Remove SGE script file */
1211 1206 if (grid) {
1212 1207 unlink(script_file);
1213 1208 }
1214 1209 #endif
1215 1210
1216 1211 /* Have we locked .make.state or .nse_depinfo? */
1217 1212 if ((make_state_lockfile != NULL) && (make_state_locked)) {
1218 1213 unlink(make_state_lockfile);
1219 1214 make_state_lockfile = NULL;
1220 1215 make_state_locked = false;
1221 1216 }
1222 1217 #ifdef NSE
1223 1218 if ((nse_depinfo_lockfile[0] != '\0') && (nse_depinfo_locked)) {
1224 1219 unlink(nse_depinfo_lockfile);
1225 1220 nse_depinfo_lockfile[0] = '\0';
1226 1221 nse_depinfo_locked = false;
1227 1222 }
1228 1223 #endif
1229 1224 /*
1230 1225 * Re-read .make.state file (it might be changed by recursive make)
1231 1226 */
1232 1227 check_state(NULL);
1233 1228
1234 1229 report_dir_enter_leave(false);
1235 1230
1236 1231 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
1237 1232 exit_status = 2;
1238 1233 #endif
1239 1234 exit(2);
1240 1235 }
1241 1236
1242 1237 /*
1243 1238 * doalarm(sig, ...)
1244 1239 *
1245 1240 * Handle the alarm interrupt but do nothing. Side effect is to
1246 1241 * cause return from wait3.
1247 1242 *
1248 1243 * Parameters:
1249 1244 * sig
1250 1245 *
1251 1246 * Global variables used:
1252 1247 */
1253 1248 /*ARGSUSED*/
1254 1249 static void
1255 1250 doalarm(int)
1256 1251 {
1257 1252 return;
1258 1253 }
1259 1254
1260 1255
1261 1256 /*
1262 1257 * read_command_options(argc, argv)
1263 1258 *
1264 1259 * Scan the cmd line options and process the ones that start with "-"
1265 1260 *
1266 1261 * Return value:
1267 1262 * -M argument, if any
1268 1263 *
1269 1264 * Parameters:
1270 1265 * argc You know what this is
1271 1266 * argv You know what this is
1272 1267 *
1273 1268 * Global variables used:
1274 1269 */
1275 1270 static void
1276 1271 read_command_options(register int argc, register char **argv)
1277 1272 {
1278 1273 register int ch;
1279 1274 int current_optind = 1;
1280 1275 int last_optind_with_double_hyphen = 0;
1281 1276 int last_optind;
1282 1277 int last_current_optind;
1283 1278 register int i;
1284 1279 register int j;
1285 1280 register int k;
1286 1281 register int makefile_next = 0; /*
1287 1282 * flag to note options:
1288 1283 * -c, f, g, j, m, o
1289 1284 */
1290 1285 const char *tptr;
1291 1286 const char *CMD_OPTS;
1292 1287
1293 1288 extern char *optarg;
1294 1289 extern int optind, opterr, optopt;
1295 1290
1296 1291 #define SUNPRO_CMD_OPTS "-~Bbc:Ddef:g:ij:K:kM:m:NnO:o:PpqRrSsTtuVvwx:"
1297 1292
1298 1293 #ifdef TEAMWARE_MAKE_CMN
1299 1294 # define SVR4_CMD_OPTS "-c:ef:g:ij:km:nO:o:pqrsTtVv"
1300 1295 #else
1301 1296 # define SVR4_CMD_OPTS "-ef:iknpqrstV"
1302 1297 #endif
1303 1298
1304 1299 /*
1305 1300 * Added V in SVR4_CMD_OPTS also, which is going to be a hidden
1306 1301 * option, just to make sure that the getopt doesn't fail when some
1307 1302 * users leave their USE_SVR4_MAKE set and try to use the makefiles
1308 1303 * that are designed to issue commands like $(MAKE) -V. Anyway it
1309 1304 * sets the same flag but ensures that getopt doesn't fail.
1310 1305 */
1311 1306
1312 1307 opterr = 0;
1313 1308 optind = 1;
1314 1309 while (1) {
1315 1310 last_optind=optind; /* Save optind and current_optind values */
1316 1311 last_current_optind=current_optind; /* in case we have to repeat this round. */
1317 1312 if (svr4) {
1318 1313 CMD_OPTS=SVR4_CMD_OPTS;
1319 1314 ch = getopt(argc, argv, SVR4_CMD_OPTS);
1320 1315 } else {
1321 1316 CMD_OPTS=SUNPRO_CMD_OPTS;
1322 1317 ch = getopt(argc, argv, SUNPRO_CMD_OPTS);
1323 1318 }
1324 1319 if (ch == EOF) {
1325 1320 if(optind < argc) {
1326 1321 /*
1327 1322 * Fixing bug 4102537:
1328 1323 * Strange behaviour of command make using -- option.
1329 1324 * Not all argv have been processed
1330 1325 * Skip non-flag argv and continue processing.
1331 1326 */
1332 1327 optind++;
1333 1328 current_optind++;
1334 1329 continue;
1335 1330 } else {
1336 1331 break;
1337 1332 }
1338 1333
1339 1334 }
1340 1335 if (ch == '?') {
1341 1336 if (optopt == '-') {
1342 1337 /* Bug 5060758: getopt() changed behavior (s10_60),
1343 1338 * and now we have to deal with cases when options
1344 1339 * with double hyphen appear here, from -$(MAKEFLAGS)
1345 1340 */
1346 1341 i = current_optind;
1347 1342 if (argv[i][0] == '-') {
1348 1343 if (argv[i][1] == '-') {
1349 1344 if (argv[i][2] != '\0') {
1350 1345 /* Check if this option is allowed */
1351 1346 tptr = strchr(CMD_OPTS, argv[i][2]);
1352 1347 if (tptr) {
1353 1348 if (last_optind_with_double_hyphen != current_optind) {
1354 1349 /* This is first time we are trying to fix "--"
1355 1350 * problem with this option. If we come here second
1356 1351 * time, we will go to fatal error.
1357 1352 */
1358 1353 last_optind_with_double_hyphen = current_optind;
1359 1354
1360 1355 /* Eliminate first hyphen character */
1361 1356 for (j=0; argv[i][j] != '\0'; j++) {
1362 1357 argv[i][j] = argv[i][j+1];
1363 1358 }
1364 1359
1365 1360 /* Repeat the processing of this argument */
1366 1361 optind=last_optind;
1367 1362 current_optind=last_current_optind;
1368 1363 continue;
1369 1364 }
1370 1365 }
1371 1366 }
1372 1367 }
1373 1368 }
1374 1369 }
1375 1370 }
1376 1371
1377 1372 if (ch == '?') {
1378 1373 if (svr4) {
1379 1374 #ifdef TEAMWARE_MAKE_CMN
1380 1375 fprintf(stderr,
1381 1376 catgets(catd, 1, 267, "Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ]\n"));
1382 1377 fprintf(stderr,
1383 1378 catgets(catd, 1, 268, " [ -j dmake_max_jobs ][ -m dmake_mode ][ -o dmake_odir ]...\n"));
1384 1379 fprintf(stderr,
1385 1380 catgets(catd, 1, 269, " [ -e ][ -i ][ -k ][ -n ][ -p ][ -q ][ -r ][ -s ][ -t ][ -v ]\n"));
1386 1381 #else
1387 1382 fprintf(stderr,
1388 1383 catgets(catd, 1, 270, "Usage : make [ -f makefile ]... [ -e ][ -i ][ -k ][ -n ][ -p ][ -q ][ -r ]\n"));
1389 1384 fprintf(stderr,
1390 1385 catgets(catd, 1, 271, " [ -s ][ -t ]\n"));
1391 1386 #endif
1392 1387 tptr = strchr(SVR4_CMD_OPTS, optopt);
1393 1388 } else {
1394 1389 #ifdef TEAMWARE_MAKE_CMN
1395 1390 fprintf(stderr,
1396 1391 catgets(catd, 1, 272, "Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ]\n"));
1397 1392 fprintf(stderr,
1398 1393 catgets(catd, 1, 273, " [ -j dmake_max_jobs ][ -K statefile ][ -m dmake_mode ][ -x MODE_NAME=VALUE ][ -o dmake_odir ]...\n"));
1399 1394 fprintf(stderr,
1400 1395 catgets(catd, 1, 274, " [ -d ][ -dd ][ -D ][ -DD ][ -e ][ -i ][ -k ][ -n ][ -p ][ -P ][ -u ][ -w ]\n"));
1401 1396 fprintf(stderr,
1402 1397 catgets(catd, 1, 275, " [ -q ][ -r ][ -s ][ -S ][ -t ][ -v ][ -V ][ target... ][ macro=value... ][ \"macro +=value\"... ]\n"));
1403 1398 #else
1404 1399 fprintf(stderr,
1405 1400 catgets(catd, 1, 276, "Usage : make [ -f makefile ][ -K statefile ]... [ -d ][ -dd ][ -D ][ -DD ]\n"));
1406 1401 fprintf(stderr,
1407 1402 catgets(catd, 1, 277, " [ -e ][ -i ][ -k ][ -n ][ -p ][ -P ][ -q ][ -r ][ -s ][ -S ][ -t ]\n"));
1408 1403 fprintf(stderr,
1409 1404 catgets(catd, 1, 278, " [ -u ][ -w ][ -V ][ target... ][ macro=value... ][ \"macro +=value\"... ]\n"));
1410 1405 #endif
1411 1406 tptr = strchr(SUNPRO_CMD_OPTS, optopt);
1412 1407 }
1413 1408 if (!tptr) {
1414 1409 fatal(catgets(catd, 1, 279, "Unknown option `-%c'"), optopt);
1415 1410 } else {
1416 1411 fatal(catgets(catd, 1, 280, "Missing argument after `-%c'"), optopt);
1417 1412 }
1418 1413 }
1419 1414
1420 1415 #if defined(linux)
1421 1416 if (ch == 1) {
1422 1417 if(optind < argc) {
1423 1418 //optind++;
1424 1419 //current_optind++;
1425 1420 makefile_next = 0;
1426 1421 current_optind = optind;
1427 1422 continue;
1428 1423 } else {
1429 1424 break;
1430 1425 }
1431 1426 }
1432 1427 #endif
1433 1428
1434 1429
1435 1430 makefile_next |= parse_command_option(ch);
1436 1431 /*
1437 1432 * If we're done processing all of the options of
1438 1433 * ONE argument string...
1439 1434 */
1440 1435 if (current_optind < optind) {
1441 1436 i = current_optind;
1442 1437 k = 0;
1443 1438 /* If there's an argument for an option... */
1444 1439 if ((optind - current_optind) > 1) {
1445 1440 k = i + 1;
1446 1441 }
1447 1442 switch (makefile_next) {
1448 1443 case 0:
1449 1444 argv[i] = NULL;
1450 1445 /* This shouldn't happen */
1451 1446 if (k) {
1452 1447 argv[k] = NULL;
1453 1448 }
1454 1449 break;
1455 1450 case 1: /* -f seen */
1456 1451 argv[i] = NOCATGETS("-f");
1457 1452 break;
1458 1453 case 2: /* -c seen */
1459 1454 argv[i] = NOCATGETS("-c");
1460 1455 #ifndef TEAMWARE_MAKE_CMN
1461 1456 warning(catgets(catd, 1, 281, "Ignoring DistributedMake -c option"));
1462 1457 #endif
1463 1458 break;
1464 1459 case 4: /* -g seen */
1465 1460 argv[i] = NOCATGETS("-g");
1466 1461 #ifndef TEAMWARE_MAKE_CMN
1467 1462 warning(catgets(catd, 1, 282, "Ignoring DistributedMake -g option"));
1468 1463 #endif
1469 1464 break;
1470 1465 case 8: /* -j seen */
1471 1466 argv[i] = NOCATGETS("-j");
1472 1467 #ifndef TEAMWARE_MAKE_CMN
1473 1468 warning(catgets(catd, 1, 283, "Ignoring DistributedMake -j option"));
1474 1469 #endif
1475 1470 break;
1476 1471 case 16: /* -M seen */
1477 1472 argv[i] = NOCATGETS("-M");
1478 1473 #ifndef TEAMWARE_MAKE_CMN
1479 1474 warning(catgets(catd, 1, 284, "Ignoring ParallelMake -M option"));
1480 1475 #endif
1481 1476 break;
1482 1477 case 32: /* -m seen */
1483 1478 argv[i] = NOCATGETS("-m");
1484 1479 #ifndef TEAMWARE_MAKE_CMN
1485 1480 warning(catgets(catd, 1, 285, "Ignoring DistributedMake -m option"));
1486 1481 #endif
1487 1482 break;
1488 1483 #ifndef PARALLEL
1489 1484 case 128: /* -O seen */
1490 1485 argv[i] = NOCATGETS("-O");
1491 1486 break;
1492 1487 #endif
1493 1488 case 256: /* -K seen */
1494 1489 argv[i] = NOCATGETS("-K");
1495 1490 break;
1496 1491 case 512: /* -o seen */
1497 1492 argv[i] = NOCATGETS("-o");
1498 1493 #ifndef TEAMWARE_MAKE_CMN
1499 1494 warning(catgets(catd, 1, 311, "Ignoring DistributedMake -o option"));
1500 1495 #endif
1501 1496 break;
1502 1497 case 1024: /* -x seen */
1503 1498 argv[i] = NOCATGETS("-x");
1504 1499 #ifndef TEAMWARE_MAKE_CMN
1505 1500 warning(catgets(catd, 1, 353, "Ignoring DistributedMake -x option"));
1506 1501 #endif
1507 1502 break;
1508 1503 default: /* > 1 of -c, f, g, j, K, M, m, O, o, x seen */
1509 1504 fatal(catgets(catd, 1, 286, "Illegal command line. More than one option requiring\nan argument given in the same argument group"));
1510 1505 }
1511 1506
1512 1507 makefile_next = 0;
1513 1508 current_optind = optind;
1514 1509 }
1515 1510 }
1516 1511 }
1517 1512
1518 1513 static void
1519 1514 quote_str(char *str, char *qstr)
1520 1515 {
1521 1516 char *to;
1522 1517 char *from;
1523 1518
1524 1519 to = qstr;
1525 1520 for (from = str; *from; from++) {
1526 1521 switch (*from) {
1527 1522 case ';': /* End of command */
1528 1523 case '(': /* Start group */
1529 1524 case ')': /* End group */
1530 1525 case '{': /* Start group */
1531 1526 case '}': /* End group */
1532 1527 case '[': /* Reg expr - any of a set of chars */
1533 1528 case ']': /* End of set of chars */
1534 1529 case '|': /* Pipe or logical-or */
1535 1530 case '^': /* Old-fashioned pipe */
1536 1531 case '&': /* Background or logical-and */
1537 1532 case '<': /* Redirect stdin */
1538 1533 case '>': /* Redirect stdout */
1539 1534 case '*': /* Reg expr - any sequence of chars */
1540 1535 case '?': /* Reg expr - any single char */
1541 1536 case '$': /* Variable substitution */
1542 1537 case '\'': /* Singe quote - turn off all magic */
1543 1538 case '"': /* Double quote - span whitespace */
1544 1539 case '`': /* Backquote - run a command */
1545 1540 case '#': /* Comment */
1546 1541 case ' ': /* Space (for MACRO=value1 value2 */
1547 1542 case '\\': /* Escape char - turn off magic of next char */
1548 1543 *to++ = '\\';
1549 1544 break;
1550 1545
1551 1546 default:
1552 1547 break;
1553 1548 }
1554 1549 *to++ = *from;
1555 1550 }
1556 1551 *to = '\0';
1557 1552 }
1558 1553
1559 1554 static void
1560 1555 unquote_str(char *str, char *qstr)
1561 1556 {
1562 1557 char *to;
1563 1558 char *from;
1564 1559
1565 1560 to = qstr;
1566 1561 for (from = str; *from; from++) {
1567 1562 if (*from == '\\') {
1568 1563 from++;
1569 1564 }
1570 1565 *to++ = *from;
1571 1566 }
1572 1567 *to = '\0';
1573 1568 }
1574 1569
1575 1570 /*
1576 1571 * Convert the MAKEFLAGS string value into a vector of char *, similar
1577 1572 * to argv.
1578 1573 */
1579 1574 static void
1580 1575 setup_makeflags_argv()
1581 1576 {
1582 1577 char *cp;
1583 1578 char *cp1;
1584 1579 char *cp2;
1585 1580 char *cp3;
1586 1581 char *cp_orig;
1587 1582 Boolean add_hyphen;
1588 1583 int i;
1589 1584 char tmp_char;
1590 1585
1591 1586 mf_argc = 1;
1592 1587 cp = getenv(makeflags->string_mb);
1593 1588 cp_orig = cp;
1594 1589
1595 1590 if (cp) {
1596 1591 /*
1597 1592 * If new MAKEFLAGS format, no need to add hyphen.
1598 1593 * If old MAKEFLAGS format, add hyphen before flags.
1599 1594 */
1600 1595
1601 1596 if ((strchr(cp, (int) hyphen_char) != NULL) ||
1602 1597 (strchr(cp, (int) equal_char) != NULL)) {
1603 1598
1604 1599 /* New MAKEFLAGS format */
1605 1600
1606 1601 add_hyphen = false;
1607 1602 #ifdef ADDFIX5060758
1608 1603 /* Check if MAKEFLAGS value begins with multiple
1609 1604 * hyphen characters, and remove all duplicates.
1610 1605 * Usually it happens when the next command is
1611 1606 * used: $(MAKE) -$(MAKEFLAGS)
1612 1607 * This is a workaround for BugID 5060758.
1613 1608 */
1614 1609 while (*cp) {
1615 1610 if (*cp != (int) hyphen_char) {
1616 1611 break;
1617 1612 }
1618 1613 cp++;
1619 1614 if (*cp == (int) hyphen_char) {
1620 1615 /* There are two hyphens. Skip one */
1621 1616 cp_orig = cp;
1622 1617 cp++;
1623 1618 }
1624 1619 if (!(*cp)) {
1625 1620 /* There are hyphens only. Skip all */
1626 1621 cp_orig = cp;
1627 1622 break;
1628 1623 }
1629 1624 }
1630 1625 #endif
1631 1626 } else {
1632 1627
1633 1628 /* Old MAKEFLAGS format */
1634 1629
1635 1630 add_hyphen = true;
1636 1631 }
1637 1632 }
1638 1633
1639 1634 /* Find the number of arguments in MAKEFLAGS */
1640 1635 while (cp && *cp) {
1641 1636 /* Skip white spaces */
1642 1637 while (cp && *cp && isspace(*cp)) {
1643 1638 cp++;
1644 1639 }
1645 1640 if (cp && *cp) {
1646 1641 /* Increment arg count */
1647 1642 mf_argc++;
1648 1643 /* Go to next white space */
1649 1644 while (cp && *cp && !isspace(*cp)) {
1650 1645 if(*cp == (int) backslash_char) {
1651 1646 cp++;
1652 1647 }
1653 1648 cp++;
1654 1649 }
1655 1650 }
1656 1651 }
1657 1652 /* Allocate memory for the new MAKEFLAGS argv */
1658 1653 mf_argv = (char **) malloc((mf_argc + 1) * sizeof(char *));
1659 1654 mf_argv[0] = NOCATGETS("MAKEFLAGS");
1660 1655 /*
1661 1656 * Convert the MAKEFLAGS string value into a vector of char *,
1662 1657 * similar to argv.
1663 1658 */
1664 1659 cp = cp_orig;
1665 1660 for (i = 1; i < mf_argc; i++) {
1666 1661 /* Skip white spaces */
1667 1662 while (cp && *cp && isspace(*cp)) {
1668 1663 cp++;
1669 1664 }
1670 1665 if (cp && *cp) {
1671 1666 cp_orig = cp;
1672 1667 /* Go to next white space */
1673 1668 while (cp && *cp && !isspace(*cp)) {
1674 1669 if(*cp == (int) backslash_char) {
1675 1670 cp++;
1676 1671 }
1677 1672 cp++;
1678 1673 }
1679 1674 tmp_char = *cp;
1680 1675 *cp = (int) nul_char;
1681 1676 if (add_hyphen) {
1682 1677 mf_argv[i] = getmem(2 + strlen(cp_orig));
1683 1678 mf_argv[i][0] = '\0';
1684 1679 (void) strcat(mf_argv[i], "-");
1685 1680 // (void) strcat(mf_argv[i], cp_orig);
1686 1681 unquote_str(cp_orig, mf_argv[i]+1);
1687 1682 } else {
1688 1683 mf_argv[i] = getmem(2 + strlen(cp_orig));
1689 1684 //mf_argv[i] = strdup(cp_orig);
1690 1685 unquote_str(cp_orig, mf_argv[i]);
1691 1686 }
1692 1687 *cp = tmp_char;
1693 1688 }
1694 1689 }
1695 1690 mf_argv[i] = NULL;
1696 1691 }
1697 1692
1698 1693 /*
1699 1694 * parse_command_option(ch)
1700 1695 *
1701 1696 * Parse make command line options.
1702 1697 *
1703 1698 * Return value:
1704 1699 * Indicates if any -f -c or -M were seen
1705 1700 *
1706 1701 * Parameters:
1707 1702 * ch The character to parse
1708 1703 *
1709 1704 * Static variables used:
1710 1705 * dmake_group_specified Set for make -g
1711 1706 * dmake_max_jobs_specified Set for make -j
1712 1707 * dmake_mode_specified Set for make -m
1713 1708 * dmake_add_mode_specified Set for make -x
1714 1709 * dmake_compat_mode_specified Set for make -x SUN_MAKE_COMPAT_MODE=
1715 1710 * dmake_output_mode_specified Set for make -x DMAKE_OUTPUT_MODE=
1716 1711 * dmake_odir_specified Set for make -o
1717 1712 * dmake_rcfile_specified Set for make -c
1718 1713 * env_wins Set for make -e
1719 1714 * ignore_default_mk Set for make -r
1720 1715 * trace_status Set for make -p
1721 1716 *
1722 1717 * Global variables used:
1723 1718 * .make.state path & name set for make -K
1724 1719 * continue_after_error Set for make -k
1725 1720 * debug_level Set for make -d
1726 1721 * do_not_exec_rule Set for make -n
1727 1722 * filter_stderr Set for make -X
1728 1723 * ignore_errors_all Set for make -i
1729 1724 * no_parallel Set for make -R
1730 1725 * quest Set for make -q
1731 1726 * read_trace_level Set for make -D
1732 1727 * report_dependencies Set for make -P
1733 1728 * send_mtool_msgs Set for make -K
1734 1729 * silent_all Set for make -s
1735 1730 * touch Set for make -t
1736 1731 */
1737 1732 static int
1738 1733 parse_command_option(register char ch)
1739 1734 {
1740 1735 static int invert_next = 0;
1741 1736 int invert_this = invert_next;
1742 1737
1743 1738 invert_next = 0;
1744 1739 switch (ch) {
1745 1740 case '-': /* Ignore "--" */
1746 1741 return 0;
1747 1742 case '~': /* Invert next option */
1748 1743 invert_next = 1;
1749 1744 return 0;
1750 1745 case 'B': /* Obsolete */
1751 1746 return 0;
1752 1747 case 'b': /* Obsolete */
1753 1748 return 0;
1754 1749 case 'c': /* Read alternative dmakerc file */
1755 1750 if (invert_this) {
1756 1751 dmake_rcfile_specified = false;
1757 1752 } else {
1758 1753 dmake_rcfile_specified = true;
1759 1754 }
1760 1755 return 2;
1761 1756 case 'D': /* Show lines read */
1762 1757 if (invert_this) {
1763 1758 read_trace_level--;
1764 1759 } else {
1765 1760 read_trace_level++;
1766 1761 }
1767 1762 return 0;
1768 1763 case 'd': /* Debug flag */
1769 1764 if (invert_this) {
1770 1765 debug_level--;
1771 1766 } else {
1772 1767 #if defined( HP_UX) || defined(linux)
1773 1768 if (debug_level < 2) /* Fixes a bug on HP-UX */
1774 1769 #endif
1775 1770 debug_level++;
1776 1771 }
1777 1772 return 0;
1778 1773 #ifdef NSE
1779 1774 case 'E':
1780 1775 if (invert_this) {
1781 1776 nse = false;
1782 1777 } else {
1783 1778 nse = true;
1784 1779 }
1785 1780 nse_init_source_suffixes();
1786 1781 return 0;
1787 1782 #endif
1788 1783 case 'e': /* Environment override flag */
1789 1784 if (invert_this) {
1790 1785 env_wins = false;
1791 1786 } else {
1792 1787 env_wins = true;
1793 1788 }
1794 1789 return 0;
1795 1790 case 'f': /* Read alternative makefile(s) */
1796 1791 return 1;
1797 1792 case 'g': /* Use alternative DMake group */
1798 1793 if (invert_this) {
1799 1794 dmake_group_specified = false;
1800 1795 } else {
1801 1796 dmake_group_specified = true;
1802 1797 }
1803 1798 return 4;
1804 1799 case 'i': /* Ignore errors */
1805 1800 if (invert_this) {
1806 1801 ignore_errors_all = false;
1807 1802 } else {
1808 1803 ignore_errors_all = true;
1809 1804 }
1810 1805 return 0;
1811 1806 case 'j': /* Use alternative DMake max jobs */
1812 1807 if (invert_this) {
1813 1808 dmake_max_jobs_specified = false;
1814 1809 } else {
1815 1810 dmake_max_jobs_specified = true;
1816 1811 }
1817 1812 return 8;
1818 1813 case 'K': /* Read alternative .make.state */
1819 1814 return 256;
1820 1815 case 'k': /* Keep making even after errors */
1821 1816 if (invert_this) {
1822 1817 continue_after_error = false;
1823 1818 } else {
1824 1819 continue_after_error = true;
1825 1820 continue_after_error_ever_seen = true;
1826 1821 }
1827 1822 return 0;
1828 1823 case 'M': /* Read alternative make.machines file */
1829 1824 if (invert_this) {
1830 1825 pmake_machinesfile_specified = false;
1831 1826 } else {
1832 1827 pmake_machinesfile_specified = true;
1833 1828 dmake_mode_type = parallel_mode;
1834 1829 no_parallel = false;
1835 1830 }
1836 1831 return 16;
1837 1832 case 'm': /* Use alternative DMake build mode */
1838 1833 if (invert_this) {
1839 1834 dmake_mode_specified = false;
1840 1835 } else {
1841 1836 dmake_mode_specified = true;
1842 1837 }
1843 1838 return 32;
1844 1839 case 'x': /* Use alternative DMake mode */
1845 1840 if (invert_this) {
1846 1841 dmake_add_mode_specified = false;
1847 1842 } else {
1848 1843 dmake_add_mode_specified = true;
1849 1844 }
1850 1845 return 1024;
1851 1846 case 'N': /* Reverse -n */
1852 1847 if (invert_this) {
1853 1848 do_not_exec_rule = true;
1854 1849 } else {
1855 1850 do_not_exec_rule = false;
1856 1851 }
1857 1852 return 0;
1858 1853 case 'n': /* Print, not exec commands */
1859 1854 if (invert_this) {
1860 1855 do_not_exec_rule = false;
1861 1856 } else {
1862 1857 do_not_exec_rule = true;
1863 1858 }
1864 1859 return 0;
1865 1860 #ifndef PARALLEL
1866 1861 case 'O': /* Send job start & result msgs */
1867 1862 if (invert_this) {
1868 1863 send_mtool_msgs = false;
1869 1864 } else {
1870 1865 #ifdef DISTRIBUTED
1871 1866 send_mtool_msgs = true;
1872 1867 #endif
1873 1868 }
1874 1869 return 128;
1875 1870 #endif
1876 1871 case 'o': /* Use alternative dmake output dir */
1877 1872 if (invert_this) {
1878 1873 dmake_odir_specified = false;
1879 1874 } else {
1880 1875 dmake_odir_specified = true;
1881 1876 }
1882 1877 return 512;
1883 1878 case 'P': /* Print for selected targets */
1884 1879 if (invert_this) {
1885 1880 report_dependencies_level--;
1886 1881 } else {
1887 1882 report_dependencies_level++;
1888 1883 }
1889 1884 return 0;
1890 1885 case 'p': /* Print description */
1891 1886 if (invert_this) {
1892 1887 trace_status = false;
1893 1888 do_not_exec_rule = false;
1894 1889 } else {
1895 1890 trace_status = true;
1896 1891 do_not_exec_rule = true;
1897 1892 }
1898 1893 return 0;
1899 1894 case 'q': /* Question flag */
1900 1895 if (invert_this) {
1901 1896 quest = false;
1902 1897 } else {
1903 1898 quest = true;
1904 1899 }
1905 1900 return 0;
1906 1901 case 'R': /* Don't run in parallel */
1907 1902 #ifdef TEAMWARE_MAKE_CMN
1908 1903 if (invert_this) {
1909 1904 pmake_cap_r_specified = false;
1910 1905 no_parallel = false;
1911 1906 } else {
1912 1907 pmake_cap_r_specified = true;
1913 1908 dmake_mode_type = serial_mode;
1914 1909 no_parallel = true;
1915 1910 }
1916 1911 #else
1917 1912 warning(catgets(catd, 1, 182, "Ignoring ParallelMake -R option"));
1918 1913 #endif
1919 1914 return 0;
1920 1915 case 'r': /* Turn off internal rules */
1921 1916 if (invert_this) {
1922 1917 ignore_default_mk = false;
1923 1918 } else {
1924 1919 ignore_default_mk = true;
1925 1920 }
1926 1921 return 0;
1927 1922 case 'S': /* Reverse -k */
1928 1923 if (invert_this) {
1929 1924 continue_after_error = true;
1930 1925 } else {
1931 1926 continue_after_error = false;
1932 1927 stop_after_error_ever_seen = true;
1933 1928 }
1934 1929 return 0;
1935 1930 case 's': /* Silent flag */
1936 1931 if (invert_this) {
1937 1932 silent_all = false;
1938 1933 } else {
1939 1934 silent_all = true;
1940 1935 }
1941 1936 return 0;
1942 1937 case 'T': /* Print target list */
1943 1938 if (invert_this) {
1944 1939 list_all_targets = false;
1945 1940 do_not_exec_rule = false;
1946 1941 } else {
1947 1942 list_all_targets = true;
1948 1943 do_not_exec_rule = true;
1949 1944 }
1950 1945 return 0;
1951 1946 case 't': /* Touch flag */
1952 1947 if (invert_this) {
1953 1948 touch = false;
1954 1949 } else {
1955 1950 touch = true;
1956 1951 }
1957 1952 return 0;
1958 1953 case 'u': /* Unconditional flag */
1959 1954 if (invert_this) {
1960 1955 build_unconditional = false;
1961 1956 } else {
1962 1957 build_unconditional = true;
1963 1958 }
1964 1959 return 0;
1965 1960 case 'V': /* SVR4 mode */
1966 1961 svr4 = true;
1967 1962 return 0;
1968 1963 case 'v': /* Version flag */
1969 1964 if (invert_this) {
1970 1965 } else {
1971 1966 #ifdef TEAMWARE_MAKE_CMN
1972 1967 fprintf(stdout, NOCATGETS("dmake: %s\n"), verstring);
1973 1968 #ifdef SUN5_0
1974 1969 exit_status = 0;
1975 1970 #endif
1976 1971 exit(0);
1977 1972 #else
1978 1973 warning(catgets(catd, 1, 324, "Ignoring DistributedMake -v option"));
1979 1974 #endif
1980 1975 }
1981 1976 return 0;
1982 1977 case 'w': /* Unconditional flag */
1983 1978 if (invert_this) {
1984 1979 report_cwd = false;
1985 1980 } else {
1986 1981 report_cwd = true;
1987 1982 }
1988 1983 return 0;
1989 1984 #if 0
1990 1985 case 'X': /* Filter stdout */
1991 1986 if (invert_this) {
1992 1987 filter_stderr = false;
1993 1988 } else {
1994 1989 filter_stderr = true;
1995 1990 }
1996 1991 return 0;
1997 1992 #endif
1998 1993 default:
1999 1994 break;
2000 1995 }
2001 1996 return 0;
2002 1997 }
2003 1998
2004 1999 /*
2005 2000 * setup_for_projectdir()
2006 2001 *
2007 2002 * Read the PROJECTDIR variable, if defined, and set the sccs path
2008 2003 *
2009 2004 * Parameters:
2010 2005 *
2011 2006 * Global variables used:
2012 2007 * sccs_dir_path Set to point to SCCS dir to use
2013 2008 */
2014 2009 static void
2015 2010 setup_for_projectdir(void)
2016 2011 {
2017 2012 static char path[MAXPATHLEN];
2018 2013 char cwdpath[MAXPATHLEN];
2019 2014 uid_t uid;
2020 2015 int done=0;
2021 2016
2022 2017 /* Check if we should use PROJECTDIR when reading the SCCS dir. */
2023 2018 sccs_dir_path = getenv(NOCATGETS("PROJECTDIR"));
2024 2019 if ((sccs_dir_path != NULL) &&
2025 2020 (sccs_dir_path[0] != (int) slash_char)) {
2026 2021 struct passwd *pwent;
2027 2022
2028 2023 {
2029 2024 uid = getuid();
2030 2025 pwent = getpwuid(uid);
2031 2026 if (pwent == NULL) {
2032 2027 fatal(catgets(catd, 1, 188, "Bogus USERID "));
2033 2028 }
2034 2029 if ((pwent = getpwnam(sccs_dir_path)) == NULL) {
2035 2030 /*empty block : it'll go & check cwd */
2036 2031 }
2037 2032 else {
2038 2033 (void) sprintf(path, NOCATGETS("%s/src"), pwent->pw_dir);
2039 2034 if (access(path, F_OK) == 0) {
2040 2035 sccs_dir_path = path;
2041 2036 done = 1;
2042 2037 } else {
2043 2038 (void) sprintf(path, NOCATGETS("%s/source"), pwent->pw_dir);
2044 2039 if (access(path, F_OK) == 0) {
2045 2040 sccs_dir_path = path;
2046 2041 done = 1;
2047 2042 }
2048 2043 }
2049 2044 }
2050 2045 if (!done) {
2051 2046 if (getcwd(cwdpath, MAXPATHLEN - 1 )) {
2052 2047
2053 2048 (void) sprintf(path, NOCATGETS("%s/%s"), cwdpath,sccs_dir_path);
2054 2049 if (access(path, F_OK) == 0) {
2055 2050 sccs_dir_path = path;
2056 2051 done = 1;
2057 2052 } else {
2058 2053 fatal(catgets(catd, 1, 189, "Bogus PROJECTDIR '%s'"), sccs_dir_path);
2059 2054 }
2060 2055 }
2061 2056 }
2062 2057 }
2063 2058 }
2064 2059 }
2065 2060
2066 2061 /*
2067 2062 * set_sgs_support()
2068 2063 *
2069 2064 * Add the libmakestate.so.1 lib to the env var SGS_SUPPORT
2070 2065 * if it's not already in there.
2071 2066 * The SGS_SUPPORT env var and libmakestate.so.1 is used by
2072 2067 * the linker ld to report .make.state info back to make.
2073 2068 */
2074 2069 static void
2075 2070 set_sgs_support()
2076 2071 {
2077 2072 int len;
2078 2073 char *newpath;
2079 2074 char *oldpath;
2080 2075 static char *prev_path;
2081 2076
2082 2077 oldpath = getenv(LD_SUPPORT_ENV_VAR);
2083 2078 if (oldpath == NULL) {
2084 2079 len = strlen(LD_SUPPORT_ENV_VAR) + 1 +
2085 2080 strlen(LD_SUPPORT_MAKE_LIB) + 1;
2086 2081 newpath = (char *) malloc(len);
2087 2082 sprintf(newpath, "%s=", LD_SUPPORT_ENV_VAR);
2088 2083 } else {
2089 2084 len = strlen(LD_SUPPORT_ENV_VAR) + 1 + strlen(oldpath) + 1 +
2090 2085 strlen(LD_SUPPORT_MAKE_LIB) + 1;
2091 2086 newpath = (char *) malloc(len);
2092 2087 sprintf(newpath, "%s=%s", LD_SUPPORT_ENV_VAR, oldpath);
2093 2088 }
2094 2089
2095 2090 #if defined(TEAMWARE_MAKE_CMN)
2096 2091
2097 2092 /* function maybe_append_str_to_env_var() is defined in avo_util library
2098 2093 * Serial make should not use this library !!!
2099 2094 */
2100 2095 maybe_append_str_to_env_var(newpath, LD_SUPPORT_MAKE_LIB);
2101 2096 #else
2102 2097 if (oldpath == NULL) {
2103 2098 sprintf(newpath, "%s%s", newpath, LD_SUPPORT_MAKE_LIB);
2104 2099 } else {
2105 2100 sprintf(newpath, "%s:%s", newpath, LD_SUPPORT_MAKE_LIB);
2106 2101 }
2107 2102 #endif
2108 2103 putenv(newpath);
2109 2104 if (prev_path) {
2110 2105 free(prev_path);
2111 2106 }
2112 2107 prev_path = newpath;
2113 2108 }
2114 2109
2115 2110 /*
2116 2111 * read_files_and_state(argc, argv)
2117 2112 *
2118 2113 * Read the makefiles we care about and the environment
2119 2114 * Also read the = style command line options
2120 2115 *
2121 2116 * Parameters:
2122 2117 * argc You know what this is
2123 2118 * argv You know what this is
2124 2119 *
2125 2120 * Static variables used:
2126 2121 * env_wins make -e, determines if env vars are RO
2127 2122 * ignore_default_mk make -r, determines if make.rules is read
2128 2123 * not_auto_depen dwight
2129 2124 *
2130 2125 * Global variables used:
2131 2126 * default_target_to_build Set to first proper target from file
2132 2127 * do_not_exec_rule Set to false when makfile is made
2133 2128 * dot The Name ".", used to read current dir
2134 2129 * empty_name The Name "", use as macro value
2135 2130 * keep_state Set if KEEP_STATE is in environment
2136 2131 * make_state The Name ".make.state", used to read file
2137 2132 * makefile_type Set to type of file being read
2138 2133 * makeflags The Name "MAKEFLAGS", used to set macro value
2139 2134 * not_auto dwight
2140 2135 * nse Set if NSE_ENV is in the environment
2141 2136 * read_trace_level Checked to se if the reader should trace
2142 2137 * report_dependencies If -P is on we do not read .make.state
2143 2138 * trace_reader Set if reader should trace
2144 2139 * virtual_root The Name "VIRTUAL_ROOT", used to check value
2145 2140 */
2146 2141 static void
2147 2142 read_files_and_state(int argc, char **argv)
2148 2143 {
2149 2144 wchar_t buffer[1000];
2150 2145 wchar_t buffer_posix[1000];
2151 2146 register char ch;
2152 2147 register char *cp;
2153 2148 Property def_make_macro = NULL;
2154 2149 Name def_make_name;
2155 2150 Name default_makefile;
2156 2151 String_rec dest;
2157 2152 wchar_t destbuffer[STRING_BUFFER_LENGTH];
2158 2153 register int i;
2159 2154 register int j;
2160 2155 Name keep_state_name;
2161 2156 int length;
2162 2157 Name Makefile;
2163 2158 register Property macro;
2164 2159 struct stat make_state_stat;
2165 2160 Name makefile_name;
2166 2161 register int makefile_next = 0;
2167 2162 register Boolean makefile_read = false;
2168 2163 String_rec makeflags_string;
2169 2164 String_rec makeflags_string_posix;
2170 2165 String_rec * makeflags_string_current;
2171 2166 Name makeflags_value_saved;
2172 2167 register Name name;
2173 2168 Name new_make_value;
2174 2169 Boolean save_do_not_exec_rule;
2175 2170 Name sdotMakefile;
2176 2171 Name sdotmakefile_name;
2177 2172 static wchar_t state_file_str;
2178 2173 static char state_file_str_mb[MAXPATHLEN];
2179 2174 static struct _Name state_filename;
2180 2175 Boolean temp;
2181 2176 char tmp_char;
2182 2177 wchar_t *tmp_wcs_buffer;
2183 2178 register Name value;
2184 2179 ASCII_Dyn_Array makeflags_and_macro;
2185 2180 Boolean is_xpg4;
2186 2181
2187 2182 /*
2188 2183 * Remember current mode. It may be changed after reading makefile
2189 2184 * and we will have to correct MAKEFLAGS variable.
2190 2185 */
2191 2186 is_xpg4 = posix;
2192 2187
2193 2188 MBSTOWCS(wcs_buffer, NOCATGETS("KEEP_STATE"));
2194 2189 keep_state_name = GETNAME(wcs_buffer, FIND_LENGTH);
2195 2190 MBSTOWCS(wcs_buffer, NOCATGETS("Makefile"));
2196 2191 Makefile = GETNAME(wcs_buffer, FIND_LENGTH);
2197 2192 MBSTOWCS(wcs_buffer, NOCATGETS("makefile"));
2198 2193 makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
2199 2194 MBSTOWCS(wcs_buffer, NOCATGETS("s.makefile"));
2200 2195 sdotmakefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
2201 2196 MBSTOWCS(wcs_buffer, NOCATGETS("s.Makefile"));
2202 2197 sdotMakefile = GETNAME(wcs_buffer, FIND_LENGTH);
2203 2198
2204 2199 /*
2205 2200 * Set flag if NSE is active
2206 2201 */
2207 2202 #ifdef NSE
2208 2203 if (getenv(NOCATGETS("NSE_ENV")) != NULL) {
2209 2204 nse = true;
2210 2205 }
2211 2206 #endif
2212 2207
2213 2208 /*
2214 2209 * initialize global dependency entry for .NOT_AUTO
2215 2210 */
2216 2211 not_auto_depen->next = NULL;
2217 2212 not_auto_depen->name = not_auto;
2218 2213 not_auto_depen->automatic = not_auto_depen->stale = false;
2219 2214
2220 2215 /*
2221 2216 * Read internal definitions and rules.
2222 2217 */
2223 2218 if (read_trace_level > 1) {
2224 2219 trace_reader = true;
2225 2220 }
2226 2221 if (!ignore_default_mk) {
2227 2222 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
2228 2223 if (svr4) {
2229 2224 MBSTOWCS(wcs_buffer, NOCATGETS("svr4.make.rules"));
2230 2225 default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
2231 2226 } else {
2232 2227 MBSTOWCS(wcs_buffer, NOCATGETS("make.rules"));
2233 2228 default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
2234 2229 }
2235 2230 #else
2236 2231 MBSTOWCS(wcs_buffer, NOCATGETS("default.mk"));
2237 2232 default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
2238 2233 #endif
2239 2234 default_makefile->stat.is_file = true;
2240 2235
2241 2236 (void) read_makefile(default_makefile,
2242 2237 true,
2243 2238 false,
2244 2239 true);
2245 2240 }
2246 2241
2247 2242 /*
2248 2243 * If the user did not redefine the MAKE macro in the
2249 2244 * default makefile (make.rules), then we'd like to
2250 2245 * change the macro value of MAKE to be some form
2251 2246 * of argv[0] for recursive MAKE builds.
2252 2247 */
2253 2248 MBSTOWCS(wcs_buffer, NOCATGETS("MAKE"));
2254 2249 def_make_name = GETNAME(wcs_buffer, wslen(wcs_buffer));
2255 2250 def_make_macro = get_prop(def_make_name->prop, macro_prop);
2256 2251 if ((def_make_macro != NULL) &&
2257 2252 (IS_EQUAL(def_make_macro->body.macro.value->string_mb,
2258 2253 NOCATGETS("make")))) {
2259 2254 MBSTOWCS(wcs_buffer, argv_zero_string);
2260 2255 new_make_value = GETNAME(wcs_buffer, wslen(wcs_buffer));
2261 2256 (void) SETVAR(def_make_name,
2262 2257 new_make_value,
2263 2258 false);
2264 2259 }
2265 2260
2266 2261 default_target_to_build = NULL;
2267 2262 trace_reader = false;
2268 2263
2269 2264 /*
2270 2265 * Read environment args. Let file args which follow override unless
2271 2266 * -e option seen. If -e option is not mentioned.
2272 2267 */
2273 2268 read_environment(env_wins);
2274 2269 if (getvar(virtual_root)->hash.length == 0) {
2275 2270 maybe_append_prop(virtual_root, macro_prop)
2276 2271 ->body.macro.exported = true;
2277 2272 MBSTOWCS(wcs_buffer, "/");
2278 2273 (void) SETVAR(virtual_root,
2279 2274 GETNAME(wcs_buffer, FIND_LENGTH),
2280 2275 false);
2281 2276 }
2282 2277
2283 2278 /*
2284 2279 * We now scan mf_argv and argv to see if we need to set
2285 2280 * any of the DMake-added options/variables in MAKEFLAGS.
2286 2281 */
2287 2282
2288 2283 makeflags_and_macro.start = 0;
2289 2284 makeflags_and_macro.size = 0;
2290 2285 enter_argv_values(mf_argc, mf_argv, &makeflags_and_macro);
2291 2286 enter_argv_values(argc, argv, &makeflags_and_macro);
2292 2287
2293 2288 /*
2294 2289 * Set MFLAGS and MAKEFLAGS
2295 2290 *
2296 2291 * Before reading makefile we do not know exactly which mode
2297 2292 * (posix or not) is used. So prepare two MAKEFLAGS strings
2298 2293 * for both posix and solaris modes because they are different.
2299 2294 */
2300 2295 INIT_STRING_FROM_STACK(makeflags_string, buffer);
2301 2296 INIT_STRING_FROM_STACK(makeflags_string_posix, buffer_posix);
2302 2297 append_char((int) hyphen_char, &makeflags_string);
2303 2298 append_char((int) hyphen_char, &makeflags_string_posix);
2304 2299
2305 2300 switch (read_trace_level) {
2306 2301 case 2:
2307 2302 append_char('D', &makeflags_string);
2308 2303 append_char('D', &makeflags_string_posix);
2309 2304 case 1:
2310 2305 append_char('D', &makeflags_string);
2311 2306 append_char('D', &makeflags_string_posix);
2312 2307 }
2313 2308 switch (debug_level) {
2314 2309 case 2:
2315 2310 append_char('d', &makeflags_string);
2316 2311 append_char('d', &makeflags_string_posix);
2317 2312 case 1:
2318 2313 append_char('d', &makeflags_string);
2319 2314 append_char('d', &makeflags_string_posix);
2320 2315 }
2321 2316 #ifdef NSE
2322 2317 if (nse) {
2323 2318 append_char('E', &makeflags_string);
2324 2319 }
2325 2320 #endif
2326 2321 if (env_wins) {
2327 2322 append_char('e', &makeflags_string);
2328 2323 append_char('e', &makeflags_string_posix);
2329 2324 }
2330 2325 if (ignore_errors_all) {
2331 2326 append_char('i', &makeflags_string);
2332 2327 append_char('i', &makeflags_string_posix);
2333 2328 }
2334 2329 if (continue_after_error) {
2335 2330 if (stop_after_error_ever_seen) {
2336 2331 append_char('S', &makeflags_string_posix);
2337 2332 append_char((int) space_char, &makeflags_string_posix);
2338 2333 append_char((int) hyphen_char, &makeflags_string_posix);
2339 2334 }
2340 2335 append_char('k', &makeflags_string);
2341 2336 append_char('k', &makeflags_string_posix);
2342 2337 } else {
2343 2338 if (stop_after_error_ever_seen
2344 2339 && continue_after_error_ever_seen) {
2345 2340 append_char('k', &makeflags_string_posix);
2346 2341 append_char((int) space_char, &makeflags_string_posix);
2347 2342 append_char((int) hyphen_char, &makeflags_string_posix);
2348 2343 append_char('S', &makeflags_string_posix);
2349 2344 }
2350 2345 }
2351 2346 if (do_not_exec_rule) {
2352 2347 append_char('n', &makeflags_string);
2353 2348 append_char('n', &makeflags_string_posix);
2354 2349 }
2355 2350 switch (report_dependencies_level) {
2356 2351 case 4:
2357 2352 append_char('P', &makeflags_string);
2358 2353 append_char('P', &makeflags_string_posix);
2359 2354 case 3:
2360 2355 append_char('P', &makeflags_string);
2361 2356 append_char('P', &makeflags_string_posix);
2362 2357 case 2:
2363 2358 append_char('P', &makeflags_string);
2364 2359 append_char('P', &makeflags_string_posix);
2365 2360 case 1:
2366 2361 append_char('P', &makeflags_string);
2367 2362 append_char('P', &makeflags_string_posix);
2368 2363 }
2369 2364 if (trace_status) {
2370 2365 append_char('p', &makeflags_string);
2371 2366 append_char('p', &makeflags_string_posix);
2372 2367 }
2373 2368 if (quest) {
2374 2369 append_char('q', &makeflags_string);
2375 2370 append_char('q', &makeflags_string_posix);
2376 2371 }
2377 2372 if (silent_all) {
2378 2373 append_char('s', &makeflags_string);
2379 2374 append_char('s', &makeflags_string_posix);
2380 2375 }
2381 2376 if (touch) {
2382 2377 append_char('t', &makeflags_string);
2383 2378 append_char('t', &makeflags_string_posix);
2384 2379 }
2385 2380 if (build_unconditional) {
2386 2381 append_char('u', &makeflags_string);
2387 2382 append_char('u', &makeflags_string_posix);
2388 2383 }
2389 2384 if (report_cwd) {
2390 2385 append_char('w', &makeflags_string);
2391 2386 append_char('w', &makeflags_string_posix);
2392 2387 }
2393 2388 #ifndef PARALLEL
2394 2389 /* -c dmake_rcfile */
2395 2390 if (dmake_rcfile_specified) {
2396 2391 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
2397 2392 dmake_rcfile = GETNAME(wcs_buffer, FIND_LENGTH);
2398 2393 append_makeflags_string(dmake_rcfile, &makeflags_string);
2399 2394 append_makeflags_string(dmake_rcfile, &makeflags_string_posix);
2400 2395 }
2401 2396 /* -g dmake_group */
2402 2397 if (dmake_group_specified) {
2403 2398 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
2404 2399 dmake_group = GETNAME(wcs_buffer, FIND_LENGTH);
2405 2400 append_makeflags_string(dmake_group, &makeflags_string);
2406 2401 append_makeflags_string(dmake_group, &makeflags_string_posix);
2407 2402 }
2408 2403 /* -j dmake_max_jobs */
2409 2404 if (dmake_max_jobs_specified) {
2410 2405 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
2411 2406 dmake_max_jobs = GETNAME(wcs_buffer, FIND_LENGTH);
2412 2407 append_makeflags_string(dmake_max_jobs, &makeflags_string);
2413 2408 append_makeflags_string(dmake_max_jobs, &makeflags_string_posix);
2414 2409 }
2415 2410 /* -m dmake_mode */
2416 2411 if (dmake_mode_specified) {
2417 2412 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
2418 2413 dmake_mode = GETNAME(wcs_buffer, FIND_LENGTH);
2419 2414 append_makeflags_string(dmake_mode, &makeflags_string);
2420 2415 append_makeflags_string(dmake_mode, &makeflags_string_posix);
2421 2416 }
2422 2417 /* -x dmake_compat_mode */
2423 2418 // if (dmake_compat_mode_specified) {
2424 2419 // MBSTOWCS(wcs_buffer, NOCATGETS("SUN_MAKE_COMPAT_MODE"));
2425 2420 // dmake_compat_mode = GETNAME(wcs_buffer, FIND_LENGTH);
2426 2421 // append_makeflags_string(dmake_compat_mode, &makeflags_string);
2427 2422 // append_makeflags_string(dmake_compat_mode, &makeflags_string_posix);
2428 2423 // }
2429 2424 /* -x dmake_output_mode */
2430 2425 if (dmake_output_mode_specified) {
2431 2426 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
2432 2427 dmake_output_mode = GETNAME(wcs_buffer, FIND_LENGTH);
2433 2428 append_makeflags_string(dmake_output_mode, &makeflags_string);
2434 2429 append_makeflags_string(dmake_output_mode, &makeflags_string_posix);
2435 2430 }
2436 2431 /* -o dmake_odir */
2437 2432 if (dmake_odir_specified) {
2438 2433 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
2439 2434 dmake_odir = GETNAME(wcs_buffer, FIND_LENGTH);
2440 2435 append_makeflags_string(dmake_odir, &makeflags_string);
2441 2436 append_makeflags_string(dmake_odir, &makeflags_string_posix);
2442 2437 }
2443 2438 /* -M pmake_machinesfile */
2444 2439 if (pmake_machinesfile_specified) {
2445 2440 MBSTOWCS(wcs_buffer, NOCATGETS("PMAKE_MACHINESFILE"));
2446 2441 pmake_machinesfile = GETNAME(wcs_buffer, FIND_LENGTH);
2447 2442 append_makeflags_string(pmake_machinesfile, &makeflags_string);
2448 2443 append_makeflags_string(pmake_machinesfile, &makeflags_string_posix);
2449 2444 }
2450 2445 /* -R */
2451 2446 if (pmake_cap_r_specified) {
2452 2447 append_char((int) space_char, &makeflags_string);
2453 2448 append_char((int) hyphen_char, &makeflags_string);
2454 2449 append_char('R', &makeflags_string);
2455 2450 append_char((int) space_char, &makeflags_string_posix);
2456 2451 append_char((int) hyphen_char, &makeflags_string_posix);
2457 2452 append_char('R', &makeflags_string_posix);
2458 2453 }
2459 2454 #endif
2460 2455
2461 2456 /*
2462 2457 * Make sure MAKEFLAGS is exported
2463 2458 */
2464 2459 maybe_append_prop(makeflags, macro_prop)->
2465 2460 body.macro.exported = true;
2466 2461
2467 2462 if (makeflags_string.buffer.start[1] != (int) nul_char) {
2468 2463 if (makeflags_string.buffer.start[1] != (int) space_char) {
2469 2464 MBSTOWCS(wcs_buffer, NOCATGETS("MFLAGS"));
2470 2465 (void) SETVAR(GETNAME(wcs_buffer, FIND_LENGTH),
2471 2466 GETNAME(makeflags_string.buffer.start,
2472 2467 FIND_LENGTH),
2473 2468 false);
2474 2469 } else {
2475 2470 MBSTOWCS(wcs_buffer, NOCATGETS("MFLAGS"));
2476 2471 (void) SETVAR(GETNAME(wcs_buffer, FIND_LENGTH),
2477 2472 GETNAME(makeflags_string.buffer.start + 2,
2478 2473 FIND_LENGTH),
2479 2474 false);
2480 2475 }
2481 2476 }
2482 2477
2483 2478 /*
2484 2479 * Add command line macro to POSIX makeflags_string
2485 2480 */
2486 2481 if (makeflags_and_macro.start) {
2487 2482 tmp_char = (char) space_char;
2488 2483 cp = makeflags_and_macro.start;
2489 2484 do {
2490 2485 append_char(tmp_char, &makeflags_string_posix);
2491 2486 } while ( tmp_char = *cp++ );
2492 2487 retmem_mb(makeflags_and_macro.start);
2493 2488 }
2494 2489
2495 2490 /*
2496 2491 * Now set the value of MAKEFLAGS macro in accordance
2497 2492 * with current mode.
2498 2493 */
2499 2494 macro = maybe_append_prop(makeflags, macro_prop);
2500 2495 temp = (Boolean) macro->body.macro.read_only;
2501 2496 macro->body.macro.read_only = false;
2502 2497 if(posix || gnu_style) {
2503 2498 makeflags_string_current = &makeflags_string_posix;
2504 2499 } else {
2505 2500 makeflags_string_current = &makeflags_string;
2506 2501 }
2507 2502 if (makeflags_string_current->buffer.start[1] == (int) nul_char) {
2508 2503 makeflags_value_saved =
2509 2504 GETNAME( makeflags_string_current->buffer.start + 1
2510 2505 , FIND_LENGTH
2511 2506 );
2512 2507 } else {
2513 2508 if (makeflags_string_current->buffer.start[1] != (int) space_char) {
2514 2509 makeflags_value_saved =
2515 2510 GETNAME( makeflags_string_current->buffer.start
2516 2511 , FIND_LENGTH
2517 2512 );
2518 2513 } else {
2519 2514 makeflags_value_saved =
2520 2515 GETNAME( makeflags_string_current->buffer.start + 2
2521 2516 , FIND_LENGTH
2522 2517 );
2523 2518 }
2524 2519 }
2525 2520 (void) SETVAR( makeflags
2526 2521 , makeflags_value_saved
2527 2522 , false
2528 2523 );
2529 2524 macro->body.macro.read_only = temp;
2530 2525
2531 2526 /*
2532 2527 * Read command line "-f" arguments and ignore -c, g, j, K, M, m, O and o args.
2533 2528 */
2534 2529 save_do_not_exec_rule = do_not_exec_rule;
2535 2530 do_not_exec_rule = false;
2536 2531 if (read_trace_level > 0) {
2537 2532 trace_reader = true;
2538 2533 }
2539 2534
2540 2535 for (i = 1; i < argc; i++) {
2541 2536 if (argv[i] &&
2542 2537 (argv[i][0] == (int) hyphen_char) &&
2543 2538 (argv[i][1] == 'f') &&
2544 2539 (argv[i][2] == (int) nul_char)) {
2545 2540 argv[i] = NULL; /* Remove -f */
2546 2541 if (i >= argc - 1) {
2547 2542 fatal(catgets(catd, 1, 190, "No filename argument after -f flag"));
2548 2543 }
2549 2544 MBSTOWCS(wcs_buffer, argv[++i]);
2550 2545 primary_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
2551 2546 (void) read_makefile(primary_makefile, true, true, true);
2552 2547 argv[i] = NULL; /* Remove filename */
2553 2548 makefile_read = true;
2554 2549 } else if (argv[i] &&
2555 2550 (argv[i][0] == (int) hyphen_char) &&
2556 2551 (argv[i][1] == 'c' ||
2557 2552 argv[i][1] == 'g' ||
2558 2553 argv[i][1] == 'j' ||
2559 2554 argv[i][1] == 'K' ||
2560 2555 argv[i][1] == 'M' ||
2561 2556 argv[i][1] == 'm' ||
2562 2557 argv[i][1] == 'O' ||
2563 2558 argv[i][1] == 'o') &&
2564 2559 (argv[i][2] == (int) nul_char)) {
2565 2560 argv[i] = NULL;
2566 2561 argv[++i] = NULL;
2567 2562 }
2568 2563 }
2569 2564
2570 2565 /*
2571 2566 * If no command line "-f" args then look for "makefile", and then for
2572 2567 * "Makefile" if "makefile" isn't found.
2573 2568 */
2574 2569 if (!makefile_read) {
2575 2570 (void) read_dir(dot,
2576 2571 (wchar_t *) NULL,
2577 2572 (Property) NULL,
2578 2573 (wchar_t *) NULL);
2579 2574 if (!posix) {
2580 2575 if (makefile_name->stat.is_file) {
2581 2576 if (Makefile->stat.is_file) {
2582 2577 warning(catgets(catd, 1, 310, "Both `makefile' and `Makefile' exist"));
2583 2578 }
2584 2579 primary_makefile = makefile_name;
2585 2580 makefile_read = read_makefile(makefile_name,
2586 2581 false,
2587 2582 false,
2588 2583 true);
2589 2584 }
2590 2585 if (!makefile_read &&
2591 2586 Makefile->stat.is_file) {
2592 2587 primary_makefile = Makefile;
2593 2588 makefile_read = read_makefile(Makefile,
2594 2589 false,
2595 2590 false,
2596 2591 true);
2597 2592 }
2598 2593 } else {
2599 2594
2600 2595 enum sccs_stat save_m_has_sccs = NO_SCCS;
2601 2596 enum sccs_stat save_M_has_sccs = NO_SCCS;
2602 2597
2603 2598 if (makefile_name->stat.is_file) {
2604 2599 if (Makefile->stat.is_file) {
2605 2600 warning(catgets(catd, 1, 191, "Both `makefile' and `Makefile' exist"));
2606 2601 }
2607 2602 }
2608 2603 if (makefile_name->stat.is_file) {
2609 2604 if (makefile_name->stat.has_sccs == NO_SCCS) {
2610 2605 primary_makefile = makefile_name;
2611 2606 makefile_read = read_makefile(makefile_name,
2612 2607 false,
2613 2608 false,
2614 2609 true);
2615 2610 } else {
2616 2611 save_m_has_sccs = makefile_name->stat.has_sccs;
2617 2612 makefile_name->stat.has_sccs = NO_SCCS;
2618 2613 primary_makefile = makefile_name;
2619 2614 makefile_read = read_makefile(makefile_name,
2620 2615 false,
2621 2616 false,
2622 2617 true);
2623 2618 }
2624 2619 }
2625 2620 if (!makefile_read &&
2626 2621 Makefile->stat.is_file) {
2627 2622 if (Makefile->stat.has_sccs == NO_SCCS) {
2628 2623 primary_makefile = Makefile;
2629 2624 makefile_read = read_makefile(Makefile,
2630 2625 false,
2631 2626 false,
2632 2627 true);
2633 2628 } else {
2634 2629 save_M_has_sccs = Makefile->stat.has_sccs;
2635 2630 Makefile->stat.has_sccs = NO_SCCS;
2636 2631 primary_makefile = Makefile;
2637 2632 makefile_read = read_makefile(Makefile,
2638 2633 false,
2639 2634 false,
2640 2635 true);
2641 2636 }
2642 2637 }
2643 2638 if (!makefile_read &&
2644 2639 makefile_name->stat.is_file) {
2645 2640 makefile_name->stat.has_sccs = save_m_has_sccs;
2646 2641 primary_makefile = makefile_name;
2647 2642 makefile_read = read_makefile(makefile_name,
2648 2643 false,
2649 2644 false,
2650 2645 true);
2651 2646 }
2652 2647 if (!makefile_read &&
2653 2648 Makefile->stat.is_file) {
2654 2649 Makefile->stat.has_sccs = save_M_has_sccs;
2655 2650 primary_makefile = Makefile;
2656 2651 makefile_read = read_makefile(Makefile,
2657 2652 false,
2658 2653 false,
2659 2654 true);
2660 2655 }
2661 2656 }
2662 2657 }
2663 2658 do_not_exec_rule = save_do_not_exec_rule;
2664 2659 allrules_read = makefile_read;
2665 2660 trace_reader = false;
2666 2661
2667 2662 /*
2668 2663 * Now get current value of MAKEFLAGS and compare it with
2669 2664 * the saved value we set before reading makefile.
2670 2665 * If they are different then MAKEFLAGS is subsequently set by
2671 2666 * makefile, just leave it there. Otherwise, if make mode
2672 2667 * is changed by using .POSIX target in makefile we need
2673 2668 * to correct MAKEFLAGS value.
2674 2669 */
2675 2670 Name mf_val = getvar(makeflags);
2676 2671 if( (posix != is_xpg4)
2677 2672 && (!strcmp(mf_val->string_mb, makeflags_value_saved->string_mb)))
2678 2673 {
2679 2674 if (makeflags_string_posix.buffer.start[1] == (int) nul_char) {
2680 2675 (void) SETVAR(makeflags,
2681 2676 GETNAME(makeflags_string_posix.buffer.start + 1,
2682 2677 FIND_LENGTH),
2683 2678 false);
2684 2679 } else {
2685 2680 if (makeflags_string_posix.buffer.start[1] != (int) space_char) {
2686 2681 (void) SETVAR(makeflags,
2687 2682 GETNAME(makeflags_string_posix.buffer.start,
2688 2683 FIND_LENGTH),
2689 2684 false);
2690 2685 } else {
2691 2686 (void) SETVAR(makeflags,
2692 2687 GETNAME(makeflags_string_posix.buffer.start + 2,
2693 2688 FIND_LENGTH),
2694 2689 false);
2695 2690 }
2696 2691 }
2697 2692 }
2698 2693
2699 2694 if (makeflags_string.free_after_use) {
2700 2695 retmem(makeflags_string.buffer.start);
2701 2696 }
2702 2697 if (makeflags_string_posix.free_after_use) {
2703 2698 retmem(makeflags_string_posix.buffer.start);
2704 2699 }
2705 2700 makeflags_string.buffer.start = NULL;
2706 2701 makeflags_string_posix.buffer.start = NULL;
2707 2702
2708 2703 if (posix) {
2709 2704 /*
2710 2705 * If the user did not redefine the ARFLAGS macro in the
2711 2706 * default makefile (make.rules), then we'd like to
2712 2707 * change the macro value of ARFLAGS to be in accordance
2713 2708 * with "POSIX" requirements.
2714 2709 */
2715 2710 MBSTOWCS(wcs_buffer, NOCATGETS("ARFLAGS"));
2716 2711 name = GETNAME(wcs_buffer, wslen(wcs_buffer));
2717 2712 macro = get_prop(name->prop, macro_prop);
2718 2713 if ((macro != NULL) && /* Maybe (macro == NULL) || ? */
2719 2714 (IS_EQUAL(macro->body.macro.value->string_mb,
2720 2715 NOCATGETS("rv")))) {
2721 2716 MBSTOWCS(wcs_buffer, NOCATGETS("-rv"));
2722 2717 value = GETNAME(wcs_buffer, wslen(wcs_buffer));
2723 2718 (void) SETVAR(name,
2724 2719 value,
2725 2720 false);
2726 2721 }
2727 2722 }
2728 2723
2729 2724 if (!posix && !svr4) {
2730 2725 set_sgs_support();
2731 2726 }
2732 2727
2733 2728
2734 2729 /*
2735 2730 * Make sure KEEP_STATE is in the environment if KEEP_STATE is on.
2736 2731 */
2737 2732 macro = get_prop(keep_state_name->prop, macro_prop);
2738 2733 if ((macro != NULL) &&
2739 2734 macro->body.macro.exported) {
2740 2735 keep_state = true;
2741 2736 }
2742 2737 if (keep_state) {
2743 2738 if (macro == NULL) {
2744 2739 macro = maybe_append_prop(keep_state_name,
2745 2740 macro_prop);
2746 2741 }
2747 2742 macro->body.macro.exported = true;
2748 2743 (void) SETVAR(keep_state_name,
2749 2744 empty_name,
2750 2745 false);
2751 2746
2752 2747 /*
2753 2748 * Read state file
2754 2749 */
2755 2750
2756 2751 /* Before we read state, let's make sure we have
2757 2752 ** right state file.
2758 2753 */
2759 2754 /* just in case macro references are used in make_state file
2760 2755 ** name, we better expand them at this stage using expand_value.
2761 2756 */
2762 2757 INIT_STRING_FROM_STACK(dest, destbuffer);
2763 2758 expand_value(make_state, &dest, false);
2764 2759
2765 2760 make_state = GETNAME(dest.buffer.start, FIND_LENGTH);
2766 2761
2767 2762 if(!stat(make_state->string_mb, &make_state_stat)) {
2768 2763 if(!(make_state_stat.st_mode & S_IFREG) ) {
2769 2764 /* copy the make_state structure to the other
2770 2765 ** and then let make_state point to the new
2771 2766 ** one.
2772 2767 */
2773 2768 memcpy(&state_filename, make_state,sizeof(state_filename));
2774 2769 state_filename.string_mb = state_file_str_mb;
2775 2770 /* Just a kludge to avoid two slashes back to back */
2776 2771 if((make_state->hash.length == 1)&&
2777 2772 (make_state->string_mb[0] == '/')) {
2778 2773 make_state->hash.length = 0;
2779 2774 make_state->string_mb[0] = '\0';
2780 2775 }
2781 2776 sprintf(state_file_str_mb,NOCATGETS("%s%s"),
2782 2777 make_state->string_mb,NOCATGETS("/.make.state"));
2783 2778 make_state = &state_filename;
2784 2779 /* adjust the length to reflect the appended string */
2785 2780 make_state->hash.length += 12;
2786 2781 }
2787 2782 } else { /* the file doesn't exist or no permission */
2788 2783 char tmp_path[MAXPATHLEN];
2789 2784 char *slashp;
2790 2785
2791 2786 if (slashp = strrchr(make_state->string_mb, '/')) {
2792 2787 strncpy(tmp_path, make_state->string_mb,
2793 2788 (slashp - make_state->string_mb));
2794 2789 tmp_path[slashp - make_state->string_mb]=0;
2795 2790 if(strlen(tmp_path)) {
2796 2791 if(stat(tmp_path, &make_state_stat)) {
2797 2792 warning(catgets(catd, 1, 192, "directory %s for .KEEP_STATE_FILE does not exist"),tmp_path);
2798 2793 }
2799 2794 if (access(tmp_path, F_OK) != 0) {
2800 2795 warning(catgets(catd, 1, 193, "can't access dir %s"),tmp_path);
2801 2796 }
2802 2797 }
2803 2798 }
2804 2799 }
2805 2800 if (report_dependencies_level != 1) {
2806 2801 Makefile_type makefile_type_temp = makefile_type;
2807 2802 makefile_type = reading_statefile;
2808 2803 if (read_trace_level > 1) {
2809 2804 trace_reader = true;
2810 2805 }
2811 2806 (void) read_simple_file(make_state,
2812 2807 false,
2813 2808 false,
2814 2809 false,
2815 2810 false,
2816 2811 false,
2817 2812 true);
2818 2813 trace_reader = false;
2819 2814 makefile_type = makefile_type_temp;
2820 2815 }
2821 2816 }
2822 2817 }
2823 2818
2824 2819 /*
2825 2820 * Scan the argv for options and "=" type args and make them readonly.
2826 2821 */
2827 2822 static void
2828 2823 enter_argv_values(int argc, char *argv[], ASCII_Dyn_Array *makeflags_and_macro)
2829 2824 {
2830 2825 register char *cp;
2831 2826 register int i;
2832 2827 int length;
2833 2828 register Name name;
2834 2829 int opt_separator = argc;
2835 2830 char tmp_char;
2836 2831 wchar_t *tmp_wcs_buffer;
2837 2832 register Name value;
2838 2833 Boolean append = false;
2839 2834 Property macro;
2840 2835 struct stat statbuf;
2841 2836
2842 2837
2843 2838 /* Read argv options and "=" type args and make them readonly. */
2844 2839 makefile_type = reading_nothing;
2845 2840 for (i = 1; i < argc; ++i) {
2846 2841 append = false;
2847 2842 if (argv[i] == NULL) {
2848 2843 continue;
2849 2844 } else if (((argv[i][0] == '-') && (argv[i][1] == '-')) ||
2850 2845 ((argv[i][0] == (int) ' ') &&
2851 2846 (argv[i][1] == (int) '-') &&
2852 2847 (argv[i][2] == (int) ' ') &&
2853 2848 (argv[i][3] == (int) '-'))) {
2854 2849 argv[i] = NULL;
2855 2850 opt_separator = i;
2856 2851 continue;
2857 2852 } else if ((i < opt_separator) && (argv[i][0] == (int) hyphen_char)) {
2858 2853 switch (parse_command_option(argv[i][1])) {
2859 2854 case 1: /* -f seen */
2860 2855 ++i;
2861 2856 continue;
2862 2857 case 2: /* -c seen */
2863 2858 if (argv[i+1] == NULL) {
2864 2859 fatal(catgets(catd, 1, 194, "No dmake rcfile argument after -c flag"));
2865 2860 }
2866 2861 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
2867 2862 name = GETNAME(wcs_buffer, FIND_LENGTH);
2868 2863 break;
2869 2864 case 4: /* -g seen */
2870 2865 if (argv[i+1] == NULL) {
2871 2866 fatal(catgets(catd, 1, 195, "No dmake group argument after -g flag"));
2872 2867 }
2873 2868 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
2874 2869 name = GETNAME(wcs_buffer, FIND_LENGTH);
2875 2870 break;
2876 2871 case 8: /* -j seen */
2877 2872 if (argv[i+1] == NULL) {
2878 2873 fatal(catgets(catd, 1, 196, "No dmake max jobs argument after -j flag"));
2879 2874 }
2880 2875 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
2881 2876 name = GETNAME(wcs_buffer, FIND_LENGTH);
2882 2877 break;
2883 2878 case 16: /* -M seen */
2884 2879 if (argv[i+1] == NULL) {
2885 2880 fatal(catgets(catd, 1, 323, "No pmake machinesfile argument after -M flag"));
2886 2881 }
2887 2882 MBSTOWCS(wcs_buffer, NOCATGETS("PMAKE_MACHINESFILE"));
2888 2883 name = GETNAME(wcs_buffer, FIND_LENGTH);
2889 2884 break;
2890 2885 case 32: /* -m seen */
2891 2886 if (argv[i+1] == NULL) {
2892 2887 fatal(catgets(catd, 1, 197, "No dmake mode argument after -m flag"));
2893 2888 }
2894 2889 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
2895 2890 name = GETNAME(wcs_buffer, FIND_LENGTH);
2896 2891 break;
2897 2892 case 128: /* -O seen */
2898 2893 if (argv[i+1] == NULL) {
2899 2894 fatal(catgets(catd, 1, 287, "No file descriptor argument after -O flag"));
2900 2895 }
2901 2896 mtool_msgs_fd = atoi(argv[i+1]);
2902 2897 /* find out if mtool_msgs_fd is a valid file descriptor */
2903 2898 if (fstat(mtool_msgs_fd, &statbuf) < 0) {
2904 2899 fatal(catgets(catd, 1, 355, "Invalid file descriptor %d after -O flag"), mtool_msgs_fd);
2905 2900 }
2906 2901 argv[i] = NULL;
2907 2902 argv[i+1] = NULL;
2908 2903 continue;
2909 2904 case 256: /* -K seen */
2910 2905 if (argv[i+1] == NULL) {
2911 2906 fatal(catgets(catd, 1, 288, "No makestate filename argument after -K flag"));
2912 2907 }
2913 2908 MBSTOWCS(wcs_buffer, argv[i+1]);
2914 2909 make_state = GETNAME(wcs_buffer, FIND_LENGTH);
2915 2910 keep_state = true;
2916 2911 argv[i] = NULL;
2917 2912 argv[i+1] = NULL;
2918 2913 continue;
2919 2914 case 512: /* -o seen */
2920 2915 if (argv[i+1] == NULL) {
2921 2916 fatal(catgets(catd, 1, 312, "No dmake output dir argument after -o flag"));
2922 2917 }
2923 2918 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
2924 2919 name = GETNAME(wcs_buffer, FIND_LENGTH);
2925 2920 break;
2926 2921 case 1024: /* -x seen */
2927 2922 if (argv[i+1] == NULL) {
2928 2923 fatal(catgets(catd, 1, 351, "No argument after -x flag"));
2929 2924 }
2930 2925 length = strlen( NOCATGETS("SUN_MAKE_COMPAT_MODE="));
2931 2926 if (strncmp(argv[i+1], NOCATGETS("SUN_MAKE_COMPAT_MODE="), length) == 0) {
2932 2927 argv[i+1] = &argv[i+1][length];
2933 2928 MBSTOWCS(wcs_buffer, NOCATGETS("SUN_MAKE_COMPAT_MODE"));
2934 2929 name = GETNAME(wcs_buffer, FIND_LENGTH);
2935 2930 dmake_compat_mode_specified = dmake_add_mode_specified;
2936 2931 break;
2937 2932 }
2938 2933 length = strlen( NOCATGETS("DMAKE_OUTPUT_MODE="));
2939 2934 if (strncmp(argv[i+1], NOCATGETS("DMAKE_OUTPUT_MODE="), length) == 0) {
2940 2935 argv[i+1] = &argv[i+1][length];
2941 2936 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
2942 2937 name = GETNAME(wcs_buffer, FIND_LENGTH);
2943 2938 dmake_output_mode_specified = dmake_add_mode_specified;
2944 2939 } else {
2945 2940 warning(catgets(catd, 1, 354, "Unknown argument `%s' after -x flag (ignored)"),
2946 2941 argv[i+1]);
2947 2942 argv[i] = argv[i + 1] = NULL;
2948 2943 continue;
2949 2944 }
2950 2945 break;
2951 2946 default: /* Shouldn't reach here */
2952 2947 argv[i] = NULL;
2953 2948 continue;
2954 2949 }
2955 2950 argv[i] = NULL;
2956 2951 if (i == (argc - 1)) {
2957 2952 break;
2958 2953 }
2959 2954 if ((length = strlen(argv[i+1])) >= MAXPATHLEN) {
2960 2955 tmp_wcs_buffer = ALLOC_WC(length + 1);
2961 2956 (void) mbstowcs(tmp_wcs_buffer, argv[i+1], length + 1);
2962 2957 value = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
2963 2958 retmem(tmp_wcs_buffer);
2964 2959 } else {
2965 2960 MBSTOWCS(wcs_buffer, argv[i+1]);
2966 2961 value = GETNAME(wcs_buffer, FIND_LENGTH);
2967 2962 }
2968 2963 argv[i+1] = NULL;
2969 2964 } else if ((cp = strchr(argv[i], (int) equal_char)) != NULL) {
2970 2965 /*
2971 2966 * Combine all macro in dynamic array
2972 2967 */
2973 2968 if(*(cp-1) == (int) plus_char)
2974 2969 {
2975 2970 if(isspace(*(cp-2))) {
2976 2971 append = true;
2977 2972 cp--;
2978 2973 }
2979 2974 }
2980 2975 if(!append)
2981 2976 append_or_replace_macro_in_dyn_array(makeflags_and_macro, argv[i]);
2982 2977
2983 2978 while (isspace(*(cp-1))) {
2984 2979 cp--;
2985 2980 }
2986 2981 tmp_char = *cp;
2987 2982 *cp = (int) nul_char;
2988 2983 MBSTOWCS(wcs_buffer, argv[i]);
2989 2984 *cp = tmp_char;
2990 2985 name = GETNAME(wcs_buffer, wslen(wcs_buffer));
2991 2986 while (*cp != (int) equal_char) {
2992 2987 cp++;
2993 2988 }
2994 2989 cp++;
2995 2990 while (isspace(*cp) && (*cp != (int) nul_char)) {
2996 2991 cp++;
2997 2992 }
2998 2993 if ((length = strlen(cp)) >= MAXPATHLEN) {
2999 2994 tmp_wcs_buffer = ALLOC_WC(length + 1);
3000 2995 (void) mbstowcs(tmp_wcs_buffer, cp, length + 1);
3001 2996 value = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
3002 2997 retmem(tmp_wcs_buffer);
3003 2998 } else {
3004 2999 MBSTOWCS(wcs_buffer, cp);
3005 3000 value = GETNAME(wcs_buffer, FIND_LENGTH);
3006 3001 }
3007 3002 argv[i] = NULL;
3008 3003 } else {
3009 3004 /* Illegal MAKEFLAGS argument */
3010 3005 continue;
3011 3006 }
3012 3007 if(append) {
3013 3008 setvar_append(name, value);
3014 3009 append = false;
3015 3010 } else {
3016 3011 macro = maybe_append_prop(name, macro_prop);
3017 3012 macro->body.macro.exported = true;
3018 3013 SETVAR(name, value, false)->body.macro.read_only = true;
3019 3014 }
3020 3015 }
3021 3016 }
3022 3017
3023 3018 /*
3024 3019 * Append the DMake option and value to the MAKEFLAGS string.
3025 3020 */
3026 3021 static void
3027 3022 append_makeflags_string(Name name, register String makeflags_string)
3028 3023 {
3029 3024 char *option;
3030 3025
3031 3026 if (strcmp(name->string_mb, NOCATGETS("DMAKE_GROUP")) == 0) {
3032 3027 option = NOCATGETS(" -g ");
3033 3028 } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_MAX_JOBS")) == 0) {
3034 3029 option = NOCATGETS(" -j ");
3035 3030 } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_MODE")) == 0) {
3036 3031 option = NOCATGETS(" -m ");
3037 3032 } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_ODIR")) == 0) {
3038 3033 option = NOCATGETS(" -o ");
3039 3034 } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_RCFILE")) == 0) {
3040 3035 option = NOCATGETS(" -c ");
3041 3036 } else if (strcmp(name->string_mb, NOCATGETS("PMAKE_MACHINESFILE")) == 0) {
3042 3037 option = NOCATGETS(" -M ");
3043 3038 } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_OUTPUT_MODE")) == 0) {
3044 3039 option = NOCATGETS(" -x DMAKE_OUTPUT_MODE=");
3045 3040 } else if (strcmp(name->string_mb, NOCATGETS("SUN_MAKE_COMPAT_MODE")) == 0) {
3046 3041 option = NOCATGETS(" -x SUN_MAKE_COMPAT_MODE=");
3047 3042 } else {
3048 3043 fatal(catgets(catd, 1, 289, "Internal error: name not recognized in append_makeflags_string()"));
3049 3044 }
3050 3045 Property prop = maybe_append_prop(name, macro_prop);
3051 3046 if( prop == 0 || prop->body.macro.value == 0 ||
3052 3047 prop->body.macro.value->string_mb == 0 ) {
3053 3048 return;
3054 3049 }
3055 3050 char mbs_value[MAXPATHLEN + 100];
3056 3051 strcpy(mbs_value, option);
3057 3052 strcat(mbs_value, prop->body.macro.value->string_mb);
3058 3053 MBSTOWCS(wcs_buffer, mbs_value);
3059 3054 append_string(wcs_buffer, makeflags_string, FIND_LENGTH);
3060 3055 }
3061 3056
3062 3057 /*
3063 3058 * read_environment(read_only)
3064 3059 *
3065 3060 * This routine reads the process environment when make starts and enters
3066 3061 * it as make macros. The environment variable SHELL is ignored.
3067 3062 *
3068 3063 * Parameters:
3069 3064 * read_only Should we make env vars read only?
3070 3065 *
3071 3066 * Global variables used:
3072 3067 * report_pwd Set if this make was started by other make
3073 3068 */
3074 3069 static void
3075 3070 read_environment(Boolean read_only)
3076 3071 {
3077 3072 register char **environment;
3078 3073 int length;
3079 3074 wchar_t *tmp_wcs_buffer;
3080 3075 Boolean alloced_tmp_wcs_buffer = false;
3081 3076 register wchar_t *name;
3082 3077 register wchar_t *value;
3083 3078 register Name macro;
3084 3079 Property val;
3085 3080 Boolean read_only_saved;
3086 3081
3087 3082 reading_environment = true;
3088 3083 environment = environ;
3089 3084 for (; *environment; environment++) {
3090 3085 read_only_saved = read_only;
3091 3086 if ((length = strlen(*environment)) >= MAXPATHLEN) {
3092 3087 tmp_wcs_buffer = ALLOC_WC(length + 1);
3093 3088 alloced_tmp_wcs_buffer = true;
3094 3089 (void) mbstowcs(tmp_wcs_buffer, *environment, length + 1);
3095 3090 name = tmp_wcs_buffer;
3096 3091 } else {
3097 3092 MBSTOWCS(wcs_buffer, *environment);
3098 3093 name = wcs_buffer;
3099 3094 }
3100 3095 value = (wchar_t *) wschr(name, (int) equal_char);
3101 3096
3102 3097 /*
3103 3098 * Looks like there's a bug in the system, but sometimes
3104 3099 * you can get blank lines in *environment.
3105 3100 */
3106 3101 if (!value) {
3107 3102 continue;
3108 3103 }
3109 3104 MBSTOWCS(wcs_buffer2, NOCATGETS("SHELL="));
3110 3105 if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
3111 3106 continue;
3112 3107 }
3113 3108 MBSTOWCS(wcs_buffer2, NOCATGETS("MAKEFLAGS="));
3114 3109 if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
3115 3110 report_pwd = true;
3116 3111 /*
3117 3112 * In POSIX mode we do not want MAKEFLAGS to be readonly.
3118 3113 * If the MAKEFLAGS macro is subsequently set by the makefile,
3119 3114 * it replaces the MAKEFLAGS variable currently found in the
3120 3115 * environment.
3121 3116 * See Assertion 50 in section 6.2.5.3 of standard P1003.3.2/D8.
3122 3117 */
3123 3118 if(posix) {
3124 3119 read_only_saved = false;
3125 3120 }
3126 3121 }
3127 3122
3128 3123 /*
3129 3124 * We ignore SUNPRO_DEPENDENCIES and NSE_DEP. Those
3130 3125 * environment variables are set by make and read by
3131 3126 * cpp which then writes info to .make.dependency.xxx and
3132 3127 * .nse_depinfo. When make is invoked by another make
3133 3128 * (recursive make), we don't want to read this because
3134 3129 * then the child make will end up writing to the parent
3135 3130 * directory's .make.state and .nse_depinfo and clobbering
3136 3131 * them.
3137 3132 */
3138 3133 MBSTOWCS(wcs_buffer2, NOCATGETS("SUNPRO_DEPENDENCIES"));
3139 3134 if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
3140 3135 continue;
3141 3136 }
3142 3137 #ifdef NSE
3143 3138 MBSTOWCS(wcs_buffer2, NOCATGETS("NSE_DEP"));
3144 3139 if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
3145 3140 continue;
3146 3141 }
3147 3142 #endif
3148 3143
3149 3144 macro = GETNAME(name, value - name);
3150 3145 maybe_append_prop(macro, macro_prop)->body.macro.exported =
3151 3146 true;
3152 3147 if ((value == NULL) || ((value + 1)[0] == (int) nul_char)) {
3153 3148 val = setvar_daemon(macro,
3154 3149 (Name) NULL,
3155 3150 false, no_daemon, false, debug_level);
3156 3151 } else {
3157 3152 val = setvar_daemon(macro,
3158 3153 GETNAME(value + 1, FIND_LENGTH),
3159 3154 false, no_daemon, false, debug_level);
3160 3155 }
3161 3156 #ifdef NSE
3162 3157 /*
3163 3158 * Must be after the call to setvar() as it sets
3164 3159 * imported to false.
3165 3160 */
3166 3161 maybe_append_prop(macro, macro_prop)->body.macro.imported = true;
3167 3162 #endif
3168 3163 val->body.macro.read_only = read_only_saved;
3169 3164 if (alloced_tmp_wcs_buffer) {
3170 3165 retmem(tmp_wcs_buffer);
3171 3166 alloced_tmp_wcs_buffer = false;
3172 3167 }
3173 3168 }
3174 3169 reading_environment = false;
3175 3170 }
3176 3171
3177 3172 /*
3178 3173 * read_makefile(makefile, complain, must_exist, report_file)
3179 3174 *
3180 3175 * Read one makefile and check the result
3181 3176 *
3182 3177 * Return value:
3183 3178 * false is the read failed
3184 3179 *
3185 3180 * Parameters:
3186 3181 * makefile The file to read
3187 3182 * complain Passed thru to read_simple_file()
3188 3183 * must_exist Passed thru to read_simple_file()
3189 3184 * report_file Passed thru to read_simple_file()
3190 3185 *
3191 3186 * Global variables used:
3192 3187 * makefile_type Set to indicate we are reading main file
3193 3188 * recursion_level Initialized
3194 3189 */
3195 3190 static Boolean
3196 3191 read_makefile(register Name makefile, Boolean complain, Boolean must_exist, Boolean report_file)
3197 3192 {
3198 3193 Boolean b;
3199 3194
3200 3195 makefile_type = reading_makefile;
3201 3196 recursion_level = 0;
3202 3197 #ifdef NSE
3203 3198 wscpy(current_makefile, makefile->string);
3204 3199 #endif
3205 3200 reading_dependencies = true;
3206 3201 b = read_simple_file(makefile, true, true, complain,
3207 3202 must_exist, report_file, false);
3208 3203 reading_dependencies = false;
3209 3204 return b;
3210 3205 }
3211 3206
3212 3207 /*
3213 3208 * make_targets(argc, argv, parallel_flag)
3214 3209 *
3215 3210 * Call doname on the specified targets
3216 3211 *
3217 3212 * Parameters:
3218 3213 * argc You know what this is
3219 3214 * argv You know what this is
3220 3215 * parallel_flag True if building in parallel
3221 3216 *
3222 3217 * Global variables used:
3223 3218 * build_failed_seen Used to generated message after failed -k
3224 3219 * commands_done Used to generate message "Up to date"
3225 3220 * default_target_to_build First proper target in makefile
3226 3221 * init The Name ".INIT", use to run command
3227 3222 * parallel Global parallel building flag
3228 3223 * quest make -q, suppresses messages
3229 3224 * recursion_level Initialized, used for tracing
3230 3225 * report_dependencies make -P, regroves whole process
3231 3226 */
3232 3227 static void
3233 3228 make_targets(int argc, char **argv, Boolean parallel_flag)
3234 3229 {
3235 3230 int i;
3236 3231 char *cp;
3237 3232 Doname result;
3238 3233 register Boolean target_to_make_found = false;
3239 3234
3240 3235 (void) doname(init, true, true);
3241 3236 recursion_level = 1;
3242 3237 parallel = parallel_flag;
3243 3238 /*
3244 3239 * make remaining args
3245 3240 */
3246 3241 #ifdef TEAMWARE_MAKE_CMN
3247 3242 /*
3248 3243 if ((report_dependencies_level == 0) && parallel) {
3249 3244 */
3250 3245 if (parallel) {
3251 3246 /*
3252 3247 * If building targets in parallel, start all of the
3253 3248 * remaining args to build in parallel.
3254 3249 */
3255 3250 for (i = 1; i < argc; i++) {
3256 3251 if ((cp = argv[i]) != NULL) {
3257 3252 commands_done = false;
3258 3253 if ((cp[0] == (int) period_char) &&
3259 3254 (cp[1] == (int) slash_char)) {
3260 3255 cp += 2;
3261 3256 }
3262 3257 if((cp[0] == (int) ' ') &&
3263 3258 (cp[1] == (int) '-') &&
3264 3259 (cp[2] == (int) ' ') &&
3265 3260 (cp[3] == (int) '-')) {
3266 3261 argv[i] = NULL;
3267 3262 continue;
3268 3263 }
3269 3264 MBSTOWCS(wcs_buffer, cp);
3270 3265 //default_target_to_build = GETNAME(wcs_buffer,
3271 3266 // FIND_LENGTH);
3272 3267 default_target_to_build = normalize_name(wcs_buffer,
3273 3268 wslen(wcs_buffer));
3274 3269 if (default_target_to_build == wait_name) {
3275 3270 if (parallel_process_cnt > 0) {
3276 3271 finish_running();
3277 3272 }
3278 3273 continue;
3279 3274 }
3280 3275 top_level_target = get_wstring(default_target_to_build->string_mb);
3281 3276 /*
3282 3277 * If we can't execute the current target in
3283 3278 * parallel, hold off the target processing
3284 3279 * to preserve the order of the targets as they appeared
3285 3280 * in command line.
3286 3281 */
3287 3282 if (!parallel_ok(default_target_to_build, false)
3288 3283 && parallel_process_cnt > 0) {
3289 3284 finish_running();
3290 3285 }
3291 3286 result = doname_check(default_target_to_build,
3292 3287 true,
3293 3288 false,
3294 3289 false);
3295 3290 gather_recursive_deps();
3296 3291 if (/* !commands_done && */
3297 3292 (result == build_ok) &&
3298 3293 !quest &&
3299 3294 (report_dependencies_level == 0) /* &&
3300 3295 (exists(default_target_to_build) > file_doesnt_exist) */) {
3301 3296 if (posix) {
3302 3297 if (!commands_done) {
3303 3298 (void) printf(catgets(catd, 1, 293, "`%s' is updated.\n"),
3304 3299 default_target_to_build->string_mb);
3305 3300 } else {
3306 3301 if (no_action_was_taken) {
3307 3302 (void) printf(catgets(catd, 1, 294, "`%s': no action was taken.\n"),
3308 3303 default_target_to_build->string_mb);
3309 3304 }
3310 3305 }
3311 3306 } else {
3312 3307 default_target_to_build->stat.time = file_no_time;
3313 3308 if (!commands_done &&
3314 3309 (exists(default_target_to_build) > file_doesnt_exist)) {
3315 3310 (void) printf(catgets(catd, 1, 295, "`%s' is up to date.\n"),
3316 3311 default_target_to_build->string_mb);
3317 3312 }
3318 3313 }
3319 3314 }
3320 3315 }
3321 3316 }
3322 3317 /* Now wait for all of the targets to finish running */
3323 3318 finish_running();
3324 3319 // setjmp(jmpbuffer);
3325 3320
3326 3321 }
3327 3322 #endif
3328 3323 for (i = 1; i < argc; i++) {
3329 3324 if ((cp = argv[i]) != NULL) {
3330 3325 target_to_make_found = true;
3331 3326 if ((cp[0] == (int) period_char) &&
3332 3327 (cp[1] == (int) slash_char)) {
3333 3328 cp += 2;
3334 3329 }
3335 3330 if((cp[0] == (int) ' ') &&
3336 3331 (cp[1] == (int) '-') &&
3337 3332 (cp[2] == (int) ' ') &&
3338 3333 (cp[3] == (int) '-')) {
3339 3334 argv[i] = NULL;
3340 3335 continue;
3341 3336 }
3342 3337 MBSTOWCS(wcs_buffer, cp);
3343 3338 default_target_to_build = normalize_name(wcs_buffer, wslen(wcs_buffer));
3344 3339 top_level_target = get_wstring(default_target_to_build->string_mb);
3345 3340 report_recursion(default_target_to_build);
3346 3341 commands_done = false;
3347 3342 if (parallel) {
3348 3343 result = (Doname) default_target_to_build->state;
3349 3344 } else {
3350 3345 result = doname_check(default_target_to_build,
3351 3346 true,
3352 3347 false,
3353 3348 false);
3354 3349 }
3355 3350 gather_recursive_deps();
3356 3351 if (build_failed_seen) {
3357 3352 build_failed_ever_seen = true;
3358 3353 warning(catgets(catd, 1, 200, "Target `%s' not remade because of errors"),
3359 3354 default_target_to_build->string_mb);
3360 3355 }
3361 3356 build_failed_seen = false;
3362 3357 if (report_dependencies_level > 0) {
3363 3358 print_dependencies(default_target_to_build,
3364 3359 get_prop(default_target_to_build->prop,
3365 3360 line_prop));
3366 3361 }
3367 3362 default_target_to_build->stat.time =
3368 3363 file_no_time;
3369 3364 if (default_target_to_build->colon_splits > 0) {
3370 3365 default_target_to_build->state =
3371 3366 build_dont_know;
3372 3367 }
3373 3368 if (!parallel &&
3374 3369 /* !commands_done && */
3375 3370 (result == build_ok) &&
3376 3371 !quest &&
3377 3372 (report_dependencies_level == 0) /* &&
3378 3373 (exists(default_target_to_build) > file_doesnt_exist) */) {
3379 3374 if (posix) {
3380 3375 if (!commands_done) {
3381 3376 (void) printf(catgets(catd, 1, 296, "`%s' is updated.\n"),
3382 3377 default_target_to_build->string_mb);
3383 3378 } else {
3384 3379 if (no_action_was_taken) {
3385 3380 (void) printf(catgets(catd, 1, 297, "`%s': no action was taken.\n"),
3386 3381 default_target_to_build->string_mb);
3387 3382 }
3388 3383 }
3389 3384 } else {
3390 3385 if (!commands_done &&
3391 3386 (exists(default_target_to_build) > file_doesnt_exist)) {
3392 3387 (void) printf(catgets(catd, 1, 298, "`%s' is up to date.\n"),
3393 3388 default_target_to_build->string_mb);
3394 3389 }
3395 3390 }
3396 3391 }
3397 3392 }
3398 3393 }
3399 3394
3400 3395 /*
3401 3396 * If no file arguments have been encountered,
3402 3397 * make the first name encountered that doesnt start with a dot
3403 3398 */
3404 3399 if (!target_to_make_found) {
3405 3400 if (default_target_to_build == NULL) {
3406 3401 fatal(catgets(catd, 1, 202, "No arguments to build"));
3407 3402 }
3408 3403 commands_done = false;
3409 3404 top_level_target = get_wstring(default_target_to_build->string_mb);
3410 3405 report_recursion(default_target_to_build);
3411 3406
3412 3407
3413 3408 if (getenv(NOCATGETS("SPRO_EXPAND_ERRORS"))){
3414 3409 (void) printf(NOCATGETS("::(%s)\n"),
3415 3410 default_target_to_build->string_mb);
3416 3411 }
3417 3412
3418 3413
3419 3414 #ifdef TEAMWARE_MAKE_CMN
3420 3415 result = doname_parallel(default_target_to_build, true, false);
3421 3416 #else
3422 3417 result = doname_check(default_target_to_build, true,
3423 3418 false, false);
3424 3419 #endif
3425 3420 gather_recursive_deps();
3426 3421 if (build_failed_seen) {
3427 3422 build_failed_ever_seen = true;
3428 3423 warning(catgets(catd, 1, 203, "Target `%s' not remade because of errors"),
3429 3424 default_target_to_build->string_mb);
3430 3425 }
3431 3426 build_failed_seen = false;
3432 3427 if (report_dependencies_level > 0) {
3433 3428 print_dependencies(default_target_to_build,
3434 3429 get_prop(default_target_to_build->
3435 3430 prop,
3436 3431 line_prop));
3437 3432 }
3438 3433 default_target_to_build->stat.time = file_no_time;
3439 3434 if (default_target_to_build->colon_splits > 0) {
3440 3435 default_target_to_build->state = build_dont_know;
3441 3436 }
3442 3437 if (/* !commands_done && */
3443 3438 (result == build_ok) &&
3444 3439 !quest &&
3445 3440 (report_dependencies_level == 0) /* &&
3446 3441 (exists(default_target_to_build) > file_doesnt_exist) */) {
3447 3442 if (posix) {
3448 3443 if (!commands_done) {
3449 3444 (void) printf(catgets(catd, 1, 299, "`%s' is updated.\n"),
3450 3445 default_target_to_build->string_mb);
3451 3446 } else {
3452 3447 if (no_action_was_taken) {
3453 3448 (void) printf(catgets(catd, 1, 300, "`%s': no action was taken.\n"),
3454 3449 default_target_to_build->string_mb);
3455 3450 }
3456 3451 }
3457 3452 } else {
3458 3453 if (!commands_done &&
3459 3454 (exists(default_target_to_build) > file_doesnt_exist)) {
3460 3455 (void) printf(catgets(catd, 1, 301, "`%s' is up to date.\n"),
3461 3456 default_target_to_build->string_mb);
3462 3457 }
3463 3458 }
3464 3459 }
3465 3460 }
3466 3461 }
3467 3462
3468 3463 /*
3469 3464 * report_recursion(target)
3470 3465 *
3471 3466 * If this is a recursive make and the parent make has KEEP_STATE on
3472 3467 * this routine reports the dependency to the parent make
3473 3468 *
3474 3469 * Parameters:
3475 3470 * target Target to report
3476 3471 *
3477 3472 * Global variables used:
3478 3473 * makefiles_used List of makefiles read
3479 3474 * recursive_name The Name ".RECURSIVE", printed
3480 3475 * report_dependency dwight
3481 3476 */
3482 3477 static void
3483 3478 report_recursion(register Name target)
3484 3479 {
3485 3480 register FILE *report_file = get_report_file();
3486 3481
3487 3482 if ((report_file == NULL) || (report_file == (FILE*)-1)) {
3488 3483 return;
3489 3484 }
3490 3485 if (primary_makefile == NULL) {
3491 3486 /*
3492 3487 * This can happen when there is no makefile and
3493 3488 * only implicit rules are being used.
3494 3489 */
3495 3490 #ifdef NSE
3496 3491 nse_no_makefile(target);
3497 3492 #endif
3498 3493 return;
3499 3494 }
3500 3495 (void) fprintf(report_file,
3501 3496 "%s: %s ",
3502 3497 get_target_being_reported_for(),
3503 3498 recursive_name->string_mb);
3504 3499 report_dependency(get_current_path());
3505 3500 report_dependency(target->string_mb);
3506 3501 report_dependency(primary_makefile->string_mb);
3507 3502 (void) fprintf(report_file, "\n");
3508 3503 }
3509 3504
3510 3505 /* Next function "append_or_replace_macro_in_dyn_array" must be in "misc.cc". */
3511 3506 /* NIKMOL */
3512 3507 extern void
3513 3508 append_or_replace_macro_in_dyn_array(ASCII_Dyn_Array *Ar, char *macro)
3514 3509 {
3515 3510 register char *cp0; /* work pointer in macro */
3516 3511 register char *cp1; /* work pointer in array */
3517 3512 register char *cp2; /* work pointer in array */
3518 3513 register char *cp3; /* work pointer in array */
3519 3514 register char *name; /* macro name */
3520 3515 register char *value; /* macro value */
3521 3516 register int len_array;
3522 3517 register int len_macro;
3523 3518
3524 3519 char * esc_value = NULL;
3525 3520 int esc_len;
3526 3521
3527 3522 if (!(len_macro = strlen(macro))) return;
3528 3523 name = macro;
3529 3524 while (isspace(*(name))) {
3530 3525 name++;
3531 3526 }
3532 3527 if (!(value = strchr(name, (int) equal_char))) {
3533 3528 /* no '=' in macro */
3534 3529 goto ERROR_MACRO;
3535 3530 }
3536 3531 cp0 = value;
3537 3532 value++;
3538 3533 while (isspace(*(value))) {
3539 3534 value++;
3540 3535 }
3541 3536 while (isspace(*(cp0-1))) {
3542 3537 cp0--;
3543 3538 }
3544 3539 if (cp0 <= name) goto ERROR_MACRO; /* no name */
3545 3540 if (!(Ar->size)) goto ALLOC_ARRAY;
3546 3541 cp1 = Ar->start;
3547 3542
3548 3543 LOOK_FOR_NAME:
3549 3544 if (!(cp1 = strchr(cp1, name[0]))) goto APPEND_MACRO;
3550 3545 if (!(cp2 = strchr(cp1, (int) equal_char))) goto APPEND_MACRO;
3551 3546 if (strncmp(cp1, name, (size_t)(cp0-name))) {
3552 3547 /* another name */
3553 3548 cp1++;
3554 3549 goto LOOK_FOR_NAME;
3555 3550 }
3556 3551 if (cp1 != Ar->start) {
3557 3552 if (!isspace(*(cp1-1))) {
3558 3553 /* another name */
3559 3554 cp1++;
3560 3555 goto LOOK_FOR_NAME;
3561 3556 }
3562 3557 }
3563 3558 for (cp3 = cp1 + (cp0-name); cp3 < cp2; cp3++) {
3564 3559 if (isspace(*cp3)) continue;
3565 3560 /* else: another name */
3566 3561 cp1++;
3567 3562 goto LOOK_FOR_NAME;
3568 3563 }
3569 3564 /* Look for the next macro name in array */
3570 3565 cp3 = cp2+1;
3571 3566 if (*cp3 != (int) doublequote_char) {
3572 3567 /* internal error */
3573 3568 goto ERROR_MACRO;
3574 3569 }
3575 3570 if (!(cp3 = strchr(cp3+1, (int) doublequote_char))) {
3576 3571 /* internal error */
3577 3572 goto ERROR_MACRO;
3578 3573 }
3579 3574 cp3++;
3580 3575 while (isspace(*cp3)) {
3581 3576 cp3++;
3582 3577 }
3583 3578
3584 3579 cp2 = cp1; /* remove old macro */
3585 3580 if ((*cp3) && (cp3 < Ar->start + Ar->size)) {
3586 3581 for (; cp3 < Ar->start + Ar->size; cp3++) {
3587 3582 *cp2++ = *cp3;
3588 3583 }
3589 3584 }
3590 3585 for (; cp2 < Ar->start + Ar->size; cp2++) {
3591 3586 *cp2 = 0;
3592 3587 }
3593 3588 if (*cp1) {
3594 3589 /* check next name */
3595 3590 goto LOOK_FOR_NAME;
3596 3591 }
3597 3592 goto APPEND_MACRO;
3598 3593
3599 3594 ALLOC_ARRAY:
3600 3595 if (Ar->size) {
3601 3596 cp1 = Ar->start;
3602 3597 } else {
3603 3598 cp1 = 0;
3604 3599 }
3605 3600 Ar->size += 128;
3606 3601 Ar->start = getmem(Ar->size);
3607 3602 for (len_array=0; len_array < Ar->size; len_array++) {
3608 3603 Ar->start[len_array] = 0;
3609 3604 }
3610 3605 if (cp1) {
3611 3606 strcpy(Ar->start, cp1);
3612 3607 retmem((wchar_t *) cp1);
3613 3608 }
3614 3609
3615 3610 APPEND_MACRO:
3616 3611 len_array = strlen(Ar->start);
3617 3612 esc_value = (char*)malloc(strlen(value)*2 + 1);
3618 3613 quote_str(value, esc_value);
3619 3614 esc_len = strlen(esc_value) - strlen(value);
3620 3615 if (len_array + len_macro + esc_len + 5 >= Ar->size) goto ALLOC_ARRAY;
3621 3616 strcat(Ar->start, " ");
3622 3617 strncat(Ar->start, name, cp0-name);
3623 3618 strcat(Ar->start, "=");
3624 3619 strncat(Ar->start, esc_value, strlen(esc_value));
3625 3620 free(esc_value);
3626 3621 return;
3627 3622 ERROR_MACRO:
3628 3623 /* Macro without '=' or with invalid left/right part */
3629 3624 return;
3630 3625 }
3631 3626
3632 3627 #ifdef TEAMWARE_MAKE_CMN
3633 3628 /*
3634 3629 * This function, if registered w/ avo_cli_get_license(), will be called
3635 3630 * if the application is about to exit because:
3636 3631 * 1) there has been certain unrecoverable error(s) that cause the
3637 3632 * application to exit immediately.
3638 3633 * 2) the user has lost a license while the application is running.
3639 3634 */
3640 3635 extern "C" void
3641 3636 dmake_exit_callback(void)
3642 3637 {
3643 3638 fatal(catgets(catd, 1, 306, "can not get a license, exiting..."));
3644 3639 exit(1);
3645 3640 }
3646 3641
3647 3642 /*
3648 3643 * This function, if registered w/ avo_cli_get_license(), will be called
3649 3644 * if the application can not get a license.
3650 3645 */
3651 3646 extern "C" void
3652 3647 dmake_message_callback(char *err_msg)
3653 3648 {
3654 3649 static Boolean first = true;
3655 3650
3656 3651 if (!first) {
3657 3652 return;
3658 3653 }
3659 3654 first = false;
3660 3655 if ((!list_all_targets) &&
3661 3656 (report_dependencies_level == 0) &&
3662 3657 (dmake_mode_type != serial_mode)) {
3663 3658 warning(catgets(catd, 1, 313, "can not get a TeamWare license, defaulting to serial mode..."));
3664 3659 }
3665 3660 }
3666 3661 #endif
3667 3662
3668 3663 #ifdef DISTRIBUTED
3669 3664 /*
3670 3665 * Returns whether -c is set or not.
3671 3666 */
3672 3667 Boolean
3673 3668 get_dmake_rcfile_specified(void)
3674 3669 {
3675 3670 return(dmake_rcfile_specified);
3676 3671 }
3677 3672
3678 3673 /*
3679 3674 * Returns whether -g is set or not.
3680 3675 */
3681 3676 Boolean
3682 3677 get_dmake_group_specified(void)
3683 3678 {
3684 3679 return(dmake_group_specified);
3685 3680 }
3686 3681
3687 3682 /*
3688 3683 * Returns whether -j is set or not.
3689 3684 */
3690 3685 Boolean
3691 3686 get_dmake_max_jobs_specified(void)
3692 3687 {
3693 3688 return(dmake_max_jobs_specified);
3694 3689 }
3695 3690
3696 3691 /*
3697 3692 * Returns whether -m is set or not.
3698 3693 */
3699 3694 Boolean
3700 3695 get_dmake_mode_specified(void)
3701 3696 {
3702 3697 return(dmake_mode_specified);
3703 3698 }
3704 3699
3705 3700 /*
3706 3701 * Returns whether -o is set or not.
3707 3702 */
3708 3703 Boolean
3709 3704 get_dmake_odir_specified(void)
3710 3705 {
3711 3706 return(dmake_odir_specified);
3712 3707 }
3713 3708
3714 3709 #endif
3715 3710
3716 3711 static void
3717 3712 report_dir_enter_leave(Boolean entering)
3718 3713 {
3719 3714 char rcwd[MAXPATHLEN];
3720 3715 static char * mlev = NULL;
3721 3716 char * make_level_str = NULL;
3722 3717 int make_level_val = 0;
3723 3718
3724 3719 make_level_str = getenv(NOCATGETS("MAKELEVEL"));
3725 3720 if(make_level_str) {
3726 3721 make_level_val = atoi(make_level_str);
3727 3722 }
3728 3723 if(mlev == NULL) {
3729 3724 mlev = (char*) malloc(MAXPATHLEN);
3730 3725 }
3731 3726 if(entering) {
3732 3727 sprintf(mlev, NOCATGETS("MAKELEVEL=%d"), make_level_val + 1);
3733 3728 } else {
3734 3729 make_level_val--;
3735 3730 sprintf(mlev, NOCATGETS("MAKELEVEL=%d"), make_level_val);
3736 3731 }
3737 3732 putenv(mlev);
3738 3733
3739 3734 if(report_cwd) {
3740 3735 if(make_level_val <= 0) {
3741 3736 if(entering) {
3742 3737 #ifdef TEAMWARE_MAKE_CMN
3743 3738 sprintf( rcwd
3744 3739 , catgets(catd, 1, 329, "dmake: Entering directory `%s'\n")
3745 3740 , get_current_path());
3746 3741 #else
3747 3742 sprintf( rcwd
3748 3743 , catgets(catd, 1, 330, "make: Entering directory `%s'\n")
3749 3744 , get_current_path());
3750 3745 #endif
3751 3746 } else {
3752 3747 #ifdef TEAMWARE_MAKE_CMN
3753 3748 sprintf( rcwd
3754 3749 , catgets(catd, 1, 331, "dmake: Leaving directory `%s'\n")
3755 3750 , get_current_path());
3756 3751 #else
3757 3752 sprintf( rcwd
3758 3753 , catgets(catd, 1, 332, "make: Leaving directory `%s'\n")
3759 3754 , get_current_path());
3760 3755 #endif
3761 3756 }
3762 3757 } else {
3763 3758 if(entering) {
3764 3759 #ifdef TEAMWARE_MAKE_CMN
3765 3760 sprintf( rcwd
3766 3761 , catgets(catd, 1, 333, "dmake[%d]: Entering directory `%s'\n")
3767 3762 , make_level_val, get_current_path());
3768 3763 #else
3769 3764 sprintf( rcwd
3770 3765 , catgets(catd, 1, 334, "make[%d]: Entering directory `%s'\n")
3771 3766 , make_level_val, get_current_path());
3772 3767 #endif
3773 3768 } else {
3774 3769 #ifdef TEAMWARE_MAKE_CMN
3775 3770 sprintf( rcwd
3776 3771 , catgets(catd, 1, 335, "dmake[%d]: Leaving directory `%s'\n")
3777 3772 , make_level_val, get_current_path());
3778 3773 #else
3779 3774 sprintf( rcwd
3780 3775 , catgets(catd, 1, 336, "make[%d]: Leaving directory `%s'\n")
3781 3776 , make_level_val, get_current_path());
3782 3777 #endif
3783 3778 }
3784 3779 }
3785 3780 printf(NOCATGETS("%s"), rcwd);
3786 3781 }
3787 3782 }
↓ open down ↓ |
3748 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX