xref: /PHP-8.2/win32/build/config.w32 (revision 279a2971)
1// vim:ft=javascript
2// "Master" config file; think of it as a configure.ac
3// equivalent.
4
5ARG_WITH("verbosity", "Output verbosity, 0-2.", "1");
6setup_verbosity();
7
8ARG_WITH("toolset", "Toolset to use for the compilation, give: vs, clang, icc. " +
9		"The only recommended and supported toolset for production use " +
10		"is Visual Studio. Use others at your own risk.", "vs");
11toolset_option_handle();
12
13ARG_WITH('cygwin', 'Path to cygwin utilities on your system', '\\cygwin');
14
15toolset_setup_compiler();
16
17HOST_ARCH = toolset_host_arch();
18TARGET_ARCH = toolset_target_arch();
19// for compatible only
20X64 = TARGET_ARCH != 'x86';
21toolset_setup_arch();
22
23toolset_setup_linker();
24toolset_setup_project_tools();
25
26// stick objects somewhere outside of the source tree
27ARG_ENABLE('object-out-dir', 'Alternate location for binary objects during build', '');
28object_out_dir_option_handle();
29
30ARG_ENABLE('debug', 'Compile with debugging symbols', "no");
31ARG_ENABLE('debug-pack', 'Release binaries with external debug symbols (--enable-debug must not be specified)', 'no');
32if (PHP_DEBUG == "yes" && PHP_DEBUG_PACK == "yes") {
33	ERROR("Use of both --enable-debug and --enable-debug-pack not allowed.");
34}
35
36if (PHP_DEBUG == "yes") {
37	ADD_FLAG("CFLAGS"," /Wall ");
38	ADD_FLAG("LDFLAGS", " /verbose ");
39}
40
41ARG_ENABLE('pgi', 'Generate PGO instrumented binaries', 'no');
42ARG_WITH('pgo', 'Compile optimized binaries using training data from folder', 'no');
43if (PHP_PGI == "yes" || PHP_PGO != "no") {
44	PGOMGR = PATH_PROG('pgomgr', WshShell.Environment("Process").Item("PATH"));
45	if (!PGOMGR) {
46		ERROR("--enable-pgi and --with-pgo options can only be used if PGO capable compiler is present.");
47	}
48	if (PHP_PGI == "yes" && PHP_PGO != "no") {
49		ERROR("Use of both --enable-pgi and --with-pgo not allowed.");
50	}
51}
52
53ARG_ENABLE('zts', 'Thread safety', 'yes');
54// Configures the hard-coded installation dir
55ARG_WITH('prefix', 'where PHP will be installed', '');
56if (PHP_PREFIX == '') {
57	PHP_PREFIX = "C:\\php";
58	if (PHP_DEBUG == "yes")
59		PHP_PREFIX += "\\debug";
60}
61DEFINE('PHP_PREFIX', PHP_PREFIX);
62
63DEFINE("BASE_INCLUDES", "/I . /I main /I Zend /I TSRM /I ext ");
64
65toolset_setup_common_cflags();
66
67if (VS_TOOLSET) {
68	ARG_WITH('mp', 'Tell Visual Studio use up to [n,auto,disable] processes for compilation', 'auto');
69	var PHP_MP_DISABLED = true;
70
71	if (PHP_MP != 'disable') {
72		if(PHP_DEBUG == 'yes') {
73			STDOUT.WriteLine('WARNING: Debug builds cannot be built using multi processing');
74		} else {
75			// no from disable-all
76			if(PHP_MP == 'auto' || PHP_MP == 'no') {
77				ADD_FLAG('CFLAGS', ' /MP ');
78				PHP_MP_DISABLED = false;
79			} else {
80				if(parseInt(PHP_MP) != 0) {
81					ADD_FLAG('CFLAGS', ' /MP'+ PHP_MP +' ');
82					PHP_MP_DISABLED = false;
83				} else {
84					STDOUT.WriteLine('WARNING: Invalid argument for MP: ' + PHP_MP);
85				}
86			}
87		}
88	}
89
90	if (!PHP_MP_DISABLED) {
91		STDOUT.WriteLine('Enabling multi process build');
92	}
93}
94
95// General link flags
96toolset_setup_common_ldlags();
97
98// General libs
99toolset_setup_common_libs();
100
101// Set some debug/release specific options
102toolset_setup_build_mode();
103
104setup_zts_stuff();
105
106// CFLAGS, LDFLAGS and BUILD_DIR are defined
107// Add compiler and link flags if PGO options are selected
108if (PHP_DEBUG != "yes" && PHP_PGI == "yes") {
109	ADD_FLAG("STATIC_EXT_CFLAGS", "/GL /O2");
110	DEFINE("PGOPGD_DIR", "$(BUILD_DIR)");
111}
112else if (PHP_DEBUG != "yes" && PHP_PGO != "no") {
113	ADD_FLAG("STATIC_EXT_CFLAGS", "/GL /O2");
114	DEFINE("PGOPGD_DIR", ((PHP_PGO.length == 0 || PHP_PGO == "yes") ? "$(BUILD_DIR)" : PHP_PGO));
115}
116
117// Find the php_build dir - it contains headers and libraries
118// that we need
119ARG_WITH('php-build', 'Path to where you extracted the development libraries (http://wiki.php.net/internals/windows/libs). Assumes that it is a sibling of this source dir (..\\deps) if not specified', 'no');
120php_build_option_handle();
121
122ARG_WITH('extra-includes', 'Extra include path to use when building everything', '');
123ARG_WITH('extra-libs', 'Extra library path to use when linking everything', '');
124
125var php_usual_include_suspects = PHP_PHP_BUILD+"\\include";
126var php_usual_lib_suspects = PHP_PHP_BUILD+"\\lib";
127
128ADD_FLAG("CFLAGS", '/I "' + php_usual_include_suspects + '" ');
129ADD_FLAG("LDFLAGS", '/libpath:"' + php_usual_lib_suspects + '" ');
130ADD_FLAG("ARFLAGS", '/nologo /libpath:"' + php_usual_lib_suspects + '" ');
131
132probe_basic_headers();
133add_extra_dirs();
134
135//DEFINE("PHP_BUILD", PHP_PHP_BUILD);
136
137ARG_WITH("analyzer", "Enable static analyzer. Pass vs for Visual Studio, clang for clang, cppcheck for Cppcheck, pvs for PVS-Studio", "no");
138if (PHP_ANALYZER == "vs") {
139	ADD_FLAG("CFLAGS", " /analyze ");
140	ADD_FLAG("CFLAGS", " /wd6308 ");
141} else if (PHP_ANALYZER == "clang") {
142	var clang_cl = false;
143
144	if (FSO.FileExists(PROGRAM_FILES + "\\LLVM\\bin\\clang-cl.exe")) {
145		clang_cl = PROGRAM_FILES + "\\LLVM\\bin\\clang-cl.exe";
146	} else if (FSO.FileExists(PROGRAM_FILESx86 + "\\LLVM\\bin\\clang-cl.exe")) {
147		clang_cl = PROGRAM_FILESx86 + "\\LLVM\\bin\\clang-cl.exe";
148	}
149
150	if (!clang_cl) {
151		if (false == PATH_PROG('clang-cl', null, 'CLANG_CL')) {
152			WARNING("Couldn't find clang binaries, static analyze was disabled");
153			PHP_ANALYZER = "no";
154		}
155	} else {
156		DEFINE("CLANG_CL", clang_cl);
157	}
158} else if (PHP_ANALYZER == "cppcheck") {
159
160	var cppcheck = false;
161
162	if (FSO.FileExists(PROGRAM_FILES + "\\Cppcheck\\cppcheck.exe")) {
163		cppcheck = PROGRAM_FILES + "\\Cppcheck\\cppcheck.exe";
164	} else if (FSO.FileExists(PROGRAM_FILESx86 + "\\Cppcheck\\cppcheck.exe")) {
165		cppcheck = PROGRAM_FILESx86 + "\\Cppcheck\\cppcheck.exe";
166	}
167	if (!cppcheck) {
168		if (false == PATH_PROG('cppcheck', null, 'CPPCHECK')) {
169			WARNING("Couldn't find Cppcheck binaries, static analyze was disabled");
170			PHP_ANALYZER = "no";
171		} else {
172			cppcheck = get_define("CPPCHECK");
173		}
174	} else {
175		DEFINE("CPPCHECK", cppcheck);
176	}
177
178	if (cppcheck) {
179		var _tmp = execute(cppcheck + " --version").split(/ /)[1];
180		var cppcheck_ver = [
181			parseInt(_tmp.split(".")[0]),
182			parseInt(_tmp.split(".")[1]),
183		];
184		if (cppcheck_ver[0] > 1 || cppcheck_ver[0] == 1 && cppcheck_ver[1] >= 77) {
185			var build_dir = get_define("BUILD_DIR");
186			var cppcheck_build_dir = build_dir + "\\cppcheck_build";
187			if (!FSO.FolderExists(cppcheck_build_dir)) {
188				FSO.CreateFolder(cppcheck_build_dir);
189			}
190			DEFINE("CPPCHECK_BUILD_DIR", cppcheck_build_dir);
191		}
192	}
193
194} else if (PHP_ANALYZER == "pvs") {
195	var pvs_studio = false;
196
197	if (FSO.FileExists(PROGRAM_FILES + "\\PVS-Studio\\x64\\PVS-Studio.exe")) {
198		pvs_studio = PROGRAM_FILES + "\\PVS-Studio\\x86\\PVS-Studio.exe";
199	} else if (FSO.FileExists(PROGRAM_FILESx86 + "\\PVS-Studio\\x64\\PVS-Studio.exe")) {
200		pvs_studio = PROGRAM_FILESx86 + "\\PVS-Studio\\x64\\PVS-Studio.exe";
201	}
202
203	if (!pvs_studio) {
204		WARNING("Couldn't find PVS-Studio binaries, static analyze was disabled");
205		PHP_ANALYZER = "no";
206	} else {
207		var pvscfg = FSO.CreateTextFile("PVS-Studio.conf", true);
208		DEFINE("PVS_STUDIO", pvs_studio);
209
210		pvscfg.WriteLine("exclude-path = " + VCINSTALLDIR);
211		if (FSO.FolderExists(PROGRAM_FILESx86 + "\\windows kits\\")) {
212			pvscfg.WriteLine("exclude-path = " + PROGRAM_FILESx86 + "\\windows kits\\");
213		} else if (FSO.FolderExists(PROGRAM_FILES + "\\windows kits\\")) {
214			pvscfg.WriteLine("exclude-path = " + PROGRAM_FILES + "\\windows kits\\");
215		}
216		pvscfg.WriteLine("vcinstalldir = " + VCINSTALLDIR);
217		pvscfg.WriteLine("platform = " + (TARGET_ARCH == 'x86' ? 'Win32' : 'x64'));
218		pvscfg.WriteLine("preprocessor = visualcpp");
219		pvscfg.WriteLine("language = C");
220		pvscfg.WriteLine("skip-cl-exe = no");
221	}
222} else {
223	PHP_ANALYZER = "no"
224}
225
226STDOUT.WriteBlankLines(1);
227STDOUT.WriteLine("Build dir: " + get_define('BUILD_DIR'));
228STDOUT.WriteLine("PHP Core:  " + get_define('PHPDLL') + " and " + get_define('PHPLIB'));
229
230ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
231	zend_ini_parser.c zend_ini_scanner.c zend_alloc.c zend_compile.c \
232	zend_constants.c zend_exceptions.c \
233	zend_execute_API.c zend_highlight.c \
234	zend_llist.c zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c \
235	zend_stack.c zend_variables.c zend.c zend_API.c zend_extensions.c \
236	zend_hash.c zend_list.c zend_builtin_functions.c zend_attributes.c \
237	zend_ini.c zend_sort.c zend_multibyte.c \
238	zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \
239	zend_object_handlers.c zend_objects_API.c \
240	zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \
241	zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \
242	zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_observer.c zend_system_id.c \
243	zend_enum.c zend_fibers.c zend_atomic.c");
244ADD_SOURCES("Zend\\Optimizer", "zend_optimizer.c pass1.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dfg.c dfa_pass.c zend_ssa.c zend_inference.c zend_func_info.c zend_call_graph.c zend_dump.c escape_analysis.c compact_vars.c dce.c sccp.c scdf.c");
245
246var PHP_ASSEMBLER = PATH_PROG({
247	'x64': 'ML64',
248	'x86': 'ML',
249	'arm64': 'armasm64'
250}[TARGET_ARCH]);
251if (!PHP_ASSEMBLER) {
252	ERROR("No assembler found, fiber cannot be built");
253}
254DEFINE('PHP_ASSEMBLER', PHP_ASSEMBLER);
255DEFINE('FIBER_ASSEMBLER', PHP_ASSEMBLER);// for compatible
256
257var FIBER_ASM_ARCH = {
258	'x64': 'x86_64',
259	'x86': 'i386',
260	'arm64': 'arm64'
261}[TARGET_ARCH];
262DEFINE('FIBER_ASM_ARCH', FIBER_ASM_ARCH); // for compatible only
263
264var FIBER_ASM_ABI = {
265	'x64': 'x86_64_ms_pe_masm',
266	'x86': 'i386_ms_pe_masm',
267	'arm64': 'arm64_aapcs_pe_armasm'
268}[TARGET_ARCH];
269DEFINE('FIBER_ASM_ABI', FIBER_ASM_ABI);
270
271if (TARGET_ARCH == 'arm64') {
272	DEFINE('FIBER_ASM_FLAGS', '-nologo -machine ARM64 -o');
273} else {
274	DEFINE('FIBER_ASM_FLAGS', '/DBOOST_CONTEXT_EXPORT=EXPORT /nologo /c /Fo');
275}
276
277ADD_FLAG('ASM_OBJS', '$(BUILD_DIR)\\Zend\\jump_' + FIBER_ASM_ABI + '.obj $(BUILD_DIR)\\Zend\\make_' + FIBER_ASM_ABI + '.obj');
278
279MFO.WriteLine('$(BUILD_DIR)\\Zend\\jump_' + FIBER_ASM_ABI + '.obj: Zend\\asm\\jump_' + FIBER_ASM_ABI + '.asm');
280MFO.WriteLine('\t$(PHP_ASSEMBLER) $(FIBER_ASM_FLAGS) $(BUILD_DIR)\\Zend\\jump_$(FIBER_ASM_ABI).obj Zend\\asm\\jump_$(FIBER_ASM_ABI).asm');
281
282MFO.WriteLine('$(BUILD_DIR)\\Zend\\make_' + FIBER_ASM_ABI + '.obj: Zend\\asm\\make_' + FIBER_ASM_ABI + '.asm');
283MFO.WriteLine('\t$(PHP_ASSEMBLER) $(FIBER_ASM_FLAGS) $(BUILD_DIR)\\Zend\\make_$(FIBER_ASM_ABI).obj Zend\\asm\\make_$(FIBER_ASM_ABI).asm');
284
285ADD_FLAG("CFLAGS_BD_ZEND", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
286if (VS_TOOLSET && VCVERS >= 1914) {
287	ADD_FLAG("CFLAGS_BD_ZEND", "/d2FuncCache1");
288}
289
290/* XXX inspect this for other toolsets */
291//AC_DEFINE('ZEND_DVAL_TO_LVAL_CAST_OK', 1);
292
293ADD_SOURCES("main", "main.c snprintf.c spprintf.c getopt.c fopen_wrappers.c \
294	php_ini_builder.c \
295	php_scandir.c php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
296	strlcat.c reentrancy.c php_variables.c php_ticks.c network.c \
297	php_open_temporary_file.c output.c internal_functions.c \
298	php_syslog.c php_odbc_utils.c safe_bcmp.c");
299ADD_FLAG("CFLAGS_BD_MAIN", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
300if (VS_TOOLSET && VCVERS >= 1914) {
301	ADD_FLAG("CFLAGS_BD_MAIN", "/d2FuncCache1");
302}
303
304AC_DEFINE('HAVE_STRNLEN', 1);
305
306ADD_SOURCES("main/streams", "streams.c cast.c memory.c filter.c plain_wrapper.c \
307	userspace.c transports.c xp_socket.c mmap.c glob_wrapper.c");
308ADD_FLAG("CFLAGS_BD_MAIN_STREAMS", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
309if (VS_TOOLSET && VCVERS >= 1914) {
310	ADD_FLAG("CFLAGS_BD_MAIN_STREAMS", "/d2FuncCache1");
311}
312
313ADD_SOURCES("win32", "dllmain.c glob.c readdir.c \
314	registry.c select.c sendmail.c time.c winutil.c wsyslog.c globals.c \
315	getrusage.c ftok.c ioutil.c codepage.c nice.c \
316	inet.c fnmatch.c sockets.c console.c signal.c");
317
318ADD_FLAG("CFLAGS_BD_WIN32", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
319if (VS_TOOLSET && VCVERS >= 1914) {
320	ADD_FLAG("CFLAGS_BD_WIN32", "/d2FuncCache1");
321}
322
323PHP_INSTALL_HEADERS("", "Zend/ TSRM/ main/ main/streams/ win32/");
324PHP_INSTALL_HEADERS("Zend/Optimizer", "zend_call_graph.h zend_cfg.h zend_dump.h zend_func_info.h zend_inference.h zend_optimizer.h zend_ssa.h");
325
326STDOUT.WriteBlankLines(1);
327
328
329/* Can we build with IPv6 support? */
330ARG_ENABLE("ipv6", "Disable IPv6 support (default is turn it on if available)", "yes");
331
332var main_network_has_ipv6 = 0;
333if (PHP_IPV6 == "yes") {
334	main_network_has_ipv6 = CHECK_HEADER_ADD_INCLUDE("wspiapi.h", "CFLAGS") ? 1 : 0;
335}
336if (main_network_has_ipv6) {
337	STDOUT.WriteLine("Enabling IPv6 support");
338	AC_DEFINE('HAVE_GAI_STRERROR', 1);
339	AC_DEFINE('HAVE_IPV6', 1);
340}
341
342/* this allows up to 256 sockets to be select()ed in a single
343 * call to select(), instead of the usual 64 */
344ARG_ENABLE('fd-setsize', "Set maximum number of sockets for select(2)", "256");
345ADD_FLAG("CFLAGS", "/D FD_SETSIZE=" + parseInt(PHP_FD_SETSIZE));
346
347/* For snapshot builders, where can we find the additional
348 * files that make up the snapshot template? */
349ARG_WITH("snapshot-template", "Path to snapshot builder template dir", "no");
350
351if (PHP_SNAPSHOT_TEMPLATE == "no") {
352	/* default is as a sibling of the php_build dir */
353	if (FSO.FolderExists(PHP_PHP_BUILD + "\\template")) {
354		PHP_SNAPSHOT_TEMPLATE = FSO.GetAbsolutePathName(PHP_PHP_BUILD + "\\template");
355	} else if (FSO.FolderExists(PHP_PHP_BUILD + "\\..\\template")) {
356		PHP_SNAPSHOT_TEMPLATE = FSO.GetAbsolutePathName(PHP_PHP_BUILD + "\\..\\template");
357	}
358}
359
360DEFINE('SNAPSHOT_TEMPLATE', PHP_SNAPSHOT_TEMPLATE);
361
362ARG_ENABLE("security-flags", "Disable the compiler security flags", "yes");
363if (PHP_SECURITY_FLAGS == "yes") {
364	ADD_FLAG("LDFLAGS", "/NXCOMPAT /DYNAMICBASE ");
365}
366
367if (CLANG_TOOLSET) {
368	ARG_WITH("uncritical-warn-choke", "Disable some uncritical warnings", "yes");
369	if (PHP_UNCRITICAL_WARN_CHOKE != "no") {
370		ADD_FLAG("CFLAGS", "-Wno-ignored-attributes -Wno-deprecated-declarations -Wno-missing-braces " +
371		"-Wno-logical-op-parentheses -Wno-msvc-include -Wno-invalid-source-encoding -Wno-unknown-pragmas " +
372		"-Wno-unused-command-line-argument -Wno-unused-function -Wno-ignored-pragma-optimize");
373	}
374
375	ARG_ENABLE("sanitizer", "Enable ASan and UBSan extensions", "no");
376	if (PHP_SANITIZER == "yes") {
377		if (COMPILER_NUMERIC_VERSION < 500) {
378			ERROR("Clang at least 5.0.0 required for sanitation plugins");
379		}
380		add_asan_opts("CFLAGS", "LIBS", "LDFLAGS");
381	}
382}
383
384ARG_WITH("codegen-arch", "Architecture for code generation: ia32. Use --enable-native-intrinsics to enable SIMD optimizations.", "no");
385toolset_setup_codegen_arch();
386
387ARG_WITH("all-shared", "Force all the non obligatory extensions to be shared", "no");
388
389// Config profiles (--with-config-profile=<name>) will save a certain config to php-src/config.<name>.bat
390// so that it can be executed like: cofig.<name> instead of a long list of parameters
391//
392// Note, nice as a name is disallowed and will generate a warning and skip saving
393ARG_WITH('config-profile', 'Name of the configuration profile to save this to in php-src/config.name.bat', 'no');
394
395ARG_ENABLE("test-ini", "Enable automatic php.ini generation. The test.ini will be put \
396		into the build dir and used to automatically load the shared extensions.", "yes");
397
398ARG_WITH("test-ini-ext-exclude", "Comma separated list of shared extensions to \
399		be excluded from the test.ini", "no");
400
401ARG_ENABLE("native-intrinsics", "Comma separated list of intrinsic optimizations to enable. \
402	Available instruction set names are sse, sse2, sse3, ssse3, sse4.1, sse4.2, avx, avx2. \
403	SSE and SSE2 are enabled by default. The best instruction set specified will \
404	automatically enable all the older instruction sets. Note, that the produced binary \
405	might not work properly, if the chosen instruction sets are not available on the target \
406	processor.", "no");
407toolset_setup_intrinsic_cflags();
408