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