记录在Windows上编译PHP的过程。

编译PHP,你需要几样工具:

  • 编译PHP master需要使用Visual Studio 2019(PHP 7.4.5依然使用的是Visual Studio 2017)
  • 微软提供的php-sdk-binary-tools
  • PHP代码php-src

根据php-sdk-binary-tools页面的介绍,编译PHP master分支,你需要执行以下步骤:

  • git clone –depth=1 https://github.com/microsoft/php-sdk-binary-tools.git
  • cd php-sdk-binary-tools\
  • git fetch –shallow-since 2019-08-26, 为了获取php-sdk-2.2.0
  • git checkout cb51b8f, 为了获取php-sdk-2.2.0
  • 执行phpsdk-vs16-x64.bat,设置Visual Studio的环境变量
  • 执行phpsdk_buildtree phpmaster, 目录会切换到phpmaster\vs16\x64
  • git clone –depth=1 https://github.com/php/php-src.git,下面PHP master分支代码
  • 执行phpsdk_deps –update –branch master来从windows.php.net - /downloads/php-sdk/deps/vs16/x64/下载依赖
    • 这个脚本似乎执行比较慢,建议手动使用wget之类的工具批量下载,然后通过unzip解压到php-sdk-binary-tools\phpmaster\vs16\x64\deps目录
  • 执行buildconf,生成configure.js,一个用javascript写的构建脚本,执行configure –help可以查看选项
  • 执行configure –enable-cli来配置
    • 如果想生成整个Windows发行版,使用configure –enable-snapshot-build,这个编译时间会比较长(可以查看其appveyor的自动构建脚本)
    • 如果想自定某些编译选项,可以在执行configure之前定义CFLAGS,比如:set CFLAGS=-DCUSTOM_MACRO=1
  • 执行nmake进行编译
  • 生成的可执行文件在x64\Release_TS,如果打包的话会生成类似php-8.0.0-dev-Win32-vs16-x64.zip的文件

其他注意事项

  • 如果需要编译单个扩展,可以configure –disable-all –with-openssl
    • –with-openssl可以指定为shared,用于编译dll
  • –with-all-shared选项可以加入很多扩展,并将其编译成dll,但是不会加入所以扩展
  • windows.php.net - /downloads/php-sdk/deps/vs16/x64/的扩展包貌似从https://github.com/winlibs
  • 对于某个扩展,可以修改ext/name/config.w32文件,来在生成configure.js之前增加一些自定义的编译选项

其他

Visual Studio Build Tools

wget批量下载

将文件URL按行放在一个文件(比如packages.txt)中,然后执行wc -nc -i packages.txt

(完)

2020-05-08 更新

让编译PHP的SQLite3扩展支持在Windows下加载插件。

sqlite3.extension_dir = “C:\Users\Molly\scoop\apps\php\7.4.5\ext_sqlite3”

修改php.ini:

[sqlite3]
; Directory pointing to SQLite3 extensions
; http://php.net/sqlite3.extension-dir
sqlite3.extension_dir = "C:\fullpath\to\ext_sqlite3"

修改ext\sqlite3\sqlite3.c:

  // 将C:\fullpath\to\ext_sqlite3替换成C:/fullpath/to/ext_sqlite3
  char* p = fullpath;
  while(*p != '\0') {
    if (*p == '\\') {
      *p = '/';
    }
    p++;
  }

  // 去掉下面这行检查
#if 0
	if (strncmp(fullpath, extension_dir, extension_dir_len) != 0) {
		php_sqlite3_error(db_obj, "Unable to open extensions outside the defined directory");
		RETURN_FALSE;
	}
#endif

(更新完)

2020-10-20更新 PHP Info

PHP Restful

PHP Debugging

PHP Redirect

Tips

configure --disable-all --enable-cli --enable-$remains --with-sqlite3=shared

error_log to print log to console

(更新完)