c/c++研究和学习

lcc源码学习(1)

      一直想阅读一个真正的使用编译器源码。开始想读gcc,毕竟是大名鼎鼎的开源元老,加上平时使用的频繁,可大体看了一下后,改主意了。代码量太大,相关资料又比较少,要是上来就一点一点啃,不知道能不能坚持下来,还是从一个简单的开始吧。上sourceforge搜出来一个国人写的ucc,倒是比较小,看了一下开发手册,结构也很清晰,本想就是它了。下载源码、编译,顺利通过。试运行,报错,cl没找到?嗯~~,cl?我是用ucc编译,怎么扯到cl啦?好在有源码,跟踪调试吧。eoh,终于发现上来预处理就没有,通过调用vc来进行预处理。这个~~~,看来还不是成型的东西了。自己没有写头文件、没有写库文件都可以理解,要是预处理也没有写,恐怕缺了一块。(没研究过,这样开源会不会有版权问题。)看来还得换一个编译器来读了。

    记起原来买过的一本书《可变目标C编译器》是写C编译器实现的,买来也就看了前两章,没看太明白就丢下了。一直没看,也不知道收到哪里去了,估计压到箱子底了。不管了,先网上google了。果然,写得是lcc。先找到链接,下一个回来。lcc, A Retargetable Compiler for ANSI C 网页说书是讲3.x版的,可既然有4.2版了,那就下个4.2的再说了。

    首先用系统带的make文件BUILD,出错,错误信息:“outp”重定义。不会吧,lcc可是实用级的编译器。打开源码查出错点,没有重复定义呀?难道跟系统函数重名?我机器上装得是vs2008,赶快上MSDN查吧。果然,从vs2008开始里增加了outp函数。总不能上来就修改源码吧,以后连个可比较的都没有。找lcc安装说明吧,这里Installing lcc有一份说明,居然是用vc5.0来BUILD的。没办法,看来这种03年的源码还得用老枪来对付。vc5.0是没得找了,装vc6吧。装完发现vc6里居然没带汇编器,看来已经整合进编译器了。得了,再找汇编器吧。说明里说要升级到6.11d的汇编器,查了一下,微软不单独提供,要从Win98DDK.EXE里提取。微软早不提供下载了,下了个比较早的也是8.0的。先用它吧,拷贝到vc的bin下。再次BUILD,成功。

    测试编译一个HelloWorld,成功。汇编代码输出,成功。比较一下,比vc6编译的exe略大。好了,总算起步了。下次开始阅读学习源码了。

------------------------------

注1:在测试编译时发现,不仅仅是vs里函数名问题,链接库也发生了改变。lcc还是使用的libc.lib,这个库目前的vs里已经不再提供了。

注2:将installing lcc里部分摘录如下:

Installation on Windows NT 4.0 or Windows 95/98

On Windows NT 4.0 and Windows 95/98, lcc is designed to work with Microsoft's Visual C++ 5.0 (VC) and Microsoft's Assembler, MASM 6.11d. It uses the VC header files, libraries, and command-line tools, and it uses MASM to assemble the code it generates. If you have MASM 6.11, make sure you upgrade to 6.11d, because earlier 6.11 releases do not generate correct COFF object files.

Building the distribution components from the ground up requires Microsoft's Visual C/C++ 5.0 compiler, Microsoft's make, nmake, and the standard Windows command interpreter. makefile.nt is written to use only nmake. As on UNIX systems, the compilation components are installed in a single build directory, and the top-level programs, lcc.exe and bprint.exe, are installed in a directory on the PATH. If the conventions used below are followed, the Windows-specific parts of the driver program, lcc.exe, can be used unmodified.

Building from the source distribution on a Windows system involves the following steps. Below, the build directory is referred to as BUILDDIR, and the distribution is in \dist\lcc\4.1.

  1. Create the build directory, perhaps using a version- and platform-specific naming convention as suggested in Installation on UNIX, and record the name of this directory in the BUILDDIR environment variable:
    C:\dist\lcc\4.1>set BUILDDIR=\progra~1\lcc\4.1\bin
    C:\dist\lcc\4.1>mkdir %BUILDDIR%

    The default build, or installation, directory is \Program Files\lcc\4.1\bin, but the nmake commands require that you use the corresponding 8.3 file name, progra~1, instead of Program Files.

  2. etc\win32.c is the Windows-specific part of the driver. It assumes that environment variable include gives the locations of the VC header files and that the linker (link.exe) and the assembler (ml.exe) are on the PATH. It also assumes that the macro LCCDIR gives the build directory. If necessary, revise a copy of etc\win32.c to reflect the conventions on your computer (see Building the Driver), then build the driver, specifying the default temporary directory, if necessary:
    C:\dist\lcc\4.1>nmake -f makefile.nt TEMPDIR=\\temp HOSTFILE=etc/win32.c lcc
    ...
            cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -c -DTEMPDIR=\"\\temp\" -Fo\progra~1\lcc\4.1\bin\lcc.obj etc/lcc.c
    lcc.c
            cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -c -Fo\progra~1\lcc\4.1\bin\host.obj etc/win32.c
    win32.c
            cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -Fe\progra~1\lcc\4.1\bin\lcc.exe \progra~1\lcc\4.1\bin\lcc.obj \progra~1\lcc\4.1\bin\host.obj

    If you make a copy of etc\win32.c, specify the path of the copy as the value of HOSTFILE. For example, if you copy etc\win32.c to BUILDDIR and edit it, use the command

    C:\dist\lcc\4.1>nmake -f makefile.nt TEMPDIR=\\temp HOSTFILE=%BUILDDIR%\win32.c lcc
  3. Build the preprocessor, compiler proper, library, and other accessories (see Building the Compiler):
    C:\dist\lcc\4.1>nmake -f makefile.nt all

    This command uses the VC command-line tools cl and lib to build bprint.exe, cpp.exe, lburg.exe, liblcc.lib, librcc.lib, and rcc.exe, all in BUILDDIR. There may be some warnings, but there should be no warnings.

  4. Create a test directory and run the test suite:
    C:\dist\lcc\4.1>mkdir %BUILDDIR%\x86\win32\tst
    C:\dist\lcc\4.1>nmake -f makefile.nt test

    This command compiles each program in tst, compares the generated assembly code and diagnostics with the expected assembly code and diagnostics, executes the program, and compares the output with the expected output (using fc). For example, when the nmake command compiles tst\8q.c, it leaves the generated assembly code and diagnostic output in %BUILDDIR%\x86\win32\tst\8q.s and %BUILDDIR%\x86\win32\tst\8q.2, and it compares them with the expected results in x86\win32\tst\8q.sbk. It builds the executable program in %BUILDDIR%\x86\win32\tst\8q.exe, runs it, and redirects the output to %BUILDDIR%\x86\win32\tst\8q.1, which it compares with x86\win32\tst\8q.1bk. The output from this step is voluminous, but there should be no differences and no errors.

  5. Run the "triple" test, which compiles rcc with itself and verifies the results:
    C:\dist\lcc\4.1>nmake -f makefile.nt triple
    ...
    \progra~1\lcc\4.1\bin\x86.c:
     Assembling: C:/TEMP/lcc2001.asm
            fc /b \progra~1\lcc\4.1\bin\1rcc.exe \progra~1\lcc\4.1\bin\2rcc.exe
    Comparing files \progra~1\lcc\4.1\bin\1rcc.exe and \progra~1\lcc\4.1\bin\2RCC.EXE
    00000088: B4 D5

    This command builds rcc twice; once using the rcc built by VC and again using the rcc built by lcc. The resulting binaries are compared using fc. They should be identical, except for one or two bytes of timestamp data, as shown at the end of the output above. If they aren't, our compiler is generating incorrect code; contact us.

  6. Copy lcc.exe and bprint.exe to a directory on your PATH, e.g.,
    C:\dist\lcc\4.1>copy %BUILDDIR%\lcc.exe \bin
            1 file(s) copied.
    
    C:\dist\lcc\4.1>copy %BUILDDIR%\bprint.exe \bin
            1 file(s) copied.
  7. Finally, clean up:
    C:\dist\lcc\4.1>nmake -f makefile.nt clean

    This command removes the derived files in BUILDDIR, but does not remove rcc.exe, etc.; "nmake -f makefile.nt clobber" cleans up and removes all executables and libraries. Test directories under BUILDDIR are not removed; you'll need to remove these by hand, e.g.,

    C:\dist\lcc\4.1>rmdir %BUILDDIR%\x86 /s
    \progra~1\lcc\4.1\bin\x86, Are you sure (Y/N)? y

posted on 2008-10-26 23:32 昆仑大鹏 阅读(2205) 评论(0)  编辑 收藏 引用 所属分类: lcc 源码学习


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理