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