Système de construction automatique de PHP

Depuis la version 4, PHP intègre un système de construction automatique vraiment flexible. Tous les modules résident dans un sous-dossier du dossier ext. En plus de ses propres sources, chaque module est constitué d'un fichier config.m4, pour la configuration de l'extension. (pour une exemple, lisez http://www.gnu.org/software/m4/manual/m4.html)

Tous ces fichiers souches sont générés automatiqement, avec les fichiers .cvsignore, par un petit script shell nommé ext_skel qui réside dans le dossier ext. Il prend comme argument le nom du module que vous voulez créer. Le script shell crée alors un dossier portant le nom du module, et y place les fchiers souches appropriés.

Etapes par étapes, le processus ressemble à ceci :
:~/cvs/php4/ext:> ./ext_skel --extname=my_module
Creating directory my_module
Creating basic files: config.m4 .cvsignore my_module.c php_my_module.h CREDITS EXPERIMENTAL tests/001.phpt my_module.php [done].

To use your new extension, you will have to execute the following steps:

1.  $ cd ..
2.  $ vi ext/my_module/config.m4
3.  $ ./buildconf
4.  $ ./configure --[with|enable]-my_module
5.  $ make
6.  $ ./php -f ext/my_module/my_module.php
7.  $ vi ext/my_module/my_module.c
8.  $ make

Repeat steps 3-6 until you are satisfied with ext/my_module/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
Cette instruction crée les fichiers mentionnés ci-dessus. Pour inclure le nouveau module dans la configuration automatique et le processus de construction, vous devez exécuter le fichier buildconf, qui regénère le script configure en cherchant dans le dossier ext et incluant tous les fichiers config.m4 s'y trouvant.

Le fichier config.m4 par défaut montré dans Exemple 46-1 est un peu plus complexe :

Exemple 46-1. Le fichier config.m4 par défaut.

dnl $Id: build.xml,v 1.1 2005/09/11 21:48:05 yannick Exp $
dnl config.m4 for extension my_module

dnl Comments in this file start with the string 'dnl'.
dnl Remove where necessary. This file will not work
dnl without editing.

dnl If your extension references something external, use with:

dnl PHP_ARG_WITH(my_module, for my_module support,
dnl Make sure that the comment is aligned:
dnl [  --with-my_module             Include my_module support])

dnl Otherwise use enable:

dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,
dnl Make sure that the comment is aligned:
dnl [  --enable-my_module           Enable my_module support])

if test "$PHP_MY_MODULE" != "no"; then
  dnl Write more examples of tests here...

  dnl # --with-my_module -> check with-path
  dnl SEARCH_PATH="/usr/local /usr"     # you might want to change this
  dnl SEARCH_FOR="/include/my_module.h"  # you most likely want to change this
  dnl if test -r $PHP_MY_MODULE/; then # path given as parameter
  dnl   MY_MODULE_DIR=$PHP_MY_MODULE
  dnl else # search default path list
  dnl   AC_MSG_CHECKING([for my_module files in default path])
  dnl   for i in $SEARCH_PATH ; do
  dnl     if test -r $i/$SEARCH_FOR; then
  dnl       MY_MODULE_DIR=$i
  dnl       AC_MSG_RESULT(found in $i)
  dnl     fi
  dnl   done
  dnl fi
  dnl
  dnl if test -z "$MY_MODULE_DIR"; then
  dnl   AC_MSG_RESULT([not found])
  dnl   AC_MSG_ERROR([Please reinstall the my_module distribution])
  dnl fi

  dnl # --with-my_module -> add include path
  dnl PHP_ADD_INCLUDE($MY_MODULE_DIR/include)

  dnl # --with-my_module -> chech for lib and symbol presence
  dnl LIBNAME=my_module # you may want to change this
  dnl LIBSYMBOL=my_module # you most likely want to change this 

  dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
  dnl [
  dnl   PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $MY_MODULE_DIR/lib, MY_MODULE_SHARED_LIBADD)
  dnl   AC_DEFINE(HAVE_MY_MODULELIB,1,[ ])
  dnl ],[
  dnl   AC_MSG_ERROR([wrong my_module lib version or lib not found])
  dnl ],[
  dnl   -L$MY_MODULE_DIR/lib -lm -ldl
  dnl ])
  dnl
  dnl PHP_SUBST(MY_MODULE_SHARED_LIBADD)

  PHP_NEW_EXTENSION(my_module, my_module.c, $ext_shared)
fi

Si vous n'êtes pas familier avec les fichiers M4 (maintenant, c'est peut être le bon moment pour l'être), ils peuvent êtreun peu confus de prime abord ; mais ils sont finalement simples ;)

Note : Tout ce qui est préfixé par dnl est traité en tant que commentaire et n'est pas analysé.

Le fichier config.m4 est responsable de l'analyse des options de la ligne de commande passée au fichier configure au moment de la configuration. Cela signifie qu'il doit vérifier l'existance des fichiers externes requis et réalise des tâches similaires à la configuration et la préparation à l'exécution.

Le fichier par défaut crée deux directives de configuration dans le script configure : --with-my_module et --enable-my_module. Utilisation de la première option lorsqu'il y a référence à des fichiers externes (comme la directive --with-apache qui réfère au dossier Apache). Utilisation de la seconde option lorsque l'utilisateur a simplement décidé d'activer votre extension. Suivant l'option que vous utilisez, vous devez décommenter l'autre, et pas seulement celle choisie ; par exemple, si vous utilisez --enable-my_module, vous devez supprimer le support de --with-my_module et vice-versa.

Par défaut, le fichier config.m4 créé par ext_skel accepte les deux directives et active automatiquement votre extension. L'activation de l'extension est faite en utilisant la macro PHP_EXTENSION. Pour modifier le comportement par défaut pour inclure votre module dans le binaire PHP lorsque l'utilisateur le désire (en spécifiant explicitement --enable-my_module ou --with-my_module), modifiez le test $PHP_MY_MODULE en == "yes":
if test "$PHP_MY_MODULE" == "yes"; then dnl
    Action.. PHP_EXTENSION(my_module, $ext_shared)
    fi
Ceci vous implique d'utiliser --enable-my_module à chaque fois que vous reconfigurez et recompilez PHP.

Note :Assurez-vous d'exécuter buildconf à chaque fois que vous modifiez config.m4!

Nous entrerons plus dans les détails des macros M4 disponibles pour vos scripts de configuration plus loin dans ce chapitre. Pour le moment, nous utiliserons simplement les fichiers par défaut.