Gentoo Archives: gentoo-dev

From: Adrian Grigo <agrigo2001@×××××××××.au>
To: "gentoo-dev@l.g.o" <gentoo-dev@l.g.o>
Subject: [gentoo-dev] New eclass: openvdb.eclass
Date: Wed, 27 May 2020 01:40:13
Message-Id: 1055740577.138748.1590543604542@mail.yahoo.com
1 Hello, I am a proxied maintainer of blender and openvdb and wish to propose a new eclass and USE_EXPAND variable to ensure the same version of the openvdb abi is used when building the blender, openvdb and openimageio packages.
2
3 The tree currently contains openvdb 4 and 5, and I plan to add 6 and 7 soon to support my new blender PR. Each major release of openvdb has a new ABI, and can also support legacy versions. However only one version can be built at a time, which is passed to cmake through OPENVDB_ABI_VERSION_NUMBER, and produces a library with functions named xxx_7abi5 when building openvdb 7 with support for abi 5. Client packages like blender and openimageio which depend on openvdb and also need to be compiled with the same version number in order to link correctly.
4
5 To enforce this I propose to add a new USE_EXPAND variable called OPENVDB_ABI, which is set to the version number the user wants to use in the system eg 5, which expands to openvdb_abi_5. The packages can then append -DOPENVDB_ABI_VERSION_NUMBER=${OPENVDB_ABI} to ensure they pass the same value to cmake.
6
7 To reduce the boilerplate code required to ensure that only one supported value is set in OPENVDB_ABI and used by all packages, so I propose to add an eclass to maintain this in one place. Similar to PYTHON_COMPAT, each ebuilds set OPENVDB_COMPAT to specify which legacy ABI they can support. The openvdb.eclass uses it to set global variables OPENVDB_REQUIRED_USE and OPENVDB_SINGLE_USEDEP and verify in pkg_prepare that only one of the openvdb_abi_X flags is set.
8
9 Each ebuild sets REQUIRED_USE="${OPENVDB_REQUIRED_USE}" which evaluates to ^^ ( openvdb_abi_3 openvdb_abi_4 ... ) to ensure only one abi is enabled from those it supports.
10 They set RDEPEND="openvdb? ( media-gfx/openvdb[${OPENVDB_SINGLE_USEDEP}] )" which evaluates to openvdb_abi_3(-)?,openvdb_abi_4(-)?,... to allow portage to enforce the same abi version is built between all packages.
11
12 With a new release of openvdb, I will only need to add it to the openvdb_abi.desc file, to an eclass internal list _OPENVDB_ALL_ABI, and to OPENVDB_COMPAT for each ebuild which supports the new version.
13
14 Please review my proposed eclass below. I have tested it works when OPENVDB_ABI is missing, set to invalid values, or set to values that cannot satisfy all package requirements simultaneously, and that the system recompiles all packages when the ABI is changed. It also works when set to appropriate values.
15
16 I considered other alternatives during development. It is possible to manually add the expanded REQUIRED_USE and RDEPEND strings to each package, but with each new version of openvdb and multiple client packages to maintain this becomes messy and error prone. The user also needs to set the same openvdb_abi_X flag for each package. While currently there are only three packages which need to be synchronised, any other package which depends on openvdb in future will benefit from this infrastructure.
17
18 Also without the USE_EXPAND variable the ebuilds do not have access to the version number to pass to the build system, and need to generate it by testing each USE flag. So I think this is the cleanest solution.
19
20 I also looked into slotting openvdb as then packages could specify the slot/subslot required eg openvdb:7/5 but don't think this is possible. This would be a major undertaking as it has a static as well as dynamic core library, another library for python, and the cmake modules that find openvdb use the output of a binary at /usr/bin/vdb_print to determine which version to link against. It would also not centralise the boilerplate code.
21
22 For further information and my discussion during development see https://github.com/redchillipadi/ebuild-overlay/issues/4
23
24 Please let me know if there is a better solution or improvements are required.
25
26 Kind Regards,
27 Adrian Grigo
28
29
30 # Copyright 1999-2020 Gentoo Authors
31 # Distributed under the terms of the GNU General Public License v2
32
33 # @ECLASS: openvdb.eclass
34 # @MAINTAINER:
35 # Adrian Grigo <agrigo2001@×××××××××.au>
36 # @ AUTHOR:
37 # Author: Adrian Grigo <agrigo2001@×××××××××.au>
38 # Based on work of: Michał Górny <mgorny@g.o> and Krzysztof Pawlik <nelchael@g.o>
39 # @SUPPORTED_EAPIS: 5 6 7
40 # @BLURB: An eclass for OpenVDB to control which ABI version is compiled
41 # @DESCRIPTION:
42 # The OpenVDB package is a library for sorting and manipulating sparse
43 # data structures with dynamic topology as required for use in volume
44 # rendering for computer graphics.
45 #
46 # Each major version of OpenVDB provides an updated ABI, as well as
47 # the ability to compile using a legacy version of the ABI.
48 # Openvdb 7 can be compiled to support version 5, 6 or 7 of the ABI.
49 #
50 # However the user needs to choose at compile time which version to
51 # build by passing OPENVDB_ABI_VERSION_NUMBER="5" to cmake.
52 # It is not possible to support multiple versions concurrently
53 # so OpenVDB and all packages depending upon it must be built for the
54 # same ABI version. This currently means blender and openvdb, and
55 # will also include >=openimageio-2.0 once it is updated
56 #
57 # The client packages have differing requirements for the ABI support.
58 # For example,
59 # Openvdb-7 supports 5-7 (older version provide ABI 3 and 4 support)
60 # Blender supports ABI 4-7
61 # Openimageio-2.0 supports ABI 5-7.
62 #
63 # To use this eclass, the user should first select which ABI to build
64 # and set OPENVDB_ABI USE_EXPAND variable in make.conf.
65 #
66 # When the client package inherits this eclass, it can use the
67 # OPENVDB_COMPAT variable in the ebuild to specify which ABI it
68 # supports, and then use the OPENVDB_SINGLE_USEDEP variable that the
69 # eclass produces to force the package to link using ABI selected in
70 # OPENVDB_ABI
71 # eg. openvdb? ( media-gfx/openvdb[${OPENVDB_SINGLE_USEDEP}] )
72 # When OPENVDB_COMPAT="X Y" the variable evaluates to
73 # openvdb_abi_X(-)? openvdb_abi_Y(-)?
74 #
75 # The client can pass the ABI version to the build system as follows:
76 # append-cppflags -DOPENVDB_ABI_VERSION_NUMBER="${OPENVDB_ABI}"
77 #
78 # This eclass includes pkg_setup which ensures that the package will
79 # only compile if only one openvdb_abi_X USE flag is set
80 #
81 # @EXAMPLE:
82 # The user needs to choose which version of the ABI supports all packages
83 # they plan to install. This is then stored in a variable in make.conf
84 # eg. OPENVDB_ABI="5" in /etc/portage/make.conf
85 #
86 # The client packages need to:
87 # - inherit this eclass.
88 # - list the ABI supported by the package in OPENVDB_COMPAT.
89 # - use OPENVDB_REQUIRED_USE to ensure that only one of the
90 #   compatible ABI can be selected by the ebuild.
91 # - include OPENVDB_SINGLE_USEDEP in RDEPEND to ensure any
92 #   dependencies build against a similar ABI.
93 # - pass the OPENVDB_ABI version to the package build system
94 #
95 # @CODE
96 # inherit openvdb
97 # OPENVDB_COMPAT=( 4 5 6 7 )
98 # REQUIRED_USE="openvdb? ( ${OPENVDB_REQUIRED_USE} )"
99 # RDEPEND="openvdb? ( media-gfx/openvdb[${OPENVDB_SINGLE_USEDEP}] )"
100 #
101 # src_configure() {
102 #   append-cppflags -DOPENVDB_ABI_VERSION_NUMBER="${OPENVDB_ABI_VERSION}"
103 #   ...
104 #   cmake-utils_src_configure
105 # }
106 # @CODE
107
108 case "${EAPI:-0}" in
109     0|1|2|3|4)
110         die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
111         ;;
112     5|6|7)
113         # EAPI=5 is required for sane USE_EXPAND dependencies
114         ;;
115     *)
116         die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
117         ;;
118 esac
119
120 EXPORT_FUNCTIONS pkg_setup
121
122 # @ECLASS-VARIABLE: OPENVDB_COMPAT
123 # @REQUIRED
124 # @DESCRIPTION:
125 # This variable contains a list of OpenVDB ABI the package supports.
126 # It must be set before the 'inherit' call and has to be an array.
127 #
128 # Example use:
129 # @CODE
130 # OPENVDB_COMPAT=( 4 5 6 7 )
131 # @CODE
132 #
133
134 # @ECLASS-VARIABLE: OPENVDB_SINGLE_USEDEP
135 # @DESCRIPTION:
136 # This is an eclass generated USE-dependency flag which can be used by
137 # any package depending on openvdb to ensure the correct ABI version
138 # support is built.
139 #
140 # Example use:
141 # @CODE
142 # RDEPEND="openvdb? ( media-gfx/openvdb[${OPENVDB_SINGLE_USEDEP}] )"
143 # @CODE
144 #
145 # Example value:
146 # @CODE
147 # openvdb_abi_3(-)?,openvdb_abi_4(-)?,openvdb_abi_5(-)?...
148 # @CODE
149
150 # @ECLASS-VARIABLE: OPENVDB_REQUIRED_USE
151 # @DESCRIPTION:
152 # This is an eclass-generated required use expression which ensures
153 # that exactly one openvdb_use_X value has been enabled.
154 #
155 # Example use:
156 # @CODE
157 # REQUIRED_USE="${OPENVDB_REQUIRED_USE}"
158 # @CODE
159 #
160 # Example value:
161 # @CODE
162 # ^^ ( openvdb_abi_3 openvdb_abi_4 openvdb_abi_5 openvdb_abi_6 openvdb_abi_7)
163 # @CODE
164
165 # @ECLASS-VARIABLE: _OPENVDB_ALL_ABI
166 # @INTERNAL
167 # @DESCRIPTION:
168 # All supported OpenVDB ABI
169 # Update this with each new major version release of OpenVDB
170 _OPENVDB_ALL_ABI=(
171     3 4 5 6 7
172 )
173 readonly _OPENVDB_ALL_ABI
174
175 # @FUNCTION: _openvdb_set_globals
176 # @INTERNAL
177 # @DESCRIPTION:
178 # Ensure that OPENVDB_COMPAT is valid and generate the
179 # OPENVDB_REQUIRED_USE and OPENVDB_SINGLE_USEDEP global variables for
180 # use by the inheriting ebuild
181 _openvdb_set_globals() {
182     local i
183
184     if ! declare -p OPENVDB_COMPAT &>/dev/null; then
185         die 'OPENVDB_COMPAT not declared.'
186     fi
187
188     if [[ $(declare -p OPENVDB_COMPAT) != "declare -a"* ]]; then
189         die 'OPENVDB_COMPAT must be an array.'
190     fi
191
192     local flags=()
193         for i in "${_OPENVDB_ALL_ABI[@]}"; do
194         if has "${i}" "${OPENVDB_COMPAT[@]}"; then
195             flags+=( "openvdb_abi_${i}" )
196         fi
197         done
198
199     if [[ ${#supp[@]} -eq 1 ]]; then
200         IUSE="+${flags[0]}"
201     else
202         IUSE="${flags[*]}"
203     fi
204
205     if [[ ! ${#flags[@]} ]]; then
206         die "No supported OpenVDB ABI in OPENVDB_COMPAT."
207     fi
208
209     local single_flags="${flags[@]/%/(-)?}"
210     local single_usedep=${single_flags// /,}
211
212     OPENVDB_REQUIRED_USE="^^ ( ${flags[*]} )"
213     OPENVDB_SINGLE_USEDEP="${single_usedep}"
214     readonly OPENVDB_REQUIRED_USE OPENVDB_SINGLE_USEDEP
215 }
216 _openvdb_set_globals
217 unset -f _openvdb_set_globals
218
219 if [[ ! ${_OPENVDB} ]]; then
220
221 # @FUNCTION: openvdb_setup
222 # @DESCRIPTION
223 # Ensure one and only one OpenVDB ABI version is selected
224 openvdb_setup() {
225     debug-print-function ${FUNCNAME} "${@}"
226
227     local i, version
228     for i in "${_OPENVDB_ABI[@]}"; do
229         if use "openvdb_abi_${i}"; then
230             if [[ ${version} ]]; then
231                 eerror "Your OPENVDB_ABI setting lists more than a single OpenVDB"
232                 eerror "ABI version. Please set it to just one value."
233                 echo
234                 die "More than one ABI in OPENVDB_ABI."
235             fi
236         fi
237
238         version="${i}"
239         echo "Using OpenVDB ABI ${version} to build"
240     done
241
242     if [[ ! ${version} ]]; then
243         eerror "No OpenVDB ABI Version selected for the system. Please set"
244         eerror "the OPENVDB_ABI variable in your make.conf to one"
245         eerror "of the values contained in all of:"
246         eerror
247         eerror "- the entire list of ABI: ${_OPENVDB_ALL_ABI[*]}"
248         eerror "- the ABI supported by this package: ${OPENVDB_COMPAT}"
249         eerror "- and the ABI supported by all other packages on your system"
250         echo
251         die "No supported OpenVDB ABI version in OPENVDB_ABI."
252     fi
253 }
254
255 # @FUNCTION: openvdb_pkg_setup
256 # @DESCRIPTION:
257 # Runs openvdb_setup.
258 openvdb_pkg_setup() {
259     debug-print-function ${FUNCNAME} "${@}"
260
261     [[ ${MERGE_TYPE} != binary ]] && openvdb_setup
262 }
263
264 _OPENVDB=1
265 fi

Replies

Subject Author
Re: [gentoo-dev] New eclass: openvdb.eclass Gerion Entrup <gerion.entrup@×××××.de>