OSDN Git Service

Merge from gcc-2.8
[pf3gnuchains/gcc-fork.git] / gcc / vmsconfig.com
1 $ !
2 $ !     Set up to compile GCC on VMS.
3 $ !
4 $ ! Set the def dir to proper place for use in batch. Works for interactive too.
5 $flnm = f$enviroment("PROCEDURE")     ! get current procedure name
6 $set default 'f$parse(flnm,,,"DEVICE")''f$parse(flnm,,,"DIRECTORY")'
7 $ !
8 $set symbol/scope=(nolocal,noglobal)
9 $if f$trnlnm("IFILE$").nes."" then close/noLog ifile$
10 $ !
11 $ echo = "write sys$output"
12 $ !
13 $ arch_indx = 1 + ((f$getsyi("CPU").ge.128).and.1)      ! vax==1, alpha==2
14 $ arch = f$element(arch_indx,"|","|vax|alpha|")
15 $ !
16 $ if f$search("config.h") .nes. "" then delete config.h.*
17 $ if arch .eqs. "vax"
18 $ then
19 $   copy [.config.'arch']xm-vms.h []config.h
20 $   echo "Linked `config.h' to `[.config.''arch']xm-vms.h'."
21 $else
22 $   open/write cfile []config.h
23 $   write cfile "#include "+"""config/"+arch+"/xm-"+arch+".h"+"""
24 $   write cfile "#include "+"""config/"+arch+"/xm-vms.h"+"""
25 $   close cfile
26 $   echo "Created `config.h'."
27 $ endif
28 $ !
29 $ if f$search("tconfig.h") .nes. "" then delete tconfig.h.*
30 $ create []tconfig.h
31 $DECK
32 /* tconfig.h == config.h :: target and host configurations are the same */
33 #include "config.h"
34 $EOD
35 $ echo "Created `tconfig.h'.
36 $ !
37 $ if f$search("hconfig.h") .nes. "" then delete hconfig.h.*
38 $ create []hconfig.h
39 $DECK
40 /* hconfig.h == config.h :: host and target configurations are the same */
41 #include "config.h"
42 $EOD
43 $ echo "Created `hconfig.h'.
44 $ !
45 $ if f$search("tm.h") .nes. "" then delete tm.h.*
46 $ !
47 $ edit/tpu/nojournal/nosection/nodisplay/command=sys$input -
48         [.config.'arch']vms.h /output=[]tm.h
49 $DECK
50 !
51 !  Copy file, changing lines of the form
52 !       #include "vax/*"
53 !  or
54 !       #include "alpha/*"
55 !  into
56 !       #include "config-*"
57 !
58    file := CREATE_BUFFER("file", GET_INFO(COMMAND_LINE, "file_name"));
59    targ := LINE_BEGIN & '#include' & SPAN(ASCII(32)+ASCII(9))
60            & '"' & ('vax' | 'alpha') & '/';
61    rang := CREATE_RANGE(BEGINNING_OF(file), END_OF(file));
62    LOOP
63       incl := SEARCH_QUIETLY(targ, FORWARD, EXACT, rang);
64       EXITIF incl = 0;
65       POSITION(BEGINNING_OF(incl));
66       ERASE(incl);
67       COPY_TEXT('#include "config-');
68       rang := CREATE_RANGE(END_OF(incl), END_OF(file));
69    ENDLOOP;
70    WRITE_FILE(file, GET_INFO(COMMAND_LINE, "output_file"));
71    QUIT
72 $  EOD
73 $ echo "Generated `tm.h' from `[.config.''arch']vms.h'."
74 $ !
75 $       !crude hack to allow compiling from [.cp] subdirectory
76 $ if f$search("config-''arch'.h") .nes. "" then delete config-'arch'.h;*
77 $ copy [.config.'arch']'arch'.h []config-'arch'.h
78 $ echo "Linked `config-''arch'.h' to `[.config.''arch']''arch'.h' for `tm.h'."
79 $ !
80 $ call make_lang_incl "options.h"
81 $ !
82 $ call make_lang_incl "specs.h"
83 $ !
84 $ if arch .eqs. "vax"
85 $ then
86 $   if f$search("''arch'.md") .nes. "" then delete 'arch'.md;*
87 $   copy [.config.'arch']'arch'.md []'arch'.md
88 $   echo "Copied `''arch'.md' from `[.config.''arch']''arch'.md'."
89 $ endif
90 $ !
91 $ if f$search("aux-output.c") .nes. "" then delete aux-output.c.*
92 $ copy [.config.'arch']'arch'.c []aux-output.c
93 $ echo "Linked `aux-output.c' to `[.config.''arch']''arch'.c'.
94 $ !
95 $ !
96 $ !
97 $ ! Create the file version.opt, which helps identify the executable.
98 $ !
99 $search version.c version_string,"="/match=and/output=t.tmp
100 $open ifile$ t.tmp
101 $read ifile$ line
102 $close ifile$
103 $delete t.tmp;
104 $line=f$element(1,"""",line)    !extract the portion between 1st & 2nd quotes
105 $! Format of 'line' is "name-nn.nn.nn[.nn] [date text]" (without the quotes).
106 $! We want "name-nn.nn.nn[.nn][-date]"; "-date" suffix is optional.
107 $id = f$element(1,"-",line)             !strip "name-" prefix
108 $if id.eqs."-" then  id = line          !no prefix found?
109 $id = f$element(0," ",id) + "-" + f$element(1," ",id)   !first two tokens
110 $id = id - "- "         !in case 2nd token was empty
111 $if f$length(id).gt.15 then  id = f$extract(0,15,id)    !length limitation
112 $!
113 $open/write ifile$ version.opt
114 $write ifile$ "ident="+""""+id+""""
115 $close ifile$
116 $purge version.opt
117 $!
118 $!
119 $! create linker options files that lists all of the components for all
120 $! possible compilers.  We do this by editing the file Makefile.in, and 
121 $! generating the relevant files from it.
122 $!
123 $!
124 $! Make a copy of the makefile if the sources are on a disk that is NFS 
125 $!    mounted on a unix machine.
126 $if f$search("Makefile.in").eqs."" .and. f$search("$M$akefile.in").nes."" -
127         then copy $M$akefile.in Makefile.in
128 $! This should be automated across all front-end subdirectories.
129 $!    For now, it's hardcoded.
130 $if f$search("[.cp]Makefile.in").eqs."" .and. f$search("[.cp]$M$akefile.in").nes."" -
131         then copy [.cp]$M$akefile.in [.cp]Makefile.in
132 $!
133 $!
134 $echo "Now processing Makefile.in to generate linker option files."
135 $edit/TPU/noJournal/noSection/noDisplay/Command=sys$input: Makefile.in -
136         /Start_Position=('arch_indx')           ! 1 for vax, 2 for alpha
137 !!
138 VARIABLE makefile_buf, opt_file_buf, complist_buf, extra_compilers; ! Globals.
139 VARIABLE arch;          ! String 'vax' or 'alpha', set in configure_makefile().
140
141 !!
142 PROCEDURE process_makefile( )
143   !
144   ! Interpret Makefile.in and subsidiary Make-lang.in templates.
145   !
146   LOCAL range1, cmark, makefilename;
147
148   makefilename    := GET_INFO (COMMAND_LINE, 'FILE_NAME'); ! "Makefile.in"
149   makefile_buf    := CREATE_BUFFER ("makefile", makefilename);
150   opt_file_buf    := CREATE_BUFFER ("opt_file");
151   complist_buf    := CREATE_BUFFER ("complist");
152   extra_compilers := CREATE_ARRAY;
153   !
154   SET (NO_WRITE, makefile_buf, ON);     ! Used as workspace; don't save it.
155   SET (OUTPUT_FILE, complist_buf, "compilers.list");
156   !
157   ! Make some textual substitutions.
158   !
159   configure_makefile ();
160   !
161   ! Collect a list of supported compilers (``COMPILERS=xxx'' macro).
162   !
163   identify_compilers ();
164   !
165   ! Plus other known compilers described by Make-lang.in makefile fragments.
166   ! Add new entries as needed; args are (target name, subdirectory name).
167   !
168   additional_compiler ("cc1plus", "cp");
169   !
170   WRITE_FILE (complist_buf);            ! Now save "compilers.list".
171   !
172   ! Add to this list, as required.  The file "Makefile.in" is searched for
173   ! a tag that looks like "LINE_BEGIN + 'tag + (optional space) + "="".
174   ! The contents are assumed to be a list of object files, and from this
175   ! list a VMS linker options file is generated.
176   !
177   generate_option_file ("OBJS",          "=", "independent.opt");
178   generate_option_file ("LIB2FUNCS",     "=", "libgcc2.list");
179   generate_option_file ("CXX_LIB2FUNCS", "=", "libgcc2-cxx.list");
180   generate_option_file ("BC_ALL",        "=", "bc_all.list");
181   generate_option_file ("BI_OBJ",        "=", "bi_all.opt");
182   !
183   ! Now change OBJS in the Makefile, so each language specific options file
184   ! does not pick up all of the language independent files.
185   !
186   POSITION (BEGINNING_OF (makefile_buf));
187   COPY_TEXT ("OBJS=");  ! New copy with empty value, seen before real OBJS.
188   SPLIT_LINE;
189   !
190   ! Lastly, process each compiler-specific object dependency list.
191   !
192   POSITION (BEGINNING_OF (complist_buf));
193   LOOP
194     cmark := MARK (NONE);
195     EXITIF (cmark = END_OF (complist_buf));
196     ! The current line contains the name of a compiler target, such as "cc1".
197     MESSAGE (CURRENT_LINE);     ! Give some interactive feedback.
198     generate_option_file (CURRENT_LINE, ":", CURRENT_LINE + "-objs.opt");
199     POSITION (cmark);
200     MOVE_VERTICAL (1);          ! Go to the next line.
201   ENDLOOP;
202 ENDPROCEDURE; !process_makefile
203 !!
204
205 PROCEDURE process_objc_lib( )
206   !
207   ! Interpret objc/Makefile, after finishing the top makefile.
208   !
209   ON_ERROR
210     [TPU$_OPENIN]:
211       MESSAGE ("Cannot load objc/Makefile for ""ObjClib""; skipping it.");
212       RETURN;
213   ENDON_ERROR;
214
215   ERASE (makefile_buf);                 !discard top Makefile
216   POSITION (END_OF (makefile_buf));
217   READ_FILE ("[.objc]Make-lang.in");    !load objc one
218   MESSAGE ("objclib");
219   pat_replace (ASCII(9), " ");          !change any <tab> to <space>
220   generate_option_file ("OBJC_O", "=", "objc-objs.opt");
221   POSITION (BEGINNING_OF (makefile_buf));
222   ! Join any continuation lines; we want the header list to be one line.
223   pat_replace ("\" & LINE_END, );
224   generate_option_file ("OBJC_H", "=", "objc-hdrs.list");
225 ENDPROCEDURE; !process_objc_lib
226 !!
227
228 PROCEDURE configure_makefile( )
229   !
230   ! Plug in some values normally handled by `configure'.  Rather than
231   ! replacing the dummy entries, insert the real entries before them.
232   !
233   IF (GET_INFO (COMMAND_LINE, 'START_RECORD') <> 2) THEN
234     arch := 'vax';
235   ELSE
236     arch := 'alpha';
237   ENDIF;
238   POSITION (BEGINNING_OF (makefile_buf));
239   COPY_TEXT ("target=" + arch + "-vms");        SPLIT_LINE;
240   COPY_TEXT ("out_file=aux-output.c");          SPLIT_LINE;     ! 'arch'/'arch'.c
241   COPY_TEXT ("out_object_file=aux-output.o");   SPLIT_LINE;     ! aux-output.obj
242   COPY_TEXT ("md_file=" + arch + ".md");        SPLIT_LINE;     ! 'arch'/'arch'.md
243   COPY_TEXT ("tm_file=tm.h");                   SPLIT_LINE;     ! 'arch'/tm-vms.h
244   pat_replace ("@" &
245     SPAN("abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ#~0123456789")
246                    & "@", );            ! strip `configure' dummy values
247 ENDPROCEDURE; !configure_makefile
248 !!
249
250 PROCEDURE identify_compilers( )
251   !
252   ! Retrieve the list of supported compilers from Makefile.in, and put them
253   ! into file "compilers.list", one per line, for subsequent access from DCL.
254   !
255   LOCAL range1;
256
257   ! Strip most comments from the makefile, to speed up subsequent processing.
258   POSITION (BEGINNING_OF (makefile_buf));
259   pat_replace (LINE_BEGIN & "#" & REMAIN & LINE_END, );
260   pat_replace ("$(exeext)", );
261   pat_replace ("@all_compilers@", );
262 !#  ! Convert directory references to VMS syntax (actually, just strip it).
263 !#  pat_replace (" $(srcdir)/", " ");
264   ! Look up the ``COMPILERS=cc1 xyzzy'' Makefile macro and put
265   ! its ``cc1 xyzzy'' value into the compilers buffer.
266   POSITION (BEGINNING_OF (complist_buf));
267 !#--at some point we may want to add this--
268 !#  recursive_fetch_tag ("CCCP", "=");    ! Include the preprocessor.
269 !#  POSITION (END_OF (complist_buf));
270   recursive_fetch_tag ("COMPILERS", "=");
271   ! Convert all spaces into newlines, then remove any blank lines.
272   pat_replace (SPAN(" "), LINE_END);
273   pat_replace (LINE_BEGIN & LINE_END, );
274 ENDPROCEDURE; !identify_compilers
275 !!
276
277 PROCEDURE additional_compiler( cname, subdir )
278   !
279   ! Load Make-lang.in for compiler CNAME from SUBDIR and append it to the
280   ! end of Makefile.in's buffer.  Add CNAME to the "compilers.list" buffer.
281   !
282   ON_ERROR
283     ! Don't abort if user removes the supporting subdirectory for a
284     ! language she's not interested in.
285     [TPU$_OPENIN]:
286       MESSAGE ("Cannot load " + subdir + "/Make-lang.in for "
287                + '"' + cname + '"' + "; skipping it.");
288       RETURN;
289   ENDON_ERROR;
290
291   POSITION (END_OF (makefile_buf));
292   SPLIT_LINE;   ! Separate with a blank line.
293   READ_FILE ("[." + subdir + "]Make-lang.in");  ! Load Makefile fragment.
294   ! Make sure that $(xxx_OTH_SRCS) expands to empty string by renaming $(it)
295   pat_replace ("_OTH_SRCS)", "_OTH_SRCS_dummy_)");
296   ! Convert subdirectory references into VMS syntax.
297   pat_replace ("$(srcdir)/" + subdir + "/", "[." + subdir + "]");
298
299     ! Temporary? hack for cp/Make-lang.in's mishandling of "input.c".
300     IF (subdir = 'cp') THEN
301       pat_replace ("[.cp]input.c", );   ! Discard this text.
302     ENDIF;
303
304   ! Add this name to compilers.list.
305   POSITION (END_OF (complist_buf));
306   COPY_TEXT (cname);
307   ! Make array entry indexed by compiler's file name; its value is arbitrary.
308   extra_compilers{cname} := subdir;
309 ENDPROCEDURE; !additional_compiler
310 !!
311
312 PROCEDURE generate_option_file( tag_name, punct, outfile_name )
313   !
314   ! Produce a file listing the names of particular object files, for use
315   ! as input to the linker and also for use in finding source names by
316   ! make-cc1.com.  Generally, any name suffix will be suppressed.
317   !
318   LOCAL range1, range2;
319
320   POSITION (BEGINNING_OF (opt_file_buf));
321   recursive_fetch_tag (tag_name, punct);
322   ! First fix up for subdirectory/Make-lang.in.
323   IF (pat_replace ("stamp-objlist" & (SPAN(" ")|LINE_END), " ") > 0) THEN
324     recursive_fetch_tag ("stamp-objlist", ":");
325   ENDIF;
326   ! Now fix up a few things in the output buffer.
327   pat_replace (("bytecode"|"Makefile") & (SPAN(" ")|LINE_END), " ");
328 !#  FILL (CURRENT_BUFFER, " ", 1, 80, 0);       ! Condense things a bit.
329   pat_replace ("." & ("o"|"c"|"y") & ((SPAN(" ")&LINE_END)|LINE_END), LINE_END);
330   pat_replace ("." & ("o"|"c"|"y") & SPAN(" "), ",");
331   pat_replace (".h" & (SPAN(" ")|LINE_END), ".h,");
332   ! Remove trailing commas, if present.
333   pat_replace ("," & ((SPAN(" ")&LINE_END)|LINE_END), LINE_END);
334   ! Get rid of spaces and blank lines.
335   pat_replace (SPAN(" "), LINE_END);
336   pat_replace (LINE_BEGIN & LINE_END, );
337   ! Second fix up for subdirectory/Make-lang.in;
338   ! avoid "sticky defaults" when linker processes the resulting options file.
339   IF (extra_compilers{outfile_name - "-objs.opt"} <> TPU$K_UNSPECIFIED) THEN
340     POSITION (BEGINNING_OF (opt_file_buf));
341     range1 := CREATE_RANGE (MARK (NONE), END_OF (CURRENT_BUFFER), NONE);
342     LOOP
343       range2 := SEARCH_QUIETLY (LINE_BEGIN | ",", FORWARD, EXACT, range1);
344       EXITIF (range2 = 0);
345       POSITION (BEGINNING_OF (range2));
346       IF (CURRENT_CHARACTER = ",") THEN  MOVE_HORIZONTAL (1); ENDIF;
347       ! If it's not already "[.subdir]name", explicitly make it "[]name".
348       IF (CURRENT_CHARACTER <> "[") THEN  COPY_TEXT ("[]"); ENDIF;
349       MOVE_HORIZONTAL (1);
350       MODIFY_RANGE (range1, MARK (NONE), END_OF (range1));
351     ENDLOOP;
352   ENDIF;
353   ! Now write the output file.
354   SET (OUTPUT_FILE, opt_file_buf, outfile_name);
355   WRITE_FILE (opt_file_buf);
356   ERASE (opt_file_buf);         ! Clear buffer out for next opt_file pass.
357 ENDPROCEDURE; !generate_option_file
358 !!
359
360 PROCEDURE recursive_fetch_tag( tag_n, punct )
361   !
362   ! Look up TAG_N, copy it to OPT_FILE_BUF, and then translate any $(...)
363   ! definitions that appear.  The translation is put at the current point.
364   !
365   LOCAL mark1, mark2, range1, tag_range, tag_string;
366
367   fetch_tag (tag_n, punct);
368   ! Substitute any makefile symbols $(...).
369   POSITION (BEGINNING_OF (CURRENT_BUFFER));
370   LOOP
371     range1 := SEARCH_QUIETLY ("$(" &
372       SPAN("abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ#~0123456789")
373                                    & ")", FORWARD, EXACT);
374     EXITIF (range1 = 0);
375     POSITION (BEGINNING_OF (range1));
376     MOVE_HORIZONTAL (2);        ! Past opening "$(".
377     mark1 := MARK (NONE);
378     POSITION (END_OF (range1));
379     MOVE_HORIZONTAL (-1);       ! In front of closing ")".
380     mark2 := MARK (NONE);
381     tag_range := CREATE_RANGE (mark1, mark2, NONE);
382     POSITION (END_OF (range1));
383     tag_string := STR (tag_range);
384     ERASE (range1);
385     fetch_tag (tag_string, "=");
386     POSITION (BEGINNING_OF (CURRENT_BUFFER));
387   ENDLOOP;
388 ENDPROCEDURE; !recursive_fetch_tag
389 !!
390
391 PROCEDURE fetch_tag( tag_n, punct )
392   !
393   ! Looks up the translation of a tag, and inserts it at the current location
394   ! in the buffer.
395   !
396   LOCAL mark0, mark1, mark2, range2;
397
398   mark0 := MARK (NONE);     ! Remember where we started; restore before return.
399   POSITION (BEGINNING_OF (makefile_buf));
400   ! The tag definition always starts in the first column, and might have
401   ! optional space(es) before "=" or ":" punctuation.
402   range2 := SEARCH_QUIETLY (LINE_BEGIN & tag_n & ((SPAN(" ") & punct) | punct),
403                             FORWARD, EXACT);
404   IF (range2 = 0) THEN
405     POSITION (mark0);
406     RETURN;
407   ENDIF;
408   POSITION (END_OF (range2));
409   MOVE_HORIZONTAL (1);          ! Move beyond "TAG=".
410   mark1 := MARK (NONE);
411   POSITION (BEGINNING_OF (range2));
412   LOOP
413     MOVE_VERTICAL (1);
414     MOVE_HORIZONTAL (-2);
415     EXITIF (CURRENT_CHARACTER <> "\");
416     ERASE_CHARACTER (1);
417     MOVE_HORIZONTAL (1);
418   ENDLOOP;
419   MOVE_HORIZONTAL (1);
420   mark2 := MARK (NONE);
421   range2 := CREATE_RANGE (mark1, mark2, NONE);
422   POSITION (mark0);
423   IF (LENGTH (range2) <> 0) THEN
424     COPY_TEXT (range2);
425   ENDIF;
426 ENDPROCEDURE; !fetch_tag
427 !!
428
429 PROCEDURE pat_replace( oldstring, newstring )
430   !
431   ! Replace all occurrences of a pattern.
432   !
433   LOCAL range1, range2, kill_it, count;
434
435   count := 0;
436   kill_it := (GET_INFO (newstring, 'TYPE') = UNSPECIFIED);      ! Omitted arg.
437   range1 := CREATE_RANGE (BEGINNING_OF (CURRENT_BUFFER),
438                           END_OF (CURRENT_BUFFER), NONE);
439   LOOP
440     range2 := SEARCH_QUIETLY (oldstring, FORWARD, EXACT, range1);
441     EXITIF (range2 = 0);
442     count := count + 1;
443     POSITION (BEGINNING_OF (range2));
444     ERASE (range2);
445     IF (newstring = LINE_END) THEN
446       SPLIT_LINE;
447     ELSE IF (NOT kill_it) THEN
448       COPY_TEXT (newstring);
449     ENDIF; ENDIF;
450     MODIFY_RANGE (range1, MARK (NONE), END_OF (range1));
451   ENDLOOP;
452   RETURN count;
453 ENDPROCEDURE; !pat_replace
454 !!
455
456 !
457 ! This is the main routine.
458 !
459 process_makefile ();
460 process_objc_lib ();    !this uses a different makefile
461 QUIT;   ! All done; don't write any modified buffers.
462 !!
463 $ echo ""
464 $!
465 $! Remove excessive versions of the option files...
466 $!
467 $ purge *.opt,*.list
468 $!
469 $!
470 $!
471 $ if f$search("config.status") .nes. "" then delete config.status.*
472 $ create config.status
473 $ open/append ifile$ config.status
474 $ write ifile$ "Links are now set up for use with a ''arch' running VMS."
475 $ close ifile$
476 $ type config.status
477 $ echo ""
478 $!
479 $ exit
480 $
481 $!
482 $! Construct a header file based on subdirectory contents
483 $!
484 $make_lang_incl: subroutine
485 $  if f$search(p1).nes."" then delete 'p1';*
486 $  create 'p1'  !empty file with ordinary text-file attributes
487 $  open/Append ifile$ 'p1'
488 $  write ifile$ "/* ''p1' */"
489 $  hfile = f$search("[]''p1'")
490 $  topdir = f$parse(hfile,,,"DIRECTORY") - "]"
491 $lang_incl_loop:
492 $  hfile = f$search("[.*]lang-''p1'")
493 $  if hfile.eqs."" then goto lang_incl_done
494 $  dir = f$parse(hfile,,,"DIRECTORY") - "]"
495 $! convert absolute path to relative one, yielding "[.subdir]"
496 $  dir = "[" + f$edit(dir - topdir,"LOWERCASE") + "]"
497 $  write ifile$ "#include ""''dir'lang-''p1'"""
498 $  goto lang_incl_loop
499 $lang_incl_done:
500 $  close ifile$
501 $  echo "Created `''p1''."
502 $ endsubroutine !make_lang_incl