[gnu.gcc.bug] notes on getting 1.34 to compile under vms

albaugh@AMES.ARC.NASA.GOV (Mike Albaugh) (04/21/89)

	The following notes are on what we needed to do to get Gnu CC 1.34
running under vms, using the version of 1.22 provided on the Decus '88 tapes.
(It's not just a job, it's an adventure :-)

	I should maybe mention that this is a locally compiled version of 1.22,
compiled with the bootstrap binaries also included on the tape, but it does
_not_ match those binaries, although it will happily re-compile itself with no
change but the time-stamps.

	The lines producing "extern int yydebug" need to be removed from
bison.simple, both in the bison and the "top" gcc directory. I am not sure
where bison gets the parser from under what circumstances.

	make-cc1.com needs to compile (and link) caller-save.c It would
also help to set verify at the beginning, to allow some hope of tracking
down the problem when it dies.

	The notes say to add `/DEFINE=("inline=")' to all the compilations
(because 1.22 doesn't handle inline). A better way is to add the line:

$ gcc == "gcc/define=(""inline="")"

to make.com. I have not gotten up the nerve to remove this definition
when re-compiling with 1.34.

	We found a way to make the make-cccp.com included with 1.32 work,
which may be helpful in many other situations. In essence, we changed the
way gcc.exe hands -d, -u, -i switches to gcc.com, to handle quoted strings
more gracefully. The files in question are included below. After these changes,
gcc 1.22 under vms will compile gcc 1.34 under vms, and more importantly, 1.34
will re-compile itself.

	Please forgive me if even _this_ doesn't work because I forgot one
or more places where our system logicals don't match yours or because on
our system gcc is already the greenhills compiler, so we call Gnu cc "gnucc".
I _think_ I re-editted all the files to take that change out, but one never
knows. There should be no problems that are not obvious and trivial to fix.

				Mike Albaugh

| Mike Albaugh (albaugh@dms.UUCP || {...decwrl!turtlevax!}weitek!dms!albaugh)
| Atari Games Corp (Arcade Games, no relation to the makers of the ST)
| 675 Sycamore Dr. Milpitas, CA 95035		voice: (408)434-1709
| The opinions expressed are my own (Boy, are they ever)

----- Cut here for gcc.c. gcc.com follows -----
/*
 *
 *	A DCL driver for GNU "CC".  It accepts a CLD syntax identical to
 *	VAX-11 "C".
 *
 *	Since GCC consists of more than 1 pass we have to do the parsing
 *	here and have a DCL Command (.COM) file do the real work -- so that
 *	multiple images can be invoked WITHOUT having to resort to LIB$SPAWN.
 *
 *	Mike Albaugh and Steve Suttles at Atari Games changed this code and
 *	gcc.com to handle quoted strings (such as those in make-cccp.com for
 *	version 1.32). We don't care if we get the credit, but we're here
 *	if you need to blame someone.
 */

char *Input_Files[100];		/* Input file specifications */
char *Defines[100];		/* /DEFINE specifications    */
char *Includes[100];		/* /INCLUDE specifications   */
char *Debug;			/* /DEBUG specification	     */
char *Object;			/* Object file name	     */
int Optimize;			/* Do optimized compile	     */
int Machine_Code;		/* Output assembly lang	     */
int Verbose;			/* Make noise while compiling*/
char cc1_Options[100];		/* Options for the CC1 pass  */
char *Undefines[100];		/* /UNDEFINE specifications  */


/*
 *	Save a string in dynamic memory
 */
char *savestr(String)
register char *String;
{
	register char *cp,*New_String;

	/*
	 *	Allocate it
	 */
	New_String = (char *)malloc(strlen(String)+1);
	/*
	 *	Copy it
	 */
	cp = New_String;
	while((*cp++ = *String++) != 0) ;
	/*
	 *	Return it
	 */
	return(New_String);
}


/*
 *	Do the parsing
 */
main()
{
	register char *cp,*cp1;
	int i;
	char Temp[256];

	/*
	 *	Get the Input files
	 */
	i = 0;
	while(cli_get_value("VCG$INPUT",Temp,sizeof(Temp)))
				Input_Files[i++] = savestr(Temp);
	/*
	 *	Do the /DEFINE qualifier
	 */
	if (cli_present("VCG$DEFINE")) {
		i = 0;
		while(cli_get_value("VCG$DEFINE",Temp,sizeof(Temp))) {
					Defines[i++] = savestr(Temp);
#ifdef	notdef
					Euniceify(&Defines[i-1]);
#endif	notdef
		}
	}
	/*
	 *	Do the /DEBUG qualifier
	 */
	if (cli_present("VCG$DEBUG")) {
		/*
		 *	Get the value (Default = ALL)
		 */
		if (!cli_get_value("VCG$DEBUG",Temp,sizeof(Temp)))
			strcpy(Temp,"ALL");
		/*
		 *	Save it
		 */
		Debug = savestr(Temp);
	}
	/*
	 *	Do the "/INCLUDE_DIRECTORY" qualifier
	 */
	if (cli_present("VCG$INCLUDE")) {
		i = 0;
		while(cli_get_value("VCG$INCLUDE",Temp,sizeof(Temp)))
					Includes[i++] = savestr(Temp);
	}
	/*
	 *	Do the /MACHINE_CODE qualifier
	 */
	if (cli_present("VCG$MACHINE")) Machine_Code = 1;
	/*
	 *	Do the /OBJECT qualifier
	 */
	if (cli_present("VCG$OBJECT")) {
		cli_get_value("VCG$OBJECT",Temp,sizeof(Temp));
		Object = savestr(Temp);
	}
	/*
	 *	Do the /OPTIMIZE qualifier
	 */
	if (cli_present("VCG$OPTIM")) Optimize = 1;
	/*
	 *	Do the /UNDEFINE qualifier
	 */
	if (cli_present("VCG$UNDEFINE")) {
		i = 0;
		while(cli_get_value("VCG$UNDEFINE",Temp,sizeof(Temp))) {
					Undefines[i++] = savestr(Temp);
#ifdef	notdef
					Euniceify(&Undefines[i-1]);
#endif	notdef
		}
	}
	/*
	 *	Do the /CC1_OPTIONS qualifier
	 */
	if (cli_present("VCG$CC1_OPTIONS"))
		cli_get_value("VCG$CC1_OPTIONS",cc1_Options,sizeof(cc1_Options));
	/*
	 *	Do the /VERBOSE qualifier
	 */
	if (cli_present("VCG$VERBOSE")) Verbose = 1;
	/*
	 *	Generate the command
	 */
	cp = Temp;

	/* Invoke the .COM file */
	cp1 = "@GNU_CC:[000000]GCC";
	while(*cp1) *cp++ = *cp1++;

	/* P1 = File to compile */
	*cp++ = ' ';
	cp1 = Input_Files[0];
	while(*cp1) *cp++ = *cp1++;

	/* P2 = Options */
	*cp++ = ' ';
	if (Optimize || Debug || Machine_Code || Verbose) {
		if (Optimize)*cp++ = 'O';
		if (Debug)*cp++ = 'D';
		if (Machine_Code)*cp++ = 'M';
		if (Verbose) *cp++ = 'V';
	} else {
		*cp++ = '"';
		*cp++ = '"';
	}

	/* P3 = Defines */
	*cp++ = ' ';
	*cp++ = '"';
	if (Defines[0]) {
		*cp++ = '"';
		*cp++ = '"';
		*cp++ = '-';
		*cp++ = 'D';
		cp1 = Defines[0];
		while(*cp1) if ( (*cp++ = *cp1++ ) == '"' ) {
			*cp++ = '"'; *cp++ = '"'; *cp++ = '"'; }
		i = 1;
		while(Defines[i]) {
			*cp++ = '"';
			*cp++ = '"';
			*cp++ = ' ';
			*cp++ = '"';
			*cp++ = '"';
			*cp++ = '-';
			*cp++ = 'D';
			cp1 = Defines[i++];
		    	while(*cp1) if ( (*cp++ = *cp1++ ) == '"' ) {
				*cp++ = '"'; *cp++ = '"'; *cp++ = '"'; }
		}
		*cp++ = '"';
		*cp++ = '"';
	}
	*cp++ = '"';

	/* P4 = Undefines */
	*cp++ = ' ';
	*cp++ = '"';
	if (Undefines[0]) {
		cp1 = Undefines[0];
		while(*cp1) *cp++ = *cp1++;

		i = 1;
		while(Undefines[i]) {
			*cp++ = ',';
			cp1 = Undefines[i++];
			while(*cp1) *cp++ = *cp1++;
		}
	}
	*cp++ = '"';
	/* P5 = Include directories */
	*cp++ = ' ';
	*cp++ = '"';
	if (Includes[0]) {
		cp1 = Includes[0];
		while(*cp1) *cp++ = *cp1++;

		i = 1;
		while(Includes[i]) {
			*cp++ = ',';
			cp1 = Includes[i++];
			while(*cp1) *cp++ = *cp1++;
		}
	}
	*cp++ = '"';

	/* P6 = CC1 compilation phase options */
	cp1 = cc1_Options;
	*cp++ = ' ';
	*cp++ = '"';
	while(*cp1) *cp++ = *cp1++;
	*cp++ = '"';

	/*
	 *	Do it
	 */
	lib_do_command(Temp, cp - Temp);
}


/*
 *	Execute the given DCL command
 */
lib_do_command(Text,Size)
char *Text;
int Size;
{
	struct {int Size; char *Ptr;} Descr;

	Descr.Ptr = Text;
	Descr.Size = Size;
	lib$do_command(&Descr);
}


/************		DCL PARSING ROUTINES		**********/

/*
 *	See if "NAME" is present
 */
int cli_present(Name)
char *Name;
{
	struct {int Size; char *Ptr;} Descr;

	Descr.Ptr = Name;
	Descr.Size = strlen(Name);
	return((cli$present(&Descr) & 1) ? 1 : 0);
}

/*
 *	Get value of "NAME"
 */
int cli_get_value(Name,Buffer,Size)
char *Name;
char *Buffer;
{
	struct {int Size; char *Ptr;} Descr1,Descr2;

	Descr1.Ptr = Name;
	Descr1.Size = strlen(Name);
	Descr2.Ptr = Buffer;
	Descr2.Size = Size-1;
	if (cli$get_value(&Descr1,&Descr2,&Descr2.Size) & 1) {
		Buffer[Descr2.Size] = 0;
		return(1);
	}
	return(0);
}


#ifdef	notdef
/*
 *	TEMPORARY:  Fixup define/undefine strings for Eunice command line
 *			processing
 */
Euniceify(sp)
char **sp;
{
#define	isupper(c) ((c >= 'A') && (c <= 'Z'))
#define tolower(c) (c - 'A' + 'a')
	register char *cp,*cp1;
	char Local[512];

	cp = *sp;
	cp1 = Local;
	while(*cp) {
		if (isupper(*cp)) {
			*cp1++ = '^';
			*cp1 = tolower(*cp);
		} else {
			*cp1 = *cp;
		}
		cp++;
		cp1++;
	}
	*cp1++ = 0;
	cp = (char *)malloc(strlen(Local)+1);
	strcpy(cp,Local);
	*sp = cp;
}
#endif	notdef
----- Cut here for gcc.com -----
$ Verifying:= 'f$verify(0)'
$! Comments at the bottom to save time (yecch!)
$!
$!  Constants:
$!
$ Version:='f$trnlnm("GNU_CC_VERSION")'
$ gcc_cpp:="$GNU_CC:[000000]GCC-CPP"
$ gcc_cc1:="$GNU_CC:[000000]GCC-CC1"
$ gcc_as:= "$GNU_CC:[000000]GCC-AS ""-vGNU CC  V''Version'"""
$!
$!  Parse the options
$!  -----------------
$ P2_Length = 'f$length(P2)'	! So we only have to calculate it once
$ Optimize := ""		!    Default = No Optimize
$ Debug := ""			!    Default = No Debug
$ Machine_Code = 0		!    Default = No Machine Code
$ Quiet := " -quiet"		!    Default = Silent
$ if 'f$locate("O",p2)' .ne. P2_Length then Optimize = " -opt"
$ if 'f$locate("D",p2)' .ne. P2_Length then Debug = " ""-G"""
$ if 'f$locate("M",p2)' .ne. P2_Length then Machine_Code = 1
$ if 'f$locate("V",p2)' .ne. P2_Length then Quiet = ""
$!
$!	Do the CC1 compilation phase options
$!
$ CC1_Options := "''P6'"
$ Save_R2_R5 := ""
$ if 'f$locate("-mdont-save-r2-r5",P6)' .eq. 'f$length(P6)' then goto 10$
$ Save_R2_R5 := " -fcall-used-r2 -fcall-used-r3 -fcall-used-r4 -fcall-used-r5"
$ l = 'f$locate("-mdont-save-r2-r5",P6)'
$ l1 = l + 17
$ CC1_Options := "''f$extract(0,l,P6)'''f$extract(l1,255,P6)'"
$ 10$:
$ Alignment := " -mvaxc-alignment"
$ if 'f$locate("-mpcc-alignment",P6)' .eq. 'f$length(P6)' then goto 20$
$ Alignment := ""
$ Alignment_Define := " ""-DPCC_ALIGNMENT"""
$ l = 'f$locate("-mpcc-alignment",CC1_Options)'
$ l1 = l + 15
$ CC1_Options := "''f$extract(0,l,CC1_Options)'''f$extract(l1,255,CC1_Options)'"
$ 20$:
$!
$!  Do the filename (default to ".C")
$!
$ Filename:='p1'
$ Extension:='f$parse(p1,,,"TYPE","SYNTAX_ONLY")'
$ if "''Extension'" .eqs. "." then Filename:='p1'.C
$!
$!	Do the object file
$!
$ Object_File:='f$parse(p1,,,"NAME","SYNTAX_ONLY")'
$!
$!	Start the pre-processor invocation string
$!
$ cpp_args:=""
$ cpp_args_length='f$length(cpp_args)'
$!
$!	Do any defines
$!
$! NOT ANY MORE, this is now in the driver
$ goto Defines_done
$ Defines_Loop:
$ if "''p3'" .eqs. "" then goto Defines_Done
$ l='f$locate(",",p3)'
$ l1 = l
$ Define:="''f$extract(0,l,p3)'"
$ l1 = l1 + 1
$ p3:="''f$extract(l1,255,p3)'"
$ l = l+5
$ cpp_args[cpp_args_length,l]:=" ""-D''Define'"""
$ cpp_args_length = cpp_args_length + l
$ goto Defines_Loop
$!
$ Defines_Done:
$!
$!	Do any undefines
$!
$ UnDefines_Loop:
$ if "''p4'" .eqs. "" then goto UnDefines_Done
$ l='f$locate(",",p4)'
$ l1 = l
$ Define:="''f$extract(0,l,p4)'"
$ l1 = l1 + 1
$ p4:="''f$extract(l1,255,p4)'"
$ l = l+5
$ cpp_args[cpp_args_length,l]:=" ""-U''Define'"""
$ cpp_args_length = cpp_args_length + l
$ goto UnDefines_Loop
$!
$ UnDefines_Done:
$!
$!	Do any include directories
$!
$ Includes_Loop:
$ if "''p5'" .eqs. "" then goto Includes_Done
$ l = 'f$locate(",",p5)'
$ l1 = l
$ Include:="''f$extract(0,l,p5)'"
$ l1 = l1 + 1
$ p5:="''f$extract(l1,255,p5)'"
$ l = l + 5
$ cpp_args[cpp_args_length,l]:=" ""-I''Include'"""
$ cpp_args_length = cpp_args_length + l
$ goto Includes_Loop
$!
$ Includes_Done:
$!
$!	Calculate the Temp file name
$!
$ Temp_File:=GCC_'f$getjpi(0,"PID")'
$!
$!	Do the "C" pre-processor
$!
$ if "''Quiet'" .eqs. "" then set verify
$ gcc_cpp 'p3''cpp_args''Alignment_Define' 'Filename' 'Temp_File'.CPP
$ status:='$status'
$ l = 'f$verify(0)'
$ if "''status'" .nes. "%X00000001" then goto CPP_Error
$!
$!	Do the "C" compilation
$!
$ Assembly_File:='Temp_File'.S
$ if Machine_Code then Assembly_File:='Object_File'.S
$ if "''Quiet'" .eqs. "" then set verify
$ gcc_cc1 'Temp_File'.CPP'Quiet' -dumpbase 'Filename''Optimize''Debug' -mgnu 'CC1_Options''Save_R2_R5''Alignment' -o 'Assembly_File'
$ status:='$status'
$ l = 'f$verify(0)'
$ delete/nolog/noconfirm 'Temp_File'.CPP;
$ if "''status'" .nes. "%X00000001" then goto CC1_Error
$!
$!	Do the assembly
$!
$ if Machine_Code then goto Exit
$ if "''Quiet'" .eqs. "" then set verify
$ gcc_as 'Temp_File'.S -o 'Object_File'.OBJ
$ status:='$status'
$ l = 'f$verify(0)'
$ delete/nolog/noconfirm 'Assembly_File';
$ if "''status'" .nes. "%X00000001" then goto Gas_Error
$ goto Exit
$!
$!	ERRORS:
$!	------
$ Gas_Error:
$ delete/nolog/noconfirm 'Temp_File'.OBJ;
$ if verifying then set verify
$ exit 'Status'	! Error in Assembly phase
$ CC1_Error:
$ delete/nolog/noconfirm 'Assembly_File';
$ if verifying then set verify
$ exit 'Status'	! Error in "C" Compilation phase
$ CPP_Error:
$ delete/nolog/noconfirm 'Temp_File'.CPP;
$ if verifying then set verify
$ exit 'Status'	! Error in "C" Pre-Processor phase
$!
$!	Done
$!
$ Exit:
$ if verifying then set verify
$ exit 'Status' ! Should be normal from here
$!
$!	GNU "CC" Compiler command file
$!
$!	Invoked from the GCC compile driver via LIB$DO_COMMAND:
$!		P1 = File to compile
$!		P2 = Options: O - Optimize
$!			      D - Debug
$!			      M - Produce Machine Code
$!			      V - Be verbose during compilation
$!		P3 != "," separated Defines
$!		P3 = already processed Defines
$!		P4 = "," separated Undefines
$!		P5 = "," separated Include directories
$!		P6 = CC1 compilation phase options, including:
$!			-mdont-save-r2-r5	(PCC style register saving)
$!			-mpcc-alignment		(PCC style struct align)
$!
$!	Mike Albaugh and Steve Suttles at Atari Games changed this code and
$!	gcc.c to handle quoted strings (such as those in make-cccp.com for
$!	version 1.32). We don't care if we get the credit, but we're here
$!	if you need to blame someone.
$!