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