本文基于PHP8的commit为:9fa1d1330138ac424f990ff03e62721120aaaec3
 
首先,我们来创建一个扩展骨架:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ php ext_skel.php --ext frag Copying config scripts... done  Copying sources... done  Copying tests... done  Success. The extension is now ready to be compiled. To do  so, use the following steps: cd  /path/to/php-src/ext/fragphpize ./configure make Don't forget to run tests once the compilation is done:  make test Thank you for using PHP! 
然后,我们进入frag目录,并且创建文件Makefile.frag:
1 2 3 4 5 6 7 8 9 10 11 12 generate: show-generate-info     touch generate.c show-generate-info:     @echo   "  +----------------------------------------------------------------------+"      @echo   "  |                                                                      |"      @echo   "  |                            GENERATE FILE                             |"      @echo   "  |                            =============                             |"      @echo   "  |                                                                      |"      @echo   "  +----------------------------------------------------------------------+"      @echo     @echo 
可以看到,这里实现的功能是创建文件generate.c。
然后,我们修改config.m4文件,完整替换为如下内容
1 2 3 4 5 6 7 8 9 10 11 12 13 PHP_ARG_ENABLE([frag],   [whether to enable  frag support],   [AS_HELP_STRING([--enable-frag],     [Enable frag support])],   [no]) if  test  "$PHP_FRAG "  != "no" ; then   AC_DEFINE(HAVE_FRAG, 1, [ Have frag support ])   PHP_ADD_MAKEFILE_FRAGMENT(Makefile.frag)   PHP_NEW_EXTENSION(frag, frag.c generate.c, $ext_shared ) fi 
我们注意到,我们需要编译的文件除了frag.c之外,还有待生成的generate.c文件。
接着,我们开始编译我们的扩展:
1 2 3 4 5 6 7 8 9 10 11 12 $ phpize Configuring for : PHP Api Version:         20190128 Zend Module Api No:      20190128 Zend Extension Api No:   420190128 $ ./configure creating libtool appending configuration tag "CXX"  to libtool configure: patching config.h.in configure: creating ./config.status config.status: creating config.h 
到这里,我们的Makefile文件已经生成了,我们会发现,在我们的Makefile文件里面,有如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 .NOEXPORT: generate: show-generate-info     touch generate.c show-generate-info:     @echo   "  +----------------------------------------------------------------------+"      @echo   "  |                                                                      |"      @echo   "  |                            GENERATE FILE                             |"      @echo   "  |                            =============                             |"      @echo   "  |                                                                      |"      @echo   "  +----------------------------------------------------------------------+"      @echo     @echo 
这实际上就是我们Makefile.frag里面的内容了。
所以,接下来我们要先创建generate.c文件:
1 2 3 4 5 6 7 8 9 10 $ make generate   +----------------------------------------------------------------------+   |                                                                      |   |                            GENERATE FILE                             |   |                            =============                             |   |                                                                      |   +----------------------------------------------------------------------+ touch generate.c 
然后编译扩展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 make ---------------------------------------------------------------------- Libraries have been installed in :    /Users/hantaohuang/codeDir/cCode/php-src/ext/frag/modules If you ever happen to want to link against installed libraries in  a given directory, LIBDIR, you must either use libtool, andspecify the full pathname of the library, or use the `-LLIBDIR'  flag during linking and do at least one of the following:    - add LIBDIR to the `DYLD_LIBRARY_PATH'  environment variable     during execution See any operating system documentation about shared libraries for  more information, such as the ld(1) and ld.so(8) manual pages. ---------------------------------------------------------------------- Build complete. Don't forget to run ' make test '.  
此时,我们完成了这次扩展的编译。
这个技巧在我们需要动态生成源文件的时候可以使用,比如json扩展它有一个词法分析的文件,他就是通过这个方法来实现构建的。