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