编译原理 H 实验环境配置

本课程推荐的实验环境有三种:

  • Windows 10 Anniversary Edition (Build 1607) or higher

    如果使用 Windows,你需要安装 Windows Subsystem for Linux (WSL)。图形化相关的工作会在 Native Windows 下完成,但代码生成推荐在 WSL 中进行,这是为了便于依赖安装。

  • Linux

  • Mac with Homebrew installed

    Linux 和 Mac 都是不错的 POSIX 环境,也都各自有好用的包管理器、便利的图形化环境。

如果你原本安装 Windows 7/8 并且不想升级 Windows 10,那么在虚拟机(如 VirtualBox)中安装一个 Linux 发行版(如 Ubuntu)将会是一个不错的选择。

1. 基本的编译执行环境

为了编译实验代码,你需要安装以下软件:

1.1. 依赖软件的安装

在 Linux 的发行版上安装这些软件会十分简单,例如, 在 Ubuntu 下,运行如下命令即可:

sudo apt install cmake g++ openjdk-8-jre pkg-config uuid-dev

而在 Windows 下,推荐通过 WSL 配置实验的编译执行环境。安装的方式和 Ubuntu 类似,但考虑到 WSL 并不需要图形部分的安装,建议将上述命令中的openjdk-8-jre更换为openjdk-8-jre-headless

在 Mac 下,你需要使用 clang 作为编译器(随 XCode 安装),单独安装 JVM,然后从 Homebrew 安装其余包:

brew install cmake pkg-config ossp-uuid

对于 Mac,部分同学可能遇到安装报错的问题。这一问题暂时没有找到出现原因(助教不是 Mac 用户),如果实在解决不了的话推荐虚拟机 Linux 解决问题。

1.2. CMake 的使用

CMake 根据内置的规则和语法来自动生成相关的makefile 文件进行编译,同时还支持静态库和动态库的构建等。

通过 CMake 管理的项目主目录下会有一个 CMakeLists.txt ,其中会包括工程包含哪些子目录等内容;而在每个子目录下,也会包含一个 CMakeLists.txt,用来管理该子目录中相关内容的构建。

编译

编译的时候,可以建立单独的文件夹(如build),让编译产生的文件和源代码区分出来,以下是一种常用的编译方式, 当前目录为项目源代码目录:

$ mkdir build
$ cd build
$ cmake ..
$ make

编写CMakeLists.txt

在 CMakeLists.txt 中,可以包含如下一些内容:

cmake_minimum_required(VERSION 3.1)  # CMake 版本要求
PROJECT(hello)                       # 项目名称

set(CMAKE_CXX_STANDARD 14)           # 设置编译器遵循的C++标准

set(CMAKE_CXX_FLAGS “-O2 -g”)        # 自定义编译选项

假设 args 代表通过空格或换行分隔的多个参数,你可以

  • 通过 include_directories(args) 来添加外部库的头文件所在的一组目录 args 作为头文件查找目录;
  • 通过 link_directories(args) 来添加外部链接库的查找目录;
  • 通过 link_libraries(args) 来添加链接的外部库;
  • 通过 target_link_libraries(hello args) 来设置生成的可执行目标及其要链接的库
  • 通过 add_library(mylib STATIC ${SRC}) 来创建静态库libmylib.a; 如果 STATIC 换成 SHARED,则为创建动态库 libmylib.so;
  • 通过 add_executable(hello ${SRC}) 来创建可执行文件 hello

你可以使用内置宏 CMAKE_CURRENT_SOURCE_DIR 来获取当前CMakeLists.txt 所在目录,例如 ${CMAKE_CURRENT_SOURCE_DIR}/..表示 CMakeLists.txt 所在目录的上一级目录。

2. ANTLR

ANTLR (ANother Tool for Language Recognition)是一个强大的解析器的生成器。在课程实验中,你将利用 ANTLR 工具读入描述要解析的语言词法和语法的文法文件(扩展名是 .g4), 生成解析器的源码。

ANTLR v4 使用 Java 实现,但是生成的解析器源码可以是 Java、C++、C#、Go、JavaScript、Swift等。

2.1. 依赖环境准备

ANTLR 工具需要 JVM 才能执行;另一方面,为了方便使用 grun,你需要一个能够编译 java 源文件的环境。因此,你需要一个完整的 Java Development Kit。

  • 如果你使用 Windows:

    由于grun工具需要图形化显示,因此在 Windows 下不推荐在 WSL 中执行,WSL 中配置桌面环境会有些 tricky。

    你需要在 Windows 中安装 Java Development Kit(推荐使用 Oracle Java SE 8),并确认你的 PowerShell 的可用性(Anniversary Edition 以上的版本应当已经自带,右键开始菜单就可以看到)。

    安装后,你需要设置好环境变量,将{Your JDK installation}\bin加入环境变量PATH中。

  • 如果你使用 Linux:

    推荐通过包管理器安装 OpenJDK 8。在你的包管理器中通过搜索确定包名,如 Ubuntu 下包名为openjdk-8-jdk, 安装之即可。

  • 如果你使用 Mac:

    类似 Windows,你需要手动安装一个 JDK,并配置好环境变量。

2.2. 获取 antlr

你需要从 ANTLR Download 下载 antlr-4.7-complete.jar

然后,你需要将该jar包的路径加入到环境变量 CLASSPATH 中,即 Bash 中执行

export CLASSPATH=".:/path/to/your/antlr-4.7-complete.jar:$CLASSPATH"

或 PowerShell 中的

$env:CLASSPATH=".;/path/to/your/antlr-4.7-complete.jar;$CLASSPATH"

你可以考虑将这一命令加入.bashrc(对于Bash)或profile.ps1(对于PowerShell),以省去你每次配置的麻烦。

2.3. antlr4 和 grun 工具

可以定义别名 antlr4 表示 ANTLR 工具,即

alias antlr4='java org.antlr.v4.Tool'

这样,你可以直接使用 antlr4 your.g4 来为your.g4 生成解析器源码。

ANTLR 的运行时库中还提供了一个灵活的测试工具 TestRig,它可以显示解析器如何匹配输入的许多相关信息。TestRig使用Java的反射机制来调用编译过的解析器。为了方便用户使用,ANTLR 提供了一个 grun 工具来使用 TestRig

grun 本质上是一个别名,可以定义如下:

alias grun='java org.antlr.v4.runtime.misc.TestRig'

alias grun='java org.antlr.v4.gui.TestRig'

如果你工作在 PowerShell 下,你应该使用Set-Alias命令。

同样的,这些别名命令也可以加入.bashrcprofile.ps1中来为你节省时间。

3. LLVM 配置

由于 Ubuntu 源中 LLVM 的打包错误、以及此后对 Clang 和 LLVM 的实验需要,这里推荐同学们自行编译 LLVM。

3.1. 获取 LLVM

这里将在当前目录下建立一个名为llvm的目录,其中包含了 LLVM 和 Clang。

wget http://releases.llvm.org/4.0.1/llvm-4.0.1.src.tar.xz
wget http://releases.llvm.org/4.0.1/cfe-4.0.1.src.tar.xz
tar xvf llvm-4.0.1.src.tar.xz
mv llvm-4.0.1-src llvm
tar xvf cfe-4.0.1.src.tar.xz
mv cfe-4.0.1.src llvm/tools/clang

3.2. 编译并安装

这里将在当前目录下建立一个名为llvm-build的目录(和llvm同级),用于构建 LLVM 和 Clang,并将安装目录配置为和这两个目录同级的llvm-install目录。

mkdir llvm-build && cd llvm-build
cmake ../llvm -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=`cd .. && pwd`/llvm-install
make -j install

在 WSL 下使用make -j,会有小概率在长时间执行后导致系统卡死,推荐考虑使用make -jn,其中将n替换为你的 CPU 逻辑处理器数目减一。例如,在 Core i7 6700HQ 上,使用make -j7

编译时间较长,基本占满你的 CPU,这段时间里你可能需要玩一会儿手机或者去冲一杯咖啡,当然去吃个饭也不错。

请注意,为了避免你的内存爆炸,这里使用了 Release 配置。这一配置下,链接时无需处理调试符号,内存占用大幅度降低。考虑到同学们不会有 Debug 进入 LLVM 中的需求,Release 配置已经足够使用。

results matching ""

    No results matching ""