使用Dockerfile和CMake编译LLVM程序¶
引言¶
Docker
是非常方便使用的虚拟容器技术,为自己的项目或程序提供一个Dockerfile
文件可以快速的建立对应的开发或部署环境,减少因为环境或工具链缺失而痛苦、漫长的前期准备工作。
LLVM
是备受瞩目的编译器项目,提供了一系列工具链,但要将其引入自己的代码中进行编译的过程却也不是那么容易,甚至会导致很多人放弃尝试。
这篇通过Dockerfile
建立一个开发环境,然后在这个环境中通过CMake
配置以顺利使用LLVM
工具链完成项目构建,以后想继续学习或使用LLVM
就可以在这个环境中拿这个模板直接操作了。
Dockerfile文件¶
这里使用的是LLVM-13
,选择了Debian-11.6
这个操作系统镜像为基础:
# 基础镜像
FROM debian:11.6
LABEL MAINTAINER lesliezhu http://lesliezhu.com
# 换成阿里云软件源
RUN echo \
deb http://mirrors.aliyun.com/debian/ bullseye main non-free contrib\
deb-src http://mirrors.aliyun.com/debian/ bullseye main non-free contrib\
deb http://mirrors.aliyun.com/debian-security bullseye/updates main\
deb-src http://mirrors.aliyun.com/debian-security bullseye/updates main\
deb http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib\
deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib\
deb http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib\
deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib\
deb http://mirrors.ustc.edu.cn/debian-security/ stable-security main non-free contrib\
deb-src http://mirrors.ustc.edu.cn/debian-security/ stable-security main non-free contrib\
> /etc/apt/sources.list
# 安装软件包
RUN apt-get -y update && \
apt-get install -y cmake && \
apt-get install -y clang-13 llvm-13 llvm-13-dev llvm-13-tools llvm-13-runtime llvm-13-linker-tools && \
apt-get install -y libgflags-dev libgtest-dev && \
apt-get install -y libboost-dev libboost-serialization-dev && \
apt-get install -y libreadline-dev zlib1g zlib1g-dev
# 设置初始化环境变量等
RUN echo '\n\n# for LLVM-13 \n\
export CC=/usr/bin/clang-13 \n\
export CXX=/usr/bin/clang++-13 \n\
ln -sf /usr/bin/llvm-config-13 /usr/bin/llvm-config \n'\
>> ~/.bashrc
构建Docker镜像环境¶
# 构建镜像
$ docker build -f Dockerfile -t ledge:builder .
# 进入镜像并自动映射挂载本地目录
$ docker run -v $PWD:$PWD -w $PWD --rm -it ledge:builder bash
这样一键启动了开发或部署运行环境,省时省力。
CMake编译LLVM程序¶
LLVM
良好的模块化设计导致的一个结果,就是配置参数比较复杂,提供专门获取编译参数的工具llvm-config
:
如果直接手写到Makefile
, 大致会类似:
$ clang++ -g -O3 `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native` program.cpp -o program
如果是使用CMake
管理的项目,则可以这样:
# 要求必须找到LLVM
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM: ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVM: ${LLVM_DIR}")
message(STATUS "Using LLVM_INCLUDE_DIRS: ${LLVM_INCLUDE_DIRS}")
message(STATUS "Using LLVM_DEFINITIONS: ${LLVM_DEFINITIONS}")
include_directories(${LLVM_INCLUDE_DIRS})
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_DEFINITIONS}")
# 执行shell命令获取链接参数
execute_process(COMMAND llvm-config --ldflags
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
TIMEOUT 20
RESULT_VARIABLE LLVM_LDFLAGS_result
OUTPUT_VARIABLE LLVM_LDFLAGS
ERROR_VARIABLE LLVM_LDFLAGS_error
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
)
message(STATUS "Using LLVM_LDFLAGS: ${LLVM_LDFLAGS}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_LDFLAGS}")
# 执行shell命令获取链接库清单
execute_process(COMMAND llvm-config --libs core orcjit native --system-libs
COMMAND tr "\n" " "
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
TIMEOUT 20
RESULT_VARIABLE LLVM_LIBS_result
OUTPUT_VARIABLE LLVM_LIBS
ERROR_VARIABLE LLVM_LIBS_error
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
)
message(STATUS "Using LLVM_LIBS: ${LLVM_LIBS}")
add_executable(program src/program.cpp)
target_link_libraries(program ${LLVM_LIBS})
这样就可以愉快的引入LLVM
并编译现有程序了。
总结¶
工欲善其事必先利其器。
- 微信搜索: 「 MinYiLife 」, 关注公众号!
- 本文链接: https://www.lesliezhu.com/blog/2023/01/05/dockerfile_for_ledge/
- 版权声明: 原创文章,如需转载请注明文章作者和出处。谢谢!