meson.build revision 338bf337
1# Copyright © 2018 Intel Corporation
2
3# Permission is hereby granted, free of charge, to any person obtaining a copy
4# of this software and associated documentation files (the "Software"), to deal
5# in the Software without restriction, including without limitation the rights
6# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7# copies of the Software, and to permit persons to whom the Software is
8# furnished to do so, subject to the following conditions:
9
10# The above copyright notice and this permission notice shall be included in
11# all copies or substantial portions of the Software.
12
13# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19# SOFTWARE.
20
21project(
22  'pixman',
23  ['c'],
24  version : '0.38.0',
25  license : 'MIT',
26  meson_version : '>= 0.47.2',
27  default_options : ['buildtype=debugoptimized'],
28)
29
30config = configuration_data()
31cc = meson.get_compiler('c')
32null_dep = dependency('', required : false)
33
34add_project_arguments(
35  cc.get_supported_arguments([
36    '-Wdeclaration-after-statement',
37    '-fno-strict-aliasing',
38    '-fvisibility=hidden',
39  ]),
40  language : ['c']
41)
42
43# GCC and Clang both ignore -Wno options that they don't recognize, so test for
44# -W<opt>, then add -Wno-<opt> if it's ignored
45foreach opt : ['unused-local-typedefs']
46  if cc.has_argument('-W' + opt)
47    add_project_arguments(['-Wno-' + opt], language : ['c'])
48  endif
49endforeach
50
51use_loongson_mmi = get_option('loongson-mmi')
52have_loongson_mmi = false
53loongson_mmi_flags = ['-mach=loongson2f']
54if not use_loongson_mmi.disabled()
55  if host_machine.cpu_family() == 'mips64' and cc.compiles('''
56      #ifndef __mips_loongson_vector_rev
57      #error "Loongson Multimedia Instructions are only available on Loongson"
58      #endif
59      #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
60      #error "Need GCC >= 4.4 for Loongson MMI compilation"
61      #endif
62      #include "pixman/loongson-mmintrin.h"
63      int main () {
64        union {
65          __m64 v;
66          char c[8];
67        } a = { .c = {1, 2, 3, 4, 5, 6, 7, 8} };
68        int b = 4;
69        __m64 c = _mm_srli_pi16 (a.v, b);
70        return 0;
71      }''',
72      args : loongson_mmi_flags,
73      name : 'Loongson MMI Intrinsic Support')
74    have_loongson_mmi = true
75  endif
76endif
77
78if have_loongson_mmi
79  config.set10('USE_LOONGSON_MMI', true)
80elif use_loongson_mmi.enabled()
81  error('Loongson MMI Support unavailable, but required')
82endif
83
84use_mmx = get_option('mmx')
85have_mmx = false
86mmx_flags = ['-mmmx', '-Winline']
87if not use_mmx.disabled()
88  if host_machine.cpu_family() == 'x86_64'
89    have_mmx = true
90  elif host_machine.cpu_family() == 'x86' and cc.compiles('''
91      #include <mmintrin.h>
92      #include <stdint.h>
93
94      /* Check support for block expressions */
95      #define _mm_shuffle_pi16(A, N)                    \
96        ({                                              \
97        __m64 ret;                                      \
98                                                        \
99        /* Some versions of clang will choke on K */    \
100        asm ("pshufw %2, %1, %0\n\t"                    \
101             : "=y" (ret)                               \
102             : "y" (A), "K" ((const int8_t)N)           \
103        );                                              \
104                                                        \
105        ret;                                            \
106        })
107
108      int main () {
109          __m64 v = _mm_cvtsi32_si64 (1);
110          __m64 w;
111
112          w = _mm_shuffle_pi16(v, 5);
113
114          /* Some versions of clang will choke on this */
115          asm ("pmulhuw %1, %0\n\t"
116               : "+y" (w)
117               : "y" (v)
118          );
119
120          return _mm_cvtsi64_si32 (v);
121      }''',
122      args : mmx_flags,
123      name : 'MMX Intrinsic Support')
124    have_mmx = true
125  endif
126endif
127
128if have_mmx
129  config.set10('USE_X86_MMX', true)
130elif use_mmx.enabled()
131  error('MMX Support unavailable, but required')
132endif
133
134use_sse2 = get_option('sse2')
135have_sse2 = false
136sse2_flags = ['-msse2', '-Winline']
137if not use_sse2.disabled()
138  if host_machine.cpu_family() == 'x86'
139    if cc.compiles('''
140        #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
141        #   if !defined(__amd64__) && !defined(__x86_64__)
142        #      error "Need GCC >= 4.2 for SSE2 intrinsics on x86"
143        #   endif
144        #endif
145        #include <mmintrin.h>
146        #include <xmmintrin.h>
147        #include <emmintrin.h>
148        int param;
149        int main () {
150          __m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c;
151          c = _mm_xor_si128 (a, b);
152          return _mm_cvtsi128_si32(c);
153        }''',
154        args : sse2_flags,
155        name : 'SSE2 Intrinsic Support')
156      have_sse2 = true
157    endif
158  elif host_machine.cpu_family() == 'x86_64'
159    have_sse2 = true
160  endif
161endif
162
163if have_sse2
164  config.set10('USE_SSE2', true)
165elif use_sse2.enabled()
166  error('sse2 Support unavailable, but required')
167endif
168
169use_ssse3 = get_option('ssse3')
170have_ssse3 = false
171ssse3_flags =['-mssse3', '-Winline']
172if not use_ssse3.disabled()
173  if host_machine.cpu_family().startswith('x86')
174    if cc.compiles('''
175        #include <mmintrin.h>
176        #include <xmmintrin.h>
177        #include <emmintrin.h>
178        int param;
179        int main () {
180          __m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c;
181          c = _mm_xor_si128 (a, b);
182          return _mm_cvtsi128_si32(c);
183        }''',
184        args : ssse3_flags,
185        name : 'SSSE3 Intrinsic Support')
186      have_ssse3 = true
187    endif
188  endif
189endif
190
191if have_ssse3
192  config.set10('USE_SSSE3', true)
193elif use_ssse3.enabled()
194  error('ssse3 Support unavailable, but required')
195endif
196
197use_vmx = get_option('vmx')
198have_vmx = false
199vmx_flags = ['-maltivec', '-mabi=altivec']
200if not use_vmx.disabled()
201  if host_machine.cpu_family().startswith('ppc')
202    if cc.compiles('''
203        #include <altivec.h>
204        int main () {
205            vector unsigned int v = vec_splat_u32 (1);
206            v = vec_sub (v, v);
207            return 0;
208        }''',
209        args : vmx_flags,
210        name : 'VMX/Altivec Intrinsic Support')
211      have_vmx = true
212    endif
213  endif
214endif
215
216if have_vmx
217  config.set10('USE_VMX', true)
218elif use_vmx.enabled()
219  error('vmx Support unavailable, but required')
220endif
221
222use_armv6_simd = get_option('arm-simd')
223have_armv6_simd = false
224if not use_armv6_simd.disabled()
225  if host_machine.cpu_family() == 'arm'
226    if cc.compiles('''
227        .text
228        .arch armv6
229        .object_arch armv4
230        .arm
231        .altmacro
232        #ifndef __ARM_EABI__
233        #error EABI is required (to be sure that calling conventions are compatible)
234        #endif
235        pld [r0]
236        uqadd8 r0, r0, r0
237        ''',
238        args : ['-x assembler-with-cpp'],
239        name : 'ARMv6 SIMD Intrinsic Support')
240      have_armv6_simd = true
241    endif
242  endif
243endif
244
245if have_armv6_simd
246  config.set10('USE_ARM_SIMD', true)
247elif use_armv6_simd.enabled()
248  error('ARMv6 SIMD Support unavailable, but required')
249endif
250
251use_neon = get_option('neon')
252have_neon = false
253if not use_neon.disabled()
254  if host_machine.cpu_family() == 'arm'
255    if cc.compiles('''
256        .text
257        .fpu neon
258        .arch armv7a
259        .object_arch armv4
260        .eabi_attribute 10, 0
261        .arm
262        .altmacro
263        #ifndef __ARM_EABI__
264        #error EABI is required (to be sure that calling conventions are compatible)
265        #endif
266        pld [r0]
267        vmovn.u16 d0, q0
268        ''',
269        args : ['-x assembler-with-cpp'],
270        name : 'NEON Intrinsic Support')
271      have_neon = true
272    endif
273  endif
274endif
275
276if have_neon
277  config.set10('USE_ARM_NEON', true)
278elif use_neon.enabled()
279  error('NEON Support unavailable, but required')
280endif
281
282use_iwmmxt = get_option('iwmmxt')
283have_iwmmxt = false
284iwmmxt_flags = ['-flax-vector-conversions', '-Winline']
285if not use_iwmmxt.disabled()
286  if get_option('iwmmxt2')
287    iwmmxt_flags += '-march=iwmmxt2'
288  else
289    iwmmxt_flags += '-march=iwmmxt'
290  endif
291
292  if host_machine.cpu_family() == 'arm'
293    if cc.compiles('''
294        #ifndef __IWMMXT__
295        #error "IWMMXT not enabled (with -march=iwmmxt)"
296        #endif
297        #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
298        #error "Need GCC >= 4.8 for IWMMXT intrinsics"
299        #endif
300        #include <mmintrin.h>
301        int main () {
302          union {
303            __m64 v;
304            char c[8];
305          } a = { .c = {1, 2, 3, 4, 5, 6, 7, 8} };
306          int b = 4;
307          __m64 c = _mm_srli_si64 (a.v, b);
308        }
309        ''',
310        args : iwmmxt_flags,
311        name : 'IWMMXT Intrinsic Support')
312      have_iwmmxt = true
313    endif
314  endif
315endif
316
317if have_iwmmxt
318  config.set10('USE_ARM_IWMMXT', true)
319elif use_iwmmxt.enabled()
320  error('NEON Support unavailable, but required')
321endif
322
323use_mips_dspr2 = get_option('mips-dspr2')
324have_mips_dspr2 = false
325mips_dspr2_flags = ['-mdspr2']
326if not use_mips_dspr2.disabled()
327  if host_machine.cpu_family() == 'mips32'
328    if cc.compiles('''
329        #if !(defined(__mips__) &&  __mips_isa_rev >= 2)
330        #error MIPS DSPr2 is currently only available on MIPS32r2 platforms.
331        #endif
332        int
333        main ()
334        {
335            int c = 0, a = 0, b = 0;
336            __asm__ __volatile__ (
337                "precr.qb.ph %[c], %[a], %[b]          \n\t"
338                : [c] "=r" (c)
339                : [a] "r" (a), [b] "r" (b)
340            );
341            return c;
342        }''',
343        args : mipds_dspr2_flags,
344        name : 'DSPr2 Intrinsic Support')
345      have_mips_dspr2 = true
346    endif
347  endif
348endif
349
350if have_mips_dspr2
351  config.set10('USE_MIPS_DSPR2', true)
352elif use_mips_dspr2.enabled()
353  error('MIPS DSPr2 Support unavailable, but required')
354endif
355
356use_gnu_asm = get_option('gnu-inline-asm')
357if not use_gnu_asm.disabled()
358  if cc.compiles('''
359      int main () {
360        /* Most modern architectures have a NOP instruction, so this is a fairly generic test. */
361        asm volatile ( "\tnop\n" : : : "cc", "memory" );
362        return 0;
363      }
364      ''',
365      name : 'GNU Inline ASM support.')
366    config.set10('USE_GCC_INLINE_ASM', true)
367  elif use_gnu_asm.enabled()
368    error('GNU inline assembly support missing but required.')
369  endif
370endif
371
372if get_option('timers')
373  config.set('PIXMAN_TIMERS', 1)
374endif
375if get_option('gnuplot')
376  config.set('PIXMAN_GNUPLOT', 1)
377endif
378
379use_openmp = get_option('openmp')
380dep_openmp = null_dep
381if not use_openmp.disabled()
382  dep_openmp = dependency('openmp', required : get_option('openmp'))
383  if dep_openmp.found()
384    config.set10('USE_OPENMP', true)
385  endif
386endif
387
388dep_gtk = dependency('gtk+-2.0', version : '>= 2.16', required : get_option('gtk'))
389dep_glib = dependency('glib-2.0', required : get_option('gtk'))
390dep_pixman = dependency('pixman-1', required : get_option('gtk'),
391                        version : '>= ' + meson.project_version())
392dep_png = dependency('libpng', required : get_option('libpng'))
393if dep_png.found()
394  config.set('HAVE_LIBPNG', 1)
395endif
396dep_m = cc.find_library('m', required : false)
397dep_threads = dependency('threads')
398if dep_threads.found()
399  config.set('HAVE_PTHREADS', 1)
400endif
401
402funcs = ['sigaction', 'alarm', 'mprotect', 'getpagesize', 'mmap']
403# mingw claimes to have posix_memalign, but it doesn't
404if host_machine.system() != 'windows'
405  funcs += 'posix_memalign'
406endif
407
408foreach f : funcs
409  if cc.has_function(f)
410    config.set('HAVE_@0@'.format(f.to_upper()), 1)
411  endif
412endforeach
413
414if cc.has_function('gettimeofday')
415  config.set('HAVE_GETTIMEOFDAY', 1)
416endif
417
418# This is only used in one test, that defines _GNU_SOURCE
419if cc.has_function('feenableexcept',
420                   prefix : '#define _GNU_SOURCE\n#include <fenv.h>',
421                   dependencies : dep_m)
422  config.set('HAVE_FEENABLEEXCEPT', 1)
423endif
424
425if cc.has_header_symbol('fenv.h', 'FE_DIVBYZERO')
426  config.set('HAVE_FEDIVBYZERO', 1)
427endif
428
429foreach h : ['sys/mman.h', 'fenv.h', 'unistd.h']
430  if cc.check_header(h)
431    config.set('HAVE_@0@'.format(h.underscorify().to_upper()), 1)
432  endif
433endforeach
434
435if (host_machine.system() == 'windows' and
436    cc.compiles('int __declspec(thread) foo;', name : 'TLS via __declspec(thread)'))
437  config.set('TLS', '__declspec(thread)')
438elif cc.compiles('int __thread foo;', name : 'TLS via __thread')
439  config.set('TLS', '__thread')
440endif
441
442if cc.links('''
443    static int x = 1;
444    static void __attribute__((constructor)) constructor_function () { x = 0; }
445    int main (void) { return x; }
446    ''',
447    name : '__attribute__((constructor))')
448  config.set('TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR', 1)
449endif
450
451if cc.links(
452    ' __float128 a = 1.0Q, b = 2.0Q; int main (void) { return a + b; }',
453    name : 'Has float128 support')
454  config.set('HAVE_FLOAT128', 1)
455endif
456
457if cc.has_function('clz')
458  config.set('HAVE_BUILTIN_CLZ', 1)
459endif
460
461if cc.links('''
462    unsigned int __attribute__ ((vector_size(16))) e, a, b;
463    int main (void) { e = a - ((b << 27) + (b >> (32 - 27))) + 1; return e[0]; }
464    ''',
465    name : 'Support for GCC vector extensions')
466  config.set('HAVE_GCC_VECTOR_EXTENSIONS', 1)
467endif
468
469if host_machine.endian() == 'big'
470  config.set('WORDS_BIGENDIAN', 1)
471endif
472
473# Required to make pixman-private.h
474config.set('PACKAGE', 'foo')
475
476version_conf = configuration_data()
477split = meson.project_version().split('.')
478version_conf.set('PIXMAN_VERSION_MAJOR', split[0])
479version_conf.set('PIXMAN_VERSION_MINOR', split[1])
480version_conf.set('PIXMAN_VERSION_MICRO', split[2])
481
482add_project_arguments('-DHAVE_CONFIG_H', language : ['c'])
483
484subdir('pixman')
485subdir('test')
486subdir('demos')
487
488pkg = import('pkgconfig')
489pkg.generate(
490  name : 'Pixman',
491  filebase : 'pixman-1',
492  description : 'The pixman library (version 1)',
493  libraries : libpixman,
494  subdirs: 'pixman-1',
495  version : meson.project_version(),
496)
497