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