2087 lines
66 KiB
Perl
2087 lines
66 KiB
Perl
.\" @(#)arch.t 1.1 10/31/94
|
|
.\"----------------------------------------------------------------------------
|
|
.\" Internal Architecture of /lib/compile
|
|
.\"----------------------------------------------------------------------------
|
|
.\" :! <% tbl | troff -ms -Tsun &
|
|
.\" <arch.t tbl | troff -ms -Tlw &
|
|
.\" <arch.t tbl | troff -ms -t >arch.dit && lpr -n arch.dit &
|
|
.\" <arch.t tbl | troff -ms -t >arch.dit && preview arch.dit &
|
|
.\" <arch.t tbl | $HOME/bin/pstroff -ms -t >arch.ps && lpr -h arch.ps
|
|
.\"
|
|
.\" <arch.t tbl | $HOME/bin/pstroff -ms -t >arch.ps
|
|
.\" rcp arch.ps welchs:/tmp
|
|
.\" rsh welchs 'cd /tmp; lpr -h arch.ps; lpq'
|
|
.\"----------------------------------------------------------------------------
|
|
.ds Lc "\fL/lib/compile\fP
|
|
.ds Cc "\fLcc\fP
|
|
.\"
|
|
.ds Vr "\fLVIRTUAL_ROOT\fP
|
|
.ds Ch "\fLCROSS_COMPILATION_HOME\fP
|
|
.ds Nv "\fLNSE_VARIANT\fP
|
|
.ds Ta "\fLTARGET_ARCH\fP
|
|
.\"
|
|
.ds Ua "\fL/usr/arch\fP
|
|
.ds Us "\*(Ua\fL.SERVER\fP
|
|
.ds Ct "\*(Ua\fL/common/\fP\fItarget_arch\fP
|
|
.ds Ha "\*(Ua\fL/\fP\fIhost_arch\fP
|
|
.ds Hc "\*(Ha\fL/common\fP
|
|
.ds Ht "\*(Ha\fL/\fP\fItarget_arch\fP
|
|
.ds Ho "\*(Ha\fL/\fP\fIother_arch\fP
|
|
.ds Hh "\*(Ha\fL/\fP\fIhost_arch\fP
|
|
.ds Vv "\fIvirtual_root\fP
|
|
.\"
|
|
.\" In -- incomplete section
|
|
.de In
|
|
.br \""".ce
|
|
\fI\(em\(em\(em this section is incomplete \(em\(em\(em\fP
|
|
.br
|
|
..
|
|
.\"
|
|
.\" Fi -- source FIle information
|
|
.de Fi
|
|
[\s-4see file \fL\\$1\fP\s+4]\\$2
|
|
..
|
|
.\" Nb -- Note section Begin
|
|
.de Nb
|
|
.ll -6n
|
|
.nr LL -6n
|
|
.in +3n
|
|
.\""" .nr Nl \\w'\\fI\\$1 \\fP'u
|
|
.nr Nl \w'\\fINote: \\fP'u
|
|
.nr Nv 3
|
|
.nr Np 2
|
|
.sp \\n(Nvp
|
|
\fI\\$1 \fP
|
|
'in +\\n(Nlu
|
|
'ps -\\n(Npp
|
|
'vs -\\n(Nvp
|
|
'nr PS -\\n(Np
|
|
'nr VS -\\n(Nv
|
|
..
|
|
.\" Ne -- Note section End
|
|
.de Ne
|
|
.nr PS +\\n(Np
|
|
.nr VS +\\n(Nv
|
|
.ps +\\n(Npp
|
|
.vs +\\n(Nvp
|
|
.in -\\n(Nlu
|
|
.in -3n
|
|
.ll +6n
|
|
.nr LL +6n
|
|
..
|
|
.\" Sc -- Centered Section header
|
|
.de Sc
|
|
.bp
|
|
.SH
|
|
.ce
|
|
\s+4\fB\\$1\fP\s-4
|
|
.LP
|
|
.XS
|
|
.if \\n(.$<2 \\$1
|
|
.if \\n(.$>=2 \\$2
|
|
.XE
|
|
..
|
|
.\" Sl -- Left-justified Section header
|
|
.de Sl
|
|
.SH
|
|
\s+2\fB\\$1\fP\s-2
|
|
.LP
|
|
.XS
|
|
.if \\n(.$>=2 \h'0.5i'\\$2\"----use 2nd arg for TOC, if present.
|
|
.if \\n(.$<2 \h'0.5i'\\$1\"-----otherwise use 1st arg
|
|
.XE
|
|
..
|
|
.\"
|
|
.nr PS 12
|
|
.nr VS 16
|
|
.LP
|
|
.\"----------------------------------------------------------------------------
|
|
.\" Reviewer's cover sheet
|
|
.\"----------------------------------------------------------------------------
|
|
\s2.\s0
|
|
.nr PS 36
|
|
.nr VS 36
|
|
.LP
|
|
.ce
|
|
.BX "\fHREVIEW COPY\fP"
|
|
.\""" .sp 0.2i
|
|
.nr PS 28
|
|
.nr VS 36
|
|
.LP
|
|
.ce 2
|
|
\f(LB/lib/compile\fP
|
|
Internal Architecture
|
|
.sp 0.5i
|
|
.nr PS 12
|
|
.nr VS 14
|
|
.LP
|
|
Mark Scott has offered your help in reviewing the attached tome
|
|
(don't you just love being volunteered?!).
|
|
Please review it as soon as possible.
|
|
The target date for review returns is Tuesday, Jan 19\u\s-4th\s+4\d
|
|
(I'm in office #104, near the front lobby).
|
|
|
|
If you wish to read source code along with this,
|
|
you can find SCCS-gotten versions of the source in directory:
|
|
.ti +8n
|
|
\fLearth:/home/buca/dweaver/lang/compile\fP
|
|
.br
|
|
RoadRunner-merged source code can be found in directory:
|
|
.ti +8n
|
|
\fLearth:/home/buca/dweaver/lang/compile/386\fP
|
|
.br
|
|
The SCCS files can be found in directory:
|
|
.ti +8n
|
|
\fLrogue:/lang/4.0/SCCS_DIRECTORIES/lang/compile/SCCS\fP
|
|
|
|
Note that:
|
|
.IP \(bu
|
|
Reviewing this does \fInot\fP increase the likelihood that you
|
|
will become fortunate enough to maintain \*(Lc!
|
|
.IP \(bu
|
|
The document is incomplete (as marked).
|
|
.IP \(bu
|
|
It represents a ``core dump'' of knowledge about \*(Lc.
|
|
I only claim a first-draft semblence of organization.
|
|
.IP \(bu
|
|
I am especially looking for comments which will improve:
|
|
.RS
|
|
.in +2n
|
|
.IP \(bu
|
|
content
|
|
(what's missing?,
|
|
what should there be more or less coverage of?,
|
|
can it be better explained from another angle?)
|
|
.IP \(bu
|
|
organization (can the information be presented better in a different order?)
|
|
.IP \(bu
|
|
level of detail (is more or less detail needed? where?)
|
|
.in -2n
|
|
.RE
|
|
.IP \(bu
|
|
Comments concerning grammar, punctuation, spelling,
|
|
and anything else are also welcome.
|
|
.IP \(bu
|
|
It has been suggested that the ``chapter'' on Cross-Compilation
|
|
be elaborated and split out into a separate document.
|
|
Comments?
|
|
.LP
|
|
.sp 0.6v
|
|
Remember, the more picky and vicious you are with your comments \fInow\fP,
|
|
the easier life will be for the person(s) who end up supporting \*(Lc
|
|
\fIlater\fP.
|
|
.sp 0.6v
|
|
Thanks very much for your help!
|
|
.ti +4n
|
|
\(em
|
|
.nr PS 12
|
|
.nr VS 16
|
|
.LP
|
|
.\"
|
|
.\"" .EH '\fB\s+2DRAFT\s-2\fP''\fB\s+2DRAFT\s-2\fP'
|
|
.\"" .OH '\fB\s+2DRAFT\s-2\fP''\fB\s+2DRAFT\s-2\fP'
|
|
.\"" .LP
|
|
.\"" .P1
|
|
.pn 1
|
|
.bp
|
|
.\"----------------------------------------------------------------------------
|
|
.\" Header page
|
|
.\"----------------------------------------------------------------------------
|
|
.LP
|
|
\s2.\s0
|
|
.sp 2.5i
|
|
|
|
.nr PS 28
|
|
.nr VS 36
|
|
.LP
|
|
.ce 2
|
|
\f(LB/lib/compile\fP
|
|
Internal Architecture
|
|
.sp 1.0i
|
|
.nr PS 14
|
|
.nr VS 20
|
|
.LP
|
|
.ce 2
|
|
David L. Weaver
|
|
\*(DY
|
|
.nr PS 12
|
|
.nr VS 16
|
|
.LP
|
|
.\"
|
|
.EH '\fB\s+2DRAFT\s-2\fP'\s12\- % \-\s0'\fB\s+2DRAFT\s-2\fP'
|
|
.OH '\fB\s+2DRAFT\s-2\fP'\s12\- % \-\s0'\fB\s+2DRAFT\s-2\fP'
|
|
.EF '\fL/lib/compile\fP'Sun Microsystems CONFIDENTIAL'\*(DY'
|
|
.OF '\fL/lib/compile\fP'Sun Microsystems CONFIDENTIAL'\*(DY'
|
|
.pn 1
|
|
.\"----------------------------------------------------------------------------
|
|
.\" The rest...
|
|
.\"----------------------------------------------------------------------------
|
|
.Sc Overview
|
|
|
|
\*(Lc is the driver program for the following Sun programming language
|
|
commands:
|
|
.TS
|
|
center;
|
|
l l l
|
|
l l l
|
|
l l l
|
|
lfL lfL l.
|
|
Command Residence in
|
|
(Driver) Filesystem Function
|
|
\_ \_ \_
|
|
cc /bin/cc C compiler
|
|
f77 /usr/bin/f77 FORTRAN-77 compiler
|
|
lint /usr/bin/lint C type-checker
|
|
m2c /usr/bin/m2c Modula-2 compiler
|
|
pc /usr/ucb/pc Pascal compiler
|
|
.TE
|
|
Since a great deal of common code existed among these compilers' drivers,
|
|
they were combined into one program, \*(Lc, in SunOS Release 3.2.
|
|
From that release up through the present (Sys4-3.2 and SunOS-4.0-Beta),
|
|
these commands have existed as symbolic links to \*(Lc.
|
|
|
|
Additionally, \*(Lc serves as the \*Qmastermind\*U behind the facilities
|
|
offered in the Sun Cross-Compiler products.
|
|
|
|
|
|
This document serves as a guide to the internal operation of \*(Lc.
|
|
It is written for technical readers,
|
|
especially those who will modify or maintain \*(Lc.
|
|
It should be a \*Qliving\*U document;
|
|
those who modify \*(Lc should modify this document accordingly.
|
|
|
|
|
|
.Nb Note:
|
|
The definitions of italicized terms with global meanings in this document
|
|
can be found in Appendix A.
|
|
.Ne
|
|
|
|
.Sc "A Chronological Tour of \f(LB/lib/compile\fP" "A Chronological Tour of \*(Lc"
|
|
|
|
If the reader is using this document as a companion to the \*(Lc source code,
|
|
the ``tour'' begins in function \fLmain()\fP
|
|
.Fi compile.c .
|
|
|
|
.Sl "Processing Arguments"
|
|
\*(Lc determines which driver it should impersonate by looking at the
|
|
name by which it was called (in \fLargv[0]\fP).
|
|
|
|
Command-line arguments fall into two general categories:
|
|
options and filenames.
|
|
An option begins with `\-', and has an entry in the driver's options table.
|
|
This options table is an array of \fLOption\fP\|s named \fLoptions[]\fP
|
|
.Fi ro_data.c .
|
|
Filenames are \*Qanything else\*U, including
|
|
source-code files,
|
|
inline-expansion template (\*Q\fL.il\fP\*U) files,
|
|
relocatable object (\*Q\fL.o\fP\*U) files,
|
|
and libraries (\*Q\fL.a\fP\*U files).
|
|
|
|
As the argument list is scanned, each argument is looked up in \fLoptions[]\fP.
|
|
\fLlookup_option()\fP
|
|
.Fi compile.c
|
|
scans this array linearly,
|
|
stopping at the first partial match in the option table.
|
|
Order is important in the table;
|
|
a given option must come before all others with shorter names which
|
|
match an initial substring of that option.
|
|
.Nb "For example:"
|
|
.br
|
|
\fL-ansi\fP must precede \fL-a\fP in the table.
|
|
Otherwise, \fL-ansi\fP on the command line would match \fL-a\fP in the table
|
|
before \fL-ansi\fP was found.
|
|
.Ne
|
|
By convention, the table is kept in generally alphabetical order,
|
|
subject to the above constraint.
|
|
|
|
The \*Qtype\*U of an option
|
|
(\fLtype\fP and \fLsubtype\fP fields of its \fLOption\fP structure)
|
|
determine how it is processed, after it is found in the table.
|
|
Typically, an option is added to the option-list for a particular compiler pass
|
|
(perhaps after being modified, in a manner appropriate to its type),
|
|
sets or resets one of the driver's internal Boolean flags,
|
|
or sets an internal variable
|
|
(such as \*Q\fL-O\fP\fIn\fP\*U sets the optimization level,
|
|
or \*Q\fL-o\ \fP\fIfile\fP\*U sets the output filename).
|
|
|
|
If no match is found in \fLoptions[]\fP and the argument begins with `\-',
|
|
a warning is issued claiming that the argument is an \*Qunknown option\*U.
|
|
The argument is then passed, unmodified, to the linker (\fLld\fP).
|
|
|
|
If no match is found and the argument does \fInot\fP begin with `\-',
|
|
it is assumed that the argument is an input filename.
|
|
A filename is added to the list of input files for the appropriate
|
|
compilation step
|
|
(e.g. \fLcpp\fP, \fLccom\fP, \fLinline\fP, \fLas\fP)
|
|
based on its suffix
|
|
(e.g. \fL.c\fP, \fL.i\fP, \fL.il\fP, \fL.s\fP, respectively).
|
|
|
|
.Sl "Setup Before Compilation"
|
|
After all of the arguments have been scanned,
|
|
\*(Lc checks for illegal combinations of options,
|
|
and treats them as described in the following table:
|
|
.KS
|
|
.TS
|
|
center;
|
|
c s l
|
|
c s l
|
|
c s l
|
|
lfL 2 lfL l.
|
|
Option
|
|
Combination Disposition
|
|
\_ \_
|
|
-sun2 -ffpa fatal error
|
|
-sun3 -fsky fatal error
|
|
-sun386 -f\fIanything\fP fatal error
|
|
-sun4 -f\fIanything\fP fatal error
|
|
\-g \-a \*Q\fL-a\fP\*U turned off
|
|
\-g \-O \*Q\fL-O\fP\*U turned off
|
|
\-g \-R \*Q\fL-R\fP\*U turned off
|
|
\-a \-O \*Q\fL-O\fP\*U turned off
|
|
\-a \-R \*Q\fL-R\fP\*U turned off
|
|
.TE
|
|
.KE
|
|
|
|
If optimization was requested without specifying an optimization level
|
|
(i.e. via vanilla \*Q\fL-O\fP\*U),
|
|
a default optimization level is assigned as follows:
|
|
.TS
|
|
center;
|
|
c c c
|
|
c c c
|
|
cfL cfL lfL.
|
|
Target Architecture Driver Default Optimization Level
|
|
\_ \_ \_
|
|
\fIall\fP f77 -O3 \fI(peephole + full global)\fP
|
|
sun4 \fIall except f77\fP -O2 \fI(peephole + partial global)\fP
|
|
\fIall except sun4\fP \fIall except f77\fP -O1 \fI(peephole only)\fP
|
|
.TE
|
|
|
|
The optimization level is verified against legal values,
|
|
as determined by a combination of the
|
|
target software release, target architecture, and language:
|
|
.KS
|
|
.nr VS -2
|
|
.LP
|
|
.TS
|
|
center;
|
|
c c c c
|
|
c c c c
|
|
c c c c
|
|
c c c c
|
|
cfL cfL cfL cfL.
|
|
Target Maximum
|
|
Software Target Optimization
|
|
Release Architecture Driver Level
|
|
\_ \_ \_ \_
|
|
|
|
3.x\** sun4 cc,f77,pc\u\(**\d,m2c\(dg -O4
|
|
3.x sun2,sun3,sun386 f77 -O3
|
|
3.x sun2,sun3,sun386 cc,pc,m2c -O1
|
|
|
|
4.0 sun2,sun3,sun4 cc,f77,pc,m2c\(dd -O4
|
|
4.0 sun386 cc,f77,pc,m2c -O1
|
|
.TE
|
|
.nr PS -4
|
|
.nr VS -3
|
|
.DS B
|
|
\(** applies to Pascal 1.05; \fL-O1\fP was the max optimization level for Pascal 1.0
|
|
\(dg as implemented; \fL-O1\fP \fIshould have been\fP the max optimization level implemented in
|
|
\h'2n'\*(Lc for 3.x-based Modula-2
|
|
\(dd as implemented; correct max optimization level for SunOS4.0-based Modula-2 is not yet known
|
|
.DE
|
|
.nr VS +3
|
|
.nr PS +4
|
|
.nr VS +2
|
|
.LP
|
|
.KE
|
|
.FS
|
|
Release ``\fL3.x\fP'' for Sun-4 actually refers to Sys4-3.2.
|
|
.FE
|
|
|
|
.KS
|
|
\*(Lc then performs setup for cross-compilation, as needed.
|
|
See \fBCross-Compilation\fP
|
|
and \fBSupport for NSE Variants\fP for details.
|
|
.KE
|
|
|
|
|
|
.Sl "Invocation of Compiler Passes"
|
|
After all of the arguments have been examined and sanitized,
|
|
\fIdriver\fP\fL_doit()\fP
|
|
.Fi setup_\fP\fIdriver\fP\fL.c
|
|
is called\**,
|
|
.FS
|
|
This is accomplished
|
|
'in +2m
|
|
through an incomprehensibly indirect function call, the code for
|
|
which (at the end of \fLmain()\fP) looks like:
|
|
.nr PS -4
|
|
.nr VS -4
|
|
.DS B
|
|
\fLif (driver.value->name != NULL) {
|
|
\h'6m'(*((int (*)())(driver.value->name)))();
|
|
}\fP
|
|
.DE
|
|
.nr PS +4
|
|
.nr VS +4
|
|
.in -2m
|
|
.FE
|
|
where \fIdriver\fP is the name of the compiler driver
|
|
which \*(Lc is impersonating.
|
|
E.g. in the case of driver \*(Cc, \fLcc_doit()\fP is called.
|
|
|
|
The \fIdriver\fP\fL_doit()\fP function in turn calls \fLdo_infiles()\fP,
|
|
which processes each input file according to its suffix.
|
|
|
|
\fLdo_infiles()\fP
|
|
.Fi setup.c
|
|
processes each of the input files on the global list \*Q\fLinfile\fP\*U.
|
|
It processes each file with a function appropriate to the file's suffix,
|
|
either \fLcompile_\fP\fIsuffix\fP\fL()\fP
|
|
.\""" .Fi setup_\fP\fIdriver\fP\fL.c
|
|
(for source-code files), or
|
|
\fLcollect_\fP\fIsuffix\fP\fL()\fP
|
|
(for relocatable object (\*Q\fL.o\fP\*U) files,
|
|
libraries (\*Q\fL.a\fP\*U files),
|
|
and lint libraries (\*Q\fL.ln\fP\*U files)).
|
|
Source files are compiled using passes appropriate to their suffix,
|
|
e.g. \*Q\fL.c\fP\*U files are compiled with C compiler passes.
|
|
Relocatable object files and library files are added
|
|
to a list of files for later processing by the link-editor.
|
|
Lint library files are added
|
|
to a list of files for later processing by \fLlint2\fP.
|
|
|
|
Each \fLcompile_\fP\fIsuffix\fP\fL()\fP
|
|
or \fLcollect_\fP\fIsuffix\fP\fL()\fP
|
|
compiler-driver function is bound to a suffix
|
|
using the \fLcompile\fP or \fLcollect\fP field (respectively)
|
|
of the suffix's entry in the \fLSuffixes\fP array of \fLSuffix\fP structures
|
|
.Fi ro_data.c .
|
|
|
|
The appropriate \fLcompile_\fP\fIsuffix\fP\fL()\fP function selects a template
|
|
of candidate program steps to run for that source language,
|
|
based on factors such as the requested optimization level.
|
|
A template of steps is an array of \fLStep\fP structures,
|
|
terminated by the \fLEND_OF_STEPS()\fP macro
|
|
.Fi ro_data.c .
|
|
\fLcompile_\fP\fIsuffix\fP\fL()\fP then calls \fLrun_steps()\fP,
|
|
passing the name of the source file
|
|
and the selected template of compilation steps.
|
|
|
|
\fLrun_steps()\fP determines which of the given program steps
|
|
should actually be executed
|
|
(using the function specified in the step's \fLexpression\fP field),
|
|
and for each step it:
|
|
.IP \(bu 3
|
|
Performs setup for the step, e.g sets the option flags to be passed to it.
|
|
This is done by executing the function specified in the \fLsetup\fP field
|
|
of the \fLStep\fP structure.
|
|
If none is specified, the default setup function for that step's
|
|
program, found in \fLprogram->setup\fP, is executed instead.
|
|
.IP \(bu
|
|
Redirects I/O to \fL/tmp\fP files or UNIX pipes as necessary
|
|
.IP \(bu
|
|
Executes the step.
|
|
.LP
|
|
|
|
|
|
If the \fL-v\fP (\fL-verbose\fP for \fLlint\fP) command-line flag is used,
|
|
\fLrun_steps()\fP reports the steps as they are executed to the user's terminal.
|
|
The \fL-dryrun\fP flag similarly reports the steps,
|
|
but also prevents them from actually being executed.
|
|
|
|
.Sc "A Physical Tour of \f(LB/lib/compile\fP" "A Physical Tour of \*(Lc"
|
|
|
|
The following table lists the source files of \*(Lc
|
|
and the general contents of each.
|
|
It is understood that most of the \fL.c\fP files contain functions
|
|
auxilliary to their main content.
|
|
.TS
|
|
center;
|
|
c cw(3.6i)
|
|
c l
|
|
lfL l.
|
|
Source File Contents
|
|
\_ \_
|
|
driver.h T{
|
|
Definitions of constants and structures,
|
|
used by all other source files
|
|
T}
|
|
compile.c T{
|
|
Main program,
|
|
cross-compilation setup functions,
|
|
routine to print ``help'' messages,
|
|
option-lookup routine
|
|
T}
|
|
ro_data.c T{
|
|
Global data tables which may be read-only,
|
|
and therefore shared by multiple instances of \*(Lc at runtime.
|
|
.\""" A few functions auxiliary to the data tables are also in this file.
|
|
T}
|
|
rw_data.c T{
|
|
Global data which must remain writable at runtime.
|
|
T}
|
|
run_pass.c T{
|
|
Functions which handle the actual execution of program steps
|
|
and production/destruction of associated temporary files.
|
|
T}
|
|
setup.c T{
|
|
Setup functions for language-independent compiler passes
|
|
(e.g. \fLcpp\fP, \fLiropt\fP, \fLld\fP, \fLas\fP).
|
|
T}
|
|
setup_cc.c T{
|
|
C-language specific compiler pass setup functions.
|
|
T}
|
|
setup_f77.c T{
|
|
FORTRAN-specific compiler pass setup functions.
|
|
T}
|
|
setup_lint.c T{
|
|
Lint-specific compiler pass setup functions.
|
|
T}
|
|
setup_m2c.c T{
|
|
Modula2-specific compiler pass setup functions.
|
|
T}
|
|
setup_pc.c T{
|
|
Pascal-specific compiler pass setup functions.
|
|
T}
|
|
driver_test.c T{
|
|
Driver program for \*(Lc regression testing.
|
|
T}
|
|
.TE
|
|
|
|
Each following section describes one of the above source files
|
|
in greater detail.
|
|
|
|
.Sl "\f(LBdriver.h\fP" "\fLdriver.h\fP"
|
|
This file contains all of the \fL#define\fP's, structure definitions, and
|
|
\fLextern\fP declarations for the whole program.
|
|
|
|
The \fLConst_int\fP and \fLNamed_int\fP abstractions are important to
|
|
understand, as they are used throughout \*(Lc.
|
|
They are defined as:
|
|
.KS
|
|
.de Sm \" make smaller, for code
|
|
.nr PS -4
|
|
.nr VS -6
|
|
.LP
|
|
..
|
|
.de Lg \" make un-smaller, after code
|
|
.nr PS +4
|
|
.nr VS +6
|
|
.LP
|
|
..
|
|
.Sm
|
|
.TS
|
|
center;
|
|
lfL s s 7 lfL s s
|
|
lfL 5 lfL lfL 7 lfL 5 lfL lfL.
|
|
typedef struct { typedef struct {
|
|
\| int value; Const_intP value;
|
|
\| char *name; char *help;
|
|
\| char *extra; Bool touched :1;
|
|
\| \| \| \| Bool redefine_ok:1;
|
|
.T&
|
|
lfL s s lfL s s.
|
|
} Const_int, *Const_intP; } Named_int, *Named_intP;
|
|
.TE
|
|
.Lg
|
|
.\""" .T&
|
|
.\""" lfL s s lfL lfL lfL.
|
|
.\""" } Const_int; Bool redefine_ok:1;
|
|
.\""" .T&
|
|
.\""" lfL s s lfL s s.
|
|
.\""" } Const_int; } Named_int;
|
|
.KE
|
|
Note that both structures have a field named ``\fLvalue\fP'',
|
|
which can be confusing.
|
|
It can be doubly confusing that \fLvalue\fP's type is different
|
|
in the two structures.
|
|
These structure-member names could be changed to something like
|
|
\fLc_value\fP and \fLn_value\fP, to relieve confusion;
|
|
doing so would require a careful editing job throughout the source files.
|
|
.\"""
|
|
.\""" The code used to say things like
|
|
.\""" .ti +4m
|
|
.\""" \fLif (target_arch.value == &arch_sun2)\fP
|
|
.\""" .br
|
|
.\""" in many places.
|
|
.\""" Such code now reads:
|
|
.\""" .ti +4m
|
|
.\""" \fLif (target_arch.value->value == ARCH_SUN2)\fP
|
|
.\""" .br
|
|
|
|
Additional structures are duplicated here,
|
|
followed by explanations of their function.
|
|
|
|
.Sm
|
|
.TS
|
|
center;
|
|
lfL s s
|
|
lfL 6 lfL lfL.
|
|
typedef struct {
|
|
\| char *suffix;
|
|
\| short int in_drivers;
|
|
\| short int out_drivers;
|
|
\| int (*compile)();
|
|
\| void (*collect)();
|
|
\| char *help;
|
|
.T&
|
|
lfL s s.
|
|
} Suffix;
|
|
|
|
.T&
|
|
lfL s s
|
|
lfL 6 lfL lfL.
|
|
typedef struct {
|
|
\| Suffix a;
|
|
\| Suffix c;
|
|
\| Suffix def;
|
|
\| Suffix f;
|
|
\| Suffix F;
|
|
\| Suffix il;
|
|
\| Suffix i;
|
|
\| Suffix ln;
|
|
\| Suffix mod;
|
|
\| Suffix o;
|
|
\| Suffix pi;
|
|
\| Suffix p;
|
|
\| Suffix r;
|
|
\| Suffix sym;
|
|
\| Suffix s;
|
|
\| Suffix S;
|
|
\| Suffix ir;
|
|
\| Suffix none;
|
|
\| Suffix sentinel_suffix_field;
|
|
.T&
|
|
lfL s s.
|
|
} Suffixes;
|
|
.TE
|
|
.Lg
|
|
There is one instance of a \fLSuffix\fP structure for each type of Suffix,
|
|
embedded in the \fLSuffixes\fP structure.
|
|
The single instance of \fLSuffixes\fP is \fLsuffixes\fP,
|
|
which is delcared in \fLro_data.c\fP.
|
|
|
|
The \fLsuffix\fP field points to the suffix in character string form,
|
|
without a leading `.'.
|
|
\fLin_drivers\fP and \fLout_drivers\fP contain bitmasks
|
|
(in \fLDRIVER_*\fP form)
|
|
indicating which drivers consume and produce (respectively)
|
|
files of the given suffix.
|
|
|
|
The \fPcompile\fP (if non-\fLNULL\fP) field points to a function named
|
|
\fLcompile_\fP\fIsuffix\fP\fL()\fP, used to compile files of this suffix.
|
|
\fPcollect\fP (if non-\fLNULL\fP) points to a function named
|
|
\fLcollect_\fP\fIsuffix\fP\fL()\fP, used to collect files of this suffix
|
|
for processing by a later compiler pass.
|
|
See the \fBInvocation of Compiler Passes\fP section for a more detailed
|
|
explanation of \fLcompile\fP and \fLcollect\fP.
|
|
|
|
.Sm
|
|
.TS
|
|
center;
|
|
lfL s s
|
|
lfL s s
|
|
lfL 6 lfL lfL.
|
|
#define PGM_TEMPLATE_LENGTH 5
|
|
typedef struct {
|
|
\| char *name;
|
|
\| char *path;
|
|
\| short int drivers;
|
|
\| char *(*setup)();
|
|
\| ListP permanent_options;
|
|
\| ListP trailing_options;
|
|
\| ListP options;
|
|
\| ListP infile;
|
|
\| char *outfile;
|
|
\| Bool has_been_initialized :1;
|
|
\| Template template[PGM_TEMPLATE_LENGTH];
|
|
.T&
|
|
lfL s s.
|
|
} Program;
|
|
|
|
.T&
|
|
lfL s s
|
|
lfL 6 lfL lfL.
|
|
typedef struct {
|
|
\| Program cpp;
|
|
\| Program m4;
|
|
\| Program ratfor;
|
|
\| Program lint1;
|
|
\| Program cat;
|
|
\| Program lint2;
|
|
\| Program m2cfe;
|
|
\| Program ccom;
|
|
\| Program pc0;
|
|
\| Program f1;
|
|
\| Program mf1;
|
|
\| Program vpaf77;
|
|
\| Program f77pass1;
|
|
\| Program iropt;
|
|
\| Program iropt_f77;
|
|
\| Program iropt_pc;
|
|
\| Program cg;
|
|
\| Program cg_f77;
|
|
\| Program cg_pc;
|
|
\| Program inline;
|
|
\| Program c2;
|
|
\| Program as;
|
|
\| Program asS;
|
|
\| Program pc3;
|
|
\| Program ld;
|
|
\| Program vpald;
|
|
\| Program m2l;
|
|
\| Program sentinel_program_field;
|
|
.T&
|
|
lfL s s.
|
|
} Programs;
|
|
.TE
|
|
.Lg
|
|
There is one instance of a \fLProgram\fP structure for each type of Program,
|
|
embedded in the \fLPrograms\fP structure.
|
|
The single instance of \fLPrograms\fP is \fLprograms\fP,
|
|
which is delcared in \fLrw_data.c\fP.
|
|
|
|
The \fLname\fP field points to the name of the program,
|
|
in character string form.
|
|
\fLpath\fP gives the full pathname of the program in the filesystem,
|
|
used when \fLexec()\fP'ing it.
|
|
|
|
\fLdrivers\fP contains a bitmask (in \fLDRIVER_*\fP form)
|
|
indicating which drivers make use of the program.
|
|
\fINote:\fP this field of the \fLProgram\fP structure doesn't seem to be
|
|
referenced anywhere in the code.
|
|
|
|
\fLsetup\fP is a pointer to the function to call
|
|
to set up for a run of the program.
|
|
|
|
\fLpermanent_options\fP
|
|
points to a list of options to pass on to the program,
|
|
which can be set once per driver command line.
|
|
These options are invariant between compilations of various files
|
|
on the command line.
|
|
For example:
|
|
.ti +5n
|
|
\fL%\fP\f(LB m2c a.mod b.def -v\fP
|
|
.br
|
|
produces these two ``\fLm2cfe\fP'' command lines:
|
|
.ti +5n
|
|
\s-4\f(LB/usr/lib/modula2/m2cfe -mod a "-M. /usr/lib/modula2" a.mod >\fP\fItemp_file\fP\s+4
|
|
.ti +5n
|
|
\s-4\f(LB/usr/lib/modula2/m2cfe -def b "-M. /usr/lib/modula2" b.def >b.sym\fP\s+4
|
|
.br
|
|
The ``\fL-M\fP'' option of the \fLm2cfe\fP program is one which is invariant
|
|
per invocation of the compiler driver (\fLm2c\fP here).
|
|
So, in this example, the \fL"-M. /usr/lib/modula2"\fP option is set once,
|
|
as a ``permanent'' option for \fLm2cfe\fP.
|
|
.\"""
|
|
.\""" Here's another example, on a Sun-4 running SunOS 3.x:
|
|
.\""" .nf
|
|
.\""" .in +5n
|
|
.\""" \fL%\fP\f(LB arch ; strings /vmunix | egrep 'SunOS|UNIX'\fP
|
|
.\""" \fLsun4\fP
|
|
.\""" \fL\s-4SunOS Release Sys4-3.2 (GENERIC) #1: Wed Nov 11 12:33:42 PST 1987\s+4\fP
|
|
.\""" \fL%\fP\f(LB f77 -O4 f.f p.p\fP
|
|
.\""" \fL\s-4f.f:
|
|
.\""" /usr/lib/f77pass1 -O f.f /tmp/f77pass1.26982.s.0.s /tmp/f77pass1.26982.i.1.s /tmp/f77pass1.26982.d.2.s
|
|
.\""" /usr/lib/iropt -O4 -o /tmp/iropt.26982.3.ir /tmp/f77pass1.26982.i.1.s
|
|
.\""" /usr/lib/cg /tmp/iropt.26982.3.ir >/tmp/cg.26982.4.s
|
|
.\""" /bin/as -o f.o -O4 /tmp/f77pass1.26982.s.0.s /tmp/cg.26982.4.s /tmp/f77pass1.26982.d.2.s
|
|
.\""" p.p:
|
|
.\""" /lib/cpp -Dunix -Dsun -Dsparc -undef p.p >/tmp/cpp.26982.5.pi
|
|
.\""" /usr/lib/pc0 -o /tmp/pc0.26982.6.none -O /tmp/cpp.26982.5.pi
|
|
.\""" /usr/lib/f1 /tmp/pc0.26982.6.none >/tmp/f1.26982.7.s
|
|
.\""" /usr/lib/inline -i /usr/lib/pc2.il </tmp/f1.26982.7.s >/tmp/inline.26982.8.s
|
|
.\""" /bin/as -o p.o -O4 /tmp/inline.26982.8.s
|
|
.\""" Linking:
|
|
.\""" /bin/ld -e start -u _MAIN_ -X -o a.out /lib/crt0.o f.o p.o -lF77 -lI77 -lU77 -lm -lc\s+4\fP
|
|
.\""" .in -5n
|
|
.\""" .fi
|
|
|
|
\fLtrailing_options\fP are ``permanent'' options which need to be added to
|
|
the \fIend\fP of the command line.
|
|
This is used by the \fL-U\fP and \fL-D\P options,
|
|
so that user-provided preprocessor (\fL/lib/cpp\fP) options will apprear
|
|
after the \*(Lc-provided arguments to \fL/lib/cpp\fP.
|
|
This is currently for aesthetics.
|
|
If \fLcpp\fP's \fL-U\fP changes to allow it to be the full semantic
|
|
equivalent of \fL#undef\fP, then this ordering will matter.
|
|
``\fL-Qoption \fP\fIpass option\fP'' also uses \fLtrailing_options\fP,
|
|
so that it can be used to override default options to any pass.
|
|
|
|
\fLoptions\fP points to a list of the options to pass the program,
|
|
on a per-execution basis.
|
|
These options may change between executions of the compiler pass.
|
|
E.g., in the \fLm2c\fP example under the explanation
|
|
of ``\fLpermanent_options\fP'' above,
|
|
the ``\fL-mod a\fP'' and ``\fL-def b\fP'' options to the \fLm2cfe\fP
|
|
program changed between its two invocations.
|
|
The \fLoptions\fP field is cleared and the list re-populated prior to
|
|
each invocation of the program with which it is associated.
|
|
|
|
\fLinfile\fP points to a list of input file names for the program.
|
|
|
|
\fLoutfile\fP points to a single output file name for the program.
|
|
|
|
\fLhas_been_initialized\fP is \fLFALSE\fP until \fLpermanent_options\fP
|
|
has been set up, then it is set \fLTRUE\fP.
|
|
Its sole purpose in life seems to be preventing \fLpermanent_options\fP
|
|
from being set more than once (thus is probably just a time optimization);
|
|
it might have well have been named something like
|
|
\fLpermanent_options_have_been_set\fP.
|
|
|
|
\fLtemplate\fP is an array giving a template for the order in which
|
|
input filenames, output filenames, and options should be passed to the
|
|
program.
|
|
It also specifies whether the standard input and/or standard output
|
|
should be set up for the program.
|
|
If the standard input is used,
|
|
the value \fLSTDIN_TEMPLATE\fP \fImust\fP be in the first element of
|
|
\fLtemplate\fP, i.e. \fLtemplate[0]\fP must equal \fLSTDIN_TEMPLATE\fP\**.
|
|
.FS
|
|
This is relied upon in
|
|
'in +2m
|
|
file \fLrun_pass.c\fP,
|
|
function \fLbuild_argv()\fP,
|
|
in the \fLSTDOUT_TEMPLATE\fP case of a \fLswitch\fP.
|
|
This dependency could be removed by scanning all of the next \fLstep\fP's
|
|
template instead of just looking at \fL(step+1)->program->template[0]\fP.
|
|
.in -2m
|
|
.FE
|
|
|
|
.Sm
|
|
.TS
|
|
center;
|
|
lfL s s
|
|
lfL 6 lfL lfL.
|
|
typedef struct {
|
|
\| ProgramP program;
|
|
\| SuffixP out_suffix;
|
|
\| int (*expression)();
|
|
\| char *(*setup)();
|
|
\| struct timeval start;
|
|
\| short int process;
|
|
\| Bool killed :1;
|
|
.T&
|
|
lfL s s.
|
|
} Step;
|
|
.TE
|
|
.Lg
|
|
\fLprogram\fP
|
|
.Incomplete
|
|
|
|
\fLout_suffix\fP
|
|
.Incomplete
|
|
|
|
\fLexpression\fP
|
|
.Incomplete
|
|
|
|
\fLsetup\fP
|
|
.Incomplete
|
|
|
|
\fLstart\fP
|
|
.Incomplete
|
|
|
|
\fLprocess\fP
|
|
.Incomplete
|
|
|
|
\fLkilled\fP
|
|
.Incomplete
|
|
|
|
.Sm
|
|
.TS
|
|
center;
|
|
lfL s s s
|
|
lfL 6 lfL s lp-2.
|
|
typedef enum {
|
|
\| end_of_list = 1, /* The last option in the list of options */
|
|
\| help_option, /* Show help message */
|
|
\| infile_option, /* This option is an infile */
|
|
\| lint1_option, /* pass to lint1 */
|
|
\| lint_i_option, /* Special check for lint -n & -i to make sure*/
|
|
\| lint_n_option, /* they do not have more options trailing*/
|
|
\| make_lint_lib_option, /* Make lint library option */
|
|
\| module_option, /* Force load modula module */
|
|
\| module_list_option, /* m2c search path option */
|
|
\| optimize_option, /* -O/-P options */
|
|
\| outfile_option, /* next arg is the outfile */
|
|
\| pass_on_lint_option, /* Pass to lint1 & lint2 */
|
|
\| pass_on_select_option, /* -Qoption handler */
|
|
\| pass_on_1_option, /* -x => prog -x */
|
|
\| pass_on_1t12_1t_option, /* -xREST => prog -xREST */
|
|
\| /* [or] -x REST => prog -xREST */
|
|
\| pass_on_1t_option, /* -xREST => prog -xREST */
|
|
\| pass_on_12_option, /* -x REST => prog -x REST */
|
|
\| pass_on_1to_option, /* -xREST => prog REST */
|
|
\| produce_option, /* -Qproduce handler */
|
|
\| path_option, /* -Qpath handler */
|
|
\| run_m2l_option, /* m2c -e handler */
|
|
\| load_m2l_option, /* m2c -E handler */
|
|
\| set_int_arg_option, /* Handle simple boolean options */
|
|
\| set_named_int_arg_option, /* Handle multiple choice options */
|
|
\| set_target_arch_option1, /* -{TARGET} (set target_arch) */
|
|
\| set_target_arch_option2, /* -target {TARGET} (set target_arch) */
|
|
\| set_target_proc_option1, /* -{PROCESSOR} (set target processor
|
|
\| * type & target_arch)
|
|
\| */
|
|
\| set_sw_release_option, /* next arg is the target S/W release */
|
|
\| temp_dir_option /* Handle -temp option */
|
|
.T&
|
|
lfL s s s
|
|
lfL s s s.
|
|
} Options;
|
|
|
|
.T&
|
|
lfL s s s
|
|
lfL 6 lfL lfL lfL.
|
|
typedef struct {
|
|
\| char *name;
|
|
\| int drivers :16;
|
|
\| Options type :8;
|
|
\| int subtype :8;
|
|
\| Named_intP variable;
|
|
\| ProgramP program;
|
|
\| Const_intP constant;
|
|
\| char *help;
|
|
.T&
|
|
lfL s s.
|
|
} Option;
|
|
.TE
|
|
.Lg
|
|
.Incomplete
|
|
|
|
.Sm
|
|
.TS
|
|
center;
|
|
lfL s s s
|
|
lfL 6 lfL lfL lp-2.
|
|
#define set_flag(flag) global_flag.flag= TRUE
|
|
#define reset_flag(flag) global_flag.flag= FALSE
|
|
#define is_on(flag) (global_flag.flag == TRUE)
|
|
#define is_off(flag) (global_flag.flag == FALSE)
|
|
.TE
|
|
.Lg
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBcompile.c\fP" "\fLcompile.c\fP"
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBro_data.c\fP" "\fLro_data.c\fP"
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBrw_data.c\fP" "\fLrw_data.c\fP"
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBrun_pass.c\fP" "\fLrun_pass.c\fP"
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBsetup.c\fP" "\fLsetup.c\fP"
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBsetup_cc.c\fP" "\fLsetup_cc.c\fP"
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBsetup_f77.c\fP" "\fLsetup_f77.c\fP"
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBsetup_lint.c\fP" "\fLsetup_lint.c\fP"
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBsetup_m2c.c\fP" "\fLsetup_m2c.c\fP"
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBsetup_pc.c\fP" "\fLsetup_pc.c\fP"
|
|
.Incomplete
|
|
|
|
.Sl "\f(LBtest_dir/driver_test.c\fP" "\fLtest_dir/driver_test.c\fP"
|
|
.Incomplete
|
|
|
|
.Sc Cross-Compilation
|
|
|
|
\*QCross-compilation\*U means translating source code (on a host system) into
|
|
executable code which is designed to run on a target system
|
|
which is meaningfully different from the host system.
|
|
\*QDifferent\*U applies to:
|
|
.IP \(bu 3
|
|
System architecture types;
|
|
compiling code on a Sun-4 for a Sun-3 target machine is an example of
|
|
\fIcross-architecture\fP compilation.
|
|
.IP \(bu
|
|
Operating system types;
|
|
compiling code on a PC/AT under XENIX
|
|
to produce binaries which will run on a PC/AT under MS-DOS,
|
|
and compiling code on a Sun-4 for a SPARC chip embedded in a controller card
|
|
are examples of \fIcross-OS\fP compilation.
|
|
.IP \(bu
|
|
Versions of a single operating system;
|
|
compiling code on a Sun-3 under SunOS-4.0 to run on a Sun-3 under SunOS-3.2
|
|
is an example of \fIcross(-OS)-release\fP compilation.
|
|
.LP
|
|
|
|
There has been discussion within the Programming Languages group as to which
|
|
types of cross-compilation we should support.
|
|
Support for all three types is present in \*(Lc,
|
|
but we only publicly claim to support cross-architecture compilation
|
|
(via our Cross-Compiler products).
|
|
Cross-OS compilation will be needed to support non-UNIX SPARC software
|
|
development.
|
|
The need for cross-release compilation is not likely to be strongly
|
|
established.
|
|
|
|
Cross-compilation typically refers to the first type,
|
|
cross-architecture compilation.
|
|
This is the type to which this this document refers,
|
|
except when stated otherwise.
|
|
|
|
The \*Q\fL-target \fP\fItarget_arch\fP\*U option specifies the target
|
|
architecture\**
|
|
.FS
|
|
For discussion of how to specify a target software release,
|
|
'in +2m
|
|
see the \fBTarget Software Releases\fP section.
|
|
.in -2m
|
|
.FE
|
|
for which one wishes to compile.
|
|
It may be abbreviated to \fL-\fP\fItarget_arch\fP for Sun target architectures.
|
|
|
|
If the host and requested target architectures are the same
|
|
(and the host and target software releases are the same),
|
|
native compilation is performed\**.
|
|
.FS
|
|
The section \fBSupport for NSE Variants\fP describes an exception to this.
|
|
.FE
|
|
Otherwise, cross-compilation is triggered.
|
|
|
|
Cross-compilation requires that during compilation
|
|
the native versions of compiler passes, \fL#include\fP files,
|
|
and libraries be supplanted with replacements appropriate to the target
|
|
architecture.
|
|
\*(Lc accomplishes this (transparently to the user)
|
|
by setting an environment variable named \*(Vr\**.
|
|
.FS
|
|
For brevity,
|
|
\*(Vr and \*(Vv
|
|
'in +2m
|
|
are both occasionally referred to as VROOT
|
|
in documentation and source-code comments.
|
|
.in -2m
|
|
.FE
|
|
\*(Vr functions similarly to the \fLPATH\fP environment variable,
|
|
except that it applies not only to executable files but to virtually
|
|
\fIall\fP files opened by the various compiler passes.
|
|
\*(Vr's value consists of a colon-separated list of directories.
|
|
When a program using \*(Vr tries to open a file with an absolute
|
|
pathname (i.e., the filename starts with `\fL/\fP'),
|
|
each component of \*(Vr is treated as the root of a filesystem, in order,
|
|
until the file can be opened under one of them.
|
|
|
|
All compilation programs (such as \*(Lc, \fLcpp\fP, \fLas\fP, \fLld\fP)
|
|
which open files or \fLexec()\fP other programs (e.g. compiler passes)
|
|
use functions from the \fLvroot\fP library.
|
|
Each function in the \fLvroot\fP library
|
|
replaces a system-call function which may be passed a filename.
|
|
An example function is \fLopen_vroot()\fP, which replaces \fLopen()\fP.
|
|
The behavior of any function in the \fLvroot\fP library
|
|
is modified by the \*(Vr environment variable, as decribed above,
|
|
when it is passed a filename with an absolute path.
|
|
|
|
.KS
|
|
During cross-compilation, \fLsetup_for_cross_compile()\fP usually\**
|
|
.FS
|
|
In the case when a specific target software release is requested,
|
|
'in +2m
|
|
\*(Vr is actually set to:
|
|
.ce
|
|
\*(Ht\fLR\fP\fIsw_release\fP\fL:\fP\fIinherited_\s-2VIRTUAL_ROOT\s+2\fP
|
|
.br
|
|
See the section on \fBTarget Software Releases\fP for more information.
|
|
.in -2m
|
|
.FE
|
|
sets the value of \*(Vr to:
|
|
|
|
.ce
|
|
\*(Ht\fL:\fP\fIinherited_\s-2VIRTUAL_ROOT\s+2\fP
|
|
.br
|
|
.KE
|
|
|
|
The first component, \*(Ht, is referred to as \*(Vv in this document.
|
|
It is sometimes called \*Qthe\*U virtual root.
|
|
This nomenclature causes it to be confused with \*(Vr,
|
|
of which it is actually only one component.
|
|
|
|
\*(Vr comprises a list of potentially many filesystem paths.
|
|
However, given that \*(Vr is an undocumented internal mechanism,
|
|
users should not be assigning it a value themselves.
|
|
Since \*(Lc is the only software tool which sets \*(Vr,
|
|
and presently doesn't \fLexec()\fP itself,
|
|
\fIinherited_\s-2VIRTUAL_ROOT\s+2\fP will typically be a null string.
|
|
So, during cross-compilation \*(Vr should look like:
|
|
|
|
.ce
|
|
\*(Ht\fL:\fP
|
|
|
|
.KS
|
|
Or, for a more concrete example:
|
|
|
|
.ce
|
|
\fL/usr/arch/sun3/sun4:\fP
|
|
.KE
|
|
|
|
Thereafter during that compilation,
|
|
when a compiler pass (e.g. \fLcpp\fP) tries to open file
|
|
\fLfoo.c\fP, it opens \fLfoo.c\fP in the current directory.
|
|
But if it tries to open a file with an absolute pathname,
|
|
say \fL/usr/include/foo.h\fP, using \fLopen_vroot()\fP,
|
|
the library function would first try opening
|
|
\fL/usr/arch/sun3/sun4/usr/include/foo.h\fP.
|
|
If that failed
|
|
(since there is a zero-length string as the second component of \*(Vr),
|
|
it would try to open \fL/usr/include/foo.h\fP.
|
|
|
|
The null second component of \*(Vr (created by the final colon)
|
|
is seldom of use to Sun's packaged cross-compiler products themselves,
|
|
since they include a complete replacement set of compiler passes\**,
|
|
.FS
|
|
Except for \fL/usr/bin/lint\fP and \fL/usr/lib/lint\fP,
|
|
'in +2m
|
|
which are not distributed with Cross-Compilers 2.0.
|
|
The null second component of \*(Vr causes the native \fLlint\fP tools
|
|
to be used in that case.
|
|
.in -2m
|
|
.FE
|
|
\fL#include\fP files, and libraries under the appropriate VROOT
|
|
directory (see \*QFilesystem Structure\*U below).
|
|
However, the null second component is needed when a user specifies an
|
|
absolute pathname to a file, so that the file is searched for under the
|
|
root of the \fIuser's\fP filesystem,
|
|
as well as under \*(Vv (the first component of \*(Vr).
|
|
|
|
For example, take the following cross-compilation command:
|
|
.ce
|
|
\fLmy_sun3%\fP\f(LB cc /usr/bob/pgm.c -target sun4\fP
|
|
.br
|
|
In this case, without the final colon in \*(Vr,
|
|
\fLcpp\fP would only try to open \fL/usr/arch/sun3/sun4/usr/bob/pgm.c\fP,
|
|
and fail.
|
|
With the colon in \*(Vr,
|
|
it then attempts to open \fL/usr/bob/pgm.c\fP and succeeds.
|
|
|
|
.Sl "Filesystem Structure"
|
|
\*(Lc expects a directory to be present on the host machine which contains
|
|
all the \*(Vv\|s needed for cross-compilation.
|
|
In Cross-Compilers release 2.0, that directory is hardwired to be \*(Ua\**.
|
|
.FS
|
|
In subsequent releases, the cross-compilation home directory will be
|
|
'in +2m
|
|
specifiable in the \*(Ch environment variable.
|
|
The default directory will remain \*(Ua.
|
|
.in -2m
|
|
.FE
|
|
|
|
The various \*(Vr directories are named:
|
|
.ce
|
|
\*(Ht
|
|
The \fIhost_arch\fP level is present so that heterogeneous hosts
|
|
can conveniently share these files across the network from a single fileserver.
|
|
|
|
In Cross-Compilers 2.0, there also exist directories named \*(Ct and \*(Hc,
|
|
containing files which are common across host architectures for a given target,
|
|
and common across target architectures for a given host, respectively.
|
|
.\""" \*(Lc is blissfully unaware of their presence;
|
|
.\""" the \*(Ht directories contain symbolic links into the common directories
|
|
.\""" wherever appropriate, so \*(Lc need only look under \*(Ht to find files.
|
|
This saves considerable amounts of disk space;
|
|
Server installaion of a full set of Cross-Compilers 2.0
|
|
(6 directions of cross-compilation)
|
|
would require approximately 120Mb if there were no sharing via
|
|
common directories, but given them, consumes only 37Mb of disk space.
|
|
|
|
\*(Lc is blissfully unaware of the presence of the common directories.
|
|
The \*(Ht directories contain symbolic links into the common directories
|
|
wherever appropriate, so \*(Lc only needs to look under \*(Ht to find files.
|
|
|
|
.Sl "Target Software Releases"
|
|
.LP
|
|
As stated earlier,
|
|
cross-compilation can just as easily refer to
|
|
cross-OS compilation or cross-OS-release compilation,
|
|
as to cross-architecture compilation.
|
|
\*(Lc can handle all three types of cross-compilation
|
|
by ensuring that each combination of
|
|
system architecture/OS/OS-version causes a different \*(Vv to be used.
|
|
|
|
As long as the compiler passes under each of the different \*(Vvs
|
|
are invoked identically, this works fine.
|
|
The \*Qgotcha\*U is that if there are any differences among the \*(Vvs
|
|
in how the compiler passes are invoked,
|
|
the driver must adjust its behavior accordingly.
|
|
|
|
For instance,
|
|
if \*(Lc was to simultaneously support compilers from both SunOS 3.x
|
|
and SunOS 4.0, it would have to know about differences such as:
|
|
.IP \(bu 3
|
|
\fLiropt\fP may be run for FORTRAN compilations in either release,
|
|
but for C and Pascal compilations it can only be run during 4.0 compilations.
|
|
.IP \(bu
|
|
The \fL-p\fP flag is passed to \fLccom\fP as \fL-XP\fP in 3.x,
|
|
but as \fL-p\fP in 4.0; similarly for \fL-J\fP.
|
|
.IP \(bu
|
|
Sun-2/3 floating-point libraries are found in
|
|
\fL/usr/lib/\fP\fIfloat_option\fP in 4.0.
|
|
.IP \(bu
|
|
\*Q\fLld\fP\*U gets \fL-dc\fP and \fL-dp\fP options by default in 4.0,
|
|
but doesn't even recognize them in 3.x.
|
|
.LP
|
|
|
|
\*(Lc indeed \fIdoes\fP know about these differences and can run
|
|
both native and cross-architecture/cross-release compilations \(en
|
|
although the capability to
|
|
perform cross-release compilation has (deliberately) been kept an
|
|
undocumented feature.
|
|
This has been done deliberately because cross-release compilation
|
|
would be difficult (at best) to support ad infinitum to the external world.
|
|
However, it works fine within the internal confines of Sun,
|
|
at least in the 4.0-to-3.x direction (aided greatly by the fact that
|
|
3.x binaries can run under SunOS 4.0).
|
|
|
|
\*(Lc supports execution of compiler passes from both SunOS 4.0 and SunOS 3.x,
|
|
if the preprocessor variable \fLHANDLE_R32\fP is defined when compiling \*(Lc.
|
|
This is currently the default in its Makefile.
|
|
If \fLHANDLE_R32\fP is not defined,
|
|
only SunOS 4.0-style compiler passes are supported.
|
|
|
|
This feature is made possible with the \*Q\fL-release \fP\fIsw_release\fP\*U
|
|
option, which specifies (independently of the target architecture)
|
|
the desired target software release.
|
|
For example,
|
|
one could install Cross-Compilers 2.0 (which are SunOS 3.x-based)
|
|
on a Sun-3 running SunOS 4.0, and compile 3.x Sun-2 binaries with the
|
|
command:
|
|
|
|
.ce
|
|
\fLmy_sun3%\fP\f(LB cc -sun2 -release 3.2 pgm.c -o pgm\fP
|
|
|
|
When the \fL-release\fP option is not specified,
|
|
\*(Lc must somehow determine whether the default target
|
|
software release is SunOS 3.x or SunOS 4.0,
|
|
so it knows what type of options to pass to the various compiler passes.
|
|
It does this by looking for \fL/usr/lib/crt0.o\fP in the filesystem
|
|
(under \*(Vr, in the case of a cross-compilation).
|
|
If it is present, it assumes that the target software release is SunOS 4.0,
|
|
since \fL/usr/lib/crt0.o\fP is not present under \fL/usr/lib\fP in SunOS 3.x.
|
|
Granted, this is a \fIgrungy\fP thing to do,
|
|
but when we handle multiple target software releases,
|
|
we have to determine the default case \fIsomehow\fP.
|
|
|
|
|
|
As suggested earlier,
|
|
a system is actually identified by not just its system architecture,
|
|
but the \fIcombination\fP of its system architecture and the
|
|
operating system which is running on it.
|
|
Therefore, the \*Qreal\*U target directories under \*(Ua have names of
|
|
\fItarget_arch\fP\fLR\fP\fIsw_release\fP.
|
|
Target directories named just \fItarget_arch\fP
|
|
(without a software release) are defaults,
|
|
referenced when no specific target software release is requested.
|
|
|
|
Although \*(Lc never references \*(Ha\fLR\fP\fIsw_release\fP,
|
|
it could be useful to install cross-compiler tools for multiple host
|
|
software releases on one server under those directories.
|
|
Each machine can reference the correct host directory
|
|
.\""" for its own architecture
|
|
as \*(Ha by
|
|
mounting \fIhost_arch\fP\fLR\fP\fIsw_release\fP
|
|
from the server on its \*(Ha\fLR\fP\fIsw_release\fP,
|
|
then making a symbolic link from
|
|
\*(Ha\fLR\fP\fIsw_release\fP to \fIhost_arch\fP.
|
|
This is the way Cross-Compilers 2.0 is installed
|
|
(see the \fBCross-Compilers 2.0\fP appendix).
|
|
|
|
Cross-compilation without a \*Q\fL-release \fP\fIsw_release\fP\*U option
|
|
compiles for the default software release for the given target.
|
|
|
|
|
|
In more detail, \*Q\fL-release \fP\fIsw_release\fP\*U has three effects:
|
|
.IP \(bu 3
|
|
It changes the \*(Vv for cross-compilation to indicate a specific
|
|
target software release instead of the default one
|
|
(e.g., \*(Ua\fL/sun3/sun4R3.2\fP instead of \*(Ua\fL/sun3/sun4\fP).
|
|
This value is kept in \fLtarget_sw_release[R_VROOT]\fP.
|
|
.IP \(bu
|
|
It sets the directory paths under \*(Vr from which to find compiler passes
|
|
and libraries (since they differ between SunOS-3.x and SunOS-4.0).
|
|
This value is kept in \fLtarget_sw_release[R_PATHS]\fP.
|
|
.IP \(bu
|
|
It affects which compiler passes are used (e.g. \fLiropt\fP for C)
|
|
and which flags are passed to the compiler passes
|
|
(again, since these differ between SunOS-3.x and SunOS-4.0).
|
|
This value is kept in \fLtarget_sw_release[R_PASSES]\fP.
|
|
.LP
|
|
|
|
.Sl "Foreign Target Architectures"
|
|
\*(Lc provides minimal support for cross-compilation for foreign target
|
|
architectures, via the \*Q\fL-target \fP\fIother_arch\fP\*U option.
|
|
Given this option, \*(Lc:
|
|
.IP \(bu 3
|
|
Sets the environment variable \*(Vr to the value \*Q\*(Ho\fL:\fP\*U
|
|
.IP \(bu
|
|
Expects \*(Ho to be populated with compiler passes,
|
|
include files, and libraries in the same locations as for the Sun
|
|
native compilers\**
|
|
.FS
|
|
If \*(Ho\fL/usr/lib/crt0.o\fP does not exist
|
|
'in +2m
|
|
and \*(Lc was built with \fL-DHANDLE_R32\fP,
|
|
foreign compiler passes, libraries, and include files
|
|
will be expected in their SunOS release 3.x locations.
|
|
Otherwise, they will be expected in their SunOS 4.0 locations.
|
|
It is highly recommended that foreign compiler passes be set up
|
|
like those for 4.0 and that the \fLcrt0.o\fP mentioned above be present
|
|
(even if unused),
|
|
since at some point \*(Lc may no longer support 3.x-style compilers.
|
|
.in -2m
|
|
.FE
|
|
.IP \(bu
|
|
Expects that the foreign compiler passes will accept the same options as
|
|
the Sun native compiler passes\**
|
|
.FS
|
|
Ditto the previous footnote,
|
|
'in +2m
|
|
for the options which are passed to the compiler passes.
|
|
Note that if a foreign pass does not accept the options passed it by
|
|
\*(Lc, a Shell script or program can be installed which filters or
|
|
converts the options as desired, and \fLexec()\fP's the actual compiler pass.
|
|
.in -2m
|
|
.FE
|
|
.IP \(bu
|
|
Does not pass the usual \fL-Dunix\fP, \fL-Dsun\fP,
|
|
and \fL-D\fP\fItarget_mach\fP options to \fLcpp\fP
|
|
(foreign cross-compilation users must set their own)
|
|
.IP \(bu
|
|
Can still pass additional options to the foreign compiler passes
|
|
via the \*Q\fL-Qoption \fP\fIpass_name\fP\fL \fP\fIoption\fP\*U mechanism
|
|
.LP
|
|
|
|
For example,
|
|
if on a Sun-4 host,
|
|
\*(Ua\fL/sun4/abc\fP contains appropriate compiler passes for target \fLabc\fP,
|
|
then
|
|
.ce
|
|
\fLmy_sun4% \fP\f(LBcc -target abc pgm.c\fP
|
|
will cross-compile \fLpgm.c\fP for target \fLabc\fP.
|
|
|
|
The \*Q\fL-release \fP\fIsw_release\fP\*U option is not meaningful
|
|
for foreign architecture cross-compilation,
|
|
since \*(Lc is ignorant of \*Qforeign software release numbers\*U.
|
|
|
|
As of the end of 1987,
|
|
the foreign-target cross-compilation functionality is being used by at
|
|
least one internal group (the CDI project; see Dan Steinberg).
|
|
|
|
.Sl "Support for NSE Variants\s-4\**\s+4" "Support for NSE Variants"
|
|
.FS
|
|
Marty Honda and Evan Adams
|
|
'in +2m
|
|
(in the NSE group) are contacts for additional NSE information.
|
|
.in -2m
|
|
.FE
|
|
Under Sun's Network Software Environment (NSE)
|
|
one can easily generate code for multiple target architectures,
|
|
through \*Qvariants\*U of one's NSE environment.
|
|
There is one variant per target architecture.
|
|
When one changes to a new variant everything \fIlooks\fP the same,
|
|
except that all target-dependent files in the filesystem have suddenly
|
|
been replaced \(en including compiler passes, include files, and libraries.
|
|
Effectively, a \*(Vv overlays the native root filesystem
|
|
(using an internal NSE mechanism known as \*Qtranslucent mounting\*U).
|
|
Apparently-native compilations magically create object code for the new
|
|
variant (target).
|
|
|
|
Although NSE's translucent mounting mechanism supplants \*(Vr in this
|
|
situation,
|
|
\*(Lc still needs to know the target architecture for which it's compiling.
|
|
It can discover this by checking some environment variables set by NSE.
|
|
If \*(Nv is set, then an NSE environment is activated.
|
|
In that case, \*(Lc obtains the name of the desired target architecture from
|
|
the \*(Ta environment variable.
|
|
\*(Ta contains the target architecture name, prefixed by a \*Q\fL-\fP\*U.
|
|
|
|
Any time a target architecture is explicitly given on the compiler command line,
|
|
it overrides the implicit target architecture specified by the NSE environment.
|
|
|
|
A subtle case to remember is when one is in a non-native variant of
|
|
an activated NSE environment and \fIexplicitly\fP specifies the
|
|
native architecture as the target architecture on the command line\**.
|
|
.FS
|
|
For example, one is working on a Sun-3,
|
|
'in +2m
|
|
with an activated NSE variant of \fLsun4\fP,
|
|
and one gives the command ``\fLcc -sun3 foo.c\fP''.
|
|
.in -2m
|
|
.FE
|
|
Can this be treated as a normal native compilation?
|
|
The answer is \fIno\fP.
|
|
Although \*(Lc normally obtains native compiler passes, include files,
|
|
and libraries from under the root filesystem (\*Q\fL/\fP\*U),
|
|
NSE has arranged for the \fIcross\fP versions of those files to appear
|
|
in their place.
|
|
In this case, \*(Hh must be populated with appropriate native compilation
|
|
pieces, and \*(Lc must set \*(Vr to \*(Hh\fL:\fP.
|
|
It then proceeds with the compilation as if it were a cross-compilation.
|
|
|
|
Support for NSE is contained in the routines
|
|
\fLset_target()\fP and \fLmain()\fP
|
|
.Fi compile.c .
|
|
|
|
.Sc "Modifying \f(LB/lib/compile\fP" "Modifying \*(Lc"
|
|
.nf\"===========================
|
|
.Sl "Coding Style"
|
|
To be brief, some clever abstractions are used in \*(Lc.
|
|
These abstractions create (sometime many) layers of indirection,
|
|
which can be a bit difficult to follow at times.
|
|
Hopefully, the material in this document helps decode some of
|
|
\*(Lc's deeper secrets.
|
|
|
|
.Sl "Lexical Conventions"
|
|
Since lexical consistency aids readability,
|
|
an attempt has been made to follow the lexical conventions present in
|
|
the original code while modifying \*(Lc.
|
|
Although this author may find other lexical conventions easier to follow
|
|
(e.g. vertically lined-up braces),
|
|
he knew that either \fIall\fP of the code or \fInone\fP
|
|
of it should be changed to follow any new conventions.
|
|
Despite automated tools to do much of such conversion work
|
|
(namely, \fLindent\fP),
|
|
expediency has so far dictated that the latter path be followed.
|
|
It is suggested that consistency be maintained,
|
|
regardless of the path chosen by subsequent maintainers.
|
|
|
|
.Sl "Recipe For Adding A Command-Line Option"
|
|
Here's a cookbook procedure for adding a new command-line option
|
|
(also see the \fBProcessing Arguments\fP section):
|
|
.IP (1) 4
|
|
Locate where to place the option in the \fLoptions[]\fP array
|
|
.Fi ro_data.c .
|
|
It should be in (case-insensitive) alphabetical order with the other
|
|
options,
|
|
although ahead of any shorter option which is an initial substring
|
|
of the new option name.
|
|
.IP (2)
|
|
Choose the option type which best fits how the new option should be handled.
|
|
See the enumeration of type \fLOptions\fP in file \fLdriver.h\fP.
|
|
For details on how each type is processed,
|
|
see \fLlookup_option()\fP in file \fLcompile.c\fP.
|
|
If there is an existing option which is handled similarly,
|
|
use it as a pattern.
|
|
If a new option type must be created:
|
|
.RS
|
|
.RS
|
|
.IP \(bu 3
|
|
add the entry to ``\fLtypedef enum {\fP...\fL} Options\fP'' in \fLdriver.h\fP
|
|
.IP \(bu 3
|
|
add \fLcase\fPs for it in the \fLswitch\fP tables in \fIboth\fP
|
|
\fLprint_help()\fP and
|
|
\fLlookup_option()\fP
|
|
.IP \(bu 3
|
|
create a new \fLOPTION_*()\fP macro for it in \fLro_data.c\fP
|
|
.RE
|
|
.RE
|
|
.IP (3)
|
|
Decide to which driver(s) the option will apply.
|
|
Select the appropriate \fLDRIVER_*\fP macro from the list in \fLdriver.h\fP
|
|
(create a new one if necessary).
|
|
.IP (4)
|
|
If the option is for internal use only,
|
|
i.e. should not be listed when the \fL-help\fP option is used,
|
|
embed the \fLDRIVER_*\fP macro reference
|
|
from step (3) in a \fLHIDE()\fP macro call,
|
|
i.e. \fLHIDE(DRIVER_*)\fP.
|
|
.IP (5)
|
|
Insert the \fLOPTION_*()\fP line at the spot chosen in step (1),
|
|
using the macro appropriate to the type chosen in step (2).
|
|
The second argument will be the value chosen in steps (3) and (4).
|
|
Fill in the other arguments to the macro as appropriate.
|
|
.IP (6)
|
|
Insert additional code where needed, if any, to handle the option.
|
|
For example, if the option sets or clears a global flag
|
|
(i.e. \fLOPTION_SET*()\fP was used),
|
|
code must be inserted somewhere to check that flag and act accordingly.
|
|
If a new option type was added,
|
|
there will be code added in the \fLcase\fP for that type
|
|
in function \fLlookup_option()\fP,
|
|
and elsewhere as necessary.
|
|
.LP
|
|
|
|
.Sl "Recipe for Adding a New Architecture"
|
|
.Incomplete
|
|
|
|
.Sl "Recipe for Adding a New Driver Type [?]"
|
|
.Incomplete
|
|
|
|
.Sl "Recipe for Adding a New Compiler Pass [?]"
|
|
.Incomplete
|
|
|
|
.Sl "General Hints"
|
|
Take care when modifying \*(Lc
|
|
to maintain support for invocation of 3.x compiler passes
|
|
(i.e. as long as support for cross-release compilation continues).
|
|
In this regard, sensitive modifications include:
|
|
.IP \(bu 3
|
|
Adding an argument to be passed to a compiler pass.
|
|
If it is an option only supported by 4.0 compiler passes,
|
|
make sure it is \fInot\fP passed to 3.x passes.
|
|
For an example, see handling of the 4.0 linker's \fL-dc\fP and \fL-dp\fP flags
|
|
in \fLsetup_ld()\fP
|
|
.Fi setup.c .
|
|
.IP \(bu
|
|
Changing how an argument is passed to a compiler pass.
|
|
Ditto the above comment.
|
|
For an example, see handling of \fL-J\fP flag for \fLccom\fP
|
|
in \fLsetup_ccom()\fP
|
|
.Fi setup_cc.c .
|
|
.IP \(bu
|
|
Changing which compiler passes are invoked
|
|
(e.g. when Modula-2 starts using IROPT).
|
|
For an example of how both versions are supported
|
|
(via two sets of compiler steps),
|
|
see \fLsetup_pc0_for_3x()\fP and
|
|
\fLsetup_pc0_for_non_3x()\fP
|
|
.Fi setup_pc.c .
|
|
.LP
|
|
|
|
Expect to use
|
|
.\""" .sp 0.2v
|
|
.in +4m
|
|
\fL#ifdef HANDLE_R32\fP
|
|
.\""" .vs -4p
|
|
.br
|
|
.\""" \&\s+4...\s-4
|
|
\&\s-8\(bu \(bu \(bu\s+8
|
|
.br
|
|
\fL#endif\fP
|
|
.in -4m
|
|
.\""" .vs +4p
|
|
and
|
|
.ti +4m
|
|
\fLswitch (target_sw_release[R_PATHS].value->value)\fP
|
|
.br
|
|
when dealing with differences between releases 3.x and 4.0.
|
|
|
|
.Sc "Regression Testing"
|
|
|
|
A regression test suite is available for \*(Lc
|
|
(currently on the Language group's integration machine, \*Qrogue\*U,
|
|
but not yet on 4.0 release machines).
|
|
It can be run by changing directories to \*(Lc's main source directory,
|
|
\fLlang/compile\fP, and issuing a \*Q\fLmake test\fP\*U command.
|
|
|
|
The test suite runs (all flavors of) the compiler driver
|
|
on a large number of test cases, using \fL-dryrun\fP.
|
|
From approximately 150 basic command lines,
|
|
over 4000 command lines are generated by the regression test.
|
|
One line is echoed to the TTY for each command tested.
|
|
The many lines of \fL-dryrun\fP output from each executed command
|
|
are compared with previously-stored (and supposedly correct) output.
|
|
If there are any differences (as reported by \*Q\fLdiff\fP\*U),
|
|
those differences are placed in files with \*Q\fL.diff\fP\*U suffixes.
|
|
|
|
At the end of the regression test, success or failure is reported.
|
|
If the test has failed,
|
|
the list of files containing the differences (the \*Q\fL.diff\fP\*U files)
|
|
is reported.
|
|
|
|
Current deficiencies of this testing include:
|
|
.IP \(bu 3
|
|
There is no way to automatically test \fIonly\fP native compilation.
|
|
Cross-compilation testing is always done along with native compilation testing;
|
|
this is hardwired in the \fLdriver_test\fP program.
|
|
Therefore, for all tests to pass,
|
|
cross-compilers have to be installed on the machine on which the test is run.
|
|
.IP \(bu
|
|
The program which does the regression testing, \fLdriver_test\fP,
|
|
does not produce a return code.
|
|
So, there is no direct way to tell if the regression test passed or not.
|
|
The \fLMakefile\fP simply checks for the presence/absence of the
|
|
\*Q\fL.diff\fP\*U files.
|
|
.LP
|
|
|
|
.Sc "Debugging Features"
|
|
|
|
.Sl "\f(LBx\fP\f(BIdriver\fP, \f(LBX\fP\f(BIdriver\fP" "\fLx\fP\fIdriver\fP, \fLX\fP\fIdriver\fP"
|
|
If the name by which \*(Lc is invoked begins with \*Q\fLx\fP\*U,
|
|
the \*Q\fLx\fP\*U is stripped off and the driver acts as if the \fL-dryrun\fP
|
|
option had been given.
|
|
Thus, \*Q\fLxcc c.c\fP\*U acts identically to \*Q\fLcc -dryrun c.c\fP\*U.
|
|
In \*(Lc's source directory,
|
|
\*Q\fLmake xlinks\fP\*U will create symbolic links to \fLcompile\fP
|
|
from \fLxcc\fP, \fLxf77\fP, \fLxlint\fP, \fLxm2c\fP, and \fLxpc\fP.
|
|
\*Q\fLmake Xlinks\fP\*U will create symbolic links to \fLcompile\fP
|
|
from \fLXcc\fP, \fLXf77\fP, \fLXlint\fP, \fLXm2c\fP, and \fLXpc\fP.
|
|
|
|
If the first character of the driver name is \*Q\fLX\fP\*U,
|
|
the \*Q\fLX\fP\*U is stripped off and the driver acts as if both the
|
|
\fL-dryrun\fP and \fL-normcmds\fP options had been given.
|
|
|
|
.Sl "\f(LB-normcmds\fP" "\fL-normcmds\fP"
|
|
When testing the driver,
|
|
\*Q\fLrm\fP\*U commands (which remove temporary files)
|
|
tend to clutter up the output from \fL-v\fP or \fL-dryrun\fP.
|
|
The \fL-normcmds\fP option suppresses the echoing (but not execution)
|
|
of \*Q\fLrm\fP\*U commands. (also see \fL-keeptmp\fP, below)
|
|
|
|
.Sl "\f(LB-debug\fP" "\fL-debug\fP"
|
|
The option \fL-debug\fP sets the internal Boolean variable
|
|
\fLglobal_flag.debug\fP to the value \fLTRUE\fP.
|
|
Use of \fL-debug\fP currently causes a small amount of debugging output
|
|
when the compiler driver is executed.
|
|
Developers should feel free to \fL#ifdef\fP-out, comment-out,
|
|
or delete code whose execution depends on the value of \fLglobal_flag.debug\fP.
|
|
All such code looks like:
|
|
.nr VS -4
|
|
.vs -4p
|
|
.DS B
|
|
\fLif ( is_on(debug) ) {
|
|
\s+8...\s-8
|
|
}\fP
|
|
.DE
|
|
.nr VS +4
|
|
.vs +4p
|
|
|
|
.Sl "\f(LB-verbose\fP, \f(LB-v\fP, \f(LB-dryrun\fP" "\fL-verbose\fP, \fL-v\fP, \fL-dryrun\fP"
|
|
\fL-verbose\fP causes compilation commands to be echoed to \fLstderr\fP
|
|
as they are executed by \*(Lc.
|
|
\fL-v\fP is shorthand for \fL-verbose\fP for all drivers except \fLlint\fP
|
|
(which already had a \fL-v\fP option).
|
|
|
|
\fL-dryrun\fP causes the same output as \fL-verbose\fP,
|
|
but the compilation commands are not executed (hence, a \*Qdry run\*U).
|
|
|
|
.KS
|
|
.Sl "\f(LB-rel{vroot,paths,passes}\fP" "\fL-rel{vroot,paths,passes}\fP"
|
|
The three effects of \*Q\fL-release \fP\fIsw_release\fP\*U
|
|
can also be \fIindividually\fP controlled using the unadvertised options:
|
|
.TS
|
|
center;
|
|
c cw(3.2i)
|
|
c c
|
|
lfL l.
|
|
Option Effect
|
|
\_ \_
|
|
-relvroot \fIsw_release\fP T{
|
|
Sets the \fIsw_release\fP used in \*(Vv (therefore, affects \*(Vr).
|
|
T}
|
|
-relpaths \fIsw_release\fP T{
|
|
Determines paths where compiler passes and
|
|
libraries are expected to be found, under \*(Vv.
|
|
T}
|
|
-relpasses \fIsw_release\fP T{
|
|
Determines which compiler passes are invoked,
|
|
and how options are passed to them.
|
|
T}
|
|
.TE
|
|
.KE
|
|
For example,
|
|
\fL-relpasses\fP \fIsw_release\fP has been used to run 4.0 compiler passes
|
|
from a directory referenced by \fL-Qpath\fP,
|
|
on a system otherwise populated with 3.x software.
|
|
|
|
.Sl "\f(LB-keeptmp\fP" "\fL-keeptmp\fP"
|
|
The compiler driver normally removes temporary files as soon as they are
|
|
no longer needed.
|
|
Deletion of temporary files is suppressed by use of the \fL-keeptmp\fP option.
|
|
|
|
.Sc "Grocery List for the Future"
|
|
|
|
.IP (1) 5
|
|
\*(Lc for unbundled products should now be built and installed
|
|
as separate driver programs,
|
|
instead of multiple symbolic links to a common (bundled) binary.
|
|
The bundled drivers (\fLcc\fP and \fLlint\fP) could still share
|
|
a common binary, if desired.
|
|
|
|
.IP (2)
|
|
Knowledge of other drivers should be weeded out each driver's own binary.
|
|
Otherwise, for example, the C compiler driver could be used to compile
|
|
a Pascal (``\fL.p\fP'') source file,
|
|
but using the wrong sequence of Pascal passes,
|
|
or passing out-of-date options to the unbundled Pascal passes.
|
|
|
|
.IP (3)
|
|
Source code to \*(Lc needs to be reorganized, to support (1) above.
|
|
For ease of maintenance,
|
|
it continues to be desirable to keep as much driver code as possible
|
|
in \fIone\fP place.
|
|
The following is a suggestion for a revised source hierarchy, where
|
|
.B src
|
|
is a directory containing common source code for all of the compiler drivers.
|
|
.ds Ci "\v'+0.2v'\s+8\(ci\s-8\v'-0.2v'\"----draw circle----
|
|
.\"" .ds Cs "\*(Ci\h'-\w'\*(Ci'/2u-0.5n'/\h'+\w'\*(Ci'/2u+0.5n'\"---circle+slash
|
|
.ds Cs "\*(Ci\h'-\w'\*(Ci'/2u-0.6n'/\"---circle+slash
|
|
.\"===========================================================================
|
|
.ds Bv "\h'0.9n'\(bv
|
|
.TS
|
|
center;
|
|
l l l lfL s s s
|
|
l l l lfL s s s
|
|
l l l lfL s s s
|
|
l l l lfL s s s
|
|
l l l lfL s s s
|
|
cfL s s s s s s.
|
|
\h'3m'\*(Bv lang
|
|
\h'3m'\*(Cs
|
|
\h'3m'\*(Bv compile
|
|
\h'3m'\*(Cs
|
|
\h'3m'\*(Bv
|
|
_
|
|
.T&
|
|
lfL lfL lfL lfL lfL lfL lfL.
|
|
\*(Bv \f(LBsrc\fP \*(Bv cc \*(Bv f77 \*(Bv pc \*(Bv pc1.05 \*(Bv m2c \*(Bv lint
|
|
\*(Cs \*(Cs \*(Cs \*(Cs \*(Cs \*(Cs \*(Cs
|
|
/\\\\ /\\\\ /\\\\ /\\\\ /\\\\ /\\\\ /\\\\
|
|
.TE
|
|
.\"===========================================================================
|
|
.IP (4)
|
|
Due to item (3),
|
|
\fLtest_dir\fP and its component files may need to be redistributed under the
|
|
component drivers' directories, as appropriate.
|
|
|
|
.IP (5)
|
|
The \fLdriver_test\fP program should be made to produce a useful
|
|
return code, so that the success or failure of regression testing would
|
|
be easier to report from \fLtest_dir/Makefile\fP.
|
|
The \fLMakefile\fPs should be updated accordingly.
|
|
|
|
.IP (6)
|
|
Compile-time support for the RoadRunner system (\fLsun386\fP architecture)
|
|
has been merged (from ECD source code) into a SunOS-4.1 version of \*(Lc
|
|
(see David Weaver for this code's location).
|
|
However, this code only supports \fLsun386\fP
|
|
.I native
|
|
compilation.
|
|
Cross-compilation to and from the \fLsun386\fP will require changing
|
|
the numerous compile-time \fL#ifdef i386\fP's in the code into appropriate
|
|
runtime decisions.
|
|
|
|
.IP (7)
|
|
There is an outstanding bug for the Modula-2 compiler driver which should
|
|
be fixed. It is immortalized in BugTraq Bug-ID #1007768.
|
|
|
|
.IP (8)
|
|
\*(Lc should also be able to function as a driver for
|
|
the assembler (``\fLas\fP'') and linker (``\fLld\fP'') programs.
|
|
This would enable cross-developers to access \fIall\fP of the
|
|
user-visible programs in a consistent manner.
|
|
Specifically, they would be able to use the
|
|
``\fL-target \fP\fItarget_arch\fP'' (or ``\fL-\fP\fItarget_arch\fP'')
|
|
flags when invoking \fLas\fP and \fLld\fP,
|
|
and get the proper cross-compilation behavior.
|
|
|
|
.IP (9)
|
|
The commentary (entitled ``The Big Picture'') at the beginning of file
|
|
\fLcompile.c\fP should either be updated,
|
|
or replaced with a reference to this document.
|
|
|
|
.IP (10)
|
|
We may want to remove knowledge of \fLratfor\fP from \*(Lc,
|
|
now that \fLratfor\fP has been de-supported [per Mark Scott Johnson].
|
|
Before hacking it out of \*(Lc,
|
|
we should double-check that we won't end up supporting \fLratfor\fP
|
|
all over again when the big SunOS/System-V merge is done
|
|
(or users form a lynch mob demanding its retention).
|
|
|
|
.IP (11)
|
|
There are places in \*(Lc which could be changed to make
|
|
it adhere to stricter type-matching.
|
|
Examples:
|
|
.nr VS -4
|
|
.IP
|
|
.TS
|
|
center;
|
|
c c
|
|
c c
|
|
lfL lfL.
|
|
Current Code Better Code
|
|
\_ \_
|
|
.sp 0.8v
|
|
char *foo(); char *foo();
|
|
if (foo()) if ( foo() != (char *)NULL )
|
|
.sp 0.8v
|
|
char c; char c;
|
|
c = 0; c = '\\\\0';
|
|
.sp 0.8v
|
|
char *cp; char *cp;
|
|
if (*cp == 0) if (*cp == '\\\\0')
|
|
.TE
|
|
.nr VS +4
|
|
.IP
|
|
Granted, these are nits,
|
|
but one might as well fix them when one runs across them.
|
|
|
|
.IP (12)
|
|
\*(Lc has not been \fLlint\fP'd in a long time.
|
|
It should be.
|
|
|
|
.IP (13)
|
|
It wouldn't hurt to split \fLcompile.c\fP into more than one source file.
|
|
|
|
.IP (14)
|
|
It would be helpful to change \*(Lc's regression testing so that
|
|
one could test just the native portion of the driver during development.
|
|
It currently always tests both native and cross-compilation;
|
|
therefore the tester must have the most recent Cross-Compiler product
|
|
installed\**.
|
|
.FS
|
|
And \fIthat\fP won't even work,
|
|
'in +2m
|
|
if one is testing an updated version of \*(Lc which acts differently during
|
|
cross-compilation than the most recent Cross-Compiler product does.
|
|
.in -2m
|
|
.FE
|
|
.LP
|
|
.\"----------------------------------------------------------------------------
|
|
.bp
|
|
.nr PS 22
|
|
.nr VS 32
|
|
.LP
|
|
.ce 99
|
|
\s+6\fBAppendix A\fP\s-6
|
|
\fBDefinition of Terms\fP
|
|
.ce 0
|
|
|
|
.nr PS 12
|
|
.nr VS 16
|
|
.LP
|
|
.XS
|
|
\" this line intentionally blank, to leave blank line in the T.O.C.
|
|
Appendix A: Definition of Terms
|
|
.XE
|
|
Italicized terms used in this document may take on one of many values,
|
|
as enumerated below.
|
|
|
|
.TS
|
|
l l l
|
|
l l l
|
|
lfI lfL l.
|
|
Term Value Meaning
|
|
\_ \_ \_
|
|
|
|
driver cc C compiler driver
|
|
f77 FORTRAN-77 compiler driver
|
|
lint FORTRAN-77 compiler driver
|
|
m2c Modula-2 compiler driver
|
|
pc Pascal compiler driver
|
|
|
|
|
|
suffix c file suffix for C source code, before \fLcpp\fP
|
|
i file suffix for C source code
|
|
p file suffix for Pascal source code, before \fLcpp\fP
|
|
pi file suffix for Pascal source code
|
|
F file suffix for FORTRAN source code, before \fLcpp\fP
|
|
f file suffix for FORTRAN source code
|
|
def file suffix for Modula-2 definition file
|
|
mod file suffix for Modula-2 module file
|
|
sym file suffix for Modula-2 symbol file
|
|
a file suffix for library files (created by \fLar\fP)
|
|
o file suffix for relocatable object file
|
|
il file suffix for inline expansion template file
|
|
S file suffix for assembler source code, before \fLcpp\fP
|
|
s file suffix for assembler source code
|
|
ln file suffix for \fLlint\fP library file
|
|
|
|
|
|
arch, sun2 Sun-2 system architecture
|
|
target_arch, sun3 Sun-3 system architecture [Carrera, Prism, Sirius]
|
|
host_arch sun4 Sun-4 system architecture [Sunrise, Cobra, ...]
|
|
sun386\(dd Sun-386 system architecture [RoadRunner]
|
|
\fIother_arch\fP Other system architecture (see Cross-Compilation)
|
|
|
|
mach, mc68010 Motorola MC68010 machine type
|
|
target_mach, mc68020 Motorola MC68020 machine type
|
|
host_mach sparc SPARC machine type
|
|
i386\(dd Intel 80386 machine type
|
|
|
|
sw_release 3.2 SunOS release 3.2, 3.4, 3.5, or Sys4-3.2
|
|
4.0 SunOS release 4.0
|
|
|
|
virtual_root T{
|
|
A directory under \*(Ua, typically \*(Ht;
|
|
used as the first component of
|
|
the \*(Vr environment variable.
|
|
T}
|
|
.TE
|
|
.FS \(dd
|
|
\*(Lc does not yet support the \fLsun386\fP architecture,
|
|
'in +2m
|
|
but should do so in SunOS release 4.1.
|
|
.in -2m
|
|
.FE
|
|
.\"----------------------------------------------------------------------------
|
|
.bp
|
|
.nr PS 22
|
|
.nr VS 32
|
|
.LP
|
|
.ce 99
|
|
\s+6\fBAppendix B\fP\s-6
|
|
\fBCross-Compilers 2.0\fP
|
|
.ce 0
|
|
|
|
.nr PS 12
|
|
.nr VS 16
|
|
.LP
|
|
.XS
|
|
Appendix B: Cross-Compilers 2.0
|
|
.XE
|
|
|
|
This appendix describes in more detail the specifics of how our
|
|
Cross-Compilers 2.0 product is contructed, distributed, installed,
|
|
and used.
|
|
|
|
.Sl "Releases"
|
|
The Cross-Compiler products currently released or planned are:
|
|
.TS
|
|
center;
|
|
c c s s s
|
|
c c s s s
|
|
c 2 c 2 c 2 c 2 c
|
|
c c c c c
|
|
c c c c c
|
|
c c c c c.
|
|
Supports
|
|
Cross- \_
|
|
Compilers Host Host SunOS Target Target SunOS
|
|
Release Architecture(s) Version(s) Architecture(s) Version(s)
|
|
\_ \_ \_ \_ \_
|
|
1.0 Sun2,3 3.x Sun2,3 3.2
|
|
2.0 Sun2,3,4 3.x, Sys4-3.2 Sun2,3,4 3.x, Sys4-3.2
|
|
2.1 Sun2,3,4 4.0 Sun2,3,4 4.0
|
|
3.0 Sun2?,3,4,386 4.1 Sun2?,3,4,386 4.1
|
|
.TE
|
|
.ds Cc "Cross-Compiler
|
|
.ds Xs "\*(Cc Server
|
|
.ds Xc "\*(Cc Client
|
|
.ds Pr "\fL/private\fP
|
|
.ds Pu "\*(Pr\fL/usr/arch\fP
|
|
.Sl "Installation"
|
|
For \*(Ccs 2.0 (and later), there are two types of installation:
|
|
\*(Xs installation and \*(Xc installation.
|
|
A \*(Xs is a system with a local disk,
|
|
onto which the software is loaded.
|
|
A \*(Xc is a system on which the \*(Cc software will be executed.
|
|
Note that:
|
|
.IP \(bu 3
|
|
\*(Xss and Clients are independent and not mutually exclusive.
|
|
A \*(Xs typically supports one or more \*(Xcs,
|
|
but a \*(Xc may be its own \*(Xs,
|
|
and two systems could be \*(Xcs of each other
|
|
(although there would be no practical reason to do so).
|
|
.IP \(bu
|
|
\*(Xss and Clients should not be confused with
|
|
ND servers and clients.
|
|
An ND client's ND server is not necessarily its \*(Xs.
|
|
\*(Xss and Clients may be (and are to some degree encouraged to be)
|
|
heterogeneous machines on the network,
|
|
which is seldom the case with ND clients and their servers.
|
|
.LP
|
|
|
|
\*(Cc installation is performed in two steps:
|
|
Server installation and Client installation.
|
|
There is a Shell script for each, placed under directory
|
|
\*(Us\fL/install\fP during Server installation.
|
|
|
|
Server installation (script \*(Us\fL/install/server\fP)
|
|
involves reading the distribution tape(s) onto a machine with a local disk,
|
|
under the directory \*(Us.
|
|
That machine then becomes the \*(Xs for subsequent Client installations.
|
|
|
|
Client installation (script \*(Us\fL/install/client\fP):
|
|
.IP \(bu 3
|
|
Sets up a private copy of \*(Ua on the Client machine.
|
|
\*(Ccs 2.0 does this by making \*(Ua a symbolic link to \*(Pu,
|
|
then populating \*(Pu.
|
|
.IP \(bu
|
|
Creates directories under \*(Pu for all appropriate
|
|
\fIhost_arch\fP\fLR\fIsw_release\fP\fL/\c
|
|
\fP\fItarget_arch\fP\fLR\fIsw_release\fP's.
|
|
.IP \(bu
|
|
Creates a symbolic link from
|
|
\*(Pr\*(Ha to
|
|
\fIhost_arch\fP\fLR\fIsw_release\fP.
|
|
.IP \(bu
|
|
For each supported target architecture,
|
|
creates a symbolic link from
|
|
\*(Pr\*(Ha\fLR\fIsw_release\fP\fL/\fP\fItarget_arch\fP to
|
|
\fItarget_arch\fP\fLR\fIsw_release\fP.
|
|
.IP \(bu
|
|
Creates a symbolic link from \*(Pu\fL/bin\fP to
|
|
\fIhost_arch\fP\fLR\fIsw_release\fP\fL/common/crossbin\fP.
|
|
.IP \(bu
|
|
Mounts the appropriate files from the \*(Xs onto the
|
|
\*(Pr\*(Ha\fLR\fP\fIsw_release\fP\fL/\fP\fItarget_arch\fP\fLR\fP\fIsw_release\fP's
|
|
(or, if the Server is the same machine as the Client,
|
|
symbolic links are used instead of NFS mounts).
|
|
.IP \(bu
|
|
Adds entries corresponding to the above mounts (if any were done)
|
|
to the Client's \fL/etc/fstab\fP.
|
|
.IP \(bu
|
|
(Optionally, but by default) installs a new \*(Lc on the Client machine.
|
|
.LP
|
|
|
|
.Sl "Filesystem Organization (\f(LB/usr/arch\fP, \f(LB/usr/arch.SERVER\fP)" "Filesystem Organization (\*(Ua, \*(Us)"
|
|
|
|
Default host and target directories for a Cross-Compiler Client
|
|
are created by making a symbolic link
|
|
from each \fIarch\fP to the appropriate \fIarch\fP\fLR\fP\fIsw_release\fP.
|
|
Initially, this is done by the Cross-Compiler Client Installation script.
|
|
For example, on a Sun-3 host running SunOS-4.0, after Client Installation
|
|
of Cross-Compilers 2.1 (which supports SunOS-4.0) for
|
|
both Sun-2 and Sun-4 targets, the following symbolic links would be present:
|
|
.TS
|
|
center;
|
|
lfL c lfL.
|
|
\*(Ua/sun3 \(-> sun3R4.0
|
|
\*(Ua/sun3/sun2 \(-> sun2R4.0
|
|
\*(Ua/sun3/sun4 \(-> sun4R4.0
|
|
.TE
|
|
|
|
The default target Sun-4 system above could be changed to a Sun-4 running
|
|
Sys4-3.2 merely by making \*(Ua\fL/sun3/sun4\fP a symbolic link to
|
|
\fLsun4R3.2\fP instead of to \fLsun4R4.0\fP\**.
|
|
.FS
|
|
Assuming that (a) the Cross-Compilers 2.0 product is installed,
|
|
'in +2m
|
|
(b) Cross-Compilers 2.0 binaries can run unchanged under SunOS-4.0
|
|
(which should be the case),
|
|
and (c) \*(Lc was built with \fL-DHANDLE_R32\fP.
|
|
.in -2m
|
|
.FE
|
|
|
|
Each Cross-Compiler Client's
|
|
\*(Ua\fL/\fP\fIhost_arch\fP directory \fImust\fP be a symbolic link
|
|
to \fIhost_arch\fP\fLR\fP\fIsw_release\fP,
|
|
where \fIhost_arch\fP and \fIsw_release\fP correspond to
|
|
the Client's architecture type and software release number, respectively.
|
|
|
|
.Sl "\f(LB/private/usr/arch\fP versus \f(LB/usr/arch\fP" "\*(Pu versus \*(Ua"
|
|
Each \*(Xc keeps a private version (under \*(Pu) of the directories
|
|
from \*(Ua down to the mount (\*(Vv) level of \*(Ht.
|
|
This private version is kept so that each Client has symbolic links
|
|
(the ones which set the default target software releases)
|
|
in those directories appropriate to its architecture and SunOS release.
|
|
|
|
.Sl "\f(LB/usr/arch.SERVER\fP versus \f(LB/usr/arch\fP" "\*(Us versus \*(Ua"
|
|
On a \*(Xs,
|
|
\*(Cc tapes are loaded into \*(Us instead of directly under \*(Ua.
|
|
This is because a homogeneous ND client of the server
|
|
(which may inherit \fL/usr\fP and therefore \*(Ua from its ND server)
|
|
may also be its \*(Xc.
|
|
In that case,
|
|
the Client could inherit a read-only \*(Ua in which it could not set up
|
|
its own defaults (via the symbolic links discussed above).
|
|
.\"---------------------------------------------------------------------------
|
|
.EH '\fB\s+2DRAFT\s-2\fP''\fB\s+2DRAFT\s-2\fP'
|
|
.OH '\fB\s+2DRAFT\s-2\fP''\fB\s+2DRAFT\s-2\fP'
|
|
.LP
|
|
.bp
|
|
.PX \" print table of contents.
|