x11-misc/alock: Take ownership of package
[gentoo.git] / eclass / fortran-2.eclass
1 # Copyright 1999-2015 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Id$
4
5 # @ECLASS: fortran-2.eclass
6 # @MAINTAINER:
7 # jlec@gentoo.org
8 # sci@gentoo.org
9 # @AUTHOR:
10 # Author Justin Lecher <jlec@gentoo.org>
11 # Test functions provided by Sebastien Fabbro and Kacper Kowalik
12 # @BLURB: Simplify fortran compiler management
13 # @DESCRIPTION:
14 # If you need a fortran compiler, then you should be inheriting this eclass.
15 # In case you only need optional support, please export FORTRAN_NEEDED before
16 # inheriting the eclass.
17 #
18 # The eclass tests for working fortran compilers
19 # and exports the variables FC and F77.
20 # Optionally, it checks for extended capabilities based on
21 # the variable options selected in the ebuild
22 # The only phase function exported is fortran-2_pkg_setup.
23 # @EXAMPLE:
24 # FORTRAN_NEEDED="lapack fortran"
25 #
26 # inherit fortran-2
27 #
28 # FORTRAN_NEED_OPENMP=1
29
30 if [[ ! ${_FORTRAN_2_CLASS} ]]; then
31
32 # @ECLASS-VARIABLE: FORTRAN_NEED_OPENMP
33 # @DESCRIPTION:
34 # Set to "1" in order to automatically have the eclass abort if the fortran
35 # compiler lacks openmp support.
36 : ${FORTRAN_NEED_OPENMP:=0}
37
38 # @ECLASS-VARIABLE: FORTRAN_STANDARD
39 # @DESCRIPTION:
40 # Set this, if a special dialect needs to be supported.
41 # Generally not needed as default is sufficient.
42 #
43 # Valid settings are any combination of: 77 90 95 2003
44 : ${FORTRAN_STANDARD:=77}
45
46 # @ECLASS-VARIABLE: FORTRAN_NEEDED
47 # @DESCRIPTION:
48 # If your package has an optional fortran support, set this variable
49 # to the space separated list of USE triggering the fortran
50 # dependency.
51 #
52 # e.g. FORTRAN_NEEDED=lapack would result in
53 #
54 # DEPEND="lapack? ( virtual/fortran )"
55 #
56 # If unset, we always depend on virtual/fortran.
57 : ${FORTRAN_NEEDED:=always}
58
59 inherit eutils toolchain-funcs
60
61 for _f_use in ${FORTRAN_NEEDED}; do
62         case ${_f_use} in
63                 always)
64                         DEPEND+=" virtual/fortran"
65                         RDEPEND+=" virtual/fortran"
66                         break
67                         ;;
68                 no)
69                         break
70                         ;;
71                 test)
72                         DEPEND+=" ${_f_use}? ( virtual/fortran )"
73                         ;;
74                 *)
75                         DEPEND+=" ${_f_use}? ( virtual/fortran )"
76                         RDEPEND+=" ${_f_use}? ( virtual/fortran )"
77                         ;;
78         esac
79 done
80 unset _f_use
81
82 # @FUNCTION: fortran_int64_abi_fflags
83 # @DESCRIPTION:
84 # Return the Fortran compiler flag to enable 64 bit integers for
85 # array indices
86 # @CODE
87 fortran_int64_abi_fflags() {
88         debug-print-function ${FUNCNAME} "${@}"
89
90         _FC=$(tc-getFC)
91         if [[ ${_FC} == *gfortran* ]]; then
92                 echo "-fdefault-integer-8"
93         elif [[ ${_FC} == ifort ]]; then
94                 echo "-integer-size 64"
95         else
96                 die "Compiler flag for 64bit interger for ${_FC} unknown"
97         fi
98 }
99
100 # @FUNCTION: _fortran_write_testsuite
101 # @INTERNAL
102 # @DESCRIPTION:
103 # writes fortran test code
104 _fortran_write_testsuite() {
105         debug-print-function ${FUNCNAME} "${@}"
106
107         local filebase=${T}/test-fortran
108
109         # f77 code
110         cat <<- EOF > "${filebase}.f"
111                end
112         EOF
113
114         # f90/95 code
115         cat <<- EOF > "${filebase}.f90"
116         end
117         EOF
118
119         # f2003 code
120         cat <<- EOF > "${filebase}.f03"
121                procedure(), pointer :: p
122                end
123         EOF
124 }
125
126 # @FUNCTION: _fortran_compile_test
127 # @USAGE: <compiler> [dialect]
128 # @INTERNAL
129 # @DESCRIPTION:
130 # Takes fortran compiler as first argument and dialect as second.
131 # Checks whether the passed fortran compiler speaks the fortran dialect
132 _fortran_compile_test() {
133         debug-print-function ${FUNCNAME} "${@}"
134
135         local filebase=${T}/test-fortran
136         local fcomp=${1}
137         local fdia=${2}
138         local fcode=${filebase}.f${fdia}
139         local ret
140
141         [[ $# -lt 1 ]] && \
142                 die "_fortran_compile_test() needs at least one argument"
143
144         [[ -f ${fcode} ]] || _fortran_write_testsuite
145
146         ${fcomp} "${fcode}" -o "${fcode}.x" \
147                 >> "${T}"/_fortran_compile_test.log 2>&1
148         ret=$?
149
150         rm -f "${fcode}.x"
151         return ${ret}
152 }
153
154 # @FUNCTION: _fortran-has-openmp
155 # @RETURN: return code of the compiler
156 # @INTERNAL
157 # @DESCRIPTION:
158 # See if the fortran supports OpenMP.
159 _fortran-has-openmp() {
160         debug-print-function ${FUNCNAME} "${@}"
161
162         local flag
163         local filebase=${T}/test-fc-openmp
164         local fcode=${filebase}.f
165         local ret
166         local _fc=$(tc-getFC)
167
168         cat <<- EOF > "${fcode}"
169                call omp_get_num_threads
170                end
171         EOF
172
173         for flag in -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp; do
174                 ${_fc} ${flag} "${fcode}" -o "${fcode}.x" \
175                         &>> "${T}"/_fortran_compile_test.log
176                 ret=$?
177                 (( ${ret} )) || break
178         done
179
180         rm -f "${fcode}.x"
181         return ${ret}
182 }
183
184 # @FUNCTION: _fortran_die_msg
185 # @INTERNAL
186 # @DESCRIPTION:
187 # Detailed description how to handle fortran support
188 _fortran_die_msg() {
189         debug-print-function ${FUNCNAME} "${@}"
190
191         echo
192         eerror "Please install currently selected gcc version with USE=fortran."
193         eerror "If you intend to use a different compiler then gfortran, please"
194         eerror "set FC variable accordingly and take care that the necessary"
195         eerror "fortran dialects are supported."
196         echo
197         die "Currently no working fortran compiler is available"
198 }
199
200 # @FUNCTION: _fortran_test_function
201 # @INTERNAL
202 # @DESCRIPTION:
203 # Internal test function for working fortran compiler.
204 # It is called in fortran-2_pkg_setup.
205 _fortran_test_function() {
206         debug-print-function ${FUNCNAME} "${@}"
207
208         local dialect
209
210         : ${F77:=$(tc-getFC)}
211
212         : ${FORTRAN_STANDARD:=77}
213         for dialect in ${FORTRAN_STANDARD}; do
214                 case ${dialect} in
215                         77) _fortran_compile_test $(tc-getF77) || \
216                                 _fortran_die_msg ;;
217                         90|95) _fortran_compile_test $(tc-getFC) 90 || \
218                                 _fortran_die_msg ;;
219                         2003) _fortran_compile_test $(tc-getFC) 03 || \
220                                 _fortran_die_msg ;;
221                         2008) die "Future" ;;
222                         *) die "${dialect} is not a Fortran dialect." ;;
223                 esac
224         done
225
226         tc-export F77 FC
227         einfo "Using following Fortran compiler:"
228         einfo "  F77: ${F77}"
229         einfo "  FC:  ${FC}"
230
231         if [[ ${FORTRAN_NEED_OPENMP} == 1 ]]; then
232                 if _fortran-has-openmp; then
233                         einfo "${FC} has OPENMP support"
234                 else
235                         die "Please install current gcc with USE=openmp or set the FC variable to a compiler that supports OpenMP"
236                 fi
237         fi
238 }
239
240 # @FUNCTION: _fortran-2_pkg_setup
241 # @INTERNAL
242 # @DESCRIPTION:
243 # _The_ fortran-2_pkg_setup() code
244 _fortran-2_pkg_setup() {
245         for _f_use in ${FORTRAN_NEEDED}; do
246         case ${_f_use} in
247                 always)
248                         _fortran_test_function && break
249                         ;;
250                 no)
251                         einfo "Forcing fortran support off"
252                         break
253                         ;;
254                 *)
255                         if use ${_f_use}; then
256                                 _fortran_test_function && break
257                         else
258                                 unset FC
259                                 unset F77
260                         fi
261                         ;;
262                 esac
263         done
264 }
265
266
267 # @FUNCTION: fortran-2_pkg_setup
268 # @DESCRIPTION:
269 # Setup functionality,
270 # checks for a valid fortran compiler and optionally for its openmp support.
271 fortran-2_pkg_setup() {
272         debug-print-function ${FUNCNAME} "${@}"
273
274         case ${EAPI:-0} in
275                 0|1|2|3)
276                         eqawarn "Support for EAPI < 4 will be removed from the"
277                         eqawarn "fortran-2.eclass in until 2013-09-30."
278                         eqawarn "Please migrate your package to a higher EAPI"
279                         eqawarn "or file a bug at https://bugs.gentoo.org"
280                         _fortran-2_pkg_setup ;;
281                 4|5)
282                         if [[ ${MERGE_TYPE} != binary ]]; then
283                                 _fortran-2_pkg_setup
284                         fi
285                         ;;
286         esac
287 }
288
289 case ${EAPI:-0} in
290         0|1|2|3|4|5|6) EXPORT_FUNCTIONS pkg_setup ;;
291         *) die "EAPI=${EAPI} is not supported" ;;
292 esac
293
294 _FORTRAN_2_ECLASS=1
295 fi