gnat.eclass 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. # Copyright 1999-2015 Gentoo Foundation
  2. # Distributed under the terms of the GNU General Public License v2
  3. # @DEAD
  4. # Removal on 2017-03-24.
  5. # Author: George Shapovalov <george@gentoo.org>
  6. # No maintainer <maintainer-needed@gentoo.org>
  7. #
  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
  12. #
  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.
  19. inherit flag-o-matic eutils multilib
  20. # The environment is set locally in src_compile and src_install functions
  21. # by the common code sourced here and in gnat-eselect module.
  22. # This is the standard location for this code (belongs to eselect-gnat,
  23. # since eselect should work even in the absense of portage tree and we can
  24. # guarantee to some extent presence of gnat-eselect when anything gnat-related
  25. # gets processed. See #192505)
  26. #
  27. # Note!
  28. # It may not be safe to source this at top level. Only source inside local
  29. # functions!
  30. GnatCommon="/usr/share/gnat/lib/gnat-common.bash"
  31. # !!NOTE!!
  32. # src_install should not be exported!
  33. # Instead gnat_src_install should be explicitly called from within src_install.
  34. EXPORT_FUNCTIONS pkg_setup pkg_postinst src_compile
  35. DESCRIPTION="Common procedures for building Ada libs using split gnat compilers"
  36. # make sure we have an appropriately recent eselect-gnat installed, as we are
  37. # using some common code here.
  38. DEPEND=">=app-eselect/eselect-gnat-1.3"
  39. # ----------------------------------
  40. # Globals
  41. # Lib install locations
  42. #
  43. # Gnat profile dependent files go under ${LibTop}/${Gnat_Profile}/${PN}
  44. # and common files go under SpecsDir, DataDir..
  45. # In order not to pollute PATH and LDPATH attempt should be mabe to install
  46. # binaries and what makes sence for individual packages under
  47. # ${AdalibLibTop}/${Gnat_Profile}/bin
  48. PREFIX=/usr
  49. AdalibSpecsDir=${PREFIX}/include/ada
  50. AdalibDataDir=${PREFIX}/share/ada
  51. AdalibLibTop=${PREFIX}/$(get_libdir)/ada
  52. # build-time locations
  53. # SL is a "localized" S, - location where sources are copied for
  54. #bi profile-specific build
  55. SL=${WORKDIR}/LocalSource
  56. # DL* are "localized destinations" where ARCH/SLOT dependent stuff should be
  57. # installed in lib_install. There are three:
  58. #
  59. DL=${WORKDIR}/LocalDest
  60. # a generic location for the lib (.a, .so) files
  61. #
  62. DLbin=${WORKDIR}/LocalBinDest
  63. # binaries that should be in the PATH, will be moved to common Ada bin dir
  64. #
  65. DLgpr=${WORKDIR}/LocalGPRDest
  66. # gpr's should go here.
  67. # file containing environment formed by gnat-eselect (build-time)
  68. BuildEnv=${WORKDIR}/BuildEnv
  69. # environment for installed lib. Profile-specific stuff should use %DL% as a top
  70. # of their location. This (%DL%) will be substituted with a proper location upon
  71. # install
  72. LibEnv=${WORKDIR}/LibEnv
  73. # env file prepared by gnat.eselect only lists new settings for env vars
  74. # we need to change that to prepend, rather than replace action..
  75. # Takes one argument - the file to expand. This file should contain only
  76. # var=value like lines.. (commenst are Ok)
  77. expand_BuildEnv() {
  78. local line
  79. for line in $(cat $1); do
  80. EnvVar=$(echo ${line}|cut -d"=" -f1)
  81. if [[ "${EnvVar}" == "PATH" ]] ; then
  82. echo "export ${line}:\${${EnvVar}}" >> $1.tmp
  83. else
  84. echo "export ${line}" >> $1.tmp
  85. fi
  86. done
  87. mv $1.tmp $1
  88. }
  89. # ------------------------------------
  90. # Dependency processing related stuff
  91. # A simple wrapper to get the relevant part of the DEPEND
  92. # params:
  93. # $1 - should contain dependency specification analogous to DEPEND,
  94. # if omitted, DEPEND is processed
  95. get_ada_dep() {
  96. [[ -z "$1" ]] && DEP="${DEPEND}" || DEP="$1"
  97. local TempStr
  98. for fn in $DEP; do # here $DEP should *not* be in ""
  99. [[ $fn =~ "virtual/ada" ]] && TempStr=${fn/*virtual\//}
  100. # above match should be to full virtual/ada, as simply "ada" is a common
  101. # part of ${PN}, even for some packages under dev-ada
  102. done
  103. # debug-print-function $FUNCNAME "TempStr=${TempStr:0:8}"
  104. [[ -n ${TempStr} ]] && echo ${TempStr:0:8}
  105. }
  106. # This function is used to check whether the requested gnat profile matches the
  107. # requested Ada standard
  108. # !!ATTN!!
  109. # This must match dependencies as specified in virtual/ada !!!
  110. #
  111. # params:
  112. # $1 - the requested gnat profile in usual form (e.g. x86_64-pc-linux-gnu-gnat-gcc-4.1)
  113. # $2 - Ada standard specification, as would be specified in DEPEND.
  114. # Valid values: ada-1995, ada-2005, ada
  115. #
  116. # This used to treat ada-1995 and ada alike, but some packages (still
  117. # requested by users) no longer compile with new compilers (not the
  118. # standard issue, but rather compiler becoming stricter most of the time).
  119. # Plus there are some "intermediary versions", not fully 2005 compliant
  120. # but already causing problems. Therefore, now we do exact matching.
  121. belongs_to_standard() {
  122. # debug-print-function $FUNCNAME $*
  123. . ${GnatCommon} || die "failed to source gnat-common lib"
  124. local GnatSlot=$(get_gnat_SLOT $1)
  125. local ReducedSlot=${GnatSlot//\./}
  126. #
  127. if [[ $2 == 'ada' ]] ; then
  128. # debug-print-function "ada or ada-1995 match"
  129. return 0 # no restrictions imposed
  130. elif [[ "$2" == 'ada-1995' ]] ; then
  131. if [[ $(get_gnat_Pkg $1) == "gcc" ]]; then
  132. # debug-print-function "got gcc profile, GnatSlot=${ReducedSlot}"
  133. [[ ${ReducedSlot} -le "42" ]] && return 0 || return 1
  134. elif [[ $(get_gnat_Pkg $1) == "gpl" ]]; then
  135. # debug-print-function "got gpl profile, GnatSlot=${ReducedSlot}"
  136. [[ ${ReducedSlot} -lt "41" ]] && return 0 || return 1
  137. else
  138. return 1 # unknown compiler encountered
  139. fi
  140. elif [[ "$2" == 'ada-2005' ]] ; then
  141. if [[ $(get_gnat_Pkg $1) == "gcc" ]]; then
  142. # debug-print-function "got gcc profile, GnatSlot=${ReducedSlot}"
  143. [[ ${ReducedSlot} -ge "43" ]] && return 0 || return 1
  144. elif [[ $(get_gnat_Pkg $1) == "gpl" ]]; then
  145. # debug-print-function "got gpl profile, GnatSlot=${ReducedSlot}"
  146. [[ ${ReducedSlot} -ge "41" ]] && return 0 || return 1
  147. else
  148. return 1 # unknown compiler encountered
  149. fi
  150. else
  151. return 1 # unknown standard requested, check spelling!
  152. fi
  153. }
  154. # ------------------------------------
  155. # Helpers
  156. #
  157. # The purpose of this one is to remove all parts of the env entry specific to a
  158. # given lib. Usefull when some lib wants to act differently upon detecting
  159. # itself installed..
  160. #
  161. # params:
  162. # $1 - name of env var to process
  163. # $2 (opt) - name of the lib to filter out (defaults to ${PN})
  164. filter_env_var() {
  165. local entries=(${!1//:/ })
  166. local libName=${2:-${PN}}
  167. local env_str
  168. for entry in ${entries[@]} ; do
  169. # this simply checks if $libname is a substring of the $entry, should
  170. # work fine with all the present libs
  171. if [[ ${entry/${libName}/} == ${entry} ]] ; then
  172. env_str="${env_str}:${entry}"
  173. fi
  174. done
  175. echo ${env_str}
  176. }
  177. # A simpler helper, for the libs that need to extract active gnat location
  178. # Returns a first entry for a specified env var. Relies on the (presently true)
  179. # convention that first gnat's entries are listed and then of the other
  180. # installed libs.
  181. #
  182. # params:
  183. # $1 - name of env var to process
  184. get_gnat_value() {
  185. local entries=(${!1//:/ })
  186. echo ${entries[0]}
  187. }
  188. # Returns a name of active gnat profile. Performs some validity checks. No input
  189. # parameters, analyzes the system setup directly.
  190. get_active_profile() {
  191. # get common code and settings
  192. . ${GnatCommon} || die "failed to source gnat-common lib"
  193. local profiles=( $(get_env_list) )
  194. if [[ ${profiles[@]} == "${MARKER}*" ]]; then
  195. return
  196. # returning empty string
  197. fi
  198. if (( 1 == ${#profiles[@]} )); then
  199. local active=${profiles[0]#${MARKER}}
  200. else
  201. die "${ENVDIR} contains multiple gnat profiles, please cleanup!"
  202. fi
  203. if [[ -f ${SPECSDIR}/${active} ]]; then
  204. echo ${active}
  205. else
  206. die "The profile active in ${ENVDIR} does not correspond to any installed gnat!"
  207. fi
  208. }
  209. # ------------------------------------
  210. # Functions
  211. # Checks the gnat backend SLOT and filters flags correspondingly
  212. # To be called from scr_compile for each profile, before actual compilation
  213. # Parameters:
  214. # $1 - gnat profile, e.g. x86_64-pc-linux-gnu-gnat-gcc-3.4
  215. gnat_filter_flags() {
  216. debug-print-function $FUNCNAME $*
  217. # We only need to filter so severely if backends < 3.4 is detected, which
  218. # means basically gnat-3.15
  219. GnatProfile=$1
  220. if [ -z ${GnatProfile} ]; then
  221. # should not get here!
  222. die "please specify a valid gnat profile for flag stripping!"
  223. fi
  224. local GnatSLOT="${GnatProfile//*-/}"
  225. if [[ ${GnatSLOT} < 3.4 ]] ; then
  226. filter-mfpmath sse 387
  227. filter-flags -mmmx -msse -mfpmath -frename-registers \
  228. -fprefetch-loop-arrays -falign-functions=4 -falign-jumps=4 \
  229. -falign-loops=4 -msse2 -frerun-loop-opt -maltivec -mabi=altivec \
  230. -fsigned-char -fno-strict-aliasing -pipe
  231. export ADACFLAGS=${ADACFLAGS:-${CFLAGS}}
  232. export ADACFLAGS=${ADACFLAGS//-Os/-O2}
  233. export ADACFLAGS=${ADACFLAGS//pentium-mmx/i586}
  234. export ADACFLAGS=${ADACFLAGS//pentium[234]/i686}
  235. export ADACFLAGS=${ADACFLAGS//k6-[23]/k6}
  236. export ADACFLAGS=${ADACFLAGS//athlon-tbird/i686}
  237. export ADACFLAGS=${ADACFLAGS//athlon-4/i686}
  238. export ADACFLAGS=${ADACFLAGS//athlon-[xm]p/i686}
  239. # gcc-2.8.1 has no amd64 support, so the following two are safe
  240. export ADACFLAGS=${ADACFLAGS//athlon64/i686}
  241. export ADACFLAGS=${ADACFLAGS//athlon/i686}
  242. else
  243. export ADACFLAGS=${ADACFLAGS:-${CFLAGS}}
  244. fi
  245. export ADAMAKEFLAGS=${ADAMAKEFLAGS:-"-cargs ${ADACFLAGS} -margs"}
  246. export ADABINDFLAGS=${ADABINDFLAGS:-""}
  247. }
  248. gnat_pkg_setup() {
  249. debug-print-function $FUNCNAME $*
  250. # check whether all the primary compilers are installed
  251. . ${GnatCommon} || die "failed to source gnat-common lib"
  252. for fn in $(cat ${PRIMELIST}); do
  253. if [[ ! -f ${SPECSDIR}/${fn} ]]; then
  254. elog "The ${fn} Ada compiler profile is specified as primary, but is not installed."
  255. elog "Please rectify the situation before emerging Ada library!"
  256. elog "Please either install again all the missing compilers listed"
  257. elog "as primary, or edit /etc/ada/primary_compilers and update the"
  258. elog "list of primary compilers there."
  259. einfo ""
  260. ewarn "If you do the latter, please don't forget to rebuild all"
  261. ewarn "affected libs!"
  262. die "Primary compiler is missing"
  263. fi
  264. done
  265. export ADAC=${ADAC:-gnatgcc}
  266. export ADAMAKE=${ADAMAKE:-gnatmake}
  267. export ADABIND=${ADABIND:-gnatbind}
  268. }
  269. gnat_pkg_postinst() {
  270. einfo "Updating gnat configuration to pick up ${PN} library..."
  271. eselect gnat update
  272. elog "The environment has been set up to make gnat automatically find files"
  273. elog "for the installed library. In order to immediately activate these"
  274. elog "settings please run:"
  275. elog
  276. #elog "env-update"
  277. elog "source /etc/profile"
  278. einfo
  279. einfo "Otherwise the settings will become active next time you login"
  280. }
  281. # standard lib_compile plug. Adapted from base.eclass
  282. lib_compile() {
  283. debug-print-function $FUNCNAME $*
  284. [ -z "$1" ] && lib_compile all
  285. cd ${SL}
  286. while [ "$1" ]; do
  287. case $1 in
  288. configure)
  289. debug-print-section configure
  290. econf || die "died running econf, $FUNCNAME:configure"
  291. ;;
  292. make)
  293. debug-print-section make
  294. emake || die "died running emake, $FUNCNAME:make"
  295. ;;
  296. all)
  297. debug-print-section all
  298. lib_compile configure make
  299. ;;
  300. esac
  301. shift
  302. done
  303. }
  304. # Cycles through installed gnat profiles and calls lib_compile and then
  305. # lib_install in turn.
  306. # Use this function to build/install profile-specific binaries. The code
  307. # building/installing common stuff (docs, etc) can go before/after, as needed,
  308. # so that it is called only once..
  309. #
  310. # lib_compile and lib_install are passed the active gnat profile name - may be used or
  311. # discarded as needed..
  312. gnat_src_compile() {
  313. debug-print-function $FUNCNAME $*
  314. # We source the eselect-gnat module and use its functions directly, instead of
  315. # duplicating code or trying to violate sandbox in some way..
  316. . ${GnatCommon} || die "failed to source gnat-common lib"
  317. compilers=( $(find_primary_compilers ) )
  318. if [[ -n ${compilers[@]} ]] ; then
  319. local i
  320. local AdaDep=$(get_ada_dep)
  321. for (( i = 0 ; i < ${#compilers[@]} ; i = i + 1 )) ; do
  322. if $(belongs_to_standard ${compilers[${i}]} ${AdaDep}); then
  323. einfo "compiling for gnat profile ${compilers[${i}]}"
  324. # copy sources
  325. mkdir "${DL}" "${DLbin}" "${DLgpr}"
  326. cp -dpR "${S}" "${SL}"
  327. # setup environment
  328. # As eselect-gnat also manages the libs, this will ensure the right
  329. # lib profiles are activated too (in case we depend on some Ada lib)
  330. generate_envFile ${compilers[${i}]} ${BuildEnv} && \
  331. expand_BuildEnv "${BuildEnv}" && \
  332. . "${BuildEnv}" || die "failed to switch to ${compilers[${i}]}"
  333. # many libs (notably xmlada and gtkada) do not like to see
  334. # themselves installed. Need to strip them from ADA_*_PATH
  335. # NOTE: this should not be done in pkg_setup, as we setup
  336. # environment right above
  337. export ADA_INCLUDE_PATH=$(filter_env_var ADA_INCLUDE_PATH)
  338. export ADA_OBJECTS_PATH=$(filter_env_var ADA_OBJECTS_PATH)
  339. # call compilation callback
  340. cd "${SL}"
  341. gnat_filter_flags ${compilers[${i}]}
  342. lib_compile ${compilers[${i}]} || die "failed compiling for ${compilers[${i}]}"
  343. # call install callback
  344. cd "${SL}"
  345. lib_install ${compilers[${i}]} || die "failed installing profile-specific part for ${compilers[${i}]}"
  346. # move installed and cleanup
  347. mv "${DL}" "${DL}-${compilers[${i}]}"
  348. mv "${DLbin}" "${DLbin}-${compilers[${i}]}"
  349. mv "${DLgpr}" "${DLgpr}-${compilers[${i}]}"
  350. rm -rf "${SL}"
  351. else
  352. einfo "skipping gnat profile ${compilers[${i}]}"
  353. fi
  354. done
  355. else
  356. ewarn "Please note!"
  357. elog "Treatment of installed Ada compilers has recently changed!"
  358. elog "Libs are now being built only for \"primary\" compilers."
  359. elog "Please list gnat profiles (as reported by \"eselect gnat list\")"
  360. elog "that you want to regularly use (i.e., not just for testing)"
  361. elog "in ${PRIMELIST}, one per line."
  362. die "please make sure you have at least one gnat compiler installed and set as primary!"
  363. fi
  364. }
  365. # This function simply moves gnat-profile-specific stuff into proper locations.
  366. # Use src_install in ebuild to install the rest of the package
  367. gnat_src_install() {
  368. debug-print-function $FUNCNAME $*
  369. # prep lib specs directory
  370. . ${GnatCommon} || die "failed to source gnat-common lib"
  371. dodir ${SPECSDIR}/${PN}
  372. compilers=( $(find_primary_compilers) )
  373. if [[ -n ${compilers[@]} ]] ; then
  374. local i
  375. local AdaDep=$(get_ada_dep)
  376. for (( i = 0 ; i < ${#compilers[@]} ; i = i + 1 )) ; do
  377. if $(belongs_to_standard ${compilers[${i}]} ${AdaDep}); then
  378. debug-print-section "installing for gnat profile ${compilers[${i}]}"
  379. local DLlocation=${AdalibLibTop}/${compilers[${i}]}
  380. dodir ${DLlocation}
  381. cp -dpR "${DL}-${compilers[${i}]}" "${D}/${DLlocation}/${PN}"
  382. cp -dpR "${DLbin}-${compilers[${i}]}" "${D}/${DLlocation}"/bin
  383. cp -dpR "${DLgpr}-${compilers[${i}]}" "${D}/${DLlocation}"/gpr
  384. # create profile-specific specs file
  385. cp ${LibEnv} "${D}/${SPECSDIR}/${PN}/${compilers[${i}]}"
  386. sed -i -e "s:%DL%:${DLlocation}/${PN}:g" "${D}/${SPECSDIR}/${PN}/${compilers[${i}]}"
  387. sed -i -e "s:%DLbin%:${DLlocation}/bin:g" "${D}/${SPECSDIR}/${PN}/${compilers[${i}]}"
  388. sed -i -e "s:%DLgpr%:${DLlocation}/gpr:g" "${D}/${SPECSDIR}/${PN}/${compilers[${i}]}"
  389. else
  390. einfo "skipping gnat profile ${compilers[${i}]}"
  391. fi
  392. done
  393. else
  394. die "please make sure you have at least one gnat compiler installed!"
  395. fi
  396. }