ROSE 编译器框架/如何添加一个新的项目目录
大多数建立在 ROSE 库之上的代码开发,其最初都是作为 projects 目录中的项目开始的。一些项目在成熟后最终被重构到 ROSE 库中。本章介绍如何在 ROSE 中添加新的项目。
Robb Matzke 在 ROSE 中添加了一个新功能,可以更轻松地将新项目添加到 ROSE/projects 中。
- 创建一个 $ROSE/projects/whatever 目录。
- 在该目录中,创建一个名为“rose.config”的文件。
- 在该文件中,添加一行 AC_CONFIG_FILES(projects/whatever/Makefile)
通过运行 ./build 将更新 rose/config/support-projects.m4。
您仍然需要有自己的 Makefile.am。最简单的示例是
- https://github.com/rose-compiler/rose-develop/blob/master/projects/SnippetTools/rose.config
- https://github.com/rose-compiler/rose-develop/blob/master/projects/SnippetTools/Makefile.am
ROSE 项目封装了使用 ROSE 库的完整程序或一组相关程序。每个项目都作为 ROSE “projects”目录的子目录存在,并且应包含文件“README”、“config/support-rose.m4”、“Makefile.am”以及任何必需的源文件、脚本、测试等。
- “README”应提供关于项目目的、算法、设计、实现等的解释。
- “support-rose.m4”将项目集成到 ROSE 构建系统中,以一种允许项目成为可选组件的方式(它们可以被禁用、重命名、删除或从分发中移除,而无需更改任何 ROSE 配置文件)。大多数旧项目都缺少此文件,因此与构建系统耦合得更紧密。
- “Makefile.am”用作 ROSE 使用的 GNU automake 系统的输入,以生成 Makefiles。
- 每个项目还应包含所有必需的源文件、文档和测试用例。
“config/support-rose.m4”文件将项目集成到 ROSE 配置和构建系统中。至少,它应该包含对 autoconf AC_CONFIG_FILES 宏的调用,其中包含项目的 Makefiles(不带“.am”扩展名)和它的 doxygen 配置文件(不带“.in”扩展名)的列表。它还可以包含任何其他必要的 autoconf 检查,这些检查尚未由 ROSE 的主配置脚本执行,包括根据项目先决条件的可用性来启用/禁用项目的代码。
这是一个示例
dnl List of all makefiles and autoconf-generated -*- autoconf -*- dnl files for this project AC_CONFIG_FILES([projects/DemoProject/Makefile projects/DemoProject/gui/Makefile projects/DemoProject/doxygen/doxygen.conf ]) dnl Even if this project is present in ROSE's "projects" directory, we might not have the dnl prerequisites to compile this project. Enable the project's makefiles by using the dnl ROSE_ENABLE_projectname automake conditional. Many prerequisites have probably already dnl been tested by ROSE's main configure script, so we don't need to list them here again dnl (although it usually doesn't hurt). AC_MSG_CHECKING([whether DemoProject prerequisites are satisfied]) if test "$ac_cv_header_gcrypt_h" = "yes"; then AC_MSG_RESULT([yes]) rose_enable_demo_project=yes else AC_MSG_RESULT([no]) rose_enable_demo_project= fi AM_CONDITIONAL([ROSE_ENABLE_DEMO_PROJECT], [test "$rose_enable_demo_project" = yes])
由于项目的全部配置都封装在“support-rose.m4”文件中,因此重命名、禁用或删除项目都非常简单:只需重命名项目目录即可重命名项目,通过重命名/删除“support-rose.m4”可以禁用项目,或通过删除项目目录可以删除项目。在进行任何这些更改后,应重新运行“build”和“configure”脚本。
由于项目是 ROSE 的自包含和可选部分,因此它们不需要与 ROSE 一起分发。这使最终用户能够将自己的私有项目放到现有的 ROSE 源代码树中,而无需修改任何 ROSE 文件,并且允许 ROSE 开发人员处理未公开分发的项目。任何不在 ROSE 的主要 Git 存储库中的项目目录都不会被分发(这包括不分发 Git 子模块,尽管子模块的占位符空目录将被分发)。
每个项目至少应有一个 Makefile.am,每个 Makefile.am 由 GNU automake 和 autoconf 处理以生成 Makefile。有关这些文件应包含的内容的详细信息,请参阅 automake 文档。一些重要的变量和目标是
- include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs: 这将引入来自更高级别 Makefiles 的定义,并且所有项目都需要它。它应该位于 Makefile.am 的顶部附近。
- SUBDIRS: 此变量应包含所有项目子目录的名称,这些目录都有 Makefiles。如果项目的唯一 Makefile 位于该项目的顶层目录中,则可以省略它。
- INCLUDES: 这将包含在编译期间需要添加的标志(类似于-I$(top_srcdir)/projects/RTC/include的标志)。您的标志应该放在$(ROSE_INCLUDES)之前,以确保找到正确文件。这将引入来自 src 目录的所有必要头文件到您的项目中。
- lib_*: 如果您要从项目中创建库,则这些变量/目标是必需的,该库可以稍后与其他项目或 src 目录链接。这是处理项目的推荐方法。
- EXTRA_DIST: 这些文件未被列为构建最终对象所需的文件(例如源文件和头文件),但仍必须包含在 ROSE tarball 分发版中。例如,这可能包括 README 或配置文件。
- check-local: 当调用 make check 时,此目标将从更高级别 Makefiles 中调用。
- clean-local: 为您提供一个步骤来手动清理项目,例如,如果您手动创建了一些文件(因此 Automake 不会自动清理它们)。
许多项目都从翻译器、分析器或优化器开始,这些翻译器、分析器或优化器接受输入代码并生成输出。
将新的项目目录添加到 ROSE 的 基本示例提交:https://github.com/rose-compiler/rose/commit/edf68927596960d96bb773efa25af5e090168f4a
请查看差异,以便您了解为新项目添加和更改哪些文件。
本质上,一个基本项目应该包含
- 一个 README 文件,解释该项目的内容、算法、设计、实现等
- 一个翻译器,作为项目的驱动程序
- 根据需要添加其他源文件和头文件,以包含项目的主要内容
- 测试输入文件
- Makefile.am 用于
- 编译和构建翻译器
- 包含 make check 规则,以便您的翻译器将被调用来处理您的输入文件并生成预期的结果
为了将您的项目连接到 ROSE 的构建系统,您还需要
- 在 projects/Makefile.am 中为您的项目目录添加一个子目录条目
- 为 每个由您的项目使用的新的 Makefile(从每个 Makefile.am 生成)在 config/support-rose.m4 中添加一行。
将项目的內容安装到用户指定目录内的单独目录中--prefix位置。这样做的原因是,我们不想污染核心 ROSE 安装空间。通过这样做,我们可以降低 ROSE 安装树的复杂性和混乱程度,同时消除跨项目文件冲突。它还使安装树保持模块化。
此示例使用前缀进行安装。它还维护 语义版本控制。
## 1. Version your project properly (http://semver.org/) rosepoly_API_VERSION=0.1.0 ## 2. Install to separate directory ## ## Installation tree should resemble: ## ## <--prefix> ## |--bin # ROSE/bin ## |--include # ROSE/include ## |--lib # ROSE/lib ## | ## |--<project>-<version> ## |--bin # <project>/bin ## |--include # <project>/include ## |--lib # <project>/lib ## exec_prefix=${prefix}/rosepoly-$(rosepoly_API_VERSION) ## Installation/include tree should resemble: ## |--<project>-<version> ## |--bin # <project>/bin ## |--include # <project>/include ## |--<project> ## |--lib # <project>/lib librosepoly_la_includedir = ${exec_prefix}/include/rosepoly
0. 安装 Doxygen 工具
使用 MacPorts 为 Apple 的 Mac OS
$ port install doxygen
# set path to MacPort's bin/
# ...
使用 LLNL 的机器之一
$ export PATH=/nfs/apps/doxygen/latest/bin:$PATH
1. 创建 Doxygen 配置文件
$ doxygen -g
Configuration file `Doxyfile' created.
Now edit the configuration file and enter
doxygen Doxyfile
to generate the documentation for your project
2. 自定义配置文件(Doxyfile)
... # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES ... # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.cpp *.hpp # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES ...
3. 生成 Doxygen 文档
# Invoke from your top-level directory
$ doxygen Doxyfile
4. 查看并验证 HTML 文档
$ firefox html/index.html &
5. 将目标添加到您的Makefile.am以生成文档
.PHONY: docs
docs:
doxygen Doxyfile # TODO: should be $(DOXYGEN)