1#!/usr/bin/env python2
2
3# Copyright 2018 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7from __future__ import print_function
8
9import os
10import sys
11
12# This script takes an existing host llvm compiler ebuild and
13# creates another build that should be installable in a prefixed location.
14# The script patches a few lines in the llvm ebuild to make that happen.
15#
16# Since the script is based on the current llvm ebuild patterns,
17# it may need to be updated if those patterns change.
18#
19# This script should normally be invoked by the shell script
20# create_llvm_extra.sh .
21
22"""
23Below is an example of the expected diff of the newly generated ebuild with
24some explanation of the diffs.
25
26diff -Nuar llvm-pre7.0_pre335547_p20180529.ebuild newly-created-file.ebuild
27--- llvm-7.0_pre331547_p20180529-r8.ebuild
28+++ newly-created-file.ebuild
29
30@@ -60,9 +60,9 @@ EGIT_REPO_URIS=(
31 fi
32
33 LICENSE="UoI-NCSA"
34-SLOT="0/${PV%%_*}"
35+SLOT="${PV%%_p[[:digit:]]*}" # Creates a unique slot so that multiple copies
36                                of the new build can be installed.
37
38 KEYWORDS="-* amd64"
39
40 # Change USE flags to match llvm ebuild installtion. To see the set of flags
41 enabled in llvm compiler ebuild, run $ sudo emerge -pv llvm
42
43-IUSE="debug +default-compiler-rt +default-libcxx doc libedit +libffi multitarget
44+IUSE="debug +default-compiler-rt +default-libcxx doc libedit +libffi +multitarget
45        ncurses ocaml python llvm-next llvm-tot test xml video_cards_radeon"
46
47 COMMON_DEPEND="
48@@ -145,6 +145,7 @@ pkg_pretend() {
49 }
50
51 pkg_setup() {
52 # This Change is to install the files in $PREFIX.
53+       export PREFIX="/usr/${PN}/${SLOT}"
54        pkg_pretend
55 }
56
57@@ -272,13 +273,13 @@
58        sed -e "/RUN/s/-warn-error A//" -i test/Bindings/OCaml/*ml  || die
59
60        # Allow custom cmake build types (like 'Gentoo')
61 # Convert use of PN to llvm in epatch commands.
62-       epatch "${FILESDIR}"/cmake/${PN}-3.8-allow_custom_cmake_build_types.patch
63+       epatch "${FILESDIR}"/cmake/llvm-3.8-allow_custom_cmake_build_types.patch
64
65        # crbug/591436
66        epatch "${FILESDIR}"/clang-executable-detection.patch
67
68        # crbug/606391
69-       epatch "${FILESDIR}"/${PN}-3.8-invocation.patch
70+       epatch "${FILESDIR}"/llvm-3.8-invocation.patch
71
72@@ -411,11 +412,14 @@ src_install() {
73                /usr/include/llvm/Config/llvm-config.h
74        )
75
76+       MULTILIB_CHOST_TOOLS=() # No need to install any multilib tools/headers.
77+       MULTILIB_WRAPPED_HEADERS=()
78        multilib-minimal_src_install
79 }
80
81 multilib_src_install() {
82        cmake-utils_src_install
83+       return # No need to install any wrappers.
84
85        local wrapper_script=clang_host_wrapper
86        cat "${FILESDIR}/clang_host_wrapper.header" \
87@@ -434,6 +438,7 @@ multilib_src_install() {
88 }
89
90 multilib_src_install_all() {
91+       return # No need to install common multilib files.
92        insinto /usr/share/vim/vimfiles
93        doins -r utils/vim/*/.
94        # some users may find it useful
95"""
96
97def process_line(line, text):
98  # Process the line and append to the text we want to generate.
99  # Check if line has any patterns that we want to handle.
100  newline = line.strip()
101  if newline.startswith('#'):
102    # Do not process comment lines.
103    text.append(line)
104  elif line.startswith('SLOT='):
105    # Change SLOT to "${PV%%_p[[:digit:]]*}"
106    SLOT_STRING='SLOT="${PV%%_p[[:digit:]]*}"\n'
107    text.append(SLOT_STRING)
108  elif line.startswith('IUSE') and 'multitarget' in line:
109    # Enable multitarget USE flag.
110    newline = line.replace('multitarget', '+multitarget')
111    text.append(newline)
112  elif line.startswith('pkg_setup()'):
113    # Setup PREFIX.
114    text.append(line)
115    text.append('\texport PREFIX="/usr/${PN}/${SLOT}"\n')
116  elif line.startswith('multilib_src_install_all()'):
117    text.append(line)
118    # Do not install any common files.
119    text.append('\treturn\n')
120  elif 'epatch ' in line:
121    # Convert any $PN or ${PN} in epatch files to llvm.
122    newline = line.replace('$PN', 'llvm')
123    newline = newline.replace('${PN}', 'llvm')
124    text.append(newline)
125  elif 'multilib-minimal_src_install' in line:
126    # Disable MULTILIB_CHOST_TOOLS and MULTILIB_WRAPPED_HEADERS
127    text.append('\tMULTILIB_CHOST_TOOLS=()\n')
128    text.append('\tMULTILIB_WRAPPED_HEADERS=()\n')
129    text.append(line)
130  elif 'cmake-utils_src_install' in line:
131    text.append(line)
132    # Do not install any wrappers.
133    text.append('\treturn\n')
134  else:
135    text.append(line)
136
137
138def main():
139  if len(sys.argv) != 3:
140     filename = os.path.basename(__file__)
141     print ('Usage: ', filename,' <input.ebuild> <output.ebuild>')
142     return 1
143
144  text = []
145  with open(sys.argv[1], 'r') as infile:
146    for line in infile:
147      process_line(line, text)
148
149  with open(sys.argv[2], 'w') as outfile:
150    outfile.write("".join(text))
151
152  return 0
153
154
155if __name__== "__main__":
156  sys.exit(main())
157