kde-plasma/breeze-gtk: x86 stable wrt bug #613144
[gentoo.git] / eclass / gnat.eclass
1 # Copyright 1999-2015 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @DEAD
5 # Removal on 2017-03-24.
6
7 # Author: George Shapovalov <george@gentoo.org>
8 # No maintainer <maintainer-needed@gentoo.org>
9 #
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
14 #
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.
21
22 inherit flag-o-matic eutils multilib
23
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)
30 #
31 # Note!
32 # It may not be safe to source this at top level. Only source inside local
33 # functions!
34 GnatCommon="/usr/share/gnat/lib/gnat-common.bash"
35
36 # !!NOTE!!
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
40
41 DESCRIPTION="Common procedures for building Ada libs using split gnat compilers"
42
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"
46
47
48 # ----------------------------------
49 # Globals
50
51 # Lib install locations
52 #
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
58 PREFIX=/usr
59 AdalibSpecsDir=${PREFIX}/include/ada
60 AdalibDataDir=${PREFIX}/share/ada
61 AdalibLibTop=${PREFIX}/$(get_libdir)/ada
62
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
67
68 # DL* are "localized destinations" where ARCH/SLOT dependent stuff should be
69 # installed in lib_install.   There are three:
70 #
71 DL=${WORKDIR}/LocalDest
72 #       a generic location for the lib (.a, .so) files
73 #
74 DLbin=${WORKDIR}/LocalBinDest
75 #       binaries that should be in the PATH, will be moved to common Ada bin dir
76 #
77 DLgpr=${WORKDIR}/LocalGPRDest
78 #       gpr's should go here.
79
80 # file containing environment formed by gnat-eselect (build-time)
81 BuildEnv=${WORKDIR}/BuildEnv
82
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
85 # install
86 LibEnv=${WORKDIR}/LibEnv
87
88
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)
93 expand_BuildEnv() {
94         local line
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
99                 else
100                         echo "export ${line}" >> $1.tmp
101                 fi
102         done
103         mv $1.tmp $1
104 }
105
106
107 # ------------------------------------
108 # Dependency processing related stuff
109
110 # A simple wrapper to get the relevant part of the DEPEND
111 # params:
112 #  $1 - should contain dependency specification analogous to DEPEND,
113 #       if omitted, DEPEND is processed
114 get_ada_dep() {
115         [[ -z "$1" ]] && DEP="${DEPEND}" || DEP="$1"
116         local TempStr
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
121         done
122 #       debug-print-function $FUNCNAME "TempStr=${TempStr:0:8}"
123         [[ -n ${TempStr} ]] && echo ${TempStr:0:8}
124 }
125
126 # This function is used to check whether the requested gnat profile matches the
127 # requested Ada standard
128 # !!ATTN!!
129 # This must match dependencies as specified in virtual/ada !!!
130 #
131 # params:
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
135 #
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//\./}
146         #
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
157                 else
158                         return 1 # unknown compiler encountered
159                 fi
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
167                 else
168                         return 1 # unknown compiler encountered
169                 fi
170         else
171                 return 1 # unknown standard requested, check spelling!
172         fi
173 }
174
175
176 # ------------------------------------
177 # Helpers
178 #
179
180
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
183 # itself installed..
184 #
185 # params:
186 #  $1 - name of env var to process
187 #  $2 (opt) - name of the lib to filter out (defaults to ${PN})
188 filter_env_var() {
189         local entries=(${!1//:/ })
190         local libName=${2:-${PN}}
191         local env_str
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}"
197                 fi
198         done
199         echo ${env_str}
200 }
201
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
205 # installed libs.
206 #
207 # params:
208 #  $1 - name of env var to process
209 get_gnat_value() {
210         local entries=(${!1//:/ })
211         echo ${entries[0]}
212 }
213
214
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"
220
221         local profiles=( $(get_env_list) )
222
223         if [[ ${profiles[@]} == "${MARKER}*" ]]; then
224                 return
225                 # returning empty string
226         fi
227
228         if (( 1 == ${#profiles[@]} )); then
229                 local active=${profiles[0]#${MARKER}}
230         else
231                 die "${ENVDIR} contains multiple gnat profiles, please cleanup!"
232         fi
233
234         if [[ -f ${SPECSDIR}/${active} ]]; then
235                 echo ${active}
236         else
237                 die "The profile active in ${ENVDIR} does not correspond to any installed gnat!"
238         fi
239 }
240
241
242
243 # ------------------------------------
244 # Functions
245
246 # Checks the gnat backend SLOT and filters flags correspondingly
247 # To be called from scr_compile for each profile, before actual compilation
248 # Parameters:
249 #  $1 - gnat profile, e.g. x86_64-pc-linux-gnu-gnat-gcc-3.4
250 gnat_filter_flags() {
251         debug-print-function $FUNCNAME $*
252
253         # We only need to filter so severely if backends < 3.4 is detected, which
254         # means basically gnat-3.15
255         GnatProfile=$1
256         if [ -z ${GnatProfile} ]; then
257                 # should not get here!
258                 die "please specify a valid gnat profile for flag stripping!"
259         fi
260
261         local GnatSLOT="${GnatProfile//*-/}"
262         if [[ ${GnatSLOT} < 3.4 ]] ; then
263                 filter-mfpmath sse 387
264
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
269
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}
281         else
282                 export ADACFLAGS=${ADACFLAGS:-${CFLAGS}}
283         fi
284
285         export ADAMAKEFLAGS=${ADAMAKEFLAGS:-"-cargs ${ADACFLAGS} -margs"}
286         export ADABINDFLAGS=${ADABINDFLAGS:-""}
287 }
288
289 gnat_pkg_setup() {
290         debug-print-function $FUNCNAME $*
291
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."
301                         einfo ""
302                         ewarn "If you do the latter, please don't forget to rebuild all"
303                         ewarn "affected libs!"
304                         die "Primary compiler is missing"
305                 fi
306         done
307
308         export ADAC=${ADAC:-gnatgcc}
309         export ADAMAKE=${ADAMAKE:-gnatmake}
310         export ADABIND=${ADABIND:-gnatbind}
311 }
312
313
314 gnat_pkg_postinst() {
315         einfo "Updating gnat configuration to pick up ${PN} library..."
316         eselect gnat update
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:"
320         elog
321         #elog "env-update"
322         elog "source /etc/profile"
323         einfo
324         einfo "Otherwise the settings will become active next time you login"
325 }
326
327
328
329
330 # standard lib_compile plug. Adapted from base.eclass
331 lib_compile() {
332         debug-print-function $FUNCNAME $*
333         [ -z "$1" ] && lib_compile all
334
335         cd ${SL}
336
337         while [ "$1" ]; do
338         case $1 in
339                 configure)
340                         debug-print-section configure
341                         econf || die "died running econf, $FUNCNAME:configure"
342                 ;;
343                 make)
344                         debug-print-section make
345                         emake || die "died running emake, $FUNCNAME:make"
346                 ;;
347                 all)
348                         debug-print-section all
349                         lib_compile configure make
350                 ;;
351         esac
352         shift
353         done
354 }
355
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..
361 #
362 # lib_compile and lib_install are passed the active gnat profile name - may be used or
363 # discarded as needed..
364 gnat_src_compile() {
365         debug-print-function $FUNCNAME $*
366
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"
370
371         compilers=( $(find_primary_compilers ) )
372         if [[ -n ${compilers[@]} ]] ; then
373                 local i
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}]}"
378
379                                 # copy sources
380                                 mkdir "${DL}" "${DLbin}" "${DLgpr}"
381                                 cp -dpR "${S}" "${SL}"
382
383                                 # setup environment
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)
395
396                                 # call compilation callback
397                                 cd "${SL}"
398                                 gnat_filter_flags ${compilers[${i}]}
399                                 lib_compile ${compilers[${i}]} || die "failed compiling for ${compilers[${i}]}"
400
401                                 # call install callback
402                                 cd "${SL}"
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}]}"
408                                 rm -rf "${SL}"
409                         else
410                                 einfo "skipping gnat profile ${compilers[${i}]}"
411                         fi
412                 done
413         else
414                 ewarn "Please note!"
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!"
421         fi
422 }
423
424
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
427 gnat_src_install() {
428         debug-print-function $FUNCNAME $*
429
430         # prep lib specs directory
431         . ${GnatCommon} || die "failed to source gnat-common lib"
432         dodir ${SPECSDIR}/${PN}
433
434         compilers=( $(find_primary_compilers) )
435         if [[ -n ${compilers[@]} ]] ; then
436                 local i
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}]}"
441
442                                 local DLlocation=${AdalibLibTop}/${compilers[${i}]}
443                                 dodir ${DLlocation}
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}]}"
452                         else
453                                 einfo "skipping gnat profile ${compilers[${i}]}"
454                         fi
455                 done
456         else
457                 die "please make sure you have at least one gnat compiler installed!"
458         fi
459 }