meson.eclass: Don't mix host *FLAGS with build *FLAGS
[gentoo.git] / eclass / meson.eclass
1 # Copyright 2017 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: meson.eclass
5 # @MAINTAINER:
6 # William Hubbs <williamh@gentoo.org>
7 # Mike Gilbert <floppym@gentoo.org>
8 # @BLURB: common ebuild functions for meson-based packages
9 # @DESCRIPTION:
10 # This eclass contains the default phase functions for packages which
11 # use the meson build system.
12 #
13 # @EXAMPLE:
14 # Typical ebuild using meson.eclass:
15 #
16 # @CODE
17 # EAPI=6
18 #
19 # inherit meson
20 #
21 # ...
22 #
23 # src_configure() {
24 #       local emesonargs=(
25 #               -Dqt4=$(usex qt4 true false)
26 #               -Dthreads=$(usex threads true false)
27 #               -Dtiff=$(usex tiff true false)
28 #       )
29 #       meson_src_configure
30 # }
31 #
32 # ...
33 #
34 # @CODE
35
36 case ${EAPI:-0} in
37         6) ;;
38         *) die "EAPI=${EAPI} is not supported" ;;
39 esac
40
41 if [[ ${__MESON_AUTO_DEPEND+set} == "set" ]] ; then
42         # See if we were included already, but someone changed the value
43         # of MESON_AUTO_DEPEND on us.  We could reload the entire
44         # eclass at that point, but that adds overhead, and it's trivial
45         # to re-order inherit in eclasses/ebuilds instead.  #409611
46         if [[ ${__MESON_AUTO_DEPEND} != ${MESON_AUTO_DEPEND} ]] ; then
47                 die "MESON_AUTO_DEPEND changed value between inherits; please inherit meson.eclass first! ${__MESON_AUTO_DEPEND} -> ${MESON_AUTO_DEPEND}"
48         fi
49 fi
50
51 if [[ -z ${_MESON_ECLASS} ]]; then
52
53 inherit ninja-utils python-utils-r1 toolchain-funcs
54
55 fi
56
57 EXPORT_FUNCTIONS src_configure src_compile src_test src_install
58
59 if [[ -z ${_MESON_ECLASS} ]]; then
60 _MESON_ECLASS=1
61
62 MESON_DEPEND=">=dev-util/meson-0.40.0
63         >=dev-util/ninja-1.7.2"
64
65 # @ECLASS-VARIABLE: MESON_AUTO_DEPEND
66 # @DESCRIPTION:
67 # Set to 'no' to disable automatically adding to DEPEND.  This lets
68 # ebuilds form conditional depends by using ${MESON_DEPEND} in
69 # their own DEPEND string.
70 : ${MESON_AUTO_DEPEND:=yes}
71 if [[ ${MESON_AUTO_DEPEND} != "no" ]] ; then
72         DEPEND=${MESON_DEPEND}
73 fi
74 __MESON_AUTO_DEPEND=${MESON_AUTO_DEPEND} # See top of eclass
75
76 # @ECLASS-VARIABLE: BUILD_DIR
77 # @DEFAULT_UNSET
78 # @DESCRIPTION:
79 # Build directory, location where all generated files should be placed.
80 # If this isn't set, it defaults to ${WORKDIR}/${P}-build.
81
82 # @ECLASS-VARIABLE: EMESON_SOURCE
83 # @DEFAULT_UNSET
84 # @DESCRIPTION:
85 # The location of the source files for the project; this is the source
86 # directory to pass to meson.
87 # If this isn't set, it defaults to ${S}
88
89 # @VARIABLE: emesonargs
90 # @DEFAULT_UNSET
91 # @DESCRIPTION:
92 # Optional meson arguments as Bash array; this should be defined before
93 # calling meson_src_configure.
94
95
96 read -d '' __MESON_ARRAY_PARSER <<"EOF"
97 import shlex
98 import sys
99
100 # See http://mesonbuild.com/Syntax.html#strings
101 def quote(str):
102         escaped = str.replace("\\\\", "\\\\\\\\").replace("'", "\\\\'")
103         return "'{}'".format(escaped)
104
105 print("[{}]".format(
106         ", ".join([quote(x) for x in shlex.split(" ".join(sys.argv[1:]))])))
107 EOF
108
109 # @FUNCTION: _meson_env_array
110 # @INTERNAL
111 # @DESCRIPTION:
112 # Parses the command line flags and converts them into an array suitable for
113 # use in a cross file.
114 #
115 # Input: --single-quote=\' --double-quote=\" --dollar=\$ --backtick=\`
116 #        --backslash=\\ --full-word-double="Hello World"
117 #        --full-word-single='Hello World'
118 #        --full-word-backslash=Hello\ World
119 #        --simple --unicode-8=© --unicode-16=𐐷 --unicode-32=𐤅
120 #
121 # Output: ['--single-quote=\'', '--double-quote="', '--dollar=$',
122 #          '--backtick=`', '--backslash=\\', '--full-word-double=Hello World',
123 #          '--full-word-single=Hello World',
124 #          '--full-word-backslash=Hello World', '--simple', '--unicode-8=©',
125 #          '--unicode-16=𐐷', '--unicode-32=𐤅']
126 #
127 _meson_env_array() {
128         python -c "${__MESON_ARRAY_PARSER}" "$@"
129 }
130
131 # @FUNCTION: _meson_create_cross_file
132 # @INTERNAL
133 # @DESCRIPTION:
134 # Creates a cross file. meson uses this to define settings for
135 # cross-compilers. This function is called from meson_src_configure.
136 _meson_create_cross_file() {
137         # Reference: http://mesonbuild.com/Cross-compilation.html
138
139         # system roughly corresponds to uname -s (lowercase)
140         local system=unknown
141         case ${CHOST} in
142                 *-aix*)          system=aix ;;
143                 *-cygwin*)       system=cygwin ;;
144                 *-darwin*)       system=darwin ;;
145                 *-freebsd*)      system=freebsd ;;
146                 *-linux*)        system=linux ;;
147                 mingw*|*-mingw*) system=windows ;;
148                 *-solaris*)      system=sunos ;;
149         esac
150
151         local cpu_family=$(tc-arch)
152         case ${cpu_family} in
153                 amd64) cpu_family=x86_64 ;;
154                 arm64) cpu_family=aarch64 ;;
155         esac
156
157         # This may require adjustment based on CFLAGS
158         local cpu=${CHOST%%-*}
159
160         cat > "${T}/meson.${CHOST}" <<-EOF
161         [binaries]
162         ar = '$(tc-getAR)'
163         c = '$(tc-getCC)'
164         cpp = '$(tc-getCXX)'
165         pkgconfig = '$(tc-getPKG_CONFIG)'
166         strip = '$(tc-getSTRIP)'
167
168         [properties]
169         c_args = $(_meson_env_array "${CFLAGS}")
170         c_link_args = $(_meson_env_array "${LDFLAGS}")
171         cpp_args = $(_meson_env_array "${CXXFLAGS}")
172         cpp_link_args = $(_meson_env_array "${LDFLAGS}")
173         fortran_args = $(_meson_env_array "${FCFLAGS}")
174         objc_args = $(_meson_env_array "${OBJCFLAGS}")
175         objcpp_args = $(_meson_env_array "${OBJCXXFLAGS}")
176
177         [host_machine]
178         system = '${system}'
179         cpu_family = '${cpu_family}'
180         cpu = '${cpu}'
181         endian = '$(tc-endian)'
182         EOF
183 }
184
185 # @FUNCTION: meson_use
186 # @USAGE: <USE flag> [option name]
187 # @DESCRIPTION:
188 # Given a USE flag and meson project option, outputs a string like:
189 #
190 #   -Doption=true
191 #   -Doption=false
192 #
193 # If the project option is unspecified, it defaults to the USE flag.
194 meson_use() {
195         usex "$1" "-D${2-$1}=true" "-D${2-$1}=false"
196 }
197
198 # @FUNCTION: meson_src_configure
199 # @DESCRIPTION:
200 # This is the meson_src_configure function.
201 meson_src_configure() {
202         debug-print-function ${FUNCNAME} "$@"
203
204         # Common args
205         local mesonargs=(
206                 --buildtype plain
207                 --libdir "$(get_libdir)"
208                 --localstatedir "${EPREFIX}/var/lib"
209                 --prefix "${EPREFIX}/usr"
210                 --sysconfdir "${EPREFIX}/etc"
211                 --wrap-mode nodownload
212                 )
213
214         if tc-is-cross-compiler; then
215                 _meson_create_cross_file || die "unable to write meson cross file"
216                 mesonargs+=( --cross-file "${T}/meson.${CHOST}" )
217         fi
218
219         # https://bugs.gentoo.org/625396
220         python_export_utf8_locale
221
222         # Append additional arguments from ebuild
223         mesonargs+=("${emesonargs[@]}")
224
225         BUILD_DIR="${BUILD_DIR:-${WORKDIR}/${P}-build}"
226         set -- meson "${mesonargs[@]}" "$@" \
227                 "${EMESON_SOURCE:-${S}}" "${BUILD_DIR}"
228         echo "$@"
229         tc-env_build "$@" || die
230 }
231
232 # @FUNCTION: meson_src_compile
233 # @DESCRIPTION:
234 # This is the meson_src_compile function.
235 meson_src_compile() {
236         debug-print-function ${FUNCNAME} "$@"
237
238         eninja -C "${BUILD_DIR}"
239 }
240
241 # @FUNCTION: meson_src_test
242 # @DESCRIPTION:
243 # This is the meson_src_test function.
244 meson_src_test() {
245         debug-print-function ${FUNCNAME} "$@"
246
247         eninja -C "${BUILD_DIR}" test
248 }
249
250 # @FUNCTION: meson_src_install
251 # @DESCRIPTION:
252 # This is the meson_src_install function.
253 meson_src_install() {
254         debug-print-function ${FUNCNAME} "$@"
255
256         DESTDIR="${D}" eninja -C "${BUILD_DIR}" install
257         einstalldocs
258 }
259
260 fi