From d3747f26a9a3083fae4c5e3e1a5765ab5c8c772a Mon Sep 17 00:00:00 2001 From: cf-zhao Date: Thu, 2 Jan 2025 22:30:07 +0800 Subject: [PATCH] [build] Enable containerize build --- README-zh.md | 65 +++++++++++++++++++++----- README.md | 87 +++++++++++++++++++++++----------- build.sh | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 241 insertions(+), 41 deletions(-) diff --git a/README-zh.md b/README-zh.md index c637ce6f0445..a71d0fa4552c 100644 --- a/README-zh.md +++ b/README-zh.md @@ -1,23 +1,64 @@ -# 编译器基础结构 +## 1、项目介绍 -欢迎来到LLVM项目! +欢迎来到openEuler社区的LLVM项目!本仓库是[llvm-project](https://github.com/llvm/llvm-project)下游仓库。 -此存储库包含 LLVM 的源代码,LLVM 是一个用于构建高度优化的编译器、优化器和运行时环境的工具包。 +此仓库包含LLVM项目的源代码,LLVM基础设施是一个用于构建高度优化的编译器、优化器和运行时环境的工具包。 -LLVM 项目有多个组件。该项目的核心本身被称为“LLVM”。它包含处理中间表示并将其转换为目标文件所需的所有工具、库和头文件。工具包括汇编程序、反汇编程序、位码分析器和位码优化器。 +LLVM项目有多个组件。该项目的核心组件被称为“LLVM”,它包含处理中间表示及将其转换为目标文件所需的所有工具(包括汇编器、反汇编器、位码分析器和为位码优化器)、库和头文件。 -C语言风格的语言使用Clang前端。该组件将C、C++、Objective-C和Objective-C++代码编译成LLVM比特码,并使用LLVM将其转换为对象文件。 +类C语言使用Clang前端,该组件将C、C++、Objective-C和Objective-C++代码编译成LLVM位码,并使用LLVM将其转换为二进制目标文件。 -其他组件包括:libc++ C++ 标准库、LLD 链接器等 +其他组件包括:C++标准库(libc++)、LLD链接器等。 -## 获取源代码并构建 LLVM +## 2、构建指导 -有关构建和运行 LLVM 的信息,请参阅 LLVM 入门页面。 +首先通过git下载源码,然后通过build.sh脚本一键式构建LLVM。构建方式有`直接命令行构建`和`容器化构建`两种。 -有关如何为 LLVM 项目做贡献的信息,请查看 为 LLVM 做贡献指南。 +### 2.1、直接命令行构建 -## 取得联系 +推荐使用openEuler操作系统进行构建,如果您使用其他操作系统,建议使用容器化构建方式。 -加入 LLVM Discourse 论坛、Discord 聊天或 OFTC 上的 #llvm IRC 频道。 +首先确保系统安装了依赖软件包,可以用如下命令安装。 +``` +yum install -y gcc g++ make cmake openssl-devel python3 \ +python3-setuptools python-wheel texinfo binutils-devel libatomic +``` +然后可以通过 `./build.sh -h`查看当前工程支持的构建选项。通过命令行执行一键式构建,例如: +``` +./build.sh -r -b release -X X86 -j 8 +``` -LLVM项目为参与者在项目内的所有沟通方式采用了行为准则。 \ No newline at end of file +### 2.2、容器化构建 + +为了解决由于开发环境差异导致的构建失败和构建产物二进制差异问题,openEuler LLVM项目提供了容器化构建方法。得益于[openEuler容器镜像项目](https://gitee.com/openeuler/openeuler-docker-images),提前制作了[llvm-build-deps容器镜像](https://gitee.com/openeuler/openeuler-docker-images/tree/master/llvm-build-deps)。开发者可以通过`build.sh`脚本的`-C`选项启用容器化构建,例如: +``` +./build.sh -C -r -b release -X X86 -j 8 // 添加了-C选项 +``` + +相关依赖: +* 开发环境需要正确安装了docker应用。 +* 用户加入了docker用户组,使得`build.sh`脚本执行docker命令时不需要再加`sudo`命令。可以通过如下命令将当前用户加入docker用户组。 +``` +sudo usermod -aG docker ${USER} +``` +注意:第一次执行容器化构建时,脚本会自动从镜像仓库拉取llvm-build-deps容器镜像。 + +## 3、贡献指导 + +1、Fork 本仓库 +2、新建 Feat_xxx 分支 +3、提交代码 +4、新建 Pull Request + +## 4、讨论与求助 + +### 4.1、上游社区 +* 加入[discourse论坛](https://discourse.llvm.org/),提出或参与问题、RFC等交流。 + +* 社区参与者的[行为规范](https://llvm.org/docs/CodeOfConduct.html). + +### 4.1、openEuler社区Compiler SIG +几种方式: +* 订阅[Compiler SIG邮件列表](https://mailweb.openeuler.org/postorius/lists/compiler@openeuler.org/) +* 在[openEuler论坛](https://forum.openeuler.org/?locale=zh_CN)发帖讨论。 +* 微信交流群:请先添加微信名`Compiler_Assistant` diff --git a/README.md b/README.md index eb8d624d75ce..8665dede3cda 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,70 @@ -# The LLVM Compiler Infrastructure +## 1. Project Introduction -Welcome to the LLVM project! +Welcome to the LLVM project in the openEuler community! This warehouse is the downstream warehouse of [llvm-project](https://github.com/llvm/llvm-project). -This repository contains the source code for LLVM, a toolkit for the -construction of highly optimized compilers, optimizers, and run-time -environments. +This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments. -The LLVM project has multiple components. The core of the project is -itself called "LLVM". This contains all of the tools, libraries, and header -files needed to process intermediate representations and convert them into -object files. Tools include an assembler, disassembler, bitcode analyzer, and -bitcode optimizer. +The LLVM project has multiple components. The core of the project is itself called "LLVM". This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer. -C-like languages use the [Clang](http://clang.llvm.org/) frontend. This -component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode --- and from there into object files, using LLVM. +C-like languages use the [Clang](https://clang.llvm.org/) frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM. -Other components include: -the [libc++ C++ standard library](https://libcxx.llvm.org), -the [LLD linker](https://lld.llvm.org), and more. +Other components include: the [libc++ C++ standard library](https://libcxx.llvm.org/), the [LLD linker](https://lld.llvm.org/), and more. -## Getting the Source Code and Building LLVM +## 2. Construction Guide -Consult the -[Getting Started with LLVM](https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm) -page for information on building and running LLVM. +You can use `git` to download the source code, and then use the `build.sh` script to build the LLVM in one-click mode. There are two build modes: `build with command line` and `build with container`. -For information on how to contribute to the LLVM project, please take a look at -the [Contributing to LLVM](https://llvm.org/docs/Contributing.html) guide. +### 2.1. Build with command line directly -## Getting in touch +You are advised to use the `openEuler` for building. If you use other operating systems, you are advised to use the containerized building mode. -Join the [LLVM Discourse forums](https://discourse.llvm.org/), [Discord -chat](https://discord.gg/xS7Z362), or #llvm IRC channel on -[OFTC](https://oftc.net/). +Ensure that the dependency software packages are installed. You can run the following command to install the software packages: -The LLVM project has adopted a [code of conduct](https://llvm.org/docs/CodeOfConduct.html) for -participants to all modes of communication within the project. +` ` ` +yum install -y gcc g++ make cmake openssl-devel python3 \ +python3-setuptools python-wheel texinfo binutils-devel libatomic +` ` ` + +You can run the `./build.sh -h` command to view the build options supported by the current project. Run the following command to perform a one-click build: + +` ` ` +./build.sh -r -b release -X X86 -j 8 +` ` ` + +### 2.2 Build with container + +The openEuler LLVM project provides a containerized building mode to solve the problems of build failures and binary differences of build products caused by development environment differences. Thanks to the [openEuler container image project](https://gitee.com/openeuler/openeuler-docker-images), the [llvm-build-deps container image](https://gitee.com/openeuler/openeuler-docker-images/tree/master/llvm-build-deps) is created in advance. Developers can enable containerized builds using the `-C` option of the `build.sh` script. For example: + +` ` ` +./build.sh -C -r -b release -X X86 -j 8 // added -C option +` ` ` + +Dependency: +* The Docker application must be correctly installed in the development environment. +* The user is added to the docker user group so that the `sudo` command is not required when the `build.sh` script executes the docker command. You can run the following command to add the current user to the docker user group: + +` ` ` +sudo usermod -aG docker ${USER} +` ` ` + +Note: When you perform a containerized build for the first time, the script automatically pulls the `llvm-build-deps container image` from the image repository. + +## 3. Contribution guidance + +1. Fork This Warehouse +2. Create the Feat_xxx branch. +3. Submit the code. +4. Create a Pull Request. + +## 4. Discussion and help-seeking + +### 4.1 Upstream Community +* Join the [Discourse Forum](https://discourse.llvm.org/) . + +* [Code of Conduct](https://llvm.org/docs/CodeOfConduct.html) for Community Participants. + +### 4.1. Compiler SIG of the openEuler community +There are several ways: +* Subscribe to the [Compiler SIG mailing list](https://mailweb.openeuler.org/postorius/lists/compiler@openeuler.org/) +* Post a discussion at the [openEuler forum](https://forum.openeuler.org/?locale=zh_CN). +* WeChat communication group: Please add the WeChat name `Compiler_Assistant` first. \ No newline at end of file diff --git a/build.sh b/build.sh index 2e6d2167b3ef..6569b933b006 100755 --- a/build.sh +++ b/build.sh @@ -17,6 +17,9 @@ use_ccache="0" enable_classic_flang="0" do_install="0" clean=0 +containerize=0 +docker=$(type -p docker) +host_arch="$(uname -m)" unit_test="" install="install" install_toolchain_only="0" @@ -53,6 +56,7 @@ Options: -A Disable ACPO. -b type Specify CMake build type (default: $buildtype). -c Use ccache (default: $use_ccache). + -C Containerize the build for openEuler compatibility. -e Build for embedded cross tool chain. -E Build for openEuler. -h Display this help message. @@ -72,13 +76,16 @@ EOF # Process command-line options. Remember the options for passing to the # containerized build script. -while getopts :aAb:d:ceEhiI:j:orstvfX: optchr; do +containerized_opts=() +while getopts :aAb:d:cCeEhiI:j:orstvfX: optchr; do case "$optchr" in a) enable_autotuner="0" + containerized_opts+=(-$optchr) ;; A) enable_acpo="0" + containerized_opts+=(-$optchr) ;; b) buildtype="$OPTARG" @@ -93,21 +100,34 @@ while getopts :aAb:d:ceEhiI:j:orstvfX: optchr; do exit 1 ;; esac + containerized_opts+=(-$optchr "$OPTARG") ;; c) use_ccache="1" + containerized_opts+=(-$optchr) + ;; + C) + if [ -z "$docker" -o ! -x "$docker" ]; then + echo "$0: no usable Docker" + exit 1 + fi + containerize=1 ;; d) build_prefix="$OPTARG" + containerized_opts+=(-$optchr "$OPTARG") ;; f) enable_classic_flang="1" + containerized_opts+=(-$optchr) ;; e) embedded_toolchain="1" + containerized_opts+=(-$optchr) ;; E) build_for_openeuler="1" + containerized_opts+=(-$optchr) ;; h) usage @@ -115,31 +135,40 @@ while getopts :aAb:d:ceEhiI:j:orstvfX: optchr; do ;; i) do_install="1" + containerized_opts+=(-$optchr) ;; I) install_dir_name="$OPTARG" install_prefix="$dir/$install_dir_name" + containerized_opts+=(-$optchr "$OPTARG") ;; j) threads="$OPTARG" + containerized_opts+=(-$optchr "$OPTARG") ;; o) install_toolchain_only=1 + containerized_opts+=(-$optchr) ;; r) clean=1 + containerized_opts+=(-$optchr) ;; s) install="install/strip" + containerized_opts+=(-$optchr) ;; t) unit_test=check-all + containerized_opts+=(-$optchr) ;; v) verbose="VERBOSE=1" + containerized_opts+=(-$optchr) ;; X) backends="$OPTARG" + containerized_opts+=(-$optchr "$OPTARG") ;; :) echo "$0: missing argument for option '-$OPTARG'" @@ -152,6 +181,105 @@ while getopts :aAb:d:ceEhiI:j:orstvfX: optchr; do esac done +# Make sure that all files under the build directory can be deleted; when some +# LLVM tests are interrupted, they can leave behind inaccessible directories. +build_cleanup() { + chmod -R u+rwX,go+rX $build_prefix > /dev/null 2>&1 +} + +# Handle interrupts. When not running a containerized build, we have to enable +# job control (-m), and make sure to delete our own long-running child +# processes. In particular, ninja and python (llvm-lit) refuse to terminate +# when Jenkins aborts the parent process and disconnects. +set -m +handle_abort() { + local rc=$1 sig=$2 + build_cleanup + trap - EXIT SIGHUP SIGINT SIGTERM + local children="$(jobs -p)" + for cgrp in $children ; do + kill -$sig -${cgrp} > /dev/null 2>&1 + done + if [ -n "$sig" ]; then + kill -$sig 0 + else + exit $rc + fi +} + +if [ $containerize -eq 0 ]; then + trap - SIGCHLD + trap 'handle_abort $?' EXIT + trap 'handle_abort 129 HUP' SIGHUP + trap 'handle_abort 130 INT' SIGINT + trap 'handle_abort 143 TERM' SIGTERM +else + cmd=$(readlink --canonicalize-existing $0) + + # Generate passwd/group files for the container. + # lit.py depends on correct results from getpwent. + homedir=$(realpath $HOME) + passwd=$(mktemp /tmp/passwd.XXXXXX) + echo "root:x:0:0::/root:/bin/bash" > $passwd + echo "user:x:$(id -u):$(id -g)::$homedir:/bin/bash" >> $passwd + + group=$(mktemp /tmp/group.XXXXXX) + echo "root:x:0:" > $group + echo "users:x:$(id -g):" >> $group + + # Re-run myself in a openEuler container. The --cap-add option is needed + # to pacify llvm-exegesis unit tests. Make sure that the container is + # stopped if the child process is interrupted (e.g. by Jenkins). + # Note that the container ID file is created with `mktemp -u` because + # `docker run` refuses to overwrite an existing ID file. + echo "Re-launching in container." + containerid=$(mktemp -u /tmp/docker-cid.$$.XXXXXX) + docker_cleanup() { + local rc=$1 sig=$2 + docker container stop $(cat $containerid) > /dev/null 2>&1 + rm $passwd $group $containerid + build_cleanup + trap - EXIT SIGHUP SIGINT SIGTERM # avoid infinite recursion + if [ -n "$sig" ]; then + kill -$sig 0 + else + exit $rc + fi + } + trap 'docker_cleanup $?' EXIT + trap 'docker_cleanup 129 HUP' SIGHUP + trap 'docker_cleanup 130 INT' SIGINT + trap 'docker_cleanup 143 TERM' SIGTERM + + DOCKER_IMAGE="llvm-build-deps:latest" + docker_opts="--rm + --cap-add=SYS_ADMIN + --cap-add=SYS_PTRACE + --security-opt seccomp=unconfined + --user $(id -u):$(id -g) + --workdir=$(realpath $PWD) + --ulimit core=0 + --ulimit stack=-1 + --cidfile $containerid + -v $homedir:$homedir + -v $passwd:/etc/passwd + -v $group:/etc/group + -e BINUTILS_INCDIR=/usr/local/include + hub.oepkgs.net/openeuler/${DOCKER_IMAGE}" + + if [ -t 1 ]; then + $docker run -it $docker_opts ${cmd} ${containerized_opts[@]} + exit $? + else + set -x + $docker run $docker_opts ${cmd} ${containerized_opts[@]} & + wait $! || exit $? + exit 0 + fi +fi + +echo "Using $threads threads." + CMAKE_OPTIONS="-DCMAKE_INSTALL_PREFIX=$install_prefix \ -DCMAKE_BUILD_TYPE=$buildtype \ -DCMAKE_C_COMPILER=$C_COMPILER_PATH \ -- Gitee