Creative Commons License
Excepto donde se indique otra cosa, todo el contenido de este lugar está bajo una licencia de Creative Commons.
Taquiones > perl > Recetas de archivos make

Recetas de archivos make

Me gusta utilizar un archivo Makefile en todos los proyectos en los que trabajo. make no es una de mis herramientas favoritas, desde luego, pero con los años he terminado acostumbrándome a ella, y no quiero emplear más atención en las herramientas que en cómo usarlas.

Plantilla base para un módulo

Esta es una de las plantillas que utilizo cada vez que tengo un proyecto nuevo:

../archive/perl/makefile_template

    1  #
    2  #    Global values
    3  MODULE=
    4  DEBIAN_PACKAGE=
    5  DESTDIR ?= /tmp
    6  
    7  #
    8  #    Source modules (all .pm files under the lib directory)
    9  MODULES=$(shell find lib -name "*.pm")
   10  BINARIES=$(wildcard bin/*.pl)
   11  EXAMPLES=$(wildcard examples/*.p[lm])
   12  CHECK_SOURCES=$(MODULES) $(BINARIES) $(EXAMPLES)
   13  
   14  #
   15  #    Test program
   16  DEBUG=
   17  ARGS=
   18  
   19  #
   20  #    External tools
   21  PERL ?= perl -Ilib
   22  PERL_CHECK ?= $(PERL-cw
   23  PERL_DEBUG ?= $(PERL-d:ptkdb
   24  PROVE=$(shell which prove)
   25  INSTALL=$(shell which install)
   26  
   27  #
   28  #    Do nothing for default
   29  all:
   30  
   31  #
   32  #    Check syntax
   33  .PHONY: check $(CHECK_SOURCES)
   34  
   35  check:    $(CHECK_SOURCES)
   36  
   37  $(CHECK_SOURCES):
   38      $(PERL_CHECK$@
   39  
   40  #
   41  #    Test programs
   42  test:    
   43      $(PROVE-v t/
   44  
   45  #
   46  #    Debug program
   47  debug:        check $(DEBUG)
   48      $(PERL_DEBUG) $(DEBUG) $(ARGS)
   49  
   50  #
   51  #    Build the perl package
   52  build:        Build
   53  
   54  Build:        Build.PL
   55      $(PERLBuild.PL installdirs=vendor
   56  
   57  binary:        build
   58      $(PERLBuild 
   59  
   60  #
   61  #    Install the perl package
   62  install:    test binary
   63      $(PERLBuild install destdir=$(DESTDIR)
   64  
   65  #
   66  #    Debian package
   67  deb:    install
   68      $(DEBUILD
   69  

Me basta con copiarla y completar los campos MODULE y DEBIAN_PACKAGE, así como los nombres de los programas, que veremos en la otra versión del archivo, para que funcione inmediatamente.

Verificando todos los fuentes de un proyecto

Si observamos las siguientes estrofas

    1  #
    2  #    Source modules (all .pm files under the lib directory)
    3  MODULES=$(shell find lib -name "*.pm")
    4  BINARIES=$(wildcard bin/*.pl)
    5  EXAMPLES=$(wildcard examples/*.p[lm])
    6  CHECK_SOURCES=$(MODULES) $(BINARIES) $(EXAMPLES)
    7  
    8  #
    9  #    Check syntax
   10  .PHONY: check $(CHECK_SOURCES)
   11  
   12  check:    $(CHECK_SOURCES)
   13  
   14  $(CHECK_SOURCES):
   15      $(PERL_CHECK$@

veremos otro truco en acción. Queremos tener un destino especial que verifique la síntaxis de todos los fuentes del proyecto y sabemos que el intérprete Perl no admite más que un único parámetro; necesitamos dos características de make:

  • Destinos múltiples
  • Destinos falsos

Con el primero indicamos en el lado izquierdo de la regla que los destinos son varios, y que debe expandir la ejecución por cada uno de ellos. La variable $@ sirve precisamente para indicárselo como en

    1  examples/example_csv.pm examples/example.pl:  examples/datasource.pm
    2      $(SPECIAL_COMMAND) $@

que lo convierte en los siguientes

    1  examples/example_csv.pm:  examples/datasource.pm
    2      $(SPECIAL_COMMAND) examples/example_csv.pm
    3  
    4  examples/example.pl:  examples/datasource.pm
    5      $(SPECIAL_COMMAND) examples/example.pl

Por otra parte nos encontramos con una acción que queremos que realice siempre (al menos en este caso), y que consiste en comprobar la síntaxis de todos los archivos del proyecto. Para ello, y una vez reunidos todos en una misma variable como $CHECK_SOURCES, indicamos que el destino clean sobre ella es falso con la expresión .PHONY, de tal manera que make no comprobará las dependencias y lo ejecutará siempre.