xref: /php-src/win32/build/config.w32 (revision 9c4beac8)
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_call_stack.c \
232	zend_compile.c 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 zend_hrtime.c zend_frameless_function.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);
255
256var FIBER_ASM_ABI = {
257	'x64': 'x86_64_ms_pe_masm',
258	'x86': 'i386_ms_pe_masm',
259	'arm64': 'arm64_aapcs_pe_armasm'
260}[TARGET_ARCH];
261DEFINE('FIBER_ASM_ABI', FIBER_ASM_ABI);
262
263if (TARGET_ARCH == 'arm64') {
264	DEFINE('FIBER_ASM_FLAGS', '-nologo -machine ARM64 -o');
265} else {
266	DEFINE('FIBER_ASM_FLAGS', '/DBOOST_CONTEXT_EXPORT=EXPORT /nologo /c /Fo');
267}
268
269ADD_FLAG('ASM_OBJS', '$(BUILD_DIR)\\Zend\\jump_' + FIBER_ASM_ABI + '.obj $(BUILD_DIR)\\Zend\\make_' + FIBER_ASM_ABI + '.obj');
270
271MFO.WriteLine('$(BUILD_DIR)\\Zend\\jump_' + FIBER_ASM_ABI + '.obj: Zend\\asm\\jump_' + FIBER_ASM_ABI + '.asm');
272MFO.WriteLine('\t$(PHP_ASSEMBLER) $(FIBER_ASM_FLAGS) $(BUILD_DIR)\\Zend\\jump_$(FIBER_ASM_ABI).obj Zend\\asm\\jump_$(FIBER_ASM_ABI).asm');
273
274MFO.WriteLine('$(BUILD_DIR)\\Zend\\make_' + FIBER_ASM_ABI + '.obj: Zend\\asm\\make_' + FIBER_ASM_ABI + '.asm');
275MFO.WriteLine('\t$(PHP_ASSEMBLER) $(FIBER_ASM_FLAGS) $(BUILD_DIR)\\Zend\\make_$(FIBER_ASM_ABI).obj Zend\\asm\\make_$(FIBER_ASM_ABI).asm');
276
277ADD_FLAG("CFLAGS_BD_ZEND", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
278if (VS_TOOLSET && VCVERS >= 1914) {
279	ADD_FLAG("CFLAGS_BD_ZEND", "/d2FuncCache1");
280}
281
282/* XXX inspect this for other toolsets */
283//AC_DEFINE('ZEND_DVAL_TO_LVAL_CAST_OK', 1);
284
285ADD_SOURCES("main", "main.c snprintf.c spprintf.c getopt.c fopen_wrappers.c \
286	php_ini_builder.c \
287	php_scandir.c php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
288	strlcat.c reentrancy.c php_variables.c php_ticks.c network.c \
289	php_open_temporary_file.c output.c internal_functions.c \
290	php_syslog.c php_odbc_utils.c safe_bcmp.c");
291ADD_FLAG("CFLAGS_BD_MAIN", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
292if (VS_TOOLSET && VCVERS >= 1914) {
293	ADD_FLAG("CFLAGS_BD_MAIN", "/d2FuncCache1");
294}
295
296AC_DEFINE('HAVE_STRNLEN', 1);
297
298AC_DEFINE('ZEND_CHECK_STACK_LIMIT', 1)
299
300ADD_SOURCES("main/streams", "streams.c cast.c memory.c filter.c plain_wrapper.c \
301	userspace.c transports.c xp_socket.c mmap.c glob_wrapper.c");
302ADD_FLAG("CFLAGS_BD_MAIN_STREAMS", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
303if (VS_TOOLSET && VCVERS >= 1914) {
304	ADD_FLAG("CFLAGS_BD_MAIN_STREAMS", "/d2FuncCache1");
305}
306
307ADD_SOURCES("win32", "dllmain.c glob.c readdir.c \
308	registry.c select.c sendmail.c time.c winutil.c wsyslog.c globals.c \
309	getrusage.c ftok.c ioutil.c codepage.c nice.c \
310	fnmatch.c sockets.c console.c signal.c");
311
312ADD_FLAG("CFLAGS_BD_WIN32", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
313if (VS_TOOLSET && VCVERS >= 1914) {
314	ADD_FLAG("CFLAGS_BD_WIN32", "/d2FuncCache1");
315}
316
317PHP_INSTALL_HEADERS("", "Zend/ TSRM/ main/ main/streams/ win32/");
318PHP_INSTALL_HEADERS("Zend/Optimizer", "zend_call_graph.h zend_cfg.h zend_dfg.h zend_dump.h zend_func_info.h zend_inference.h zend_optimizer.h zend_ssa.h zend_worklist.h");
319
320STDOUT.WriteBlankLines(1);
321
322
323/* Can we build with IPv6 support? */
324ARG_ENABLE("ipv6", "Disable IPv6 support (default is turn it on if available)", "yes");
325
326var main_network_has_ipv6 = 0;
327if (PHP_IPV6 == "yes") {
328	main_network_has_ipv6 = CHECK_HEADER_ADD_INCLUDE("wspiapi.h", "CFLAGS") ? 1 : 0;
329}
330if (main_network_has_ipv6) {
331	STDOUT.WriteLine("Enabling IPv6 support");
332	AC_DEFINE('HAVE_GAI_STRERROR', 1);
333	AC_DEFINE('HAVE_IPV6', 1);
334}
335
336/* this allows up to 256 sockets to be select()ed in a single
337 * call to select(), instead of the usual 64 */
338ARG_ENABLE('fd-setsize', "Set maximum number of sockets for select(2)", "256");
339ADD_FLAG("CFLAGS", "/D FD_SETSIZE=" + parseInt(PHP_FD_SETSIZE));
340
341/* For snapshot builders, where can we find the additional
342 * files that make up the snapshot template? */
343ARG_WITH("snapshot-template", "Path to snapshot builder template dir", "no");
344
345if (PHP_SNAPSHOT_TEMPLATE == "no") {
346	/* default is as a sibling of the php_build dir */
347	if (FSO.FolderExists(PHP_PHP_BUILD + "\\template")) {
348		PHP_SNAPSHOT_TEMPLATE = FSO.GetAbsolutePathName(PHP_PHP_BUILD + "\\template");
349	} else if (FSO.FolderExists(PHP_PHP_BUILD + "\\..\\template")) {
350		PHP_SNAPSHOT_TEMPLATE = FSO.GetAbsolutePathName(PHP_PHP_BUILD + "\\..\\template");
351	}
352}
353
354DEFINE('SNAPSHOT_TEMPLATE', PHP_SNAPSHOT_TEMPLATE);
355
356ARG_ENABLE("security-flags", "Disable the compiler security flags", "yes");
357if (PHP_SECURITY_FLAGS == "yes") {
358	ADD_FLAG("LDFLAGS", "/NXCOMPAT /DYNAMICBASE ");
359}
360
361if (CLANG_TOOLSET) {
362	ARG_WITH("uncritical-warn-choke", "Disable some uncritical warnings", "yes");
363	if (PHP_UNCRITICAL_WARN_CHOKE != "no") {
364		ADD_FLAG("CFLAGS", "-Wno-ignored-attributes -Wno-deprecated-declarations -Wno-missing-braces " +
365		"-Wno-logical-op-parentheses -Wno-msvc-include -Wno-invalid-source-encoding -Wno-unknown-pragmas " +
366		"-Wno-unused-command-line-argument -Wno-unused-function -Wno-ignored-pragma-optimize");
367	}
368
369	ARG_ENABLE("sanitizer", "Enable ASan and UBSan extensions", "no");
370	if (PHP_SANITIZER == "yes") {
371		if (COMPILER_NUMERIC_VERSION < 500) {
372			ERROR("Clang at least 5.0.0 required for sanitation plugins");
373		}
374		add_asan_opts("CFLAGS", "LIBS", "LDFLAGS");
375	}
376}
377
378ARG_WITH("codegen-arch", "Architecture for code generation: ia32. Use --enable-native-intrinsics to enable SIMD optimizations.", "no");
379toolset_setup_codegen_arch();
380
381ARG_WITH("all-shared", "Force all the non obligatory extensions to be shared", "no");
382
383// Config profiles (--with-config-profile=<name>) will save a certain config to php-src/config.<name>.bat
384// so that it can be executed like: cofig.<name> instead of a long list of parameters
385//
386// Note, nice as a name is disallowed and will generate a warning and skip saving
387ARG_WITH('config-profile', 'Name of the configuration profile to save this to in php-src/config.name.bat', 'no');
388
389ARG_ENABLE("test-ini", "Enable automatic php.ini generation. The test.ini will be put \
390		into the build dir and used to automatically load the shared extensions.", "yes");
391
392ARG_WITH("test-ini-ext-exclude", "Comma separated list of shared extensions to \
393		be excluded from the test.ini", "no");
394
395ARG_ENABLE("native-intrinsics", "Comma separated list of intrinsic optimizations to enable. \
396	Available instruction set names are sse, sse2, sse3, ssse3, sse4.1, sse4.2, avx, avx2. \
397	SSE and SSE2 are enabled by default. The best instruction set specified will \
398	automatically enable all the older instruction sets. Note, that the produced binary \
399	might not work properly, if the chosen instruction sets are not available on the target \
400	processor.", "no");
401toolset_setup_intrinsic_cflags();
402