Configuration and Links
All the code in the previous example is a standalone version of C that you've written in PHP user space. If you're working on a project that needs to be bonded to a PHP extension, you'll need to link to at least one external library.
Autoconf
In a simple application, you may have added the following cflags and Ldflags to your makefile.
Cflags = ${cflags}-i/usr/local/foobar/include
ldflags = ${ldflags}-lfoobar-l/usr/local/foobar/lib
People who want to build your application without Libfoobar, or who install Libfoobar in another location, will get a processed error message to help him find the cause of the error.
Most of the development source software (OSS) and PHP that have been developed over the last decade have leveraged a utility autoconf to generate complex configure scripts with simple macros. The resulting script performs the task of locating whether the dependent library has a header file installed. Based on this information, a package can customize the build line of code, or provide a meaningful error message before the compile time is wasted.
When building PHP extensions, whether or not you plan to publish publicly, you need to use this autoconf mechanism. Even if you are already familiar with autoconf, please take a few minutes to read this chapter, and PHP introduces some custom macros that are not autoconf for general installation.
Unlike the traditional autoconf step (where the Configure.in file contains all the configuration macros for the package), PHP is only using configure.in to manage the coordination of small CONFIG.M4 scripts under many bit-domain source trees, including various extensions, SAPI, the core itself, and Zendengine.
You've seen a simple version of CONFIG.M4 in the previous section. Next, we'll add additional autoconf syntax to this file so that your extension can collect more configuration information.
Find a library
The config.m4 script is used to check that the dependent library is installed. Extensions such as MySQL, LDAP, GMP, and other features designed for PHP user space and C library implementations. If their dependent libraries are not installed, or if the installed version is too old, either compile the error or cause the resulting binaries to run.
Header file Scan
The simplest step in a dependency-Library scan is to check your scripts for included files that will be used when linking. The following code attempts to find zlib.h in some common locations:
Php_arg_with (zlib,[for zlib Support]
[ with-zlib Include zlib Support])
if test "$PHP _zlib"!= "no"; Then for
i in/usr/usr/local/opt does
if test-f $i/include/zlib/zlib.h then
zlib_dir= $i
fi
done< C10/>if test-z "$ZLIB _dir"; Then
ac_msg_error ([Zlib not Installed (http://www.zlib.org)])
fi
Php_add_library_with_path (z, $ZLIB _dir/lib, Zlib_shared_libadd)
php_add_include ($ZLIB _dir/include)
ac_msg_result ([Found in $ZLIB _dir])
Ac_define (Have_zlib,1,[libz found and included])
Php_new_extension (zlib, ZLIB.C, $ext _shared)
php_subst (zlib_shared_libadd)
fi
The config.m4 file is obviously bigger than you've used so far. Luckily, its syntax is straightforward and if you're familiar with bash scripts, it's not unfamiliar.
The first occurrence of the file in the 5th chapter, "Your first extension", starts with the Php_arg_with () macro. The behavior of this macro is the same as the php_arg_enable () macro you have used, but it will cause the/configure option to be--with-extname/--without-extname and not--enable-extname/-- Disable-extname.
Looking back at these macros, they are functionally equivalent, except that the end user gives your package some hints. You can use any of the same methods on the private extensions you create. However, if you plan to publish publicly, you should know PHP's formal coding standard, which points out that enable/disable is used for extensions that do not need to link to external libraries, with/without instead.
Since the extension we assume here will link the zlib library, your CONFIG.M4 script will look for zlib.h header files that are included in the extended source code. This is done by checking some of the standard locations/usr,/usr/local, and Zlib.h in the Include/zlib directory in/opt to locate the next two directories.
If Zlib.h is found, the base path is set to the temporary variable Zlib_dir. Once the loop completes, the Config.m4 script checks to see if the Zlib_dir contains content to determine if zlib.h is found. If not found, a meaningful error is generated to let the user know./configure cannot continue.
At this point, the script assumes that the header file exists and the corresponding library must exist, so use it to modify the build environment in the next two lines, eventually adding-lz-l$zlib_dir/lib to Ldflags and-i$zlib_dir/include to Cflags.
Finally, the output of a confirmation message indicates that the zlib installation has been found and that its path is used during compilation. Other parts of the config.m4 you should be familiar with the study in the previous section. Define a #define for config.h, define the extension and specify its source code files, and identify a variable that completes the work of attaching the extension to the build system.
Functional Testing
To date, this CONFIG.M4 example indicates that a required header file was found. Although this is sufficient, it still does not ensure that the resulting binary is properly linked because there may not be a matching library file or the version is incorrect.
The easiest way to check if a zlib.h corresponds to a libz.so library file is to check if the file exists:
if! Test-f $ZLIB _dir/lib/libz.so; Then
ac_msg_error ([zlib.h found, but libz.so not present!])
Fi
Of course, this is just one side of the problem. What if you installed other libraries with the same name but are incompatible with the library you are looking for? The best way to ensure that your extensions can be successfully compiled is to test the content that is needed to actually compile the libraries you find. To do this, you need to add the following code before the Php_add_library_with_path call in CONFIG.M4:
Php_check_library (z, deflateinit,,[
ac_msg_error ([Invalid zlib extension, gzinit () not found])
],-l$zlib_dir /lib)
This tool macro expands the output to a complete program,./configure will attempt to compile it. If the compilation succeeds, the symbol representing the second parameter definition exists in the library specified by the first parameter. Once successful, the autoconf script specified in the third parameter will be executed; After the failure, the autoconf script specified in the fourth parameter executes. In this case, the third argument is empty, because no message is the best message (it should be one of the Unix philosophies), and the fifth parameter is the left-behind parameter that specifies the additional compiler and linker tags, where the-L is fatal with an extra path for locating the library.