In addition to a Makefile, Autoperl produces a configuration script called 'configure' that can be used to check for required library dependencies, as well as alter any of the standard file installation directories (prefix, bindir, datadir, etc.)
With the large variety of free UNIX systems available today, it is impossible to ensure that every library is installed on every system. Autoperl provides a dependency checking system that will alert the user to any missing libraries prior to building and installing the software.
In the C/C++ application development world, GNU Autoconf/Automake has been the standard way for resolving cross-platform differences. Autoperl attempts to make the Autoconf/Automake system available to the Perl application development process.
1. Compilation
At this time, Autoperl does not support the Perl compiler (perlcc) that ships with many Unix systems. perlcc does not produce 100% correct binary code in all cases, and is still experimental.
During the compilation phase, Autoperl will process each source code file and check for syntax errors.
2. Linking
Autoperl employs a novel approach to the linking stage of the build process.
It passes the primary source code file through a custom preprocessor that
replaces any calls to "require
3. Runtime Variables
Autoperl allows you to easily access it's configuration variables from within your application. Everytime the configuration script is run, a header file called 'config.h' is produces that contains all of the compile-time constants. This header file can be included in your application, and accessed as native Perl variables.
The next step is to create a file called Makefile.am that contains information about your project. The syntax of this file is compatible with Automake, with a few Perl-specific extensions.
make all make test make install make uninstall make dist make package make cleanBy default, running 'make' with no arguments will run the 'make all' target.
The 'make all' target compiles all source code files and combines them into a single executable file.
The 'make install' target installs the software on the local system. If used in combination with the DESTDIR environment variable, you can install all files under a temporary subdirectory. This is useful for creating binary packages.
The 'make uninstall' target removes the software from the local system.
The 'make test' target runs all tests under the 't/' directory
The 'make dist' target produces a gzipped tarball containing the source code and everything necessary to build the application.
The 'make package' target produces a native binary package, if Autoperl knows how to do that on your operating system.
The 'make clean' target removes temporary files and generated files, including the Makefile.
make install DESTDIR=foo $(INSTALL) README foo/ make[1]: Entering directory /home/mark/projects/autoperl-0.9.1/src $(INSTALL) Autoperl.pm foo/You probably don't want this. Use this instead:
make install DESTDIR=pwd`fooThis is considered an Autoperl bug.
If you choose to follow this convention, your top-level Makefile.am will be very simple. It will consist of a SUBDIRS definition that lists each of the subdirectories in your project.
The following is the top-level Makefile.am for Autoperl:
PROGRAM = autoperl VERSION = 1.26 AUTHOR = Mark HeilySUBDIRS = doc src t sbin_PROGRAMS = src/autoperl.pl EXTRA_DIST = TODO BUGS t/all.t upload: @echo scp -r configure-$(VERSION) $(PROGRAM)-$(VERSION).tar.gz doc/*.html \ COPYING TODO BUGS ChangeLog \ heily.com:/home/mark/public_html/projects/autoperl @echo scp configure-$(VERSION) heily.com:/home/mark/public_html/projects/autoperl/configure perl -e 'print "cd /incoming\nput autoperl-$(VERSION).tar.gz\nput configure-$(VERSION)\n"' | ftp -a upload.sourceforge.net upload-doc: cp ChangeLog TODO BUGS doc/ cd doc ; tar -cvf - . | ssh mheily@sofi-firewall.sourceforge.net tar -C /home/groups/a/au/autoperl/htdocs -xv test-all: rm -rf /tmp/ap-test perl -Isrc src/autoperl.pl ./configure make make install DESTDIR=/tmp/ap-test find /tmp/ap-test/ test-pkg: perl -Isrc src/autoperl.pl ./configure make package pkg_add *.tgz diff: # This doesn't work well b/c 'configure' version is unknown diff -ruN configure configure-$(VERSION) #include "incl.1"
There are some special variables and makefile targets that you should be aware of:
Here's an example from the Autoperl source tree:
EXTRA_DIST = autoperl.1 index.html.in manual.html.in autoperl.pod \ screenshots.html autoperl_configure.png autoperl_usage.png man1_MANS = autoperl.1 pkgdata_DOCS = index.html howto.html manual.html autoperl-man1.html all-local: clean gzip -c autoperl.1 > autoperl.1.gz pod2html autoperl.pod > autoperl-man1.html m4 -DVERSION=$(VERSION) index.html.in > index.html m4 -DAP_VERSION=$(VERSION) manual.html.in > manual.html rm -f pod2h* version-stamp clean-local: rm -f index.html manual.html autoperl-man1.html
The above Makefile.am is used to generate the documentation by passing it through m4.
If you don't want to override the built-in Autoperl targets, you can extend them using hooks. The following hooks are defined:
These hooks are executed after the built-in Makefile targets have run.
These hooks are:
For example, the following code would produce a listing of all the custom arguments passed in to ./configure:
sub post_configure_hook { foreach (keys %ap::config) { print "$_ : " . $ap::config{$_} . "\n"; } }
A real-world example can be found in the top level of the Autoperl source tree. Here, post_make_all_hook() is called to create a versioned ./configure script.
sub post_make_all_hook { die unless -e 'src/autoperl'; system "cp src/autoperl configure-".$ap::config{version}; }
#include "another.file"
Variables can be referenced within the #include directive, so the following works:
./configure --include-file=my.inc (inside Makefile.am) #include "$(include_file)"
In the above example, the contents of 'my.inc' would be inserted into the Makefile.
custom-target: echo hi { return "\t" . "/bin/true" . "\n"; } echo bye
In the above example, the embedded Perl code would be evaluated during the ./configure stage to produce a Makefile that looks like this:
custom-target: echo hi /bin/true bye
It is possible to access the %ap::config variable from within an embedded Perl snippet, so you have access to all of the configuration parameters set by the ./configure script.
Here's an example from Autoperl:
# Generated by autoperl 1.26 unless (defined $ap::CONFIG_H) { $ap::CONFIG_H = 1; %ap::config = ( 'docdir' => '/usr/local/share/doc', 'mandir' => '/usr/local/man', 'pkgdatadir' => '/usr/local/share/autoperl', 'author' => 'Mark Heily', 'program' => 'autoperl', 'ovr_custom' => 'default', 'crap' => 'good', 'infodir' => '/usr/local/info', 'cc' => '/usr/bin/perl -c', 'sysconfdir' => '/usr/local/etc', 'bindir' => '/usr/local/bin', 'confdir' => '/usr/local/etc/autoperl', 'libexecdir' => '/usr/local/libexec', 'make' => '/usr/bin/make', 'autoperl' => '$(TOPDIR)/configure --autoperl', 'localedir' => '/usr/local/locale', 'install' => '$(TOPDIR)/configure --autoperl install -p', 'version' => '1.26', 'includedir' => '/usr/local/lib/site_perl', 'datadir' => '/usr/local/share', 'sbindir' => '/usr/local/sbin', 'libdir' => '/usr/local/lib', 'perl' => '/usr/bin/perl', 'def_custom' => 'default', 'ld' => '$(TOPDIR)/configure --autoperl link', 'destdir' => '', 'prefix' => '/usr/local', 'localstatedir' => '/usr/local/var' ); # Allow references to $ap::foo $ap::{docdir} = sub { '/usr/local/share/doc' }; $ap::{mandir} = sub { '/usr/local/man' }; $ap::{pkgdatadir} = sub { '/usr/local/share/autoperl' }; $ap::{author} = sub { 'Mark Heily ' }; $ap::{program} = sub { 'autoperl' }; $ap::{ovr_custom} = sub { 'default' }; $ap::{crap} = sub { 'good' }; $ap::{infodir} = sub { '/usr/local/info' }; $ap::{cc} = sub { '/usr/bin/perl -c' }; $ap::{sysconfdir} = sub { '/usr/local/etc' }; $ap::{bindir} = sub { '/usr/local/bin' }; $ap::{confdir} = sub { '/usr/local/etc/autoperl' }; $ap::{libexecdir} = sub { '/usr/local/libexec' }; $ap::{make} = sub { '/usr/bin/make' }; $ap::{autoperl} = sub { '$(TOPDIR)/configure --autoperl' }; $ap::{localedir} = sub { '/usr/local/locale' }; $ap::{install} = sub { '$(TOPDIR)/configure --autoperl install -p' }; $ap::{version} = sub { '1.26' }; $ap::{includedir} = sub { '/usr/local/lib/site_perl' }; $ap::{datadir} = sub { '/usr/local/share' }; $ap::{sbindir} = sub { '/usr/local/sbin' }; $ap::{libdir} = sub { '/usr/local/lib' }; $ap::{perl} = sub { '/usr/bin/perl' }; $ap::{def_custom} = sub { 'default' }; $ap::{ld} = sub { '$(TOPDIR)/configure --autoperl link' }; $ap::{destdir} = sub { '' }; $ap::{prefix} = sub { '/usr/local' }; $ap::{localstatedir} = sub { '/usr/local/var' }; # Allow references to $ap::config{foo} or $ap::config->{foo} $ap::config = \%ap::config; } 1;
All of the variables listed above could have been modified by various parameters passed into the configuration script.
To use config.h in your program, simply 'require' it into every source code file that needs to reference these variables. This allows you can reference the variables as follows:
$ap::config{foo}
For example, if a user typed:
./configure --foo=1 --bar=2 --baz=3
The config.h would look like:
$ap::config = +{ foo => 1, bar => 2, baz => 3, };
There are two special prefixes: --with/--without and --enable/--disable. These are convenient ways of implicitly declaring a boolean value at configure time.
For example, if a user typed:
./configure --with-foo --without-bar --enable-baz
The config.h would look like:
$ap::config = +{ foo => 1, bar => 0, baz => 1, };If your application uses custom arguments, it's a good idea to declare them in configure.in. While this is not strictly necessary, it ensures that your argument is documented and initialized with a default value.
To declare a custom argument, use the _ARG and _ARG_HELP variables in Makefile.am as follows:
argname_ARG =argname_ARG_HELP = help string
For example:
with_ssl_ARG = 0 with_ssl_ARG_HELP = enable support for SSL/TLS
This would allow a user to pass the flag '--with-ssl' to ./configure
For example,
AC_CONFIG_FILES = index.html
would cause index.html.in to be parsed:
@PROGRAM@ Documentation
and generate an index.html like so:
YourProgramName Documentation
Autoperl allows the user to designate what directories the package should be installed. When running configure, the options below can be given (prepended with '--'), e.g. --prefix=/usr Prefix DO NOT confuse prefix with destdir -- destdir is used to relocate the entire package to a subdirectory. See the section *VARIABLES* for information about the destdir variable. --prefix A prefix used in constructing the default values of the variables listed below. The default value of prefix should be /usr/local. Executables --bindir The directory for installing executable programs that users can run. The default is $(prefix)/bin, which is normally /usr/local/bin --sbindir The directory for installing executable programs that can be run from the shell, but are only generally useful to system administrators. The default is $(prefix)/sbin, which is normally /usr/local/sbin --libexecdir The directory for installing executable programs to be run by other programs rather than by users. The default is $(prefix)/libexec, which is normally /usr/local/libexec. Documentation --docdir The directory containing ASCII documentation, examples, etc., for this package. The default is $(datadir)/doc. --mandir The directory for The configure script has the ability to: - Check for missing or broken library dependencies - Check for required system binaries in the user's path - Define an alternate installation prefix or custom install path using DESTDIR - Enable or disable certain application-specific features at build time The generated Makefile has the ability to: - Build a source tarball via the 'make dist' target - Install the application via the 'make install' target - Remove temporary files via the 'make clean' target installing the Man pages for this package. The default is $(datadir)/man. --infodir The directory for installing the Info files for this package. The default is $(datadir)/info. Libraries --libdir The directory for installing library dependencies. Do not install executables here, they probably ought to go in $(libexecdir) instead. The default is $(prefix)/lib. Consider this as the package's private library path. Data --datadir The root of the directory tree for read-only architecture-independent data files. The default is $(prefix)/share. --localstatedir The directory for installing data files which the programs modify while they run, and that pertain to one specific machine. Users should never need to modify files in this directory to configure the package's operation; put such configuration information in separate files that go in $(datadir) or $(sysconfdir). The default is $(prefix)/var. --sharedstatedir The directory for installing architecture-independent data files which the programs modify while they run. The default is $(prefix)/com. --localedir The directory for installing locale-specific message catalogs for this package. The default is $(datadir)/locale. Configuration files --sysconfdir The directory for installing read-only data files that pertain to a single machine--that is to say, files for configuring a host. Mailer and network configuration files, /etc/passwd, and so forth belong here. All the files in this directory should be ordinary ASCII text files. The default is /etc. --confdir The directory for package-specific configuration files. The default is '/etc/${packagename}' Unimplemented Not all of the GNU installation directories have been implemented; those omitted are exec_prefix In the GNU system, $exec_prefix is used in constructing the default values of some of the variables listed below. The default value of exec_prefix should be $(prefix). Generally, $(exec_prefix) is used for directories that contain machine-specific files (such as executables and subroutine libraries), while $(prefix) is used directly for other directories. Autoperl makes no such distinction. Use prefix instead. man1dir, man2dir, ... man1ext, man2ext, ... Use mandir instead, and append which section of the manual is appropriate. For example, $(mandir)/man1/ For more information, see the GNU Coding Standards, section 7.2.4.
This section describes features of Autoperl that are considered to be experimental. * Support for other languages There is basic support for building C and Python programs with Autoperl. For examples, see recvmail and mboard on http://heily.com/mark/projects * Building native binary packages
package.in file format: The format is:: Anything after a hash mark (#) is considered to be a comment, and is ignored. Blank lines are ignored, unless they are part of a multi-line field. Valid keywords are: - Package The name of the binary package to produce. Usually the same name as the program. - Title A one-line title, less than 75 characters. - Description A multiline description of the program. - License The name of the copyright license used by the program - Project-URI The program's home page on the World Wide Web. - Source-URI A URI where the source code can be downloaded from. - VuXML-URI A URI where the VuXML vulnerabilities document can be downloaded from. - Requires A comma-seperated list of requried executables or headers Here is an example from the Autoperl source code. ---cut here--- # $Id$ # # package.in for Autoperl # Package: autoperl Title: A configuration and build system for Perl applications Project-URI: http://heily.com/~mark/projects/autoperl Source-URI: %{project_uri}/autoperl-%{version}.tar.gz VuXML-URI: %{project_uri}/advisories.xml Requires: perl, uname License: Artistic Description: Autoperl is a configuration and build system for Perl applications that is modelled after the GNU Autoconf and Automake tools. ---cut here---
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See the file called COPYING for the complete text of the license.