Subversion Repositories tendra.SVN

Rev

Rev 5 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
6 7u83 2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
6 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
6 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
6 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
6 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
6 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "filename.h"
63
#include "list.h"
64
#include "archive.h"
65
#include "execute.h"
66
#include "flags.h"
67
#include "options.h"
68
#include "stages.h"
69
#include "startup.h"
70
#include "suffix.h"
71
#include "utility.h"
72
 
73
 
74
/*
6 7u83 75
 * BINARY OBJECT FILE TYPE
76
 *
77
 * The type of binary object file to be produced, for example, by the assembler
78
 * varies according to whether it will later be included in a spec archive.
79
 * This value determines this file type.
80
 */
2 7u83 81
 
6 7u83 82
int binary_obj_type = BINARY_OBJ;
2 7u83 83
 
84
 
85
/*
6 7u83 86
 * COPY A FILE
87
 *
88
 * This routine moves the file from to the file to. If to is null then from is
89
 * copied to the standard output. All the routines in this module return their
90
 * set of output files. This may be null if an error has occurred.
91
 */
2 7u83 92
 
6 7u83 93
static filename *
94
do_move(filename *from, filename *to)
2 7u83 95
{
6 7u83 96
	if (from == null) {
97
		return (from);
98
	}
99
	if (to) {
100
		if (streq(from->name, to->name)) {
101
			return (to);
102
		}
103
		cmd_list(exec_move);
104
		cmd_filename(from);
105
		cmd_filename(to);
106
	} else {
107
		cmd_list(exec_cat);
108
		cmd_filename(from);
109
	}
110
	return (execute(from, to));
2 7u83 111
}
112
 
113
 
114
/*
6 7u83 115
 * PRESERVE A FILE
116
 *
117
 * This routine preserves the file p by moving it, if necessary, to the work
118
 * directory. It returns the new location of p.
119
 */
2 7u83 120
 
6 7u83 121
filename *
122
do_keep(filename *p)
2 7u83 123
{
6 7u83 124
	if (p->storage == TEMP_FILE) {
125
		filename *q = make_filename(p, p->type, PRESERVED_FILE);
126
		cmd_list(exec_move);
127
		cmd_filename(p);
128
		cmd_filename(q);
129
		IGNORE execute(no_filename, no_filename);
130
		return (q);
131
	}
132
	return (p);
2 7u83 133
}
134
 
135
 
136
/*
6 7u83 137
 * TEMPORARY FILE NAME
138
 *
139
 * This is set by uniq_filename to be either its output file or a temporary
140
 * file if the output corresponds to an input file.
141
 */
2 7u83 142
 
6 7u83 143
static filename *uniq_tempfile = null;
2 7u83 144
 
145
 
146
/*
6 7u83 147
 * MAKE A UNIQUE FILE NAME
148
 *
149
 * This routine creates a filename with name nm, type t and storage s. If this
150
 * coincides with one of the files in input then a temporary file is stored in
151
 * uniq_tempfile, otherwise it holds the output file.
152
 */
2 7u83 153
 
6 7u83 154
static filename *
155
uniq_filename(char *nm, int t, int s, filename *input)
2 7u83 156
{
6 7u83 157
	filename *p = find_filename(nm, t);
158
	filename *q = make_filename(p, t, s);
159
	uniq_tempfile = q;
160
	for (p = input; p != null; p = p->next) {
161
		if (streq(p->name, q->name)) {
162
			if (p->storage == TEMP_FILE) {
163
				uniq_tempfile = make_filename(no_filename, t,
164
							      TEMP_FILE);
165
			} else {
166
				char *m;
167
				static char plus[] = { EXTRA_KEY, 0 };
168
				q->name = string_concat(q->name, plus);
169
				switch (t)EXHAUSTIVE {
170
				case INDEP_TDF:
171
					m = "merged TDF capsule";
172
					break;
173
				case TDF_ARCHIVE:
174
					m = "archive file";
175
					break;
176
				case C_SPEC:
177
					m = "linked C spec file";
178
					break;
179
				case CPP_SPEC:
180
					m = "linked C++ spec file";
181
					break;
182
				case EXECUTABLE:
183
					m = "executable";
184
					break;
185
				}
186
				error(WARNING,
187
				      "Renaming %s '%s' to '%s' to avoid clash with input",
188
				      m, p->name, q->name);
189
			}
190
			return (q);
2 7u83 191
		}
192
	}
6 7u83 193
	return (q);
2 7u83 194
}
195
 
196
 
197
/*
6 7u83 198
 * PRINT PRODUCER/PREPROCESSOR OPTIONS
199
 *
200
 * The C/C++ to TDF producers and the TDF C/C++ preprocessor accept the same
201
 * command-line options; the parameter 'pp' is used to determine which startup
202
 * files are appropriate.
203
 */
2 7u83 204
 
6 7u83 205
static void
206
producer_options(int pp)
2 7u83 207
{
6 7u83 208
	boolean is_c = (pp == PRODUCE_ID || pp == PREPROC_ID);
209
	if (!flag_nepc && std_prod_portfile) {
210
		cmd_string("-n");
211
		cmd_string(std_prod_portfile->item);
2 7u83 212
	}
6 7u83 213
	if (flag_diag) {
214
		if (flag_diag == 1) {
215
			cmd_string("-g1");
216
		} else {
217
			cmd_string("-g2");
218
		}
2 7u83 219
	}
6 7u83 220
	if (flag_incl) {
221
		cmd_string("-H");
2 7u83 222
	}
6 7u83 223
	if (flag_startup) {
224
		if (is_c) {
225
			cmd_list(std_prod_startup);
226
			cmd_list(usr_prod_startup);
227
		} else {
228
			cmd_list(std_cpp_prod_startup);
229
			cmd_list(usr_cpp_prod_startup);
230
		}
231
		if (startup_opt) {
232
			cmd_string(startup_opt);
233
		}
234
		cmd_list(usr_prod_foptions);
235
		cmd_list(usr_prod_eoptions);
236
		if (endup_opt) {
237
			cmd_string(endup_opt);
238
		}
239
	}
240
	cmd_list(usr_prod_incldirs);
241
	if (!is_c) {
242
		cmd_list(std_cpp_prod_incldirs);
243
	}
244
	cmd_list(std_prod_incldirs);
245
	if (flag_startup) {
246
		if (is_c) {
247
			cmd_list(std_prod_startdirs);
248
		} else {
249
			cmd_list(std_cpp_prod_startdirs);
250
		}
251
	}
252
	if (checker) {
253
		cmd_string("-c");
254
	}
255
	if (make_pretty) {
256
		cmd_string("-t");
257
	}
258
	return;
2 7u83 259
}
260
 
261
 
262
/*
6 7u83 263
 * APPLY THE C PRODUCER
264
 *
265
 * This routine applies the C to TDF producer to input and returns the result.
266
 */
2 7u83 267
 
6 7u83 268
filename *
269
do_produce(filename *input)
2 7u83 270
{
6 7u83 271
	boolean spec_produced;
272
	filename *output, *spec;
273
	if (input == null) {
274
		return (input);
2 7u83 275
	}
6 7u83 276
	output = make_filename(input, INDEP_TDF, where(INDEP_TDF));
277
	cmd_list(exec_produce);
278
	if (allow_specs == 1) {
279
		spec = make_filename(input, C_SPEC, where(C_SPEC));
280
		if (dump_opts) {
281
			cmd_string(string_concat(dump_opts, spec->name));
282
		} else {
283
			cmd_string("-s");
284
			cmd_string(spec->name);
285
		}
286
	}
287
	cmd_list(opt_produce);
288
	producer_options(PRODUCE_ID);
289
	cmd_filename(input);
290
	cmd_filename(output);
2 7u83 291
 
6 7u83 292
	/* Execute the command */
293
	enable_delayed_signal();
294
	output = execute(input, output);
295
	spec_produced = (allow_specs == 1) && (last_return != 2) &&
296
	    (checker || output != null);
297
	disable_delayed_signal();
298
	process_delayed_signal();
299
	if (spec_produced) {
300
		SET(spec);
301
		output = add_filename(output, spec);
302
	}
303
	if (allow_specs == 2) {
304
		spec = make_filename(input, C_SPEC, where(C_SPEC));
305
		cmd_list(exec_touch);
306
		cmd_filename(spec);
307
		cmd_string("-k");
308
		spec = execute(no_filename, spec);
309
		output = add_filename(output, spec);
310
	}
311
	return (output);
2 7u83 312
}
313
 
314
 
315
/*
6 7u83 316
 * APPLY THE C PREPROCESSOR
317
 *
318
 * This routine applies the TDF C preprocessor to input and returns the result.
319
 * If files of type PREPROC_C are not being preserved then the output is sent
320
 * to the standard output.
321
 */
2 7u83 322
 
6 7u83 323
filename *
324
do_preproc(filename *input)
2 7u83 325
{
6 7u83 326
	filename *output;
327
	if (input == null) {
328
		return (input);
329
	}
330
	if (checker && !use_system_cc) {
331
		return (input);
332
	}
333
	if (keeps[PREPROC_C]) {
334
		output = make_filename(input, PREPROC_C, where(PREPROC_C));
335
	} else {
336
		output = null;
337
	}
338
	cmd_list(exec_preproc);
339
	cmd_list(opt_preproc);
340
	producer_options(PREPROC_ID);
341
	cmd_filename(input);
342
	if (output) {
343
		cmd_filename(output);
344
	}
345
	output = execute(input, output);
346
	return (output);
2 7u83 347
}
348
 
349
 
350
/*
6 7u83 351
 * APPLY THE C++ PRODUCER
352
 *
353
 * This routine applies the C++ to TDF producer to input and returns the
354
 * result.
355
 */
2 7u83 356
 
6 7u83 357
filename *
358
do_cpp_produce(filename *input)
359
{
360
	filename *spec;
361
	filename *output, *producer_output;
362
	if (input == null) {
363
		return (input);
364
	}
365
	output = make_filename(input, INDEP_TDF, where(INDEP_TDF));
366
	cmd_list(exec_cpp_produce);
367
	if (allow_specs == 1) {
368
		spec = make_filename(input, CPP_SPEC, where(CPP_SPEC));
369
		if (dump_opts) {
370
			cmd_string(string_concat(dump_opts, spec->name));
371
		} else {
372
			cmd_string("-s");
373
			cmd_string(spec->name);
374
		}
375
	}
376
	cmd_list(opt_cpp_produce);
377
	producer_options(CPP_PRODUCE_ID);
378
	cmd_filename(input);
379
	cmd_filename(output);
380
	producer_output = execute(input, output);
2 7u83 381
 
6 7u83 382
	/*
383
	 * If we are in checker mode and intermodular checks are enabled we
384
	 * must ignore any errors from the producer and continue to run the
385
	 * dump_linker.
386
	 */
387
	if (checker) {
388
		reset_exec_error();
2 7u83 389
	} else {
6 7u83 390
		output = producer_output;
2 7u83 391
	}
6 7u83 392
	if (allow_specs == 1) {
393
		SET(spec);
394
		output = add_filename(output, spec);
395
	}
396
	if (allow_specs == 2 && output) {
397
		spec = make_filename(input, CPP_SPEC, where(CPP_SPEC));
398
		cmd_list(exec_touch);
399
		cmd_filename(spec);
400
		cmd_string("-k");
401
		spec = execute(no_filename, spec);
402
		output = add_filename(output, spec);
403
	}
404
	return (output);
2 7u83 405
}
406
 
407
 
408
/*
6 7u83 409
 * APPLY THE C++ PREPROCESSOR
410
 *
411
 * This routine applies the TDF C++ preprocessor to input and returns the
412
 * result. If files of type PREPROC_C are not being preserved then the output
413
 * is copied to the standard output.
414
 */
2 7u83 415
 
6 7u83 416
filename *
417
do_cpp_preproc(filename *input)
2 7u83 418
{
6 7u83 419
	filename *output;
420
	if (input == null) {
421
		return (input);
422
	}
423
	if (checker && !use_system_cc) {
424
		return (input);
425
	}
426
	if (keeps[PREPROC_CPP]) {
427
		output = make_filename(input, PREPROC_CPP, where(PREPROC_CPP));
428
	} else {
429
		output = null;
430
	}
431
	cmd_list(exec_cpp_preproc);
432
	cmd_list(opt_cpp_preproc);
433
	producer_options(CPP_PREPROC_ID);
434
	cmd_filename(input);
435
	if (output != null) {
436
		cmd_filename(output);
437
	}
438
	output = execute(input, output);
439
	return (output);
2 7u83 440
}
441
 
442
 
443
/*
6 7u83 444
 * APPLY THE TDF LINKER
445
 *
446
 * This routine applies the TDF linker to input and returns the result. This
447
 * is the normal action of the TDF linker - linking target independent TDF with
448
 * the TDF libraries to form target dependent TDF (also see do_tdf_build).
449
 */
2 7u83 450
 
6 7u83 451
filename *
452
do_tdf_link(filename *input)
2 7u83 453
{
6 7u83 454
	filename *output;
455
	if (input == null || stops[INDEP_TDF]) {
456
		return (input);
457
	}
458
	output = make_filename(input, DEP_TDF, where(DEP_TDF));
459
	cmd_list(exec_tdf_link);
460
	cmd_list(opt_tdf_link);
461
	cmd_list(usr_tdf_link_libdirs);
462
	cmd_list(std_tdf_link_libdirs);
463
	cmd_list(usr_tdf_link_libs);
464
	cmd_list(std_tdf_link_libs);
465
	cmd_string("-o");
466
	cmd_filename(output);
467
	cmd_filename(input);
468
	if (tokdef_output) {
469
		cmd_string(tokdef_output);
470
	}
471
	return (execute(input, output));
2 7u83 472
}
473
 
474
 
475
/*
6 7u83 476
 * APPLY THE TDF LINKER TO BUILD A COMPLEX
477
 *
478
 * This routine applies the TDF linker to combine a set of target independent
479
 * TDF capsules, input, into a single independent TDF capsule, which is then
480
 * returned. To avoid possible clashes with the input files, the output is
481
 * firstly directed to a temporary file, which is then moved to the output
482
 * file.
483
 */
2 7u83 484
 
6 7u83 485
filename *
486
do_tdf_build(filename *input)
2 7u83 487
{
6 7u83 488
	int keep;
489
	filename *output;
490
	if (input == null) {
491
		return (input);
492
	}
493
	if (exec_error) {
494
		return (null);
495
	}
496
	keep = where(INDEP_TDF_COMPLEX);
497
	output = uniq_filename(name_j_file, INDEP_TDF, keep, input);
498
	cmd_list(exec_tdf_link);
499
	cmd_list(opt_tdf_link);
500
	if (flag_merge_all) {
501
		cmd_string("-a");
502
		cmd_string("-k");
503
		cmd_string("tag");
504
		cmd_string("main");
505
	}
506
	cmd_string("-o");
507
	cmd_filename(uniq_tempfile);
508
	cmd_filename(input);
509
	return (do_move(execute(input, uniq_tempfile), output));
2 7u83 510
}
511
 
512
 
513
/*
6 7u83 514
 * APPLY THE TRANSLATOR
515
 *
516
 * This routine applies the TDF translator to the input files, input, and
517
 * returns the result. This routine is complicated by the fact that most TDF
518
 * translators produce assembler source, but some bypass the assembler to
519
 * directly produce binary object files. The mips translator produces two
520
 * output files, a .G file and a .T file, so this is also a special case.
521
 */
2 7u83 522
 
6 7u83 523
filename *
524
do_translate(filename *input)
2 7u83 525
{
6 7u83 526
	int t;
527
	filename *output;
528
	if (input == null || stops[DEP_TDF]) {
529
		return (input);
530
	}
531
	if (use_assembler) {
532
		t = AS_SOURCE;
533
		output = make_filename(input, t, where(t));
2 7u83 534
	} else {
6 7u83 535
		t = binary_obj_type;
536
		output = make_filename(input, t, where(t));
537
		output->type = BINARY_OBJ;
2 7u83 538
	}
6 7u83 539
	cmd_list(exec_translate);
540
	if (flag_diag) {
541
		if (flag_diag == 2) {
542
			cmd_string("-J");
543
		} else {
544
			if (flag_optim) {
545
				cmd_string("-HO");
546
			} else {
547
				cmd_string("-H");
548
			}
549
		}
550
	}
551
	if (flag_nepc) {
552
		cmd_string("-E");
553
	}
554
	if (use_mips_assembler) {
555
		static char *vflag = null;
556
		if (vflag == null) {
557
			vflag = string_concat("-V", version_flag);
558
		}
559
		cmd_string(vflag);
560
	}
561
	cmd_list(opt_translate);
2 7u83 562
 
6 7u83 563
	if (use_mips_assembler || use_alpha_assembler) {
564
		/* Deal with the mips assembler */
565
		t = MIPS_G_FILE;
566
		output->aux = make_filename(input, t, where(t));
567
		t = MIPS_T_FILE;
568
		output->aux->aux = make_filename(input, t, where(t));
569
		if (keeps[AS_SOURCE]) {
570
			cmd_string("-S");
571
			cmd_filename(input);
572
			cmd_filename(output->aux);
573
			cmd_filename(output->aux->aux);
574
			cmd_filename(output);
575
		} else {
576
			cmd_filename(input);
577
			cmd_filename(output->aux);
578
			cmd_filename(output->aux->aux);
579
		}
580
	} else if (use_assembler) {
581
		/* Deal with normal assemblers */
582
		cmd_filename(input);
583
		cmd_filename(output);
2 7u83 584
	} else {
6 7u83 585
		/* Deal with non-assemblers */
586
		if (keeps[AS_SOURCE]) {
587
			t = AS_SOURCE;
588
			output->aux = make_filename(input, t, where(t));
589
			cmd_string("-S");
590
			cmd_filename(input);
591
			cmd_filename(output);
592
			cmd_filename(output->aux);
593
		} else {
594
			cmd_filename(input);
595
			cmd_filename(output);
596
		}
2 7u83 597
	}
6 7u83 598
	return (execute(input, output));
2 7u83 599
}
600
 
601
 
602
/*
6 7u83 603
 * APPLY THE ASSEMBLER
604
 *
605
 * This routine applies the assembler to the input files, input, and returns
606
 * the result. The routine is complicated because of the need to handle the .G
607
 * and .T files output by the mips translator.
608
 */
2 7u83 609
 
6 7u83 610
filename *
611
do_assemble(filename *input)
2 7u83 612
{
6 7u83 613
	filename *output;
614
	int t = binary_obj_type;
615
	if (input == null || stops[AS_SOURCE]) {
616
		return (input);
617
	}
618
	output = make_filename(input, t, where(t));
619
	output->type = BINARY_OBJ;
620
	if (input->aux && input->aux->type == MIPS_G_FILE &&
621
	    input->aux->aux && input->aux->aux->type == MIPS_T_FILE) {
622
		/* Deal with the mips assembler */
623
		cmd_list(exec_assemble_mips);
624
		cmd_list(opt_assemble_mips);
625
		cmd_string("-o");
626
		cmd_filename(output);
627
		cmd_filename(input->aux);
628
		cmd_string("-t");
629
		cmd_filename(input->aux->aux);
630
	} else {
631
		/* Deal with normal assemblers */
632
		cmd_list(exec_assemble);
633
		cmd_list(opt_assemble);
634
		cmd_string("-o");
635
		cmd_filename(output);
636
		cmd_filename(input);
637
	}
638
	return (execute(input, output));
2 7u83 639
}
640
 
641
 
642
/*
6 7u83 643
 * LIST OF LIBRARIES
644
 *
645
 * This is set by linker_options to be the list of libraries passed to the
646
 * linker. Needs to be passed twice in the case of DYNLINK with shared
647
 * libaries.
648
 */
2 7u83 649
 
6 7u83 650
static list *dl_libs = null;
2 7u83 651
 
652
 
653
/*
6 7u83 654
 * DYNLINK SWITCH
655
 *
656
 * This remains 0 if normal linking is being done, and is set to 1 before the
657
 * first-stage dynamic-initialisation linking. After the first call to
658
 * 'linker_options', the value is increase so that it becomes two for the
659
 * second-stage link.
660
 */
2 7u83 661
 
6 7u83 662
static int dl_state = 0;
2 7u83 663
 
664
 
665
/*
6 7u83 666
 * PRINT LINK/DYNLINK OPTIONS
667
 *
668
 * The link and dynlink stages use the same command-line options with the
669
 * exception of crt0, crt1 and crtn files since the dynamic-initialisation
670
 * linking doesn't produce an executable. The variable 'use_dynlink' is either
671
 * 1, 2 or 3 depending on whether the CRT startup files are linked on the
672
 * first, second or both of the two dynlink stages.
673
 */
2 7u83 674
 
6 7u83 675
static void
676
linker_options(filename *input, filename *output)
2 7u83 677
{
6 7u83 678
	if (use_system_cc) {
679
		cmd_list(exec_cc);
680
		if (flag_diag) {
681
			cmd_string("-g");
682
		}
683
		if (flag_strip) {
684
			cmd_string("-s");
685
		}
686
		cmd_list(opt_cc);
687
		cmd_string("-o");
688
		cmd_filename(output);
2 7u83 689
	} else {
6 7u83 690
		cmd_list(exec_link);
691
		if (dl_state == 1) {
692
			cmd_string("-r");
693
		} else {
694
			cmd_list(std_link_entry);
695
		}
696
		if (flag_strip && (dl_state != 1)) {
697
			cmd_string("-s");
698
		}
699
		cmd_list(opt_link);
700
		cmd_string("-o");
701
		cmd_filename(output);
702
		if ((dl_state == 0) || (dl_state & use_dynlink)!= 0) {
703
			cmd_list(std_link_crt0);
704
			cmd_list(std_link_crt1);
705
		}
2 7u83 706
	}
6 7u83 707
	if (use_hp_linker) {
708
		filename *p;
709
		for (p = input; p != null; p = p->next) {
710
			char *arg = p->name;
711
			if (strneq(arg, "-B", 2)) {
712
				cmd_string("-B");
713
				cmd_string(arg + 2);
714
			} else if (strneq(arg, "-L", 2)) {
715
				cmd_string("-L");
716
				cmd_string(arg + 2);
717
			} else if (strneq(arg, "-l", 2)) {
718
				/*
719
				 * Save up -l options for inclusion after any
720
				 * -L options.
721
				 */
722
				dl_libs = add_item(dl_libs, arg);
723
			} else {
724
				cmd_string(arg);
725
			}
726
		}
727
	} else {
728
		filename *p;
729
		for (p = input; p != null; p = p->next) {
730
			char *arg = p->name;
731
			if (strneq(arg, "-l", 2)) {
732
				/*
733
				 * Save up -l options for inclusion after any
734
				 * -L options.
735
				 */
736
				dl_libs = add_item(dl_libs, arg);
737
			} else if (dl_state && (p->storage == INPUT_OPTION)) {
738
				/*
739
				 * Add input options to user link options for
740
				 * subsequent use.
741
				 */
742
				opt_link = add_item(opt_link, arg);
743
				cmd_string(arg);
744
			} else {
745
				cmd_string(arg);
746
			}
747
		}
2 7u83 748
	}
6 7u83 749
	if (!use_system_cc) {
750
		/* usr_link_libdirs forms part of input */
751
		cmd_list(std_link_libdirs);
2 7u83 752
	}
6 7u83 753
	/* now include the -l options */
754
	if (dl_libs != null) {
755
		cmd_list(dl_libs);
2 7u83 756
	}
6 7u83 757
	if (!use_system_cc) {
758
		/* usr_link_libs forms part of input */
759
		cmd_list(std_link_libs);
760
		cmd_list(std_link_c_libs);
761
		if ((dl_state == 0) || (dl_state & use_dynlink)!= 0) {
762
			cmd_list(std_link_crtp_n);
763
			cmd_list(std_link_crtn);
764
		}
2 7u83 765
	}
6 7u83 766
	dl_state++;
767
	return;
2 7u83 768
}
769
 
770
 
771
/*
6 7u83 772
 * APPLY THE RS6000/SPARC DYNAMIC INITIALISATION PROGRAM
773
 *
774
 * This routine calls the program to create a .s file with the necessary
775
 * dynamic initialisation calls for AIX and SunOS, and adds the corresponding
776
 * .o to the file list.
777
 */
2 7u83 778
 
6 7u83 779
filename *
780
do_dynlink(filename *input)
2 7u83 781
{
6 7u83 782
	filename *linked_ofiles, *extra_sfile, *output = null;
783
	if (input == null || stops[BINARY_OBJ]) {
784
		return (input);
785
	}
786
	if (checker && !use_system_cc) {
787
		return (input);
788
	}
789
	if (!exec_error) {
790
		linked_ofiles = make_filename(no_filename, binary_obj_type,
791
					      TEMP_FILE);
792
		dl_state = 1;
793
		linker_options(input, linked_ofiles);
794
		IGNORE execute(input, output);
795
	}
796
	if (!exec_error) {
797
		output = make_filename(no_filename, AS_SOURCE, TEMP_FILE);
798
		cmd_list(exec_dynlink);
799
		cmd_list(opt_dynlink);
800
		SET(linked_ofiles);
801
		cmd_filename(linked_ofiles);
802
		cmd_filename(output);
803
		extra_sfile = execute(linked_ofiles, output);
804
	}
805
	if (exec_error) {
806
		last_return = 1;
807
		return (null);
808
	}
809
	SET(linked_ofiles);
810
	SET(extra_sfile);
811
	output = do_assemble(extra_sfile);
812
	if (use_dynlink == 3) {
813
		return (add_filename(output, input));
814
	}
815
	return (add_filename(output, linked_ofiles));
2 7u83 816
}
817
 
818
 
819
/*
6 7u83 820
 * APPLY THE SYSTEM LINKER
821
 *
822
 * This routine applies the system linker to the input files, input, and
823
 * returns the result. The output executable name is, by default,
824
 * EXECUTABLE_NAME. Things are slightly complicated by the fact that the HP
825
 * linkers insist on certain options being in two parts.
826
 */
2 7u83 827
 
6 7u83 828
filename *
829
do_link(filename *input)
2 7u83 830
{
6 7u83 831
	int keep;
832
	filename *output;
833
	if (input == null || stops[BINARY_OBJ]) {
834
		return (input);
835
	}
836
	if (checker && !use_system_cc) {
837
		return (input);
838
	}
839
	if (exec_error) {
840
		last_return = 1;
841
		return (null);
842
	}
843
	keep = where(EXECUTABLE);
844
	output = uniq_filename(EXECUTABLE_NAME, EXECUTABLE, keep, no_filename);
845
	linker_options(input, output);
846
	return (execute(input, output));
2 7u83 847
}
848
 
849
 
850
/*
6 7u83 851
 * APPLY THE TDF NOTATION COMPILER
852
 *
853
 * This routine applies the TDF notation compiler to the input files, input,
854
 * and returns the result.
855
 */
2 7u83 856
 
6 7u83 857
filename *
858
do_notation(filename *input)
2 7u83 859
{
6 7u83 860
	int keep;
861
	filename *output;
862
	if (input == null) {
863
		return (input);
864
	}
865
	keep = where(INDEP_TDF);
866
	if (tokdef_name && streq(input->name, tokdef_name)) {
867
		keep = TEMP_FILE;
868
	}
869
	output = make_filename(input, INDEP_TDF, keep);
870
	cmd_list(exec_notation);
871
	cmd_list(opt_notation);
872
	cmd_list(usr_prod_incldirs);
873
	cmd_filename(input);
874
	cmd_filename(output);
875
	return (execute(input, output));
2 7u83 876
}
877
 
878
 
879
/*
6 7u83 880
 * APPLY THE PL_TDF COMPILER
881
 *
882
 * This routine applies the PL_TDF compiler to the input files, input, and
883
 * returns the result.
884
 */
2 7u83 885
 
6 7u83 886
filename *
887
do_pl_tdf(filename *input)
2 7u83 888
{
6 7u83 889
	filename *output;
890
	if (input == null) {
891
		return (input);
892
	}
893
	output = make_filename(input, INDEP_TDF, where(INDEP_TDF));
894
	cmd_list(exec_pl_tdf);
895
	cmd_list(opt_pl_tdf);
896
	cmd_list(usr_pl_tdf_incldirs);
897
	if (flag_diag) {
898
		cmd_string("-g");
899
	}
900
	cmd_filename(input);
901
	cmd_filename(output);
902
	return (execute(input, output));
2 7u83 903
}
904
 
905
 
906
/*
6 7u83 907
 * APPLY THE TDF PRETTY PRINTER
908
 *
909
 * This routine applies the TDF pretty printer to the input files, input, and
910
 * returns the result.
911
 */
2 7u83 912
 
6 7u83 913
filename *
914
do_pretty(filename *input)
2 7u83 915
{
6 7u83 916
	filename *output;
917
	if (input == null || stops[DEP_TDF]) {
918
		return (input);
919
	}
920
	output = make_filename(input, PRETTY_TDF, where(PRETTY_TDF));
921
	cmd_list(exec_pretty);
922
	if (flag_diag) {
923
		cmd_string("-g");
924
	}
925
	cmd_list(opt_pretty);
926
	cmd_filename(input);
927
	cmd_filename(output);
928
	return (execute(input, output));
2 7u83 929
}
930
 
931
 
932
/*
6 7u83 933
 * SPLIT A TDF ARCHIVE
934
 *
935
 * This routine splits the TDF archive, input, and returns the result.
936
 */
2 7u83 937
 
6 7u83 938
filename *
939
do_split_arch(filename *input)
2 7u83 940
{
6 7u83 941
	if (input == null) {
942
		return (input);
943
	}
944
	cmd_list(exec_split_arch);
945
	cmd_filename(input);
946
	return (execute(input, no_filename));
2 7u83 947
}
948
 
949
 
950
/*
6 7u83 951
 * BUILD A TDF ARCHIVE
952
 *
953
 * This routine creates a TDF archive from the input files, input, and the
954
 * archive options, opt_archive, and returns the result. The output archive
955
 * name is, by default, TDF_ARCHIVE_NAME. The aux field of the output contains
956
 * the archive contents.
957
 */
2 7u83 958
 
6 7u83 959
filename *
960
do_build_arch(filename *input)
2 7u83 961
{
6 7u83 962
	int keep;
963
	filename *output;
964
	if (input == null || stops[INDEP_TDF]) {
965
		return (input);
966
	}
967
	if (exec_error) {
968
		return (null);
969
	}
970
	archive_type = TDF_ARCHIVE;
971
	keep = where(TDF_ARCHIVE);
972
	output = uniq_filename(TDF_ARCHIVE_NAME, TDF_ARCHIVE, keep,
973
			       no_filename);
974
	cmd_list(exec_build_arch);
975
	cmd_filename(output);
976
	cmd_filename(input);
977
	if (opt_archive) {
978
		cmd_string(ARCHIVE_OPTION_START);
979
		cmd_list(opt_archive);
980
	}
981
	output = execute(input, output);
982
	if (output) {
983
		output->aux = input;
984
	}
985
	return (output);
2 7u83 986
}
987
 
988
 
989
/*
6 7u83 990
 * BUILD AN ARCHIVE FILE
991
 *
992
 * This routine creates an archive file of type t from the input files and
993
 * returns the result. The aux field of the output contains the archive
994
 * contents.
995
 */
2 7u83 996
 
6 7u83 997
filename *
998
do_build_file(filename *input, int t)
2 7u83 999
{
6 7u83 1000
	int s;
1001
	filename *output;
1002
	if (input == null) {
1003
		return (input);
1004
	}
1005
	if (!(keeps[t] || keeps_aux[t] == 1)) {
1006
		return (input);
1007
	}
1008
	archive_type = t;
1009
	s = input->type;
1010
	input->type = UNKNOWN_TYPE;
1011
	output = make_filename(input, t, where(t));
1012
	input->type = s;
1013
	cmd_list(exec_build_arch);
1014
	cmd_filename(output);
1015
	cmd_filename(input);
1016
	if (allow_specs == 2) {
1017
		cmd_string(ARCHIVE_OPTION_START);
1018
		cmd_string("--2CS");
1019
	}
1020
	output = execute(input, output);
1021
	if (output) {
1022
		output->aux = input;
1023
	}
1024
	return (output);
2 7u83 1025
}
1026
 
1027
 
1028
/*
6 7u83 1029
 * LINK A NUMBER OF C AND C++ SPECS
1030
 *
1031
 * This routine links a number of C++ specs, input, into one, which is then
1032
 * returned. To avoid possible clashes with the input files, the output is
1033
 * firstly directed to a temporary file, which is then moved to the output
1034
 * file. The variable t is the dummy file type, C_SPEC_1, C_SPEC_2, CPP_SPEC_1
1035
 * or CPP_SPEC_2.
1036
 */
2 7u83 1037
 
6 7u83 1038
filename *
1039
do_link_specs(filename *input, int t)
2 7u83 1040
{
6 7u83 1041
	int keep;
1042
	filename *output, *spec_file;
1043
	if (input == null) {
1044
		return (input);
2 7u83 1045
	}
6 7u83 1046
	if (t == C_SPEC_2 || t == CPP_SPEC_2) {
1047
		/* Don't link in these cases */
1048
		if (stops[BINARY_OBJ]) {
1049
			return (input);
1050
		}
2 7u83 1051
	}
6 7u83 1052
	if (exec_error && !checker) {
1053
		last_return = 1;
1054
		return (null);
1055
	}
1056
	keep = where(t);
1057
	if (allow_specs == 1 && dump_opts == null) {
1058
		output = make_filename(no_filename, INDEP_TDF, TEMP_FILE);
1059
		if (t == C_SPEC_1 || t == C_SPEC_2) {
1060
			spec_file = uniq_filename(name_k_file, C_SPEC, keep,
1061
						  input);
1062
			cmd_list(exec_spec_link);
1063
			cmd_list(opt_spec_link);
1064
		} else {
1065
			spec_file = uniq_filename(name_K_file, CPP_SPEC, keep,
1066
						  input);
1067
			cmd_list(exec_cpp_spec_link);
1068
			cmd_list(opt_cpp_spec_link);
1069
		}
1070
		if (checker) {
1071
			cmd_string("-c");
1072
		}
1073
		if (make_pretty) {
1074
			cmd_string("-t");
1075
		}
1076
		cmd_string("-s");
1077
		cmd_string(uniq_tempfile->name);
1078
		cmd_filename(input);
1079
		cmd_filename(output);
1080
		output = execute(input, output);
1081
		if (checker) {
1082
			output = null;
1083
		}
1084
		output = add_filename(output, do_move(uniq_tempfile,
1085
						      spec_file));
2 7u83 1086
	} else {
6 7u83 1087
		if (t == C_SPEC_1 || t == C_SPEC_2) {
1088
			output = uniq_filename(name_k_file, C_SPEC, keep,
1089
					       input);
1090
		} else {
1091
			output = uniq_filename(name_K_file, CPP_SPEC, keep,
1092
					       input);
1093
		}
1094
		if (allow_specs == 1) {
1095
			cmd_list(exec_dump_link);
1096
			cmd_list(opt_dump_link);
1097
			cmd_filename(input);
1098
			cmd_filename(output);
1099
			output = execute(input, output);
1100
		} else {
1101
			cmd_list(exec_touch);
1102
			cmd_filename(uniq_tempfile);
1103
			cmd_string("-k");
1104
			output = execute(no_filename, output);
1105
		}
2 7u83 1106
	}
6 7u83 1107
	return (output);
2 7u83 1108
}
1109
 
1110
 
1111
/*
6 7u83 1112
 * USE THE SYSTEM COMPILER
1113
 *
1114
 * tcc may optionally be used do invoke the system compiler, cc. This routine
1115
 * applies cc to the input files, input, compiling as far as files of type t,
1116
 * and returning the output files.
1117
 */
2 7u83 1118
 
6 7u83 1119
filename *
1120
do_cc(filename *input, int t)
2 7u83 1121
{
6 7u83 1122
	char *flag;
1123
	filename *output;
1124
	if (input == null) {
1125
		return (input);
1126
	}
1127
	output = make_filename(input, t, where(t));
1128
	if (t == PREPROC_C) {
1129
		if (keeps[t]) {
1130
			flag = "-P";
1131
		} else {
1132
			flag = "-E";
1133
			output = null;
1134
		}
1135
	} else if (t == AS_SOURCE) {
1136
		flag = "-S";
2 7u83 1137
	} else {
6 7u83 1138
		flag = "-c";
1139
		output->type = BINARY_OBJ;
2 7u83 1140
	}
6 7u83 1141
	cmd_list(exec_cc);
1142
	cmd_string(flag);
1143
	if (flag_diag) {
1144
		cmd_string("-g");
2 7u83 1145
	}
6 7u83 1146
	cmd_list(opt_cc);
1147
	if (use_sparc_cc == 2 && output) {
1148
		filename *real_output;
1149
		real_output = make_filename(input, output->type,
1150
					    PRESERVED_FILE);
1151
		real_output->name = find_basename(real_output->name);
1152
		cmd_filename(input);
1153
		real_output = execute(input, real_output);
1154
		return (do_move(real_output, output));
1155
	} else {
1156
		if (output) {
1157
			cmd_string("-o");
1158
			cmd_filename(output);
1159
		}
1160
		cmd_filename(input);
1161
		return (execute(input, output));
1162
	}
2 7u83 1163
}