-
Notifications
You must be signed in to change notification settings - Fork 175
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tc-build: Add initial scripts and update README
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
- Loading branch information
1 parent
945a02c
commit e9200f4
Showing
6 changed files
with
633 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,59 @@ | ||
# tc-build | ||
A set of scripts to build LLVM and binutils | ||
# Toolchain build scripts | ||
|
||
There are times where a tip of tree LLVM build will have some issue fixed and it isn't available to you, maybe because it isn't in a release or it isn't available through your distribution's package management system. At that point, to get that fix, LLVM needs to be compiled, which sounds scary but is [rather simple](https://llvm.org/docs/GettingStarted.html). The `build-llvm.sh` script takes it a step farther by trying to optimize both LLVM's build time by: | ||
|
||
* Trimming down a lot of things that kernel developers don't care about: | ||
* Documentation | ||
* LLVM tests | ||
* Ocaml bindings | ||
* libfuzzer | ||
* Building with the faster tools available (in order of fastest to slowest): | ||
* clang + lld | ||
* clang/gcc + ld.gold | ||
* clang/gcc + ld.bfd | ||
|
||
It also aims to make kernel compilation go a little bit faster by generating a toolchain that is optimized for the host CPU (using `-O2 -march=native -mtune=native`). | ||
|
||
## Getting started | ||
|
||
These scripts have been tested in a Docker image of the following distributions, with the following packages installed: | ||
|
||
* ### Debian/Ubuntu | ||
|
||
``` | ||
apt install ca-certificates ccache clang cmake curl file gcc g++ git make ninja-build python texinfo zlib1g-dev | ||
``` | ||
|
||
On Debian Buster or Ubuntu Bionic/Cosmic/Disco, `apt-get install lld` should be added as well for faster compiles. | ||
|
||
* ### Fedora | ||
|
||
``` | ||
dnf install ccache clang cmake gcc gcc-c++ git lld ninja-build python zlib-devel | ||
``` | ||
|
||
* ### Arch Linux | ||
|
||
``` | ||
pacman -S base-devel ccache clang cmake git lld ninja python | ||
``` | ||
|
||
These scripts should be distribution agnostic. Please feel free to add different distribution install commands here through a pull request. | ||
|
||
## build-llvm.sh | ||
|
||
By default, `./build-llvm.sh` will clone LLVM, grab the latest binutils tarball (for the LLVMgold.so plugin), and build LLVM, clang, and lld. Run `./build-llvm.sh -h` for more options. | ||
|
||
## build-binutils.sh | ||
|
||
This script builds a standalone copy of binutils. This might be needed because certain distributions like Arch Linux (whose options the script uses) might symlink `/usr/lib/LLVMgold.so` to `/usr/lib/bfd-plugins` ([source](https://bugs.archlinux.org/task/28479)), which can cause issues when using the system's linker for LTO (even with `LD_LIBRARY_PATH`): | ||
|
||
``` | ||
bfd plugin: LLVM gold plugin has failed to create LTO module: Unknown attribute kind (60) (Producer: 'LLVM9.0.0svn' Reader: 'LLVM 7.0.1') | ||
``` | ||
|
||
Having a standalone copy of binutils (ideally in the same folder at the LLVM toolchain so that one `PATH` modification is needed) works around this without any adverse side effects. Another workaround is bind mounting the new `LLVMgold.so` to `/usr/lib/LLVMgold.so`. | ||
|
||
## Getting help | ||
|
||
Please open an issue on this repo and include your distribution, shell, the command you ran, and the error output. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Usage: ./build-binutils.sh [options] | ||
|
||
Description: Fetchs and builds binutils | ||
|
||
Parameters: | ||
-I | --install-folder: | ||
By default, the script will create a "usr" folder in the same folder as this script | ||
and install binutils there. If you'd like to have it installed somewhere else, pass | ||
it to this parameter. This can either be an absolute or relative path. | ||
|
||
For example: -I ~/binutils | ||
|
||
-t | --target: | ||
The script can build binutils targeting arm-linux-gnueabi, aarch64-linux-gnu, | ||
powerpc-linux-gnu, powerpc64le-linux-gnu, and x86_64-linux-gnu (host if on x86_64). | ||
|
||
You can either pass the full target or just the first part (arm, aarch64, etc) or all | ||
if you want to build all targets. | ||
|
||
Example: -t all, -t aarch64, -t arm-linux-gnueabi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#!/usr/bin/env bash | ||
# shellcheck disable=SC2191 | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# Copyright (C) 2019 The ClangBuiltLinux Authors | ||
# Description: Builds a standalone copy of binutils | ||
|
||
|
||
# Properly set target if on x86_64 machine | ||
function x86_64_target() { | ||
if [[ $(uname -m) = "x86_64" ]]; then | ||
echo "host" | ||
else | ||
echo "x86_64-linux-gnu" | ||
fi | ||
} | ||
|
||
|
||
# Initialize helper functions and export current working directory for absolute paths later | ||
function script_setup { | ||
# Move into the folder that this script is called from (no message because this will never happen) | ||
cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" || exit | ||
source common.sh | ||
ROOT=${PWD} | ||
} | ||
|
||
|
||
# Parse the script parameters | ||
function parse_parameters() { | ||
TARGETS=() | ||
while (( ${#} )); do | ||
case ${1} in | ||
"-t"|"--target") | ||
shift | ||
[[ ${#} -lt 1 ]] && die "-t flag requires a value!" | ||
case ${1} in | ||
"all") TARGETS=( aarch64-linux-gnu arm-linux-gnueabi | ||
powerpc-linux-gnu powerpc64le-linux-gnu | ||
"$(x86_64_target)" ) ;; | ||
arm*) TARGETS+=( arm-linux-gnueabi ) ;; | ||
aarch64*) TARGETS+=( aarch64-linux-gnu ) ;; | ||
powerpc64le*) TARGETS+=( powerpc64-linux-gnu ) ;; | ||
powerpc*) TARGETS+=( powerpc-linux-gnu ) ;; | ||
x86*|"host") TARGETS+=( "$(x86_64_target)" ) ;; | ||
esac ;; | ||
"-h"|"--help") cat build-binutils-usage.txt; builtin exit 0 ;; | ||
*) die "Invalid parameter '${1}' specified! Run './build-binutils.sh -h' to see all options." ;; | ||
esac | ||
shift | ||
done | ||
[[ -z ${TARGETS[*]} ]] && die "No targets specified! Please run './build-binutils.sh' to see all the options." | ||
} | ||
|
||
|
||
# Setup the build folder | ||
function setup_build_folder() { | ||
BUILD_FOLDER=${ROOT}/build/binutils/${TARGET} | ||
rm -rf "${BUILD_FOLDER}" | ||
mkdir -p "${BUILD_FOLDER}" | ||
cd "${BUILD_FOLDER}" || die "Couldn't create build folder??" | ||
} | ||
|
||
|
||
# Configure binutils | ||
function configure_binutils() { | ||
COMMON_FLAGS=( --prefix="${INSTALL_FOLDER:="${ROOT}"/usr}" | ||
--enable-deterministic-archives | ||
--enable-gold | ||
--enable-ld=default | ||
--enable-plugins | ||
--quiet | ||
CFLAGS="-O2 -march=native -mtune=native" | ||
CXXFLAGS="-O2 -march=native -mtune=native" ) | ||
CONFIGURE=${ROOT}/${BINUTILS}/configure | ||
|
||
case ${TARGET} in | ||
arm-*|aarch64-*) | ||
"${CONFIGURE}" \ | ||
--disable-multilib \ | ||
--disable-nls \ | ||
--program-prefix="${TARGET}"- \ | ||
--target="${TARGET}" \ | ||
--with-gnu-as \ | ||
--with-gnu-ld \ | ||
--with-sysroot="${INSTALL_FOLDER}/${TUPLE}" \ | ||
"${COMMON_FLAGS[@]}" ;; | ||
powerpc*) | ||
"${CONFIGURE}" \ | ||
--enable-lto \ | ||
--enable-relro \ | ||
--enable-shared \ | ||
--enable-threads \ | ||
--disable-gdb \ | ||
--disable-sim \ | ||
--disable-werror \ | ||
--program-prefix="${TARGET}"- \ | ||
--target="${TARGET}" \ | ||
--with-pic \ | ||
--with-system-zlib \ | ||
"${COMMON_FLAGS[@]}" ;; | ||
x86*|host) | ||
"${CONFIGURE}" \ | ||
--enable-lto \ | ||
--enable-relro \ | ||
--enable-shared \ | ||
--enable-targets=x86_64-pep \ | ||
--enable-threads \ | ||
--disable-gdb \ | ||
--disable-werror \ | ||
"$([[ $(uname -m) != x86_64 ]] && echo "--program-prefix=${TARGET}- --target=${TARGET}")" \ | ||
--with-pic \ | ||
--with-system-zlib \ | ||
"${COMMON_FLAGS[@]}" | ||
[[ ${TARGET} = "host" ]] && make -s configure-host V=0 ;; | ||
esac | ||
} | ||
|
||
|
||
# Build binutils | ||
function build_binutils() { | ||
time make -s -j"$(nproc)" V=0 || die "Error building ${TARGET} binutils" | ||
} | ||
|
||
|
||
# Install binutils | ||
function install_binutils { | ||
make -s prefix="${INSTALL_FOLDER}" install V=0 || die "Error installing ${TARGET} binutils" | ||
} | ||
|
||
|
||
# Main for loop | ||
function for_all_targets() { | ||
for TARGET in "${TARGETS[@]}"; do | ||
setup_build_folder | ||
configure_binutils | ||
build_binutils | ||
install_binutils | ||
done | ||
} | ||
|
||
|
||
script_setup | ||
parse_parameters "${@}" | ||
dwnld_binutils | ||
for_all_targets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
Usage: ./build-llvm.sh [options] | ||
|
||
Description: Fetchs LLVM and binutils then builds a LLVM, clang, lld, and the LLVMgold plugin. | ||
|
||
Environment variables: | ||
The script can take into account specific environment variables. They can be | ||
invoked in one of three ways: | ||
$ export VAR=value && ./build-llvm.sh | ||
$ VAR=value ./build-llvm.sh | ||
$ ./build-llvm.sh VAR=value | ||
|
||
CC: | ||
Path to or name of the C compiler. If unset, the script will try to use | ||
clang if it is available, falling back to gcc if necessary. | ||
|
||
CXX: | ||
Path to or name of the C++ compiler. If unset, the script will use clang++ | ||
if CC is clang or g++ if CC is gcc. | ||
|
||
LD: | ||
Path to or name of the linker. If unset and using clang, the script will | ||
attempt to find ld.lld then ld.gold, falling back to ld.bfd (because they | ||
are objectively faster). | ||
|
||
Parameters: | ||
-b | --branch: | ||
By default, the script builds the master branch (tip of tree) of LLVM. If you would | ||
like to build an older branch, use this parameter. This may be helpful in tracking | ||
down an older bug to properly bisect. This value is just passed along to 'git checkout' | ||
so it can be a branch name, tag name, or hash. | ||
|
||
NOTE: Some of the cmake defines may not work on older branches! | ||
|
||
Example: -b release/8.x | ||
|
||
-d | --debug: | ||
By default, the script builds LLVM in the release configuration with all of | ||
the tests turned off and optimization at O2. This disables that optimization, | ||
builds the tests, and changes the configuration to debug. This can help with | ||
reporting problems to LLVM developers but will make compilation of both LLVM | ||
and the kernel go slower. | ||
|
||
-i | --incremental: | ||
By default, the script removes all build artifacts from previous compiles. This | ||
prevents that, allowing for dirty builds and faster compiles. | ||
|
||
-I | --install-folder: | ||
By default, the script will create a "usr" folder in the same folder as this script | ||
and install the LLVM toolchain there. If you'd like to have it installed somewhere | ||
else, pass it to this parameter. This can either be an absolute or relative path. | ||
|
||
Example: -I ~/llvm | ||
|
||
-n | --no-pull: | ||
By default, the script always updates the LLVM repo before building. This prevents | ||
that, which can be helpful during something like bisecting. | ||
|
||
-p | --projects: | ||
Currently, the script only enables the clang, compiler-rt, and lld folders in LLVM. If | ||
you would like to override this, you can use this parameter and supply a list that is | ||
supported by LLVM_ENABLE_PROJECTS. | ||
|
||
See step #5 here: https://llvm.org/docs/GettingStarted.html#getting-started-quickly-a-summary | ||
|
||
Example: -p "clang;lld;libcxx" | ||
|
||
-t | --targets: | ||
LLVM is multitargeted by default. Currently, this script only enables the arm32, aarch64, | ||
powerpc, and x86 backends because that's what the Linux kernel is currently concerned with. | ||
If you would like to override this, you can use this parameter and supply a list that is | ||
supported by LLVM_TARGETS_TO_BUILD: https://llvm.org/docs/CMake.html#llvm-specific-variables | ||
|
||
Example: -t "AArch64;X86" |
Oops, something went wrong.