sys-process/glances: 3.1.4.1-r1 amd64 stable, bug #720368
[gentoo.git] / eclass / llvm.eclass
1 # Copyright 1999-2020 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: llvm.eclass
5 # @MAINTAINER:
6 # Michał Górny <mgorny@gentoo.org>
7 # @AUTHOR:
8 # Michał Górny <mgorny@gentoo.org>
9 # @SUPPORTED_EAPIS: 6 7
10 # @BLURB: Utility functions to build against slotted LLVM
11 # @DESCRIPTION:
12 # The llvm.eclass provides utility functions that can be used to build
13 # against specific version of slotted LLVM (with fallback to :0 for old
14 # versions).
15 #
16 # This eclass does not generate dependency strings. You need to write
17 # a proper dependency string yourself to guarantee that appropriate
18 # version of LLVM is installed.
19 #
20 # Example use for a package supporting LLVM 5 to 7:
21 # @CODE
22 # inherit cmake-utils llvm
23 #
24 # RDEPEND="
25 #       <sys-devel/llvm-8:=
26 #       || (
27 #               sys-devel/llvm:7
28 #               sys-devel/llvm:6
29 #               sys-devel/llvm:5
30 #       )
31 # "
32 # DEPEND=${RDEPEND}
33 #
34 # LLVM_MAX_SLOT=7
35 #
36 # # only if you need to define one explicitly
37 # pkg_setup() {
38 #       llvm_pkg_setup
39 #       do-something-else
40 # }
41 # @CODE
42 #
43 # Example for a package needing LLVM+clang w/ a specific target:
44 # @CODE
45 # inherit cmake-utils llvm
46 #
47 # # note: do not use := on both clang and llvm, it can match different
48 # # slots then. clang pulls llvm in, so we can skip the latter.
49 # RDEPEND="
50 #       >=sys-devel/clang-6:=[llvm_targets_AMDGPU(+)]
51 # "
52 # DEPEND=${RDEPEND}
53 #
54 # llvm_check_deps() {
55 #       has_version -d "sys-devel/clang:${LLVM_SLOT}[llvm_targets_AMDGPU(+)]"
56 # }
57 # @CODE
58
59 case "${EAPI:-0}" in
60         0|1|2|3|4|5)
61                 die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
62                 ;;
63         6|7)
64                 ;;
65         *)
66                 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
67                 ;;
68 esac
69
70 EXPORT_FUNCTIONS pkg_setup
71
72 if [[ ! ${_LLVM_ECLASS} ]]; then
73
74 # make sure that the versions installing straight into /usr/bin
75 # are uninstalled
76 DEPEND="!!sys-devel/llvm:0"
77
78 # @ECLASS-VARIABLE: LLVM_MAX_SLOT
79 # @DEFAULT_UNSET
80 # @DESCRIPTION:
81 # Highest LLVM slot supported by the package. Needs to be set before
82 # llvm_pkg_setup is called. If unset, no upper bound is assumed.
83
84 # @ECLASS-VARIABLE: _LLVM_KNOWN_SLOTS
85 # @INTERNAL
86 # @DESCRIPTION:
87 # Correct values of LLVM slots, newest first.
88 declare -g -r _LLVM_KNOWN_SLOTS=( 11 10 9 8 )
89
90 # @FUNCTION: get_llvm_prefix
91 # @USAGE: [-b|-d] [<max_slot>]
92 # @DESCRIPTION:
93 # Find the newest LLVM install that is acceptable for the package,
94 # and print an absolute path to it.
95 #
96 # If -b is specified, the checks are performed relative to BROOT,
97 # and BROOT-path is returned.  This is appropriate when your package
98 # calls llvm-config executable.  -b is supported since EAPI 7.
99 #
100 # If -d is specified, the checks are performed relative to ESYSROOT,
101 # and ESYSROOT-path is returned.  This is appropriate when your package
102 # uses CMake find_package(LLVM).  -d is the default.
103 #
104 # If <max_slot> is specified, then only LLVM versions that are not newer
105 # than <max_slot> will be considered. Otherwise, all LLVM versions would
106 # be considered acceptable. The function does not support specifying
107 # minimal supported version -- the developer must ensure that a version
108 # new enough is installed via providing appropriate dependencies.
109 #
110 # If llvm_check_deps() function is defined within the ebuild, it will
111 # be called to verify whether a particular slot is accepable. Within
112 # the function scope, LLVM_SLOT will be defined to the SLOT value
113 # (0, 4, 5...). The function should return a true status if the slot
114 # is acceptable, false otherwise. If llvm_check_deps() is not defined,
115 # the function defaults to checking whether sys-devel/llvm:${LLVM_SLOT}
116 # is installed.
117 get_llvm_prefix() {
118         debug-print-function ${FUNCNAME} "${@}"
119
120         local hv_switch=-d
121         while [[ ${1} == -* ]]; do
122                 case ${1} in
123                         -b|-d) hv_switch=${1};;
124                         *) break;;
125                 esac
126                 shift
127         done
128
129         local prefix=
130         if [[ ${EAPI} != 6 ]]; then
131                 case ${hv_switch} in
132                         -b)
133                                 prefix=${BROOT}
134                                 ;;
135                         -d)
136                                 prefix=${ESYSROOT}
137                                 ;;
138                 esac
139         else
140                 case ${hv_switch} in
141                         -b)
142                                 die "${FUNCNAME} -b is not supported in EAPI ${EAPI}"
143                                 ;;
144                         -d)
145                                 prefix=${EPREFIX}
146                                 hv_switch=
147                                 ;;
148                 esac
149         fi
150
151         local max_slot=${1}
152         local slot
153         for slot in "${_LLVM_KNOWN_SLOTS[@]}"; do
154                 # skip higher slots
155                 if [[ -n ${max_slot} ]]; then
156                         if [[ ${max_slot} == ${slot} ]]; then
157                                 max_slot=
158                         else
159                                 continue
160                         fi
161                 fi
162
163                 if declare -f llvm_check_deps >/dev/null; then
164                         local LLVM_SLOT=${slot}
165                         llvm_check_deps || continue
166                 else
167                         # check if LLVM package is installed
168                         has_version ${hv_switch} "sys-devel/llvm:${slot}" || continue
169                 fi
170
171                 echo "${prefix}/usr/lib/llvm/${slot}"
172                 return
173         done
174
175         # max_slot should have been unset in the iteration
176         if [[ -n ${max_slot} ]]; then
177                 die "${FUNCNAME}: invalid max_slot=${max_slot}"
178         fi
179
180         die "No LLVM slot${1:+ <= ${1}} found installed!"
181 }
182
183 # @FUNCTION: llvm_pkg_setup
184 # @DESCRIPTION:
185 # Prepend the appropriate executable directory for the newest
186 # acceptable LLVM slot to the PATH. For path determination logic,
187 # please see the get_llvm_prefix documentation.
188 #
189 # The highest acceptable LLVM slot can be set in LLVM_MAX_SLOT variable.
190 # If it is unset or empty, any slot is acceptable.
191 #
192 # The PATH manipulation is only done for source builds. The function
193 # is a no-op when installing a binary package.
194 #
195 # If any other behavior is desired, the contents of the function
196 # should be inlined into the ebuild and modified as necessary.
197 llvm_pkg_setup() {
198         debug-print-function ${FUNCNAME} "${@}"
199
200         if [[ ${MERGE_TYPE} != binary ]]; then
201                 local llvm_path=$(get_llvm_prefix "${LLVM_MAX_SLOT}")/bin
202                 local IFS=:
203                 local split_path=( ${PATH} )
204                 local new_path=()
205                 local x added=
206
207                 # prepend new path before first LLVM version found
208                 for x in "${split_path[@]}"; do
209                         if [[ ${x} == */usr/lib/llvm/*/bin ]]; then
210                                 if [[ ${x} != ${llvm_path} ]]; then
211                                         new_path+=( "${llvm_path}" )
212                                 elif [[ ${added} && ${x} == ${llvm_path} ]]; then
213                                         # deduplicate
214                                         continue
215                                 fi
216                                 added=1
217                         fi
218                         new_path+=( "${x}" )
219                 done
220                 # ...or to the end of PATH
221                 [[ ${added} ]] || new_path+=( "${llvm_path}" )
222
223                 export PATH=${new_path[*]}
224         fi
225 }
226
227 _LLVM_ECLASS=1
228 fi