xref: /php-src/ext/opcache/config.m4 (revision ff76cb73)
1PHP_ARG_ENABLE([opcache],
2  [whether to enable Zend OPcache support],
3  [AS_HELP_STRING([--disable-opcache],
4    [Disable Zend OPcache support])],
5  [yes])
6
7PHP_ARG_ENABLE([huge-code-pages],
8  [whether to enable copying PHP CODE pages into HUGE PAGES],
9  [AS_HELP_STRING([--disable-huge-code-pages],
10    [Disable copying PHP CODE pages into HUGE PAGES])],
11  [yes],
12  [no])
13
14PHP_ARG_ENABLE([opcache-jit],
15  [whether to enable JIT],
16  [AS_HELP_STRING([--disable-opcache-jit],
17    [Disable JIT])],
18  [yes],
19  [no])
20
21PHP_ARG_WITH([capstone],,
22  [AS_HELP_STRING([--with-capstone],
23    [support opcache JIT disassembly through capstone])],
24  [no],
25  [no])
26
27if test "$PHP_OPCACHE" != "no"; then
28
29  dnl Always build as shared extension
30  ext_shared=yes
31
32  if test "$PHP_HUGE_CODE_PAGES" = "yes"; then
33    AC_DEFINE(HAVE_HUGE_CODE_PAGES, 1, [Define to enable copying PHP CODE pages into HUGE PAGES (experimental)])
34  fi
35
36  if test "$PHP_OPCACHE_JIT" = "yes"; then
37    case $host_cpu in
38      i[[34567]]86*|x86*|aarch64|amd64)
39        ;;
40      *)
41        AC_MSG_WARN([JIT not supported by host architecture])
42        PHP_OPCACHE_JIT=no
43        ;;
44    esac
45    if test "$host_vendor" = "apple" && test "$host_cpu" = "aarch64" && test "$PHP_THREAD_SAFETY" = "yes"; then
46      AC_MSG_WARN([JIT not supported on Apple Silicon with ZTS])
47      PHP_OPCACHE_JIT=no
48    fi
49  fi
50
51  if test "$PHP_OPCACHE_JIT" = "yes" ; then
52    AC_DEFINE(HAVE_JIT, 1, [Define to enable JIT])
53    AC_DEFINE(ZEND_JIT_IR, 1, [Use JIT IR framework])
54    ZEND_JIT_SRC="jit/zend_jit.c jit/zend_jit_vm_helpers.c jit/ir/ir.c jit/ir/ir_strtab.c \
55		jit/ir/ir_cfg.c	jit/ir/ir_sccp.c jit/ir/ir_gcm.c jit/ir/ir_ra.c jit/ir/ir_save.c \
56		jit/ir/ir_dump.c jit/ir/ir_gdb.c jit/ir/ir_perf.c jit/ir/ir_check.c \
57		jit/ir/ir_patch.c jit/ir/ir_emit.c"
58
59    dnl Find out which ABI we are using.
60    case $host_alias in
61      x86_64-*-darwin*)
62        IR_TARGET=IR_TARGET_X64
63        DASM_FLAGS="-D X64APPLE=1 -D X64=1"
64        DASM_ARCH="x86"
65        ;;
66      *x86_64*|amd64-*-freebsd*)
67        IR_TARGET=IR_TARGET_X64
68        DASM_FLAGS="-D X64=1"
69        DASM_ARCH="x86"
70        ;;
71      i[[34567]]86*)
72        IR_TARGET=IR_TARGET_X86
73        DASM_ARCH="x86"
74        ;;
75      x86*)
76        IR_TARGET=IR_TARGET_X86
77        DASM_ARCH="x86"
78        ;;
79      aarch64*)
80        IR_TARGET=IR_TARGET_AARCH64
81        DASM_ARCH="aarch64"
82        ;;
83     esac
84
85    AS_IF([test x"$with_capstone" = "xyes"],[
86      PKG_CHECK_MODULES([CAPSTONE],[capstone >= 3.0.0],[
87        AC_DEFINE([HAVE_CAPSTONE], [1], [Capstone is available])
88        PHP_EVAL_LIBLINE($CAPSTONE_LIBS, OPCACHE_SHARED_LIBADD)
89        PHP_EVAL_INCLINE($CAPSTONE_CFLAGS)
90        ZEND_JIT_SRC="$ZEND_JIT_SRC jit/ir/ir_disasm.c"
91      ],[
92        AC_MSG_ERROR([capstone >= 3.0 required but not found])
93      ])
94    ])
95
96    PHP_SUBST(IR_TARGET)
97    PHP_SUBST(DASM_FLAGS)
98    PHP_SUBST(DASM_ARCH)
99
100    JIT_CFLAGS="-I@ext_builddir@/jit/ir -D${IR_TARGET} -DIR_PHP"
101    if test "$ZEND_DEBUG" = "yes"; then
102      JIT_CFLAGS="${JIT_CFLAGS} -DIR_DEBUG"
103    fi
104  fi
105
106  AC_CHECK_FUNCS([mprotect shm_create_largepage])
107
108  AC_MSG_CHECKING(for sysvipc shared memory support)
109  AC_RUN_IFELSE([AC_LANG_SOURCE([[
110#include <sys/types.h>
111#include <sys/wait.h>
112#include <sys/ipc.h>
113#include <sys/shm.h>
114#include <unistd.h>
115#include <string.h>
116
117int main(void) {
118  pid_t pid;
119  int status;
120  int ipc_id;
121  char *shm;
122  struct shmid_ds shmbuf;
123
124  ipc_id = shmget(IPC_PRIVATE, 4096, (IPC_CREAT | SHM_R | SHM_W));
125  if (ipc_id == -1) {
126    return 1;
127  }
128
129  shm = shmat(ipc_id, NULL, 0);
130  if (shm == (void *)-1) {
131    shmctl(ipc_id, IPC_RMID, NULL);
132    return 2;
133  }
134
135  if (shmctl(ipc_id, IPC_STAT, &shmbuf) != 0) {
136    shmdt(shm);
137    shmctl(ipc_id, IPC_RMID, NULL);
138    return 3;
139  }
140
141  shmbuf.shm_perm.uid = getuid();
142  shmbuf.shm_perm.gid = getgid();
143  shmbuf.shm_perm.mode = 0600;
144
145  if (shmctl(ipc_id, IPC_SET, &shmbuf) != 0) {
146    shmdt(shm);
147    shmctl(ipc_id, IPC_RMID, NULL);
148    return 4;
149  }
150
151  shmctl(ipc_id, IPC_RMID, NULL);
152
153  strcpy(shm, "hello");
154
155  pid = fork();
156  if (pid < 0) {
157    return 5;
158  } else if (pid == 0) {
159    strcpy(shm, "bye");
160    return 6;
161  }
162  if (wait(&status) != pid) {
163    return 7;
164  }
165  if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
166    return 8;
167  }
168  if (strcmp(shm, "bye") != 0) {
169    return 9;
170  }
171  return 0;
172}
173]])],[have_shm_ipc=yes],[have_shm_ipc=no],[have_shm_ipc=no])
174  if test "$have_shm_ipc" = "yes"; then
175    AC_DEFINE(HAVE_SHM_IPC, 1, [Define if you have SysV IPC SHM support])
176  fi
177  AC_MSG_RESULT([$have_shm_ipc])
178
179  AC_MSG_CHECKING(for mmap() using MAP_ANON shared memory support)
180  AC_RUN_IFELSE([AC_LANG_SOURCE([[
181#include <sys/types.h>
182#include <sys/wait.h>
183#include <sys/mman.h>
184#include <unistd.h>
185#include <string.h>
186
187#ifndef MAP_ANON
188# ifdef MAP_ANONYMOUS
189#  define MAP_ANON MAP_ANONYMOUS
190# endif
191#endif
192#ifndef MAP_FAILED
193# define MAP_FAILED ((void*)-1)
194#endif
195
196int main(void) {
197  pid_t pid;
198  int status;
199  char *shm;
200
201  shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
202  if (shm == MAP_FAILED) {
203    return 1;
204  }
205
206  strcpy(shm, "hello");
207
208  pid = fork();
209  if (pid < 0) {
210    return 5;
211  } else if (pid == 0) {
212    strcpy(shm, "bye");
213    return 6;
214  }
215  if (wait(&status) != pid) {
216    return 7;
217  }
218  if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
219    return 8;
220  }
221  if (strcmp(shm, "bye") != 0) {
222    return 9;
223  }
224  return 0;
225}
226]])],[have_shm_mmap_anon=yes],[have_shm_mmap_anon=no],[
227  case $host_alias in
228    *linux*|*midipix)
229      have_shm_mmap_anon=yes
230      ;;
231    *)
232      have_shm_mmap_anon=no
233      ;;
234  esac
235])
236  if test "$have_shm_mmap_anon" = "yes"; then
237    AC_DEFINE(HAVE_SHM_MMAP_ANON, 1, [Define if you have mmap(MAP_ANON) SHM support])
238  fi
239  AC_MSG_RESULT([$have_shm_mmap_anon])
240
241  dnl Check POSIX shared memory object operations and link required library as
242  dnl needed: rt (older Linux and Solaris <= 10). Most systems have it in the C
243  dnl standard library (newer Linux, illumos, Solaris 11.4, macOS, BSD-based
244  dnl systems...). Haiku has it in the root library, which is linked by default.
245  LIBS_save="$LIBS"
246  LIBS=
247  AC_SEARCH_LIBS([shm_open], [rt],
248    [AC_CACHE_CHECK([for mmap() using shm_open() shared memory support],
249      [php_cv_shm_mmap_posix],
250      [AC_RUN_IFELSE([AC_LANG_SOURCE([[
251#include <sys/types.h>
252#include <sys/wait.h>
253#include <sys/mman.h>
254#include <sys/stat.h>
255#include <fcntl.h>
256#include <unistd.h>
257#include <string.h>
258#include <stdlib.h>
259#include <stdio.h>
260
261#ifndef MAP_FAILED
262# define MAP_FAILED ((void*)-1)
263#endif
264
265int main(void) {
266  pid_t pid;
267  int status;
268  int fd;
269  char *shm;
270  char tmpname[4096];
271
272  sprintf(tmpname,"/opcache.test.shm.%dXXXXXX", getpid());
273  if (mktemp(tmpname) == NULL) {
274    return 1;
275  }
276  fd = shm_open(tmpname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
277  if (fd == -1) {
278    return 2;
279  }
280  if (ftruncate(fd, 4096) < 0) {
281    close(fd);
282    shm_unlink(tmpname);
283    return 3;
284  }
285
286  shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
287  if (shm == MAP_FAILED) {
288    return 4;
289  }
290  shm_unlink(tmpname);
291  close(fd);
292
293  strcpy(shm, "hello");
294
295  pid = fork();
296  if (pid < 0) {
297    return 5;
298  } else if (pid == 0) {
299    strcpy(shm, "bye");
300    return 6;
301  }
302  if (wait(&status) != pid) {
303    return 7;
304  }
305  if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
306    return 8;
307  }
308  if (strcmp(shm, "bye") != 0) {
309    return 9;
310  }
311  return 0;
312}]])],
313      [php_cv_shm_mmap_posix=yes],
314      [php_cv_shm_mmap_posix=no],
315      [php_cv_shm_mmap_posix=no])
316    ])
317
318    if test "$php_cv_shm_mmap_posix" = "yes"; then
319      AS_VAR_IF([ac_cv_search_shm_open], ["none required"],,
320        [OPCACHE_SHARED_LIBADD="$OPCACHE_SHARED_LIBADD $ac_cv_search_shm_open"])
321      AC_DEFINE([HAVE_SHM_MMAP_POSIX], [1],
322        [Define if you have POSIX mmap() SHM support])
323    fi
324  ])
325  LIBS="$LIBS_save"
326
327  PHP_NEW_EXTENSION(opcache,
328	ZendAccelerator.c \
329	zend_accelerator_blacklist.c \
330	zend_accelerator_debug.c \
331	zend_accelerator_hash.c \
332	zend_accelerator_module.c \
333	zend_persist.c \
334	zend_persist_calc.c \
335	zend_file_cache.c \
336	zend_shared_alloc.c \
337	zend_accelerator_util_funcs.c \
338	shared_alloc_shm.c \
339	shared_alloc_mmap.c \
340	shared_alloc_posix.c \
341	$ZEND_JIT_SRC,
342	shared,,"-Wno-implicit-fallthrough -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 ${JIT_CFLAGS}",,yes)
343
344  PHP_ADD_EXTENSION_DEP(opcache, pcre)
345
346  if test "$have_shm_ipc" != "yes" && test "$php_cv_shm_mmap_posix" != "yes" && test "$have_shm_mmap_anon" != "yes"; then
347    AC_MSG_ERROR([No supported shared memory caching support was found when configuring opcache. Check config.log for any errors or missing dependencies.])
348  fi
349
350  if test "$PHP_OPCACHE_JIT" = "yes"; then
351    PHP_ADD_BUILD_DIR([$ext_builddir/jit], 1)
352    PHP_ADD_BUILD_DIR([$ext_builddir/jit/ir], 1)
353    PHP_ADD_MAKEFILE_FRAGMENT($ext_srcdir/jit/Makefile.frag)
354  fi
355  PHP_SUBST(OPCACHE_SHARED_LIBADD)
356fi
357