21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * main.cc
28 *
29 * make program main routine plus some helper routines
30 */
31
32 /*
33 * Included files
34 */
35 #if defined(TEAMWARE_MAKE_CMN)
36 # include <avo/intl.h>
37 #endif
38
39 #include <bsd/bsd.h> /* bsd_signal() */
40
41 #ifdef DISTRIBUTED
42 # include <dm/Avo_AcknowledgeMsg.h>
43 # include <rw/xdrstrea.h>
44 # include <dmrc/dmrc.h> /* dmakerc file processing */
45 #endif
46
47 #include <locale.h> /* setlocale() */
48 #include <mk/defs.h>
49 #include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
50 #include <mksh/macro.h> /* getvar() */
51 #include <mksh/misc.h> /* getmem(), setup_char_semantics() */
52
53 #if defined(TEAMWARE_MAKE_CMN)
54 #endif
55
56 #include <pwd.h> /* getpwnam() */
57 #include <setjmp.h>
58 #include <signal.h>
59 #include <stdlib.h>
60 #include <sys/errno.h> /* ENOENT */
61 #include <sys/stat.h> /* fstat() */
62 #include <fcntl.h> /* open() */
63
64 # include <sys/systeminfo.h> /* sysinfo() */
65
148
149 extern int main(int, char * []);
150
151 static void append_makeflags_string(Name, String);
152 static void doalarm(int);
153 static void enter_argv_values(int , char **, ASCII_Dyn_Array *);
154 static void make_targets(int, char **, Boolean);
155 static int parse_command_option(char);
156 static void read_command_options(int, char **);
157 static void read_environment(Boolean);
158 static void read_files_and_state(int, char **);
159 static Boolean read_makefile(Name, Boolean, Boolean, Boolean);
160 static void report_recursion(Name);
161 static void set_sgs_support(void);
162 static void setup_for_projectdir(void);
163 static void setup_makeflags_argv(void);
164 static void report_dir_enter_leave(Boolean entering);
165
166 extern void expand_value(Name, register String , Boolean);
167
168 #ifdef DISTRIBUTED
169 extern int dmake_ofd;
170 extern FILE* dmake_ofp;
171 extern int rxmPid;
172 extern XDR xdrs_out;
173 #endif
174 #ifdef TEAMWARE_MAKE_CMN
175 static const char verstring[] = "illumos make";
176 #endif
177
178 jmp_buf jmpbuffer;
179 extern nl_catd catd;
180
181 /*
182 * main(argc, argv)
183 *
184 * Parameters:
185 * argc You know what this is
186 * argv You know what this is
187 *
188 * Static variables used:
189 * list_all_targets make -T seen
190 * trace_status make -p seen
191 *
192 * Global variables used:
193 * debug_level Should we trace make actions?
228 struct stat out_stat, err_stat;
229 hostid = gethostid();
230 bsd_signals();
231
232 (void) setlocale(LC_ALL, "");
233
234
235 #ifdef DMAKE_STATISTICS
236 if (getenv(NOCATGETS("DMAKE_STATISTICS"))) {
237 getname_stat = true;
238 }
239 #endif
240
241 #if defined(TEAMWARE_MAKE_CMN)
242 catd = catopen(AVO_DOMAIN_DMAKE, NL_CAT_LOCALE);
243 #endif
244
245 // ---> fprintf(stderr, catgets(catd, 15, 666, "--- SUN make ---\n"));
246
247
248 #if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL)
249 /*
250 * I put libmksdmsi18n_init() under #ifdef because it requires avo_i18n_init()
251 * from avo_util library.
252 */
253 libmksdmsi18n_init();
254 #endif
255
256
257 #ifndef TEAMWARE_MAKE_CMN
258 textdomain(NOCATGETS("SUNW_SPRO_MAKE"));
259 #endif /* TEAMWARE_MAKE_CMN */
260
261 #ifdef TEAMWARE_MAKE_CMN
262 g_argc = argc;
263 g_argv = (char **) malloc((g_argc + 1) * sizeof(char *));
264 for (i = 0; i < argc; i++) {
265 g_argv[i] = argv[i];
266 }
267 g_argv[i] = NULL;
268 #endif /* TEAMWARE_MAKE_CMN */
459 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("parallel"))) {
460 dmake_mode_type = parallel_mode;
461 no_parallel = false;
462 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("serial"))) {
463 dmake_mode_type = serial_mode;
464 no_parallel = true;
465 } else {
466 fatal(catgets(catd, 1, 307, "Unknown dmake mode argument `%s' after -m flag"), dmake_value2->string_mb);
467 }
468 }
469
470 if ((!list_all_targets) &&
471 (report_dependencies_level == 0)) {
472 /*
473 * Check to see if either DMAKE_RCFILE or DMAKE_MODE is defined.
474 * They could be defined in the env, in the makefile, or on the
475 * command line.
476 * If neither is defined, and $(HOME)/.dmakerc does not exists,
477 * then print a message, and default to parallel mode.
478 */
479 #ifdef DISTRIBUTED
480 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
481 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
482 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
483 dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
484 if ((((prop = get_prop(dmake_name->prop, macro_prop)) == NULL) ||
485 ((dmake_value = prop->body.macro.value) == NULL)) &&
486 (((prop2 = get_prop(dmake_name2->prop, macro_prop)) == NULL) ||
487 ((dmake_value2 = prop2->body.macro.value) == NULL))) {
488 Boolean empty_dmakerc = true;
489 char *homedir = getenv(NOCATGETS("HOME"));
490 if ((homedir != NULL) && (strlen(homedir) < (sizeof(def_dmakerc_path) - 16))) {
491 sprintf(def_dmakerc_path, NOCATGETS("%s/.dmakerc"), homedir);
492 if ((((statval = stat(def_dmakerc_path, &statbuf)) != 0) && (errno == ENOENT)) ||
493 ((statval == 0) && (statbuf.st_size == 0))) {
494 } else {
495 Avo_dmakerc *rcfile = new Avo_dmakerc();
496 Avo_err *err = rcfile->read(def_dmakerc_path, NULL, TRUE);
497 if (err) {
498 fatal(err->str);
499 }
500 empty_dmakerc = rcfile->was_empty();
501 delete rcfile;
502 }
503 }
504 if (empty_dmakerc) {
505 if (getenv(NOCATGETS("DMAKE_DEF_PRINTED")) == NULL) {
506 putenv(NOCATGETS("DMAKE_DEF_PRINTED=TRUE"));
507 (void) fprintf(stdout, catgets(catd, 1, 302, "dmake: defaulting to parallel mode.\n"));
508 (void) fprintf(stdout, catgets(catd, 1, 303, "See the man page dmake(1) for more information on setting up the .dmakerc file.\n"));
509 }
510 dmake_mode_type = parallel_mode;
511 no_parallel = false;
512 }
513 }
514 #else
515 if(dmake_mode_type == distributed_mode) {
516 dmake_mode_type = parallel_mode;
517 no_parallel = false;
518 }
519 #endif /* DISTRIBUTED */
520 }
521 }
522 #endif
523
524 #ifdef TEAMWARE_MAKE_CMN
525 parallel_flag = true;
526 putenv(strdup(NOCATGETS("DMAKE_CHILD=TRUE")));
527
528 //
529 // If dmake is running with -t option, set dmake_mode_type to serial.
530 // This is done because doname() calls touch_command() that runs serially.
531 // If we do not do that, maketool will have problems.
532 //
533 if(touch) {
534 dmake_mode_type = serial_mode;
535 no_parallel = true;
536 }
537 #else
538 parallel_flag = false;
539 #endif
547 * is not set. This variable may be used in order to preserve
548 * the 'old' behaviour.
549 */
550 out_err_same = true;
551 char * dmake_sep_var = getenv(NOCATGETS("__DMAKE_SEPARATE_STDERR"));
552 if (dmake_sep_var == NULL || (0 != strcasecmp(dmake_sep_var, NOCATGETS("NO")))) {
553 struct stat stdout_stat;
554 struct stat stderr_stat;
555 if( (fstat(1, &stdout_stat) == 0)
556 && (fstat(2, &stderr_stat) == 0) )
557 {
558 if( (stdout_stat.st_dev != stderr_stat.st_dev)
559 || (stdout_stat.st_ino != stderr_stat.st_ino) )
560 {
561 out_err_same = false;
562 }
563 }
564 }
565 #endif
566
567 #ifdef DISTRIBUTED
568 /*
569 * At this point, DMake should startup an rxm with any and all
570 * DMake command line options. Rxm will, among other things,
571 * read the rc file.
572 */
573 if ((!list_all_targets) &&
574 (report_dependencies_level == 0) &&
575 (dmake_mode_type == distributed_mode)) {
576 startup_rxm();
577 }
578 #endif
579
580 /*
581 * Enable interrupt handler for alarms
582 */
583 (void) bsd_signal(SIGALRM, (SIG_PF)doalarm);
584
585 /*
586 * Check if make should report
587 */
588 if (getenv(sunpro_dependencies->string_mb) != NULL) {
589 FILE *report_file;
590
591 report_dependency("");
592 report_file = get_report_file();
593 if ((report_file != NULL) && (report_file != (FILE*)-1)) {
594 (void) fprintf(report_file, "\n");
595 }
596 }
597
598 /*
636 /* when there is only one slash and it's the first
637 ** character, make_state_dir should point to '/'.
638 */
639 if(make_state_dir[0] == '\0') {
640 make_state_dir[0] = '/';
641 make_state_dir[1] = '\0';
642 }
643 if (make_state_dir[0] == (int) slash_char) {
644 temp_file_directory = strdup(make_state_dir);
645 } else {
646 char tmp_current_path2[MAXPATHLEN];
647
648 (void) sprintf(tmp_current_path2,
649 "%s/%s",
650 get_current_path(),
651 make_state_dir);
652 temp_file_directory = strdup(tmp_current_path2);
653 }
654 }
655
656 #ifdef DISTRIBUTED
657 building_serial = false;
658 #endif
659
660 report_dir_enter_leave(true);
661
662 make_targets(argc, argv, parallel_flag);
663
664 report_dir_enter_leave(false);
665
666 if (build_failed_ever_seen) {
667 if (posix) {
668 exit_status = 1;
669 }
670 exit(1);
671 }
672 exit_status = 0;
673 exit(0);
674 /* NOTREACHED */
675 }
676
677 /*
678 * cleanup_after_exit()
727
728 printf(NOCATGETS("\n Unallocated: %ld\n"), freename_names_count);
729 printf(NOCATGETS(" Names: %ld\n"), freename_names_count);
730 printf(NOCATGETS(" Strings: %ld Kb (%ld bytes)\n"), freename_bytes_count/1000, freename_bytes_count);
731 printf(NOCATGETS(" Structs: %ld Kb (%ld bytes)\n"), freename_struct_count/1000, freename_struct_count);
732 printf(NOCATGETS(" Total bytes: %ld Kb (%ld bytes)\n"), freename_struct_count/1000 + freename_bytes_count/1000, freename_struct_count + freename_bytes_count);
733
734 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));
735
736 printf(NOCATGETS("\n>>> Other:\n"));
737 printf(
738 NOCATGETS(" Env (%ld): %ld Kb (%ld bytes)\n"),
739 env_alloc_num,
740 env_alloc_bytes/1000,
741 env_alloc_bytes
742 );
743
744 }
745 #endif
746
747 /*
748 #ifdef DISTRIBUTED
749 if (get_parent() == TRUE) {
750 #endif
751 */
752
753 parallel = false;
754 /* If we used the SVR4_MAKE, don't build .DONE or .FAILED */
755 if (!getenv(USE_SVR4_MAKE)){
756 /* Build the target .DONE or .FAILED if we caught an error */
757 if (!quest && !list_all_targets) {
758 Name failed_name;
759
760 MBSTOWCS(wcs_buffer, NOCATGETS(".FAILED"));
761 failed_name = GETNAME(wcs_buffer, FIND_LENGTH);
762 if ((exit_status != 0) && (failed_name->prop != NULL)) {
763 #ifdef TEAMWARE_MAKE_CMN
764 /*
765 * [tolik] switch DMake to serial mode
766 */
767 dmake_mode_type = serial_mode;
768 no_parallel = true;
769 #endif
770 (void) doname(failed_name, false, true);
771 } else {
772 if (!trace_status) {
814 (void) unlink(rp->stderr_file);
815 retmem_mb(rp->stderr_file);
816 rp->stderr_file = NULL;
817 }
818 command_changed = true;
819 /*
820 line = get_prop(rp->target->prop, line_prop);
821 if (line != NULL) {
822 line->body.line.command_used = NULL;
823 }
824 */
825 }
826 /* Remove the statefile lock file if the file has been locked */
827 if ((make_state_lockfile != NULL) && (make_state_locked)) {
828 (void) unlink(make_state_lockfile);
829 make_state_lockfile = NULL;
830 make_state_locked = false;
831 }
832 /* Write .make.state */
833 write_state_file(1, (Boolean) 1);
834 /*
835 #ifdef DISTRIBUTED
836 }
837 #endif
838 */
839
840 #if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
841 job_adjust_fini();
842 #endif
843
844 #ifdef TEAMWARE_MAKE_CMN
845 catclose(catd);
846 #endif
847 #ifdef DISTRIBUTED
848 if (rxmPid > 0) {
849 // Tell rxm to exit by sending it an Avo_AcknowledgeMsg
850 Avo_AcknowledgeMsg acknowledgeMsg;
851 RWCollectable *msg = (RWCollectable *)&acknowledgeMsg;
852
853 int xdrResult = xdr(&xdrs_out, msg);
854
855 if (xdrResult) {
856 fflush(dmake_ofp);
857 } else {
858 /*
859 fatal(catgets(catd, 1, 266, "couldn't tell rxm to exit"));
860 */
861 kill(rxmPid, SIGTERM);
862 }
863
864 waitpid(rxmPid, NULL, 0);
865 rxmPid = 0;
866 }
867 #endif
868 }
869
870 /*
871 * handle_interrupt()
872 *
873 * This is where C-C traps are caught.
874 *
875 * Parameters:
876 *
877 * Global variables used (except DMake 1.0):
878 * current_target Sometimes the current target is removed
879 * do_not_exec_rule But not if -n is on
880 * quest or -q
881 * running_list List of parallel running processes
882 * touch Current target is not removed if -t on
883 */
884 void
885 handle_interrupt(int)
886 {
887 Property member;
888 Running rp;
889
890 (void) fflush(stdout);
891 #ifdef DISTRIBUTED
892 if (rxmPid > 0) {
893 // Tell rxm to exit by sending it an Avo_AcknowledgeMsg
894 Avo_AcknowledgeMsg acknowledgeMsg;
895 RWCollectable *msg = (RWCollectable *)&acknowledgeMsg;
896
897 int xdrResult = xdr(&xdrs_out, msg);
898
899 if (xdrResult) {
900 fflush(dmake_ofp);
901 } else {
902 kill(rxmPid, SIGTERM);
903 rxmPid = 0;
904 }
905 }
906 #endif
907 if (childPid > 0) {
908 kill(childPid, SIGTERM);
909 childPid = -1;
910 }
911 for (rp = running_list; rp != NULL; rp = rp->next) {
912 if (rp->state != build_running) {
913 continue;
914 }
915 if (rp->pid > 0) {
916 kill(rp->pid, SIGTERM);
917 rp->pid = -1;
918 }
919 }
920 if (getpid() == getpgrp()) {
921 bsd_signal(SIGTERM, SIG_IGN);
922 kill (-getpid(), SIGTERM);
923 }
924 #ifdef TEAMWARE_MAKE_CMN
925 /* Clean up all parallel/distributed children already finished */
926 finish_children(false);
1602 }
1603 return 1024;
1604 case 'N': /* Reverse -n */
1605 if (invert_this) {
1606 do_not_exec_rule = true;
1607 } else {
1608 do_not_exec_rule = false;
1609 }
1610 return 0;
1611 case 'n': /* Print, not exec commands */
1612 if (invert_this) {
1613 do_not_exec_rule = false;
1614 } else {
1615 do_not_exec_rule = true;
1616 }
1617 return 0;
1618 case 'O': /* Send job start & result msgs */
1619 if (invert_this) {
1620 send_mtool_msgs = false;
1621 } else {
1622 #ifdef DISTRIBUTED
1623 send_mtool_msgs = true;
1624 #endif
1625 }
1626 return 128;
1627 case 'o': /* Use alternative dmake output dir */
1628 if (invert_this) {
1629 dmake_odir_specified = false;
1630 } else {
1631 dmake_odir_specified = true;
1632 }
1633 return 512;
1634 case 'P': /* Print for selected targets */
1635 if (invert_this) {
1636 report_dependencies_level--;
1637 } else {
1638 report_dependencies_level++;
1639 }
1640 return 0;
1641 case 'p': /* Print description */
1642 if (invert_this) {
1643 trace_status = false;
1644 do_not_exec_rule = false;
3392 * This function, if registered w/ avo_cli_get_license(), will be called
3393 * if the application can not get a license.
3394 */
3395 extern "C" void
3396 dmake_message_callback(char *err_msg)
3397 {
3398 static Boolean first = true;
3399
3400 if (!first) {
3401 return;
3402 }
3403 first = false;
3404 if ((!list_all_targets) &&
3405 (report_dependencies_level == 0) &&
3406 (dmake_mode_type != serial_mode)) {
3407 warning(catgets(catd, 1, 313, "can not get a TeamWare license, defaulting to serial mode..."));
3408 }
3409 }
3410 #endif
3411
3412 #ifdef DISTRIBUTED
3413 /*
3414 * Returns whether -c is set or not.
3415 */
3416 Boolean
3417 get_dmake_rcfile_specified(void)
3418 {
3419 return(dmake_rcfile_specified);
3420 }
3421
3422 /*
3423 * Returns whether -g is set or not.
3424 */
3425 Boolean
3426 get_dmake_group_specified(void)
3427 {
3428 return(dmake_group_specified);
3429 }
3430
3431 /*
3432 * Returns whether -j is set or not.
3433 */
3434 Boolean
3435 get_dmake_max_jobs_specified(void)
3436 {
3437 return(dmake_max_jobs_specified);
3438 }
3439
3440 /*
3441 * Returns whether -m is set or not.
3442 */
3443 Boolean
3444 get_dmake_mode_specified(void)
3445 {
3446 return(dmake_mode_specified);
3447 }
3448
3449 /*
3450 * Returns whether -o is set or not.
3451 */
3452 Boolean
3453 get_dmake_odir_specified(void)
3454 {
3455 return(dmake_odir_specified);
3456 }
3457
3458 #endif
3459
3460 static void
3461 report_dir_enter_leave(Boolean entering)
3462 {
3463 char rcwd[MAXPATHLEN];
3464 static char * mlev = NULL;
3465 char * make_level_str = NULL;
3466 int make_level_val = 0;
3467
3468 make_level_str = getenv(NOCATGETS("MAKELEVEL"));
3469 if(make_level_str) {
3470 make_level_val = atoi(make_level_str);
3471 }
3472 if(mlev == NULL) {
3473 mlev = (char*) malloc(MAXPATHLEN);
3474 }
3475 if(entering) {
3476 sprintf(mlev, NOCATGETS("MAKELEVEL=%d"), make_level_val + 1);
3477 } else {
3478 make_level_val--;
|
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * main.cc
28 *
29 * make program main routine plus some helper routines
30 */
31
32 /*
33 * Included files
34 */
35 #if defined(TEAMWARE_MAKE_CMN)
36 # include <avo/intl.h>
37 #endif
38
39 #include <bsd/bsd.h> /* bsd_signal() */
40
41
42 #include <locale.h> /* setlocale() */
43 #include <mk/defs.h>
44 #include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
45 #include <mksh/macro.h> /* getvar() */
46 #include <mksh/misc.h> /* getmem(), setup_char_semantics() */
47
48 #if defined(TEAMWARE_MAKE_CMN)
49 #endif
50
51 #include <pwd.h> /* getpwnam() */
52 #include <setjmp.h>
53 #include <signal.h>
54 #include <stdlib.h>
55 #include <sys/errno.h> /* ENOENT */
56 #include <sys/stat.h> /* fstat() */
57 #include <fcntl.h> /* open() */
58
59 # include <sys/systeminfo.h> /* sysinfo() */
60
143
144 extern int main(int, char * []);
145
146 static void append_makeflags_string(Name, String);
147 static void doalarm(int);
148 static void enter_argv_values(int , char **, ASCII_Dyn_Array *);
149 static void make_targets(int, char **, Boolean);
150 static int parse_command_option(char);
151 static void read_command_options(int, char **);
152 static void read_environment(Boolean);
153 static void read_files_and_state(int, char **);
154 static Boolean read_makefile(Name, Boolean, Boolean, Boolean);
155 static void report_recursion(Name);
156 static void set_sgs_support(void);
157 static void setup_for_projectdir(void);
158 static void setup_makeflags_argv(void);
159 static void report_dir_enter_leave(Boolean entering);
160
161 extern void expand_value(Name, register String , Boolean);
162
163 #ifdef TEAMWARE_MAKE_CMN
164 static const char verstring[] = "illumos make";
165 #endif
166
167 jmp_buf jmpbuffer;
168 extern nl_catd catd;
169
170 /*
171 * main(argc, argv)
172 *
173 * Parameters:
174 * argc You know what this is
175 * argv You know what this is
176 *
177 * Static variables used:
178 * list_all_targets make -T seen
179 * trace_status make -p seen
180 *
181 * Global variables used:
182 * debug_level Should we trace make actions?
217 struct stat out_stat, err_stat;
218 hostid = gethostid();
219 bsd_signals();
220
221 (void) setlocale(LC_ALL, "");
222
223
224 #ifdef DMAKE_STATISTICS
225 if (getenv(NOCATGETS("DMAKE_STATISTICS"))) {
226 getname_stat = true;
227 }
228 #endif
229
230 #if defined(TEAMWARE_MAKE_CMN)
231 catd = catopen(AVO_DOMAIN_DMAKE, NL_CAT_LOCALE);
232 #endif
233
234 // ---> fprintf(stderr, catgets(catd, 15, 666, "--- SUN make ---\n"));
235
236
237 #if defined(TEAMWARE_MAKE_CMN)
238 /*
239 * I put libmksdmsi18n_init() under #ifdef because it requires avo_i18n_init()
240 * from avo_util library.
241 */
242 libmksdmsi18n_init();
243 #endif
244
245
246 #ifndef TEAMWARE_MAKE_CMN
247 textdomain(NOCATGETS("SUNW_SPRO_MAKE"));
248 #endif /* TEAMWARE_MAKE_CMN */
249
250 #ifdef TEAMWARE_MAKE_CMN
251 g_argc = argc;
252 g_argv = (char **) malloc((g_argc + 1) * sizeof(char *));
253 for (i = 0; i < argc; i++) {
254 g_argv[i] = argv[i];
255 }
256 g_argv[i] = NULL;
257 #endif /* TEAMWARE_MAKE_CMN */
448 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("parallel"))) {
449 dmake_mode_type = parallel_mode;
450 no_parallel = false;
451 } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("serial"))) {
452 dmake_mode_type = serial_mode;
453 no_parallel = true;
454 } else {
455 fatal(catgets(catd, 1, 307, "Unknown dmake mode argument `%s' after -m flag"), dmake_value2->string_mb);
456 }
457 }
458
459 if ((!list_all_targets) &&
460 (report_dependencies_level == 0)) {
461 /*
462 * Check to see if either DMAKE_RCFILE or DMAKE_MODE is defined.
463 * They could be defined in the env, in the makefile, or on the
464 * command line.
465 * If neither is defined, and $(HOME)/.dmakerc does not exists,
466 * then print a message, and default to parallel mode.
467 */
468 if(dmake_mode_type == distributed_mode) {
469 dmake_mode_type = parallel_mode;
470 no_parallel = false;
471 }
472 }
473 }
474 #endif
475
476 #ifdef TEAMWARE_MAKE_CMN
477 parallel_flag = true;
478 putenv(strdup(NOCATGETS("DMAKE_CHILD=TRUE")));
479
480 //
481 // If dmake is running with -t option, set dmake_mode_type to serial.
482 // This is done because doname() calls touch_command() that runs serially.
483 // If we do not do that, maketool will have problems.
484 //
485 if(touch) {
486 dmake_mode_type = serial_mode;
487 no_parallel = true;
488 }
489 #else
490 parallel_flag = false;
491 #endif
499 * is not set. This variable may be used in order to preserve
500 * the 'old' behaviour.
501 */
502 out_err_same = true;
503 char * dmake_sep_var = getenv(NOCATGETS("__DMAKE_SEPARATE_STDERR"));
504 if (dmake_sep_var == NULL || (0 != strcasecmp(dmake_sep_var, NOCATGETS("NO")))) {
505 struct stat stdout_stat;
506 struct stat stderr_stat;
507 if( (fstat(1, &stdout_stat) == 0)
508 && (fstat(2, &stderr_stat) == 0) )
509 {
510 if( (stdout_stat.st_dev != stderr_stat.st_dev)
511 || (stdout_stat.st_ino != stderr_stat.st_ino) )
512 {
513 out_err_same = false;
514 }
515 }
516 }
517 #endif
518
519
520 /*
521 * Enable interrupt handler for alarms
522 */
523 (void) bsd_signal(SIGALRM, (SIG_PF)doalarm);
524
525 /*
526 * Check if make should report
527 */
528 if (getenv(sunpro_dependencies->string_mb) != NULL) {
529 FILE *report_file;
530
531 report_dependency("");
532 report_file = get_report_file();
533 if ((report_file != NULL) && (report_file != (FILE*)-1)) {
534 (void) fprintf(report_file, "\n");
535 }
536 }
537
538 /*
576 /* when there is only one slash and it's the first
577 ** character, make_state_dir should point to '/'.
578 */
579 if(make_state_dir[0] == '\0') {
580 make_state_dir[0] = '/';
581 make_state_dir[1] = '\0';
582 }
583 if (make_state_dir[0] == (int) slash_char) {
584 temp_file_directory = strdup(make_state_dir);
585 } else {
586 char tmp_current_path2[MAXPATHLEN];
587
588 (void) sprintf(tmp_current_path2,
589 "%s/%s",
590 get_current_path(),
591 make_state_dir);
592 temp_file_directory = strdup(tmp_current_path2);
593 }
594 }
595
596
597 report_dir_enter_leave(true);
598
599 make_targets(argc, argv, parallel_flag);
600
601 report_dir_enter_leave(false);
602
603 if (build_failed_ever_seen) {
604 if (posix) {
605 exit_status = 1;
606 }
607 exit(1);
608 }
609 exit_status = 0;
610 exit(0);
611 /* NOTREACHED */
612 }
613
614 /*
615 * cleanup_after_exit()
664
665 printf(NOCATGETS("\n Unallocated: %ld\n"), freename_names_count);
666 printf(NOCATGETS(" Names: %ld\n"), freename_names_count);
667 printf(NOCATGETS(" Strings: %ld Kb (%ld bytes)\n"), freename_bytes_count/1000, freename_bytes_count);
668 printf(NOCATGETS(" Structs: %ld Kb (%ld bytes)\n"), freename_struct_count/1000, freename_struct_count);
669 printf(NOCATGETS(" Total bytes: %ld Kb (%ld bytes)\n"), freename_struct_count/1000 + freename_bytes_count/1000, freename_struct_count + freename_bytes_count);
670
671 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));
672
673 printf(NOCATGETS("\n>>> Other:\n"));
674 printf(
675 NOCATGETS(" Env (%ld): %ld Kb (%ld bytes)\n"),
676 env_alloc_num,
677 env_alloc_bytes/1000,
678 env_alloc_bytes
679 );
680
681 }
682 #endif
683
684 parallel = false;
685 /* If we used the SVR4_MAKE, don't build .DONE or .FAILED */
686 if (!getenv(USE_SVR4_MAKE)){
687 /* Build the target .DONE or .FAILED if we caught an error */
688 if (!quest && !list_all_targets) {
689 Name failed_name;
690
691 MBSTOWCS(wcs_buffer, NOCATGETS(".FAILED"));
692 failed_name = GETNAME(wcs_buffer, FIND_LENGTH);
693 if ((exit_status != 0) && (failed_name->prop != NULL)) {
694 #ifdef TEAMWARE_MAKE_CMN
695 /*
696 * [tolik] switch DMake to serial mode
697 */
698 dmake_mode_type = serial_mode;
699 no_parallel = true;
700 #endif
701 (void) doname(failed_name, false, true);
702 } else {
703 if (!trace_status) {
745 (void) unlink(rp->stderr_file);
746 retmem_mb(rp->stderr_file);
747 rp->stderr_file = NULL;
748 }
749 command_changed = true;
750 /*
751 line = get_prop(rp->target->prop, line_prop);
752 if (line != NULL) {
753 line->body.line.command_used = NULL;
754 }
755 */
756 }
757 /* Remove the statefile lock file if the file has been locked */
758 if ((make_state_lockfile != NULL) && (make_state_locked)) {
759 (void) unlink(make_state_lockfile);
760 make_state_lockfile = NULL;
761 make_state_locked = false;
762 }
763 /* Write .make.state */
764 write_state_file(1, (Boolean) 1);
765
766 #if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
767 job_adjust_fini();
768 #endif
769
770 #ifdef TEAMWARE_MAKE_CMN
771 catclose(catd);
772 #endif
773 }
774
775 /*
776 * handle_interrupt()
777 *
778 * This is where C-C traps are caught.
779 *
780 * Parameters:
781 *
782 * Global variables used (except DMake 1.0):
783 * current_target Sometimes the current target is removed
784 * do_not_exec_rule But not if -n is on
785 * quest or -q
786 * running_list List of parallel running processes
787 * touch Current target is not removed if -t on
788 */
789 void
790 handle_interrupt(int)
791 {
792 Property member;
793 Running rp;
794
795 (void) fflush(stdout);
796 if (childPid > 0) {
797 kill(childPid, SIGTERM);
798 childPid = -1;
799 }
800 for (rp = running_list; rp != NULL; rp = rp->next) {
801 if (rp->state != build_running) {
802 continue;
803 }
804 if (rp->pid > 0) {
805 kill(rp->pid, SIGTERM);
806 rp->pid = -1;
807 }
808 }
809 if (getpid() == getpgrp()) {
810 bsd_signal(SIGTERM, SIG_IGN);
811 kill (-getpid(), SIGTERM);
812 }
813 #ifdef TEAMWARE_MAKE_CMN
814 /* Clean up all parallel/distributed children already finished */
815 finish_children(false);
1491 }
1492 return 1024;
1493 case 'N': /* Reverse -n */
1494 if (invert_this) {
1495 do_not_exec_rule = true;
1496 } else {
1497 do_not_exec_rule = false;
1498 }
1499 return 0;
1500 case 'n': /* Print, not exec commands */
1501 if (invert_this) {
1502 do_not_exec_rule = false;
1503 } else {
1504 do_not_exec_rule = true;
1505 }
1506 return 0;
1507 case 'O': /* Send job start & result msgs */
1508 if (invert_this) {
1509 send_mtool_msgs = false;
1510 } else {
1511 }
1512 return 128;
1513 case 'o': /* Use alternative dmake output dir */
1514 if (invert_this) {
1515 dmake_odir_specified = false;
1516 } else {
1517 dmake_odir_specified = true;
1518 }
1519 return 512;
1520 case 'P': /* Print for selected targets */
1521 if (invert_this) {
1522 report_dependencies_level--;
1523 } else {
1524 report_dependencies_level++;
1525 }
1526 return 0;
1527 case 'p': /* Print description */
1528 if (invert_this) {
1529 trace_status = false;
1530 do_not_exec_rule = false;
3278 * This function, if registered w/ avo_cli_get_license(), will be called
3279 * if the application can not get a license.
3280 */
3281 extern "C" void
3282 dmake_message_callback(char *err_msg)
3283 {
3284 static Boolean first = true;
3285
3286 if (!first) {
3287 return;
3288 }
3289 first = false;
3290 if ((!list_all_targets) &&
3291 (report_dependencies_level == 0) &&
3292 (dmake_mode_type != serial_mode)) {
3293 warning(catgets(catd, 1, 313, "can not get a TeamWare license, defaulting to serial mode..."));
3294 }
3295 }
3296 #endif
3297
3298
3299 static void
3300 report_dir_enter_leave(Boolean entering)
3301 {
3302 char rcwd[MAXPATHLEN];
3303 static char * mlev = NULL;
3304 char * make_level_str = NULL;
3305 int make_level_val = 0;
3306
3307 make_level_str = getenv(NOCATGETS("MAKELEVEL"));
3308 if(make_level_str) {
3309 make_level_val = atoi(make_level_str);
3310 }
3311 if(mlev == NULL) {
3312 mlev = (char*) malloc(MAXPATHLEN);
3313 }
3314 if(entering) {
3315 sprintf(mlev, NOCATGETS("MAKELEVEL=%d"), make_level_val + 1);
3316 } else {
3317 make_level_val--;
|