打算用LLVM做基础以及后端,写个T3的编译器。具体该怎么做还没想,先学一下怎么创建一个LLVM的Project。
Creating an LLVM Project
- OverView
- Create a project from the Sample Project
- Source tree layout
- Writing LLVM-style Makefiles
- Required Variables
- Variables for Building Subdirectories
- Variables for Building Libraries
- Variables for Building Programs
- Miscellaneous Variables
- Placement of object code
- Further help
writen by John Criswell
OverView
使用LLVM构建系统,能让使用LLVM头文件、库、工具的第三方项目易于构建。为了能使用该构建系统的便利之处,项目的Makefile做以下几件事情。
-
- 设置make变量,下面是一个LLVM构建系统需要在Makefile中设置的几个变量:
- PROJECT_NAME - 项目的名称。
- LLVM_SRC_ROOT - LLVM源代码目录树的根目录。
- LLVM_OBJ_ROOT - LLVM对象目录树的根目录。
- PROJ_SRC_ROOT - 项目源代码目录树的根目录。
- PROJ_OBJ_ROOT - 项目对象目录树的根目录。
- PROJ_INSTALL_ROOT - 项目安装根目录。
- LEVEL - 当前目录到项目根目录(PROJ_OBJ_ROOT)的相对路径
- 从$(LLVM_OBJ_ROOT)中包含Makefile.config
- 从$(LLVM_SRC_ROOT)中包含Makefile.rules
- 设置make变量,下面是一个LLVM构建系统需要在Makefile中设置的几个变量:
可以通过两种方式来设置所有上述变量:
-
- 编写自己的Makefile,并将这些值硬编码进去。
- 使用LLVM预制的样本项目。这个样本项目包含Makefile文件以及用于配置LLVM位置的配置脚本,并且具有支持单个源目录对应多个对象目录的功能。
该文档将会阐述如何以llvm/projects/sample中的样本项目为基础构建自己的项目。如果需要自己设计构建系统,通过对样本项目以及LLVM Makefiles的学习,应该可以提供足够的信息。
Create a project from the Sample Project
按照以下几步开展项目
-
- 拷贝llvm/projects/sample目录到任意位置,以需要的名称重命名该目录。
- 如果是使用svn下载了LLVM,从新建项目的目录树下移除所有.svn目录。这可以使得Subversion不会误认为新建项目位于llvm/trunk/projects/sample下。
- 添加项目代码以及Makefile文件到项目的目录树下。
- 如果想使用configure脚本来配置新建项目,需要对autoconf/configure.ac进行如下修改
- 更新autoconf/configure.ac后,使用如下命令重新生成配置脚本。 必须使用2.59以上版本的Autoconf以及1.9以上版本的aclocal。
- 在你想存放中间对象的目录运行configure。使用如下的选项告知新建项目LLVM所在目录。
搞定!现在只需要在新建项目的根目录输入gmake(在GNU/Linux系统下使用make)就可以生成了。
Source Tree Layout
为了使用LLVM生成系统,需要组织新建项目的源代码布局从而可以使用LLVM生成系统的特性。主要就是让新建项目的源代码布局和LLVM的源代码布局相似。最好的方式就是从llvm/project/sample拷贝项目树,并修改使之符合新项目的需求。
在顶层的目录下,你应该有如下几个目录:
lib
这个子目录应该包含所有新建项目的源代码。对于每个库,都应该在lib下有一个独立的目录,该目录包含该库的所有的源文件。
库文件可以是对象文件、压缩包或者动态链接库。lib目录将所有这些放在一个便利的目录下,使之可以在晚些时候进行链接。
include
该子目录应该包含新建项目的所有"全局"头文件。在这里"全局"是指被新建项目中一个以上的库或者可执行文件使用。
当你把头文件放在include目录下,它会自动被LLVM生成系统找到。
tools
该子目录应该包含新建项目中所有可执行文件所需的源文件。对于新建项目中的每个"程序",都应该在tools下面有个子目录包含所有该"程序"的源代码。
test
该子目录应该包含能验证新建项目正确工作的测试例,自动测试是相当有用的。
当前,LLVM生成系统提供了两种关于测试的支持:
-
- LLVM提供了一个tcl程序来支持测试。可以在llvm/lib/llvm-dg.exp找到它。这个测试程序根据实际测试例的RUN行来决定如何进行测试。从TestingGuide可以获得更多细节。参考llvm/test中的MakeFile,使用Dejagnu来进行新建项目的测试。
- LLVM中有个名为llvm-test的可选包,它提供了使用LLVM gcc前端编译所使用的基准以及程序。可以使用这些程序来测试代码,收集统计信息,并与当前的LLVM性能统计进行比较。现在,还没有办法将llvm/test直接关联到新建项目的测试,需要将这些代码放到新建项目的目录中来使用。
某些情况下,需要将tools目录紧跟着lib目录。
Writting LLVM Style Makefiles
LLVM生成系统提供了生成库和可执行文件的便利方式。新建项目的大部分Makefiles应该只需要定义一些变量。下面就是可以设置的一些变量以及他们的作用。
Required Variables
LEVEL
该变量为以新建项目顶层目录为参照时当前Makefile的相对目录。譬如,新建项目的代码位于/tmp/src,Makefile位于/tmp/src/jump/high,那么LEVEL应设置为"../.."。
Variables for Building Subdirectories
DIRS
该变量为需要进行生成的子目录列表。列表中的子目录会一次一个按照指定顺序进行生成工作。
PARALLEL_DIRS
该变量为能并行生成的子目录列表。列表中的子目录会在DIRS中的目录生成之后再进行生成。
OPTIONAL_DIRS
这是一些可选的子目录列表,如果存在则进行生成,不存在也不会产生错误。按照给出的顺序串行进行生成。
Variables for Building Libraries
LIBRARYNAME
该变量包含了将要生成库的基本名称。譬如,要生成一个名为libsample.a的库,则LIBRARYNAME应设置为sample。
BUILD_ARCHIVE
默认情况下,library是直接连接到程序中的.o文件。要创建一个存档(archive, 也就是静态库),设置BUILD_ARCHIVE。
SHARED_LIBRARY
如果SHARED_LIBRARY在Makefile中定义了,那么将会创建一个共享(动态)库。
Variables for Building Programs
TOOLNAME
该变量包含了将要生成的程序名称。例如,需要生成一个名为sample的可执行程序,那么TOOLNAME应该设置为sample。
USEDLIBS
该变量为需要链接到程序中的库列表。这些库可以是LLVM的库也可以是lib目录下的库。这些库必须指定为基本名称。例如,要链接libsample.a,需要将USEDLIBS设置为sample。
当然,这项工作只对静态链接的库有效。
LIBS
如果需要链接动态库,将-l<library base name>添加到LIBS变量中。LLVM构建系统将会在同样位置查找动态链接库,就像对静态库的处理一样。
例如,要链接libsample.so,应该在Makefile中加入这样一行:
LIBS += -lsample
Miscellaneous Variables
ExtraSource
该变量包含构建所需要的外部源文件列表。在用于包含Lex以及Yacc程序输出时很有用。
CFLAGS
CPPFLAGS
这两个变量分别用于向C以及C++编译器添加选项。经常的用途是告诉编译器额外的头文件所在的目录。
强烈建议附加CFLAGS以及CPPFLAGS而不是重写他们。主文件可能已经有了你不想重写的有用选项。
Placement of Object Code
生成库以及可执行文件的最终位置取决于构建的方式是Debug、Realse还是Profile。
Libraries
所有的库(静态或动态)将会存储在PROJ_OBJ_ROOT/<type>/lib,其中的type为Debug、Release、Profile。
Executables
所有的可执行文件将存储在PROJ_OBJ_ROOT/<type>/bin,其中的type为Debug、Release、Profile。
Further Help
如果在创建LLVM项目时遇到了问题,LLVM组将会很乐意提供帮助。可以将问题发布到LLVM Developers Mailing List。