xref: /PHP-7.2/Zend/Zend.m4 (revision 902d39a3)
1dnl
2dnl $Id$
3dnl
4dnl This file contains Zend specific autoconf functions.
5dnl
6
7AC_DEFUN([LIBZEND_CHECK_INT_TYPE],[
8AC_MSG_CHECKING(for $1)
9AC_TRY_COMPILE([
10#if HAVE_SYS_TYPES_H
11#include <sys/types.h>
12#endif
13#if HAVE_INTTYPES_H
14#include <inttypes.h>
15#elif HAVE_STDINT_H
16#include <stdint.h>
17#endif],
18[if (($1 *) 0)
19  return 0;
20if (sizeof ($1))
21  return 0;
22],[
23  AC_DEFINE_UNQUOTED([HAVE_]translit($1,a-z_-,A-Z__), 1,[Define if $1 type is present. ])
24  AC_MSG_RESULT(yes)
25], AC_MSG_RESULT(no)
26)dnl
27])
28
29AC_DEFUN([LIBZEND_BASIC_CHECKS],[
30
31AC_REQUIRE([AC_PROG_YACC])
32AC_REQUIRE([AC_PROG_CC])
33AC_REQUIRE([AC_PROG_CC_C_O])
34AC_REQUIRE([AC_HEADER_STDC])
35
36LIBZEND_BISON_CHECK
37
38dnl Ugly hack to get around a problem with gcc on AIX.
39if test "$CC" = "gcc" -a "$ac_cv_prog_cc_g" = "yes" -a \
40   "`uname -sv`" = "AIX 4"; then
41	CFLAGS=`echo $CFLAGS | sed -e 's/-g//'`
42fi
43
44dnl Hack to work around a Mac OS X cpp problem
45dnl Known versions needing this workaround are 5.3 and 5.4
46if test "$ac_cv_prog_gcc" = "yes" -a "`uname -s`" = "Rhapsody"; then
47        CPPFLAGS="$CPPFLAGS -traditional-cpp"
48fi
49
50AC_CHECK_HEADERS(
51inttypes.h \
52stdint.h \
53limits.h \
54malloc.h \
55string.h \
56unistd.h \
57stdarg.h \
58sys/types.h \
59sys/time.h \
60signal.h \
61unix.h \
62stdlib.h \
63dlfcn.h)
64
65AC_TYPE_SIZE_T
66AC_TYPE_SIGNAL
67
68AC_DEFUN([LIBZEND_LIBDL_CHECKS],[
69AC_CHECK_LIB(dl, dlopen, [LIBS="-ldl $LIBS"])
70AC_CHECK_FUNC(dlopen,[AC_DEFINE(HAVE_LIBDL, 1,[ ])])
71])
72
73AC_DEFUN([LIBZEND_DLSYM_CHECK],[
74dnl
75dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name.
76dnl
77AC_MSG_CHECKING([whether dlsym() requires a leading underscore in symbol names])
78_LT_AC_TRY_DLOPEN_SELF([
79  AC_MSG_RESULT(no)
80], [
81  AC_MSG_RESULT(yes)
82  AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, 1, [Define if dlsym() requires a leading underscore in symbol names. ])
83], [
84  AC_MSG_RESULT(no)
85], [])
86])
87
88dnl This is required for QNX and may be some BSD derived systems
89AC_CHECK_TYPE( uint, unsigned int )
90AC_CHECK_TYPE( ulong, unsigned long )
91
92dnl Check if int32_t and uint32_t are defined
93LIBZEND_CHECK_INT_TYPE(int32_t)
94LIBZEND_CHECK_INT_TYPE(uint32_t)
95
96dnl Checks for library functions.
97AC_FUNC_VPRINTF
98AC_FUNC_MEMCMP
99AC_FUNC_ALLOCA
100AC_CHECK_FUNCS(memcpy strdup getpid kill strtod strtol finite fpclass sigsetjmp)
101AC_ZEND_BROKEN_SPRINTF
102
103AC_CHECK_DECLS([isfinite, isnan, isinf], [], [], [[#include <math.h>]])
104
105ZEND_FP_EXCEPT
106
107ZEND_CHECK_FLOAT_PRECISION
108
109dnl test whether double cast to long preserves least significant bits
110AC_MSG_CHECKING(whether double cast to long preserves least significant bits)
111
112AC_TRY_RUN([
113#include <limits.h>
114
115int main()
116{
117	if (sizeof(long) == 4) {
118		double d = (double) LONG_MIN * LONG_MIN + 2e9;
119
120		if ((long) d == 2e9 && (long) -d == -2e9) {
121			exit(0);
122		}
123	} else if (sizeof(long) == 8) {
124		double correct = 18e18 - ((double) LONG_MIN * -2); /* Subtract ULONG_MAX + 1 */
125
126		if ((long) 18e18 == correct) { /* On 64-bit, only check between LONG_MAX and ULONG_MAX */
127			exit(0);
128		}
129	}
130	exit(1);
131}
132], [
133  AC_DEFINE([ZEND_DVAL_TO_LVAL_CAST_OK], 1, [Define if double cast to long preserves least significant bits])
134  AC_MSG_RESULT(yes)
135], [
136  AC_MSG_RESULT(no)
137], [
138  AC_MSG_RESULT(no)
139])
140
141])
142
143AC_DEFUN([LIBZEND_ENABLE_DEBUG],[
144
145AC_ARG_ENABLE(debug,
146[  --enable-debug          Compile with debugging symbols],[
147  ZEND_DEBUG=$enableval
148],[
149  ZEND_DEBUG=no
150])
151
152])
153
154AC_DEFUN([LIBZEND_OTHER_CHECKS],[
155
156AC_ARG_ENABLE(maintainer-zts,
157[  --enable-maintainer-zts Enable thread safety - for code maintainers only!!],[
158  ZEND_MAINTAINER_ZTS=$enableval
159],[
160  ZEND_MAINTAINER_ZTS=no
161])
162
163AC_ARG_ENABLE(inline-optimization,
164[  --disable-inline-optimization
165                          If building zend_execute.lo fails, try this switch],[
166  ZEND_INLINE_OPTIMIZATION=$enableval
167],[
168  ZEND_INLINE_OPTIMIZATION=yes
169])
170
171AC_MSG_CHECKING(whether to enable thread-safety)
172AC_MSG_RESULT($ZEND_MAINTAINER_ZTS)
173
174AC_MSG_CHECKING(whether to enable inline optimization for GCC)
175AC_MSG_RESULT($ZEND_INLINE_OPTIMIZATION)
176
177AC_MSG_CHECKING(whether to enable Zend debugging)
178AC_MSG_RESULT($ZEND_DEBUG)
179
180if test "$ZEND_DEBUG" = "yes"; then
181  AC_DEFINE(ZEND_DEBUG,1,[ ])
182  echo " $CFLAGS" | grep ' -g' >/dev/null || DEBUG_CFLAGS="-g"
183  if test "$CFLAGS" = "-g -O2"; then
184  	CFLAGS=-g
185  fi
186  test -n "$GCC" && DEBUG_CFLAGS="$DEBUG_CFLAGS -Wall"
187  test -n "$GCC" && test "$USE_MAINTAINER_MODE" = "yes" && \
188    DEBUG_CFLAGS="$DEBUG_CFLAGS -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations"
189else
190  AC_DEFINE(ZEND_DEBUG,0,[ ])
191fi
192
193test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS"
194
195if test "$ZEND_MAINTAINER_ZTS" = "yes"; then
196  AC_DEFINE(ZTS,1,[ ])
197  CFLAGS="$CFLAGS -DZTS"
198  LIBZEND_CPLUSPLUS_CHECKS
199fi
200
201changequote({,})
202if test -n "$GCC" && test "$ZEND_INLINE_OPTIMIZATION" != "yes"; then
203  INLINE_CFLAGS=`echo $ac_n "$CFLAGS $ac_c" | sed s/-O[0-9s]*//`
204else
205  INLINE_CFLAGS="$CFLAGS"
206fi
207changequote([,])
208
209AC_C_INLINE
210
211AC_SUBST(INLINE_CFLAGS)
212
213AC_MSG_CHECKING(target system is Darwin)
214if echo "$target" | grep "darwin" > /dev/null; then
215  AC_DEFINE([DARWIN], 1, [Define if the target system is darwin])
216  AC_MSG_RESULT(yes)
217else
218  AC_MSG_RESULT(no)
219fi
220
221dnl test and set the alignment define for ZEND_MM
222dnl this also does the logarithmic test for ZEND_MM.
223AC_MSG_CHECKING(for MM alignment and log values)
224
225AC_TRY_RUN([
226#include <stdio.h>
227
228typedef union _mm_align_test {
229  void *ptr;
230  double dbl;
231  long lng;
232} mm_align_test;
233
234#if (defined (__GNUC__) && __GNUC__ >= 2)
235#define ZEND_MM_ALIGNMENT (__alignof__ (mm_align_test))
236#else
237#define ZEND_MM_ALIGNMENT (sizeof(mm_align_test))
238#endif
239
240int main()
241{
242  int i = ZEND_MM_ALIGNMENT;
243  int zeros = 0;
244  FILE *fp;
245
246  while (i & ~0x1) {
247    zeros++;
248    i = i >> 1;
249  }
250
251  fp = fopen("conftest.zend", "w");
252  fprintf(fp, "%d %d\n", ZEND_MM_ALIGNMENT, zeros);
253  fclose(fp);
254
255  exit(0);
256}
257], [
258  LIBZEND_MM_ALIGN=`cat conftest.zend | cut -d ' ' -f 1`
259  LIBZEND_MM_ALIGN_LOG2=`cat conftest.zend | cut -d ' ' -f 2`
260  AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT, $LIBZEND_MM_ALIGN, [ ])
261  AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT_LOG2, $LIBZEND_MM_ALIGN_LOG2, [ ])
262], [], [
263  dnl cross-compile needs something here
264  LIBZEND_MM_ALIGN=8
265])
266
267AC_MSG_RESULT(done)
268
269dnl test for memory allocation using mmap(MAP_ANON)
270AC_MSG_CHECKING(for memory allocation using mmap(MAP_ANON))
271
272AC_TRY_RUN([
273#include <sys/types.h>
274#include <sys/stat.h>
275#include <fcntl.h>
276#include <sys/mman.h>
277#include <stdlib.h>
278#include <stdio.h>
279#ifndef MAP_ANON
280# ifdef MAP_ANONYMOUS
281#  define MAP_ANON MAP_ANONYMOUS
282# endif
283#endif
284#ifndef MREMAP_MAYMOVE
285# define MREMAP_MAYMOVE 0
286#endif
287#ifndef MAP_FAILED
288# define MAP_FAILED ((void*)-1)
289#endif
290
291#define SEG_SIZE (256*1024)
292
293int main()
294{
295	void *seg = mmap(NULL, SEG_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
296	if (seg == MAP_FAILED) {
297		return 1;
298	}
299	if (munmap(seg, SEG_SIZE) != 0) {
300		return 2;
301	}
302	return 0;
303}
304], [
305  AC_DEFINE([HAVE_MEM_MMAP_ANON], 1, [Define if the target system has support for memory allocation using mmap(MAP_ANON)])
306  AC_MSG_RESULT(yes)
307], [
308  AC_MSG_RESULT(no)
309], [
310  dnl cross-compile needs something here
311  AC_MSG_RESULT(no)
312])
313
314dnl test for memory allocation using mmap("/dev/zero")
315AC_MSG_CHECKING(for memory allocation using mmap("/dev/zero"))
316
317AC_TRY_RUN([
318#include <sys/types.h>
319#include <sys/stat.h>
320#include <fcntl.h>
321#include <sys/mman.h>
322#include <stdlib.h>
323#include <stdio.h>
324#ifndef MAP_ANON
325# ifdef MAP_ANONYMOUS
326#  define MAP_ANON MAP_ANONYMOUS
327# endif
328#endif
329#ifndef MREMAP_MAYMOVE
330# define MREMAP_MAYMOVE 0
331#endif
332#ifndef MAP_FAILED
333# define MAP_FAILED ((void*)-1)
334#endif
335
336#define SEG_SIZE (256*1024)
337
338int main()
339{
340	int fd;
341	void *seg;
342
343	fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
344	if (fd < 0) {
345		return 1;
346	}
347	seg = mmap(NULL, SEG_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
348	if (seg == MAP_FAILED) {
349		return 2;
350	}
351	if (munmap(seg, SEG_SIZE) != 0) {
352		return 3;
353	}
354	if (close(fd) != 0) {
355		return 4;
356	}
357	return 0;
358}
359], [
360  AC_DEFINE([HAVE_MEM_MMAP_ZERO], 1, [Define if the target system has support for memory allocation using mmap("/dev/zero")])
361  AC_MSG_RESULT(yes)
362], [
363  AC_MSG_RESULT(no)
364], [
365  dnl cross-compile needs something here
366  AC_MSG_RESULT(no)
367])
368
369AC_CHECK_FUNCS(mremap)
370
371
372AC_ARG_ENABLE(zend-signals,
373[  --disable-zend-signals  whether to enable zend signal handling],[
374  ZEND_SIGNALS=$enableval
375],[
376  ZEND_SIGNALS=yes
377])
378
379AC_CHECK_FUNC(sigaction, [
380	AC_DEFINE(HAVE_SIGACTION, 1, [Whether sigaction() is available])
381], [
382	ZEND_SIGNALS=no
383])
384if test "$ZEND_SIGNALS" = "yes"; then
385	AC_DEFINE(ZEND_SIGNALS, 1, [Use zend signal handling])
386	CFLAGS="$CFLAGS -DZEND_SIGNALS"
387fi
388
389AC_MSG_CHECKING(whether to enable zend signal handling)
390AC_MSG_RESULT($ZEND_SIGNALS)
391
392])
393
394AC_DEFUN([LIBZEND_CPLUSPLUS_CHECKS],[
395
396])
397
398AC_MSG_CHECKING(whether /dev/urandom exists)
399if test -r "/dev/urandom" && test -c "/dev/urandom"; then
400  AC_DEFINE([HAVE_DEV_URANDOM], 1, [Define if the target system has /dev/urandom device])
401  AC_MSG_RESULT(yes)
402else
403  AC_MSG_RESULT(no)
404fi
405
406AC_MSG_CHECKING(whether /dev/arandom exists)
407if test -r "/dev/arandom" && test -c "/dev/arandom"; then
408  AC_DEFINE([HAVE_DEV_ARANDOM], 1, [Define if the target system has /dev/arandom device])
409  AC_MSG_RESULT(yes)
410else
411  AC_MSG_RESULT(no)
412fi
413
414AC_ARG_ENABLE(gcc-global-regs,
415[  --disable-gcc-global-regs
416                          whether to enable GCC global register variables],[
417  ZEND_GCC_GLOBAL_REGS=$enableval
418],[
419  ZEND_GCC_GLOBAL_REGS=yes
420])
421AC_MSG_CHECKING(for global register variables support)
422if test "$ZEND_GCC_GLOBAL_REGS" != "no"; then
423  AC_TRY_COMPILE([
424#if defined(__GNUC__)
425# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
426#else
427# define ZEND_GCC_VERSION 0
428#endif
429#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(i386)
430# define ZEND_VM_FP_GLOBAL_REG "%esi"
431# define ZEND_VM_IP_GLOBAL_REG "%edi"
432#elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__x86_64__)
433# define ZEND_VM_FP_GLOBAL_REG "%r14"
434# define ZEND_VM_IP_GLOBAL_REG "%r15"
435#elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__powerpc64__)
436# define ZEND_VM_FP_GLOBAL_REG "r28"
437# define ZEND_VM_IP_GLOBAL_REG "r29"
438#elif defined(__IBMC__) && ZEND_GCC_VERSION >= 4002 && defined(__powerpc64__)
439# define ZEND_VM_FP_GLOBAL_REG "r28"
440# define ZEND_VM_IP_GLOBAL_REG "r29"
441#else
442# error "global register variables are not supported"
443#endif
444typedef int (*opcode_handler_t)(void);
445register void *FP  __asm__(ZEND_VM_FP_GLOBAL_REG);
446register const opcode_handler_t *IP __asm__(ZEND_VM_IP_GLOBAL_REG);
447int emu(const opcode_handler_t *ip, void *fp) {
448	const opcode_handler_t *orig_ip = IP;
449	void *orig_fp = FP;
450	IP = ip;
451	FP = fp;
452	while ((*ip)());
453	FP = orig_fp;
454	IP = orig_ip;
455}
456  ], [
457  ], [
458    ZEND_GCC_GLOBAL_REGS=yes
459  ], [
460    ZEND_GCC_GLOBAL_REGS=no
461  ])
462fi
463if test "$ZEND_GCC_GLOBAL_REGS" = "yes"; then
464  AC_DEFINE([HAVE_GCC_GLOBAL_REGS], 1, [Define if the target system has support for global register variables])
465else
466  HAVE_GCC_GLOBAL_REGS=no
467fi
468AC_MSG_RESULT($ZEND_GCC_GLOBAL_REGS)
469
470dnl
471dnl Check if atof() accepts NAN
472dnl
473AC_CACHE_CHECK(whether atof() accepts NAN, ac_cv_atof_accept_nan,[
474AC_TRY_RUN([
475#include <math.h>
476#include <stdlib.h>
477
478#ifdef HAVE_ISNAN
479#define zend_isnan(a) isnan(a)
480#elif defined(HAVE_FPCLASS)
481#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
482#else
483#define zend_isnan(a) 0
484#endif
485
486int main(int argc, char** argv)
487{
488	return zend_isnan(atof("NAN")) ? 0 : 1;
489}
490],[
491  ac_cv_atof_accept_nan=yes
492],[
493  ac_cv_atof_accept_nan=no
494],[
495  ac_cv_atof_accept_nan=no
496])])
497if test "$ac_cv_atof_accept_nan" = "yes"; then
498  AC_DEFINE([HAVE_ATOF_ACCEPTS_NAN], 1, [whether atof() accepts NAN])
499fi
500
501dnl
502dnl Check if atof() accepts INF
503dnl
504AC_CACHE_CHECK(whether atof() accepts INF, ac_cv_atof_accept_inf,[
505AC_TRY_RUN([
506#include <math.h>
507#include <stdlib.h>
508
509#ifdef HAVE_ISINF
510#define zend_isinf(a) isinf(a)
511#elif defined(INFINITY)
512/* Might not work, but is required by ISO C99 */
513#define zend_isinf(a) (((a)==INFINITY)?1:0)
514#elif defined(HAVE_FPCLASS)
515#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF))
516#else
517#define zend_isinf(a) 0
518#endif
519
520int main(int argc, char** argv)
521{
522	return zend_isinf(atof("INF")) && zend_isinf(atof("-INF")) ? 0 : 1;
523}
524],[
525  ac_cv_atof_accept_inf=yes
526],[
527  ac_cv_atof_accept_inf=no
528],[
529  ac_cv_atof_accept_inf=no
530])])
531if test "$ac_cv_atof_accept_inf" = "yes"; then
532  AC_DEFINE([HAVE_ATOF_ACCEPTS_INF], 1, [whether atof() accepts INF])
533fi
534
535dnl
536dnl Check if HUGE_VAL == INF
537dnl
538AC_CACHE_CHECK(whether HUGE_VAL == INF, ac_cv_huge_val_inf,[
539AC_TRY_RUN([
540#include <math.h>
541#include <stdlib.h>
542
543#ifdef HAVE_ISINF
544#define zend_isinf(a) isinf(a)
545#elif defined(INFINITY)
546/* Might not work, but is required by ISO C99 */
547#define zend_isinf(a) (((a)==INFINITY)?1:0)
548#elif defined(HAVE_FPCLASS)
549#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF))
550#else
551#define zend_isinf(a) 0
552#endif
553
554int main(int argc, char** argv)
555{
556	return zend_isinf(HUGE_VAL) ? 0 : 1;
557}
558],[
559  ac_cv_huge_val_inf=yes
560],[
561  ac_cv_huge_val_inf=no
562],[
563  ac_cv_huge_val_inf=yes
564])])
565dnl This is the most probable fallback so we assume yes in case of cross compile.
566if test "$ac_cv_huge_val_inf" = "yes"; then
567  AC_DEFINE([HAVE_HUGE_VAL_INF], 1, [whether HUGE_VAL == INF])
568fi
569
570dnl
571dnl Check if HUGE_VAL + -HUGEVAL == NAN
572dnl
573AC_CACHE_CHECK(whether HUGE_VAL + -HUGEVAL == NAN, ac_cv_huge_val_nan,[
574AC_TRY_RUN([
575#include <math.h>
576#include <stdlib.h>
577
578#ifdef HAVE_ISNAN
579#define zend_isnan(a) isnan(a)
580#elif defined(HAVE_FPCLASS)
581#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
582#else
583#define zend_isnan(a) 0
584#endif
585
586int main(int argc, char** argv)
587{
588#if defined(__sparc__) && !(__GNUC__ >= 3)
589	/* prevent bug #27830 */
590	return 1;
591#else
592	return zend_isnan(HUGE_VAL + -HUGE_VAL) ? 0 : 1;
593#endif
594}
595],[
596  ac_cv_huge_val_nan=yes
597],[
598  ac_cv_huge_val_nan=no
599],[
600  ac_cv_huge_val_nan=yes
601])])
602dnl This is the most probable fallback so we assume yes in case of cross compile.
603if test "$ac_cv_huge_val_nan" = "yes"; then
604  AC_DEFINE([HAVE_HUGE_VAL_NAN], 1, [whether HUGE_VAL + -HUGEVAL == NAN])
605fi
606