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