⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 install.html

📁 lcc source code enjoy your self
💻 HTML
📖 第 1 页 / 共 3 页
字号:
char *cpp[] = { LCCDIR "cpp",
	"-D__STDC__=1", "-Dsparc", "-D__sparc__", "-Dsun", "-D__sun__", "-Dunix",
	"$1", "$2", "$3", 0 };
char *include[] = { "-I" LCCDIR "include", "-I/usr/local/include",
	"-I/usr/include", 0 };
char *com[] = { LCCDIR "rcc", "-target=sparc/solaris",
	"$1", "$2", "$3", 0 };
char *as[] = { "/usr/ccs/bin/as", "-Qy", "-s", "-o", "$3", "$1", "$2", 0 };
char *ld[] = { "/usr/ccs/bin/ld", "-o", "$3", "$1",
	SUNDIR "crti.o", SUNDIR "crt1.o",
	SUNDIR "values-xa.o", "$2", "",
	"-Y", "P," SUNDIR ":/usr/ccs/lib:/usr/lib", "-Qy",
	"-L" LCCDIR, "-llcc", "-lm", "-lc", SUNDIR "crtn.o", 0 };

extern char *concat(char *, char *);

int option(char *arg) {
	if (strncmp(arg, "-lccdir=", 8) == 0) {
		cpp[0] = concat(&arg[8], "/cpp");
		include[0] = concat("-I", concat(&arg[8], "/include"));
		ld[12] = concat("-L", &arg[8]);
		com[0] = concat(&arg[8], "/rcc");
	} else if (strcmp(arg, "-p") == 0) {
		ld[5] = SUNDIR "mcrt1.o";
		ld[10] = "P," SUNDIR "libp:/usr/ccs/lib/libp:/usr/lib/libp:"
			 SUNDIR ":/usr/ccs/lib:/usr/lib";
	} else if (strcmp(arg, "-b") == 0)
		;
	else if (strncmp(arg, "-ld=", 4) == 0)
		ld[0] = &arg[4];
	else
		return 0;
	return 1;
}</pre>
</blockquote>

<p><code>LCCDIR</code> defaults to <code>&quot;/usr/local/lib/lcc/&quot;</code> unless
it's defined by a <code>-D</code> option as part of <code>CFLAGS</code> in the make
command, e.g.,</p>

<blockquote>
  <pre>% make HOSTFILE=etc/solaris.c CFLAGS='-DLCCDIR=\&quot;/v/lib/lcc/\&quot;' lcc</pre>
</blockquote>

<p>Note the trailing slash; <code>SUNDIR</code> is provided so you can use <code>etc/solaris.c</code>
even if you have a different version of the Sun Pro compiler suite. If you're using the
gcc compiler tools instead of the Sun Pro tools, see <a HREF="../etc/gcc-solaris.c"><code>etc/gcc-solaris.c</code></a>.</p>

<p>Most of the host-specific code is platform-specific data and templates for the commands
that invoke the preprocessor, compiler, assembler, and loader. The <code>suffixes</code>
array lists the file name suffixes for C source files, preprocessed source files, assembly
language source files, object files, and executable files. <code>suffixes</code> must be
terminated with a null pointer, as shown above. The initialization of <code>suffixes</code>
in <code><a HREF="../etc/solaris.c">etc/solaris.c</a></code> are the typical ones for UNIX
systems. Each element of <code>suffixes</code> is actually a list of suffixes, separated
by semicolons; <code><a HREF="../etc/win32.c">etc/win32.c</a></code> holds an example:</p>

<blockquote>
  <pre>char *suffixes[] = { &quot;.c;.C&quot;, &quot;.i;.I&quot;, &quot;.asm;.ASM;.s;.S&quot;, &quot;.obj;.OBJ&quot;, &quot;.exe&quot;, 0 };</pre>
</blockquote>

<p>When a list is given, the first suffix is used whenever lcc needs to generate a file
name. For example, with <code><a HREF="../etc/win32.c">etc/win32.c</a></code>, lcc emits
the generated assembly code into <code>.asm</code> files.</p>

<p>The <code>inputs</code> array holds a null-terminated string of directories separated
by colons or semicolons. These are used as the default value of <code>LCCINPUTS</code>, if
the environment variable <code>LCCINPUTS</code> is not set; see the <a HREF="lcc.pdf">man
page</a>.</p>

<p>Each command template is an array of pointers to strings terminated with a null
pointer; the strings are full path names of commands, arguments, or argument placeholders,
which are described below. Commands are executed in a child process, and templates can
contain multiple commands by separating commands with newlines. The driver runs each
command in a new process.</p>

<p>The <code>cpp</code> array gives the command for running lcc's preprocessor, <code>cpp</code>.
Literal arguments specified in templates, e.g., <code>&quot;-Dsparc&quot;</code> in the <code>cpp</code>
command above, are passed to the command as given.</p>

<p>The strings <code>&quot;$1&quot;</code>, <code>&quot;$2&quot;</code>, and <code>&quot;$3&quot;</code>
in templates are placeholders for <em>lists</em> of arguments that are substituted in a
copy of the template before the command is executed. <code>$1</code> is replaced by the <em>options</em>
specified by the user; for the preprocessor, this list always contains at least <code>-D__LCC__</code>.
<code>$2</code> is replaced by the <em>input</em> files, and <code>$3</code> is replaced
by the <em>output</em> file.</p>

<p>Zero-length arguments after replacement are removed from the argument list before the
command is invoked. So, for example, if the preprocessor is invoked without an output
file, <code>&quot;$3&quot;</code> becomes <code>&quot;&quot;</code>, which is removed from
the final argument list.</p>

<p>The <code>include</code> array is a list of <code>-I</code> options that specify which
directives should be searched to satisfy include directives. These directories are
searched in the order given. The first directory should be the one to which the ANSI
header files were copied as described in <a HREF="#unix">UNIX</a> or <a HREF="#win32">Windows</a>
installation instructions. The driver adds these options to <code>cpp</code>'s arguments
when it invokes the preprocessor, except when <code>-N</code> is specified.</p>

<p><code>com</code> gives the command for invoking the compiler. This template can appear
as shown above in a custom host-specific part, but the option <code>-target=sparc/solaris</code>
should be edited to the <em>target</em><code>/</code><em>os</em> for your platform. If <code>com[1]</code>
includes the string &quot;<code>win32</code>&quot;, the driver assumes it's running on
Windows. lcc can generate code for <em>all</em> of the <em>target</em><code>/</code><em>os</em>
combinations listed in the file <code>src/bind.c</code>. The <code>-target</code> option
specifies the default combination. The driver's <code>-Wf</code> option can be used to
specify other combinations; the <a HREF="lcc.pdf">man page</a> elaborates.</p>

<p><code>as</code> gives the command for invoking the assembler. On Linux, you must be
running at least version 2.8.1 of the GNU assembler; earlier versions mis-assemble some
instructions emitted by lcc.</p>

<p><code>ld</code> gives the command for invoking the loader. For the other commands, the
list <code>$2</code> contains a single file; for <code>ld</code>, <code>$2</code> contains
all &quot;.o&quot; files and libraries, and <code>$3</code> is <code>a.out</code>, unless
the <code>-o</code> option is specified. As suggested in the code above, <code>ld</code>
must also specify the appropriate startup code and default libraries, including the lcc
library, <code>liblcc.a</code>.</p>

<p>The <code>option</code> function is described below; the minimal <code>option</code>
function just returns 0.</p>

<p>You can test <code>lcc</code> with the options <code>-v -v</code> to display the
commands that would be executed, e.g.,</p>

<blockquote>
  <pre>% $BUILDDIR/lcc -v -v foo.c baz.c mylib.a -lX11
$BUILDDIR/sparc-solaris/lcc $ Id: lcc.c,v 4.33 2001/06/28 22:19:58 drh $
foo.c:
/usr/local/lib/lcc/cpp -D__STDC__=1 -Dsparc -D__sparc__ -Dsun -D__sun__ -Dunix -D__LCC__i
/usr/local/lib/lcc/rcc -target=sparc/solaris -v /tmp/lcc4060.i /tmp/lcc4061.s
/usr/ccs/bin/as -Qy -s -o /tmp/lcc4062.o /tmp/lcc4061.s
baz.c:
/usr/local/lib/lcc/cpp -D__STDC__=1 -Dsparc -D__sparc__ -Dsun -D__sun__ -Dunix -D__LCC__i
/usr/local/lib/lcc/rcc -target=sparc/solaris -v /tmp/lcc4060.i /tmp/lcc4061.s
/usr/ccs/bin/as -Qy -s -o /tmp/lcc4063.o /tmp/lcc4061.s
/usr/ccs/bin/ld -o a.out /opt/SUNWspro/SC4.2/lib/crti.o /opt/SUNWspro/SC4.2/lib/crt1.o /o
rm /tmp/lcc4063.o /tmp/lcc4060.i /tmp/lcc4061.s /tmp/lcc4062.o</pre>
</blockquote>

<p>As the output shows, <code>lcc</code> places temporary files in <code>/tmp</code>; if
any of the environment variables <code>TMP</code>, <code>TEMP</code>, and <code>TMPDIR</code>
are set, they override this default (in the order shown) as does the <code>-tempdir=</code><em>dir</em>
option. The default can be changed by defining <code>TEMPDIR</code> in <code>CFLAGS</code>
when building the driver.</p>

<p>The <code>option</code> function is called for the options <code>-Wo</code>, <code>-g</code>,
<code>-p</code>, <code>-pg</code>, and <code>-b</code> because these compiler options
might also affect the loader's arguments. For these options, the driver calls <code>option(arg)</code>
to give the host-specific code an opportunity to edit the <code>ld</code> command, if
necessary. <code>option</code> can change <code>ld</code>, if necessary, and return 1 to
announce its acceptance of the option. If the option is unsupported, <code>option</code>
should return 0.</p>

<p>For example, in response to <code>-g</code>, the <code>option</code> function shown
above accepts the option but does nothing else, because the <code>ld</code> and <code>as</code>
commands don't need to be modified on the SPARC. <code>-g</code> will also be added to the
compiler's options by the host-independent part of the driver. The <code>-p</code> causes <code>option</code>
to change the name of the startup code and changed the list of libraries. The <code>-b</code>
option turns on <code>lcc</code>'s per-expression profiling, the code for which is in <code>liblcc.a</code>,
so <code>option</code> need no nothing.</p>

<p>On SPARCs, the driver also recognizes <code>-Bstatic</code> and <code>-Bdynamic</code>
as linker options. The driver recognizes but ignores &quot;<code>-target</code> <em>name</em>&quot;
option.</p>

<p>The option <code>-Wo</code><em>arg</em> causes the driver to pass <em>arg</em> to <code>option</code>.
Such options have no other effect; this mechanism is provided to support system-specific
options that affect the commands executed by the driver. As illustrated above,
host-specific parts should support the <code>-Wo-lccdir=</code><em>dir</em> option, which
causes lcc's compilation components to be found in <em>dir</em>, because this option is
used by the test scripts, and because the driver simulates a <code>-Wo-lccdir</code>
option with the value of the environment variable <code>LCCDIR</code>, if it's defined.
The code above rebuilds the paths to the include files, preprocessor, compiler, and
library by calling <code>concat</code>, which is defined in <code>etc/lcc.c</code>.</p>

<h2><a NAME="rcc">Building the Compiler and Accessories</a></h2>

<p>To build the rest of compilation components make sure <code>BUILDDIR</code> is set
appropriately and type &quot;<code>make all</code>&quot;. This command builds <code>librcc.a</code>
(the compiler's private library), <code>rcc</code> (the compiler proper), <code>lburg</code>
(the code-generator generator), <code>cpp</code> (the preprocessor), <code>liblcc.a</code>
(the runtime library), and <code>bprint</code> (the profile printer), all in <code>BUILDDIR</code>.
There may be warnings, but there should be no errors. If you're using an ANSI/ISO compiler
other than <code>cc</code>, specify its name with the <code>CC=</code> option, e.g.,
&quot;<code>make CC=gcc all</code>&quot;. If you're running on a DEC ALPHA, use &quot;<code>make
CC='cc -std1' all</code>&quot;; the <code>-std1</code> option is essential on 
the ALPHA.</p>

<p>Once <code>rcc</code> is built with the host C compiler, run the test suite to verify
that <code>rcc</code> is working correctly. If any of the steps below fail, contact us
(see <a HREF="#bugs"><em>Reporting Bugs</em></a>). The commands in the makefile run the
shell script <code>src/run.sh</code> on each C program in the test suite, <code>tst/*.c</code>.
It uses the driver, <code>$BUILDDIR/lcc</code>, so you must have the driver in the build
directory before testing <code>rcc</code>. The <em>target</em><code>/</code><em>os</em>
combination is read from the variable <code>TARGET</code>, which must be specified when
invoking <code>make</code>:</p>

<blockquote>
  <pre>% make TARGET=sparc/solaris test
mkdir -p $BUILDDIR/sparc-solaris/sparc/solaris/tst
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/8q.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/array.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/cf.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/cq.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/cvt.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/fields.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/front.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/incr.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/init.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/limits.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/paranoia.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/sort.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/spill.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/stdarg.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/struct.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/switch.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/wf1.s:
$BUILDDIR/sparc-solaris/rcc -target=sparc/solaris $BUILDDIR/sparc-solaris/sparc/solaris/tst/yacc.s:</pre>
</blockquote>

<p>Each line in the output above is of the form</p>

<blockquote>
  <p><code>$BUILDDIR/rcc -target=</code><em>target</em><code>/</code><em>os</em><code> $BUILDDIR/</code><em>target</em><code>/</code><em>os</em><code>/</code><em>X</em><code>.s:</code></p>
</blockquote>

<p>where <em>X</em> is the base name of the C program <em>X</em><code>.c</code> in the
test suite. The actual value of <code>BUILDDIR</code> will, of course, appear in 
place of <code>$BUILDDIR</code>. This output identifies the compiler and the target, e.g., &quot;<code>$BUILDDIR/rcc</code>
is generating code for a <code>sparc</code> running the <code>solaris</code> operating
system.&quot;</p>

<p>For each program in the test suite, <code>src/run.sh</code> compiles the program, drops
the generated assembly language code in <code>BUILDDIR</code>/<em>target</em><code>/</code><em>os</em>,
and uses <code>diff</code> to compare the generated assembly code with the expected code
(the code expected for <code>tst/8q.c</code> on the SPARC under Solaris is in <code>sparc/solaris/tst/8q.sbk</code>,
etc.). If there are differences, the script executes the generated code with the input
given in <code>tst</code> (the input for <code>tst/8q.c</code> is in <code>tst/8q.0</code>,
etc.) and compares the output with the expected output (the expected output from <code>tst/8q.c</code>
on the SPARC under Solaris is in <code>sparc/solaris/tst/8q.1bk</code>, etc.). The script
also compares the diagnostics from the compiler with the expected diagnostics.</p>

<p>On some systems, there may be a few differences between the generated code and the
expected code. These differences occur because the expected code is generated by cross
compilation and the least significant bits of some floating-point constants differ from
those bits in constants generated on your system. On Linux, there may be differences
because of differences in the header files between our system and yours. There should be
no differences in the output from executing the test programs.</p>

<p>Next, run the &quot;triple test&quot;, which builds <code>rcc</code> using itself:</p>

<blockquote>
  <pre>% make triple
$BUILDDIR/sparc-solaris/lcc -A -d0.6 -Wo-lccdir=$(BUILDDIR) -Isrc -I$(BUILDDIR) -o $BUILDDIR/sparc-solaris/1rcc -B$BUILDDIR/sparc-solaris/ src/alloc.c ...
src/alloc.c:
...
$BUILDDIR/sparc-solaris/lcc -A -d0.6 -Wo-lccdir=$(BUILDDIR) -Isrc -I$(BUILDDIR) -o $BUILDDIR/sparc-solaris/2rcc -B$BUILDDIR/sparc-solaris/1 src/alloc.c ...

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -