aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Gupta <manojgupta@google.com>2018-08-02 13:42:29 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-08-02 21:50:23 -0700
commit4a3dce09b5295b0d21129ec68660b96dfb3776e5 (patch)
treec7efe92dd048d030f16e06a8afefffebe8596887
parent49b1436c7639311adedc26d0f4982429f33f2f43 (diff)
downloadtoolchain-utils-4a3dce09b5295b0d21129ec68660b96dfb3776e5.tar.gz
toolchain-utils: Add a tool to create llvm-extra ebuild.
llvm-extra ebuild is a slotted llvm compiler ebuild that can be installed in parallel to the regualr llvm compiler. Use of llvm-extra package is to provide an alternate clang in case the normal clang compiler binary can't be used. e.g. After a llvm upgrade, some package foo is miscompiled. To avoid the miscompilation, we can use llvm-extra ebuild to install the previous clang. To use the clang installed by llvm-extra, modify the CFLAGS and LDFLAGS to pass the patch of the clang binary installed by llvm-extra package. e.g. append-flags -Xclang-path=/usr/llvm-extra/version/clang append-ldflags -Xclang-path=/usr/llvm-extra/version/clang This CL only adds the tool that can generate the llvm-extra ebuilds from a given llvm ebuild. BUG=chromium:773887 TEST= ./create_llvm_extra.sh /path/to/llvm/llvm-7.0_pre331547_p20180529-r8.ebuild worked. A new llvm-extra ebuild was generated. Change-Id: I7e3e20a2740f5e7135dbcd252cc271945c6ddd34 Reviewed-on: https://chromium-review.googlesource.com/1161213 Commit-Ready: Manoj Gupta <manojgupta@chromium.org> Tested-by: Manoj Gupta <manojgupta@chromium.org> Reviewed-by: Caroline Tice <cmtice@chromium.org>
-rwxr-xr-xllvm_extra/create_ebuild_file.py156
-rwxr-xr-xllvm_extra/create_llvm_extra.sh88
2 files changed, 244 insertions, 0 deletions
diff --git a/llvm_extra/create_ebuild_file.py b/llvm_extra/create_ebuild_file.py
new file mode 100755
index 00000000..459e702a
--- /dev/null
+++ b/llvm_extra/create_ebuild_file.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python2
+
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from __future__ import print_function
+
+import os
+import sys
+
+# This script takes an existing host llvm compiler ebuild and
+# creates another build that should be installable in a prefixed location.
+# The script patches a few lines in the llvm ebuild to make that happen.
+#
+# Since the script is based on the current llvm ebuild patterns,
+# it may need to be updated if those patterns change.
+#
+# This script should normally be invoked by the shell script
+# create_llvm_extra.sh .
+
+"""
+Below is an example of the expected diff of the newly generated ebuild with
+some explanation of the diffs.
+
+diff -Nuar llvm-pre7.0_pre335547_p20180529.ebuild newly-created-file.ebuild
+--- llvm-7.0_pre331547_p20180529-r8.ebuild
++++ newly-created-file.ebuild
+
+@@ -60,9 +60,9 @@ EGIT_REPO_URIS=(
+ fi
+
+ LICENSE="UoI-NCSA"
+-SLOT="0/${PV%%_*}"
++SLOT="${PV%%_p[[:digit:]]*}" # Creates a unique slot so that multiple copies
+ of the new build can be installed.
+
+ KEYWORDS="-* amd64"
+
+ # Change USE flags to match llvm ebuild installtion. To see the set of flags
+ enabled in llvm compiler ebuild, run $ sudo emerge -pv llvm
+
+-IUSE="debug +default-compiler-rt +default-libcxx doc libedit +libffi multitarget
++IUSE="debug +default-compiler-rt +default-libcxx doc libedit +libffi +multitarget
+ ncurses ocaml python llvm-next llvm-tot test xml video_cards_radeon"
+
+ COMMON_DEPEND="
+@@ -145,6 +145,7 @@ pkg_pretend() {
+ }
+
+ pkg_setup() {
+ # This Change is to install the files in $PREFIX.
++ export PREFIX="/usr/${PN}/${SLOT}"
+ pkg_pretend
+ }
+
+@@ -272,13 +273,13 @@
+ sed -e "/RUN/s/-warn-error A//" -i test/Bindings/OCaml/*ml || die
+
+ # Allow custom cmake build types (like 'Gentoo')
+ # Convert use of PN to llvm in epatch commands.
+- epatch "${FILESDIR}"/cmake/${PN}-3.8-allow_custom_cmake_build_types.patch
++ epatch "${FILESDIR}"/cmake/llvm-3.8-allow_custom_cmake_build_types.patch
+
+ # crbug/591436
+ epatch "${FILESDIR}"/clang-executable-detection.patch
+
+ # crbug/606391
+- epatch "${FILESDIR}"/${PN}-3.8-invocation.patch
++ epatch "${FILESDIR}"/llvm-3.8-invocation.patch
+
+@@ -411,11 +412,14 @@ src_install() {
+ /usr/include/llvm/Config/llvm-config.h
+ )
+
++ MULTILIB_CHOST_TOOLS=() # No need to install any multilib tools/headers.
++ MULTILIB_WRAPPED_HEADERS=()
+ multilib-minimal_src_install
+ }
+
+ multilib_src_install() {
+ cmake-utils_src_install
++ return # No need to install any wrappers.
+
+ local wrapper_script=clang_host_wrapper
+ cat "${FILESDIR}/clang_host_wrapper.header" \
+@@ -434,6 +438,7 @@ multilib_src_install() {
+ }
+
+ multilib_src_install_all() {
++ return # No need to install common multilib files.
+ insinto /usr/share/vim/vimfiles
+ doins -r utils/vim/*/.
+ # some users may find it useful
+"""
+
+def process_line(line, text):
+ # Process the line and append to the text we want to generate.
+ # Check if line has any patterns that we want to handle.
+ newline = line.strip()
+ if newline.startswith('#'):
+ # Do not process comment lines.
+ text.append(line)
+ elif line.startswith('SLOT='):
+ # Change SLOT to "${PV%%_p[[:digit:]]*}"
+ SLOT_STRING='SLOT="${PV%%_p[[:digit:]]*}"\n'
+ text.append(SLOT_STRING)
+ elif line.startswith('IUSE') and 'multitarget' in line:
+ # Enable multitarget USE flag.
+ newline = line.replace('multitarget', '+multitarget')
+ text.append(newline)
+ elif line.startswith('pkg_setup()'):
+ # Setup PREFIX.
+ text.append(line)
+ text.append('\texport PREFIX="/usr/${PN}/${SLOT}"\n')
+ elif line.startswith('multilib_src_install_all()'):
+ text.append(line)
+ # Do not install any common files.
+ text.append('\treturn\n')
+ elif 'epatch ' in line:
+ # Convert any $PN or ${PN} in epatch files to llvm.
+ newline = line.replace('$PN', 'llvm')
+ newline = newline.replace('${PN}', 'llvm')
+ text.append(newline)
+ elif 'multilib-minimal_src_install' in line:
+ # Disable MULTILIB_CHOST_TOOLS and MULTILIB_WRAPPED_HEADERS
+ text.append('\tMULTILIB_CHOST_TOOLS=()\n')
+ text.append('\tMULTILIB_WRAPPED_HEADERS=()\n')
+ text.append(line)
+ elif 'cmake-utils_src_install' in line:
+ text.append(line)
+ # Do not install any wrappers.
+ text.append('\treturn\n')
+ else:
+ text.append(line)
+
+
+def main():
+ if len(sys.argv) != 3:
+ filename = os.path.basename(__file__)
+ print ('Usage: ', filename,' <input.ebuild> <output.ebuild>')
+ return 1
+
+ text = []
+ with open(sys.argv[1], 'r') as infile:
+ for line in infile:
+ process_line(line, text)
+
+ with open(sys.argv[2], 'w') as outfile:
+ outfile.write("".join(text))
+
+ return 0
+
+
+if __name__== "__main__":
+ sys.exit(main())
diff --git a/llvm_extra/create_llvm_extra.sh b/llvm_extra/create_llvm_extra.sh
new file mode 100755
index 00000000..6f34a0b2
--- /dev/null
+++ b/llvm_extra/create_llvm_extra.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This script takes an existing llvm ebuild file and generate a llvm-extra
+# ebuild. The newly generated llvm-extra ebuild can be installed as a regular
+# host package.
+# The new ebuild should be generated in sys-devel/llvm-extra directory.
+# The script also copies all the files from files/ directory.
+# The generated llvm-extra ebuild is slotted so multiple instances of
+# llvm-extra ebuilds can be installed at same time.
+# The slot is derived based on the _pre<num> string in the llvm ebuild name.
+# e.g. For llvm-7.0_pre331547_p20180529-r8.ebuild, the slot will be
+# 7.0_pre331547.
+#
+# Usage:
+# ./create_llvm_extra.sh /path/to/llvm-7.0_pre331547_p20180529-r8.ebuild
+#
+# To use the clang installed by llvm-extra, modify the CFLAGS and
+# LDFLAGS of a pckage to pass the patch of the clang binary installed by
+# the llvm-extra package.
+# e.g. append-flags -Xclang-path=/usr/llvm-extra/version/clang
+# append-ldflags -Xclang-path=/usr/llvm-extra/version/clang
+#
+
+SCRIPT_DIR=$(realpath $(dirname "$0"))
+
+function check_cmd() {
+ if [[ "$#" -ne 1 ]]; then
+ echo "Exactly 1 argument expected"
+ echo "Usage $0 <path_to_llvm_ebuild>"
+ exit 1
+ fi
+ if [[ ! -f "$1" ]]; then
+ echo "$1 is not a file"
+ exit 1;
+ fi
+}
+
+function create_llvm_extra_ebuild() {
+ EBUILD_PREFIX=llvm-extra
+ EBUILD_DIR=$(dirname "$1")
+ EBUILD_FILE_NAME=$(basename "$1")
+ NEW_EBUILD_FILE_NAME="${EBUILD_FILE_NAME/llvm/$EBUILD_PREFIX}"
+ NEW_EBUILD_FILENAME_NO_EXT="${NEW_EBUILD_FILE_NAME%.*}"
+ NEW_EBUILD_DIR="${EBUILD_DIR}/../${EBUILD_PREFIX}"
+ NEW_EBUILD_PV="${NEW_EBUILD_FILENAME_NO_EXT#"$EBUILD_PREFIX-"}"
+ NEW_EBUILD_SLOT="${NEW_EBUILD_PV%%_p[[:digit:]]*}"
+
+ mkdir -p "${NEW_EBUILD_DIR}"
+ if [[ -d "${EBUILD_DIR}/files" ]]; then
+ cp -rf "${EBUILD_DIR}/files" "${NEW_EBUILD_DIR}"
+ fi
+
+ if [[ -f "${NEW_EBUILD_DIR}/${NEW_EBUILD_FILE_NAME}" ]]; then
+ echo "Removing existing ebuild file ${NEW_EBUILD_FILE_NAME}"
+ rm -f "${NEW_EBUILD_DIR}/${NEW_EBUILD_FILE_NAME}"
+ fi
+ # Generate the llvm-extra ebuild file.
+ "${SCRIPT_DIR}"/create_ebuild_file.py "$1" "${NEW_EBUILD_DIR}/${NEW_EBUILD_FILE_NAME}"
+ if [[ $? -ne 0 ]]; then
+ echo "Creation of ${NEW_EBUILD_DIR}/${NEW_EBUILD_FILE_NAME} failed"
+ exit 1
+ fi
+ echo "***"
+ echo "***"
+ echo "${NEW_EBUILD_DIR}/${NEW_EBUILD_FILE_NAME} has been created."
+
+ echo "***"
+ echo "Test if it builds by running \$ sudo emerge ${EBUILD_PREFIX}:${NEW_EBUILD_SLOT}"
+ echo "***"
+ echo "If it works, Go ahead and submit the newly generated ebuild"\
+ "and any other files in ${NEW_EBUILD_DIR}."
+ echo "***"
+ echo "Don't forget to add sys-devel/${EBUILD_PREFIX}:${NEW_EBUILD_SLOT} to"\
+ "the dependencies in virtual/target-chromium-os-sdk ebuild."
+ echo "***"
+ echo "***"
+}
+
+
+set -e
+# Sanity checks.
+check_cmd "${@}"
+# Create llvm-extra ebuild.
+create_llvm_extra_ebuild "${@}"