LLVM系列第一章:编译LLVM源码
LLVM系列第二章:写一个Hello World
本文目录
- 系列文章目录
- 前言
- 一、项目结构
- 二、项目细节
- 1. 程序模块
- 2. 引入LLVM
- 3. Hello World
- 三、编译LLVM
- 1. 生成项目文件
- 2. 编译
- 3. 安装
- 三、编译Hello World
- 1. 生成项目文件
- 2. 编译
- 3. 安装
- 4. 运行
- 四、总结
前言
在此记录下基于LLVM写一个Hello World的过程,以备查阅。
开发环境的配置请参考第一章 《LLVM系列第一章:编译LLVM源码》。
一、项目结构我们把这个简单的项目命名为SimpleLang。可以参考LLVM及Clang的源码组织结构,来组织我们自己的代码(示例):
% tree -I "build|build-simplelang|llvm-12"
.
├── CMakeLists.txt
├── README.md
├── cmake
│ └── modules
│ └── AddSimpleLang.cmake
├── include
│ └── simplelang
│ └── Basic
│ ├── Version.h
│ └── Version.inc.in
├── lib
│ ├── Basic
│ │ ├── CMakeLists.txt
│ │ └── Version.cpp
│ └── CMakeLists.txt
└── tools
├── CMakeLists.txt
└── driver
├── CMakeLists.txt
└── Driver.cpp
9 directories, 11 files
注意我们自己的项目可以放在任何位置,没有必要放在LLVM的源码目录下。
二、项目细节 1. 程序模块这个简单项目包含了两个模块:
- simplelang,一个简单的可执行文件
- simplelangBasic,一个简单的library(库)
simplelang将会调用simplelangBasic中的函数,并把结果打印出来。simplelang需要链接simplelangBasic,才能调用其函数。
以下是跟项目组织结构相关的部分CMake脚本。
(1) Hello World项目根目录(示例):
# CMakeLists.txt add_subdirectory(lib) add_subdirectory(tools)
(2) lib目录(示例):
# lib/CMakeLists.txt add_subdirectory(Basic)
# lib/Basic/CMakeLists.txt add_simplelang_library(simplelangBasic ....cpp )
注意到这里会构建出simplelangBasic library。
(3) tools目录(示例):
# tools/CMakeLists.txt add_simplelang_subdirectory(driver)
# tools/driver/CMakeLists.txt set(LLVM_LINK_COMPONENTS Support ) add_simplelang_tool(simplelang ....cpp ) target_link_libraries(simplelang PRIVATE simplelangBasic )
注意到这里会构建出simplelang, 并且让其链接simplelangBasic。
2. 引入LLVM我们需要做一些与LLVM相关的配置,才能让我们的项目顺利地使用LLVM(示例):
find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_PATH}")
list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR})
include(AddLLVM)
include(HandleLLVMOptions)
include_directories("${LLVM_BINARY_DIR}/include" "${LLVM_INCLUDE_DIR}")
link_directories("${LLVM_LIBRARY_DIR}")
set(SIMPLELANG_BUILT_STANDALONE 1)
3. Hello World
我们的C++代码放在两个文件中:
- tools/driver/Driver.cpp,属于模块simplelang
- lib/Basic/Version.cpp,属于模块simplelangBasic
main函数在Driver.cpp中(示例):
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/raw_ostream.h"
#include "simplelang/Basic/Version.h"
int main(int argc, const char **argv)
{
llvm::InitLLVM X(argc, argv);
llvm::outs() << "Hello World! (version " << simplelang::getSimpleLangVersion() << ")n";
}
我们看到以上代码调用了函数getSimpleLangVersion(),它来自于Version.cpp(示例):
std::string simplelang::getSimpleLangVersion()
{
return SIMPLELANG_VERSION_STRING;
}
其中SIMPLELANG_VERSION_STRING仅仅是个string而已,它的值为"0.1"。
三、编译LLVM 1. 生成项目文件用CMake工具生成项目文件(示例):
mkdir build cd build cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_EXTERNAL_PROJECTS=simplelang -DLLVM_EXTERNAL_SIMPLELANG_SOURCE_DIR=../simplelang -DCMAKE_INSTALL_PREFIX=../llvm-12 /path/to/llvm-project/llvm
注意/path/to/llvm-project代表的是llvm-project的源代码路径。
输出log如下(示例):
-- The C compiler identification is AppleClang 13.0.0.13000029 -- The CXX compiler identification is AppleClang 13.0.0.13000029 -- The ASM compiler identification is Clang with GNU-like command-line -- Found assembler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Found libtool - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool ... -- Configuring done -- Generating done -- Build files have been written to: /path/to/hello-world/build2. 编译
用ninja工具进行编译(示例):
ninja
输出log如下(示例):
[2996/2996] Linking CXX executable bin/obj2yaml3. 安装
用ninja进行安装(示例):
ninja install
输出log如下(示例):
[0/1] Install the project... -- Install configuration: "Release" -- Installing: /path/to/hello-world/llvm-12/include/llvm ...三、编译Hello World 1. 生成项目文件
用CMake生成项目文件(示例):
mkdir build-simplelang cd build-simplelang cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_DIR=../llvm-12/lib/cmake/llvm -DCMAKE_INSTALL_PREFIX=../llvm-12 ../
输出log如下(示例):
-- The C compiler identification is AppleClang 13.0.0.13000029 -- The CXX compiler identification is AppleClang 13.0.0.13000029 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Found ZLIB: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/usr/lib/libz.tbd (found version "1.2.11") -- Found LibXml2: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/usr/lib/libxml2.tbd (found version "2.9.4") -- Linker detection: ld64 ... ... -- Building with -fPIC -- Configuring done -- Generating done -- Build files have been written to: /path/to/hello-world/build-simplelang2. 编译
用ninja进行编译(示例):
ninja
输出log如下(示例):
[4/4] Linking CXX executable tools/driver/simplelang3. 安装
用ninja进行安装(示例):
ninja install
输出log如下(示例):
[0/1] Install the project... -- Install configuration: "Release" -- Installing: /path/to/hello-world/llvm-12/lib/libsimplelangBasic.a -- Installing: /path/to/hello-world/llvm-12/bin/simplelang4. 运行
运行Hello World(示例):
../llvm-12/bin/simplelang
输出结果如下(示例):
Hello World! (version 0.1)四、总结
我们参考LLVM的项目组织结构,写了一个Hello World,并且编译运行成功。完整源码示例请参看:
https://github.com/wuzhanglin/llvm-hello-world



