1 # Copyright 1999-2015 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
5 # Author: George Shapovalov <george@gentoo.org>
6 # Belongs to: ada herd <ada@gentoo.org>
8 # This eclass provides the framework for ada lib installation with the split and
9 # SLOTted gnat compilers (gnat-xxx, gnatbuild.eclass). Each lib gets built once
10 # for every installed gnat compiler. Activation of a particular bunary module is
11 # performed by eselect-gnat, when the active compiler gets switched
13 # The ebuilds should define the lib_compile and lib_install functions that are
14 # called from the (exported) gnat_src_compile function of eclass. These
15 # functions should operate similarly to the starndard src_compile and
16 # src_install. The only difference, that they should use $SL variable instead of
17 # $S (this is where the working copy of source is held) and $DL instead of $D as
18 # its installation point.
20 inherit flag-o-matic eutils multilib
22 # The environment is set locally in src_compile and src_install functions
23 # by the common code sourced here and in gnat-eselect module.
24 # This is the standard location for this code (belongs to eselect-gnat,
25 # since eselect should work even in the absense of portage tree and we can
26 # guarantee to some extent presence of gnat-eselect when anything gnat-related
27 # gets processed. See #192505)
30 # It may not be safe to source this at top level. Only source inside local
32 GnatCommon="/usr/share/gnat/lib/gnat-common.bash"
35 # src_install should not be exported!
36 # Instead gnat_src_install should be explicitly called from within src_install.
37 EXPORT_FUNCTIONS pkg_setup pkg_postinst src_compile
39 DESCRIPTION="Common procedures for building Ada libs using split gnat compilers"
41 # make sure we have an appropriately recent eselect-gnat installed, as we are
42 # using some common code here.
43 DEPEND=">=app-eselect/eselect-gnat-1.3"
46 # ----------------------------------
49 # Lib install locations
51 # Gnat profile dependent files go under ${LibTop}/${Gnat_Profile}/${PN}
52 # and common files go under SpecsDir, DataDir..
53 # In order not to pollute PATH and LDPATH attempt should be mabe to install
54 # binaries and what makes sence for individual packages under
55 # ${AdalibLibTop}/${Gnat_Profile}/bin
57 AdalibSpecsDir=${PREFIX}/include/ada
58 AdalibDataDir=${PREFIX}/share/ada
59 AdalibLibTop=${PREFIX}/$(get_libdir)/ada
61 # build-time locations
62 # SL is a "localized" S, - location where sources are copied for
63 #bi profile-specific build
64 SL=${WORKDIR}/LocalSource
66 # DL* are "localized destinations" where ARCH/SLOT dependent stuff should be
67 # installed in lib_install. There are three:
69 DL=${WORKDIR}/LocalDest
70 # a generic location for the lib (.a, .so) files
72 DLbin=${WORKDIR}/LocalBinDest
73 # binaries that should be in the PATH, will be moved to common Ada bin dir
75 DLgpr=${WORKDIR}/LocalGPRDest
76 # gpr's should go here.
78 # file containing environment formed by gnat-eselect (build-time)
79 BuildEnv=${WORKDIR}/BuildEnv
81 # environment for installed lib. Profile-specific stuff should use %DL% as a top
82 # of their location. This (%DL%) will be substituted with a proper location upon
84 LibEnv=${WORKDIR}/LibEnv
87 # env file prepared by gnat.eselect only lists new settings for env vars
88 # we need to change that to prepend, rather than replace action..
89 # Takes one argument - the file to expand. This file should contain only
90 # var=value like lines.. (commenst are Ok)
93 for line in $(cat $1); do
94 EnvVar=$(echo ${line}|cut -d"=" -f1)
95 if [[ "${EnvVar}" == "PATH" ]] ; then
96 echo "export ${line}:\${${EnvVar}}" >> $1.tmp
98 echo "export ${line}" >> $1.tmp
105 # ------------------------------------
106 # Dependency processing related stuff
108 # A simple wrapper to get the relevant part of the DEPEND
110 # $1 - should contain dependency specification analogous to DEPEND,
111 # if omitted, DEPEND is processed
113 [[ -z "$1" ]] && DEP="${DEPEND}" || DEP="$1"
115 for fn in $DEP; do # here $DEP should *not* be in ""
116 [[ $fn =~ "virtual/ada" ]] && TempStr=${fn/*virtual\//}
117 # above match should be to full virtual/ada, as simply "ada" is a common
118 # part of ${PN}, even for some packages under dev-ada
120 # debug-print-function $FUNCNAME "TempStr=${TempStr:0:8}"
121 [[ -n ${TempStr} ]] && echo ${TempStr:0:8}
124 # This function is used to check whether the requested gnat profile matches the
125 # requested Ada standard
127 # This must match dependencies as specified in vitrual/ada !!!
130 # $1 - the requested gnat profile in usual form (e.g. x86_64-pc-linux-gnu-gnat-gcc-4.1)
131 # $2 - Ada standard specification, as would be specified in DEPEND.
132 # Valid values: ada-1995, ada-2005, ada
134 # This used to treat ada-1995 and ada alike, but some packages (still
135 # requested by users) no longer compile with new compilers (not the
136 # standard issue, but rather compiler becoming stricter most of the time).
137 # Plus there are some "intermediary versions", not fully 2005 compliant
138 # but already causing problems. Therefore, now we do exact matching.
139 belongs_to_standard() {
140 # debug-print-function $FUNCNAME $*
141 . ${GnatCommon} || die "failed to source gnat-common lib"
142 local GnatSlot=$(get_gnat_SLOT $1)
143 local ReducedSlot=${GnatSlot//\./}
145 if [[ $2 == 'ada' ]] ; then
146 # debug-print-function "ada or ada-1995 match"
147 return 0 # no restrictions imposed
148 elif [[ "$2" == 'ada-1995' ]] ; then
149 if [[ $(get_gnat_Pkg $1) == "gcc" ]]; then
150 # debug-print-function "got gcc profile, GnatSlot=${ReducedSlot}"
151 [[ ${ReducedSlot} -le "42" ]] && return 0 || return 1
152 elif [[ $(get_gnat_Pkg $1) == "gpl" ]]; then
153 # debug-print-function "got gpl profile, GnatSlot=${ReducedSlot}"
154 [[ ${ReducedSlot} -lt "41" ]] && return 0 || return 1
156 return 1 # unknown compiler encountered
158 elif [[ "$2" == 'ada-2005' ]] ; then
159 if [[ $(get_gnat_Pkg $1) == "gcc" ]]; then
160 # debug-print-function "got gcc profile, GnatSlot=${ReducedSlot}"
161 [[ ${ReducedSlot} -ge "43" ]] && return 0 || return 1
162 elif [[ $(get_gnat_Pkg $1) == "gpl" ]]; then
163 # debug-print-function "got gpl profile, GnatSlot=${ReducedSlot}"
164 [[ ${ReducedSlot} -ge "41" ]] && return 0 || return 1
166 return 1 # unknown compiler encountered
169 return 1 # unknown standard requested, check spelling!
174 # ------------------------------------
179 # The purpose of this one is to remove all parts of the env entry specific to a
180 # given lib. Usefull when some lib wants to act differently upon detecting
184 # $1 - name of env var to process
185 # $2 (opt) - name of the lib to filter out (defaults to ${PN})
187 local entries=(${!1//:/ })
188 local libName=${2:-${PN}}
190 for entry in ${entries[@]} ; do
191 # this simply checks if $libname is a substring of the $entry, should
192 # work fine with all the present libs
193 if [[ ${entry/${libName}/} == ${entry} ]] ; then
194 env_str="${env_str}:${entry}"
200 # A simpler helper, for the libs that need to extract active gnat location
201 # Returns a first entry for a specified env var. Relies on the (presently true)
202 # convention that first gnat's entries are listed and then of the other
206 # $1 - name of env var to process
208 local entries=(${!1//:/ })
213 # Returns a name of active gnat profile. Performs some validity checks. No input
214 # parameters, analyzes the system setup directly.
215 get_active_profile() {
216 # get common code and settings
217 . ${GnatCommon} || die "failed to source gnat-common lib"
219 local profiles=( $(get_env_list) )
221 if [[ ${profiles[@]} == "${MARKER}*" ]]; then
223 # returning empty string
226 if (( 1 == ${#profiles[@]} )); then
227 local active=${profiles[0]#${MARKER}}
229 die "${ENVDIR} contains multiple gnat profiles, please cleanup!"
232 if [[ -f ${SPECSDIR}/${active} ]]; then
235 die "The profile active in ${ENVDIR} does not correspond to any installed gnat!"
241 # ------------------------------------
244 # Checks the gnat backend SLOT and filters flags correspondingly
245 # To be called from scr_compile for each profile, before actual compilation
247 # $1 - gnat profile, e.g. x86_64-pc-linux-gnu-gnat-gcc-3.4
248 gnat_filter_flags() {
249 debug-print-function $FUNCNAME $*
251 # We only need to filter so severely if backends < 3.4 is detected, which
252 # means basically gnat-3.15
254 if [ -z ${GnatProfile} ]; then
255 # should not get here!
256 die "please specify a valid gnat profile for flag stripping!"
259 local GnatSLOT="${GnatProfile//*-/}"
260 if [[ ${GnatSLOT} < 3.4 ]] ; then
261 filter-mfpmath sse 387
263 filter-flags -mmmx -msse -mfpmath -frename-registers \
264 -fprefetch-loop-arrays -falign-functions=4 -falign-jumps=4 \
265 -falign-loops=4 -msse2 -frerun-loop-opt -maltivec -mabi=altivec \
266 -fsigned-char -fno-strict-aliasing -pipe
268 export ADACFLAGS=${ADACFLAGS:-${CFLAGS}}
269 export ADACFLAGS=${ADACFLAGS//-Os/-O2}
270 export ADACFLAGS=${ADACFLAGS//pentium-mmx/i586}
271 export ADACFLAGS=${ADACFLAGS//pentium[234]/i686}
272 export ADACFLAGS=${ADACFLAGS//k6-[23]/k6}
273 export ADACFLAGS=${ADACFLAGS//athlon-tbird/i686}
274 export ADACFLAGS=${ADACFLAGS//athlon-4/i686}
275 export ADACFLAGS=${ADACFLAGS//athlon-[xm]p/i686}
276 # gcc-2.8.1 has no amd64 support, so the following two are safe
277 export ADACFLAGS=${ADACFLAGS//athlon64/i686}
278 export ADACFLAGS=${ADACFLAGS//athlon/i686}
280 export ADACFLAGS=${ADACFLAGS:-${CFLAGS}}
283 export ADAMAKEFLAGS=${ADAMAKEFLAGS:-"-cargs ${ADACFLAGS} -margs"}
284 export ADABINDFLAGS=${ADABINDFLAGS:-""}
288 debug-print-function $FUNCNAME $*
290 # check whether all the primary compilers are installed
291 . ${GnatCommon} || die "failed to source gnat-common lib"
292 for fn in $(cat ${PRIMELIST}); do
293 if [[ ! -f ${SPECSDIR}/${fn} ]]; then
294 elog "The ${fn} Ada compiler profile is specified as primary, but is not installed."
295 elog "Please rectify the situation before emerging Ada library!"
296 elog "Please either install again all the missing compilers listed"
297 elog "as primary, or edit /etc/ada/primary_compilers and update the"
298 elog "list of primary compilers there."
300 ewarn "If you do the latter, please don't forget to rebuild all"
301 ewarn "affected libs!"
302 die "Primary compiler is missing"
306 export ADAC=${ADAC:-gnatgcc}
307 export ADAMAKE=${ADAMAKE:-gnatmake}
308 export ADABIND=${ADABIND:-gnatbind}
312 gnat_pkg_postinst() {
313 einfo "Updating gnat configuration to pick up ${PN} library..."
315 elog "The environment has been set up to make gnat automatically find files"
316 elog "for the installed library. In order to immediately activate these"
317 elog "settings please run:"
320 elog "source /etc/profile"
322 einfo "Otherwise the settings will become active next time you login"
328 # standard lib_compile plug. Adapted from base.eclass
330 debug-print-function $FUNCNAME $*
331 [ -z "$1" ] && lib_compile all
338 debug-print-section configure
339 econf || die "died running econf, $FUNCNAME:configure"
342 debug-print-section make
343 emake || die "died running emake, $FUNCNAME:make"
346 debug-print-section all
347 lib_compile configure make
354 # Cycles through installed gnat profiles and calls lib_compile and then
355 # lib_install in turn.
356 # Use this function to build/install profile-specific binaries. The code
357 # building/installing common stuff (docs, etc) can go before/after, as needed,
358 # so that it is called only once..
360 # lib_compile and lib_install are passed the active gnat profile name - may be used or
361 # discarded as needed..
363 debug-print-function $FUNCNAME $*
365 # We source the eselect-gnat module and use its functions directly, instead of
366 # duplicating code or trying to violate sandbox in some way..
367 . ${GnatCommon} || die "failed to source gnat-common lib"
369 compilers=( $(find_primary_compilers ) )
370 if [[ -n ${compilers[@]} ]] ; then
372 local AdaDep=$(get_ada_dep)
373 for (( i = 0 ; i < ${#compilers[@]} ; i = i + 1 )) ; do
374 if $(belongs_to_standard ${compilers[${i}]} ${AdaDep}); then
375 einfo "compiling for gnat profile ${compilers[${i}]}"
378 mkdir "${DL}" "${DLbin}" "${DLgpr}"
379 cp -dpR "${S}" "${SL}"
382 # As eselect-gnat also manages the libs, this will ensure the right
383 # lib profiles are activated too (in case we depend on some Ada lib)
384 generate_envFile ${compilers[${i}]} ${BuildEnv} && \
385 expand_BuildEnv "${BuildEnv}" && \
386 . "${BuildEnv}" || die "failed to switch to ${compilers[${i}]}"
387 # many libs (notably xmlada and gtkada) do not like to see
388 # themselves installed. Need to strip them from ADA_*_PATH
389 # NOTE: this should not be done in pkg_setup, as we setup
390 # environment right above
391 export ADA_INCLUDE_PATH=$(filter_env_var ADA_INCLUDE_PATH)
392 export ADA_OBJECTS_PATH=$(filter_env_var ADA_OBJECTS_PATH)
394 # call compilation callback
396 gnat_filter_flags ${compilers[${i}]}
397 lib_compile ${compilers[${i}]} || die "failed compiling for ${compilers[${i}]}"
399 # call install callback
401 lib_install ${compilers[${i}]} || die "failed installing profile-specific part for ${compilers[${i}]}"
402 # move installed and cleanup
403 mv "${DL}" "${DL}-${compilers[${i}]}"
404 mv "${DLbin}" "${DLbin}-${compilers[${i}]}"
405 mv "${DLgpr}" "${DLgpr}-${compilers[${i}]}"
408 einfo "skipping gnat profile ${compilers[${i}]}"
413 elog "Treatment of installed Ada compilers has recently changed!"
414 elog "Libs are now being built only for \"primary\" compilers."
415 elog "Please list gnat profiles (as reported by \"eselect gnat list\")"
416 elog "that you want to regularly use (i.e., not just for testing)"
417 elog "in ${PRIMELIST}, one per line."
418 die "please make sure you have at least one gnat compiler installed and set as primary!"
423 # This function simply moves gnat-profile-specific stuff into proper locations.
424 # Use src_install in ebuild to install the rest of the package
426 debug-print-function $FUNCNAME $*
428 # prep lib specs directory
429 . ${GnatCommon} || die "failed to source gnat-common lib"
430 dodir ${SPECSDIR}/${PN}
432 compilers=( $(find_primary_compilers) )
433 if [[ -n ${compilers[@]} ]] ; then
435 local AdaDep=$(get_ada_dep)
436 for (( i = 0 ; i < ${#compilers[@]} ; i = i + 1 )) ; do
437 if $(belongs_to_standard ${compilers[${i}]} ${AdaDep}); then
438 debug-print-section "installing for gnat profile ${compilers[${i}]}"
440 local DLlocation=${AdalibLibTop}/${compilers[${i}]}
442 cp -dpR "${DL}-${compilers[${i}]}" "${D}/${DLlocation}/${PN}"
443 cp -dpR "${DLbin}-${compilers[${i}]}" "${D}/${DLlocation}"/bin
444 cp -dpR "${DLgpr}-${compilers[${i}]}" "${D}/${DLlocation}"/gpr
445 # create profile-specific specs file
446 cp ${LibEnv} "${D}/${SPECSDIR}/${PN}/${compilers[${i}]}"
447 sed -i -e "s:%DL%:${DLlocation}/${PN}:g" "${D}/${SPECSDIR}/${PN}/${compilers[${i}]}"
448 sed -i -e "s:%DLbin%:${DLlocation}/bin:g" "${D}/${SPECSDIR}/${PN}/${compilers[${i}]}"
449 sed -i -e "s:%DLgpr%:${DLlocation}/gpr:g" "${D}/${SPECSDIR}/${PN}/${compilers[${i}]}"
451 einfo "skipping gnat profile ${compilers[${i}]}"
455 die "please make sure you have at least one gnat compiler installed!"