{"id":32215499,"url":"https://github.com/rlauer6/autoconf-template-perl","last_synced_at":"2025-10-22T07:47:19.863Z","repository":{"id":75533952,"uuid":"404329911","full_name":"rlauer6/autoconf-template-perl","owner":"rlauer6","description":"Autoconfiscate your Perl programs!","archived":false,"fork":false,"pushed_at":"2024-08-08T13:57:51.000Z","size":251,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-22T07:47:14.626Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rlauer6.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-08T11:57:59.000Z","updated_at":"2024-08-08T13:57:48.000Z","dependencies_parsed_at":"2024-08-05T22:27:26.216Z","dependency_job_id":"c900a718-a224-4073-9e20-146ce77da334","html_url":"https://github.com/rlauer6/autoconf-template-perl","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/rlauer6/autoconf-template-perl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rlauer6%2Fautoconf-template-perl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rlauer6%2Fautoconf-template-perl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rlauer6%2Fautoconf-template-perl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rlauer6%2Fautoconf-template-perl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rlauer6","download_url":"https://codeload.github.com/rlauer6/autoconf-template-perl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rlauer6%2Fautoconf-template-perl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280402182,"owners_count":26324587,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-22T02:00:06.515Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-22T07:47:18.601Z","updated_at":"2025-10-22T07:47:19.845Z","avatar_url":"https://github.com/rlauer6.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"# README\n\nLast Updated: 08/06/24\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://upload.wikimedia.org/wikipedia/en/2/22/Heckert_GNU_white.svg\"\nwidth=\"25%\" height=\"25%\"\u003e\n\nAurelio A. Heckert, CC BY-SA 2.0\n[https://creativecommons.org/licenses/by-sa/2.0], via Wikimedia\nCommons\n\u003c/p\u003e\n\n---\n\nThis is the README for the `autoconf-template-perl` project.  It\ncontains, among other things a collection of useful tools for creating\n_autoconfiscated_ Perl based projects.  If you are on a system that uses\nthe Redhat Package Manager, you can also use the `.spec` file in\nthis project to create an rpm for your project.\n\n\u003e I guess the fancy word I learned working with one of my employers for frameworks\n\u003e like this is __accelerator__.\n\nSee [`ChangeLog`](ChangeLog) for a listing of files that have changed since the\nlast release.\n\nSee [`NEWS`](NEWS.md) for the lastest news on releases.\n\n---\n\n# TODO\n\n* [x] add web assets to RPM\n* [x] index for documentation\n* [x] `make cpan` for tarball distributions\n* [x] create CPAN distributions\n* [ ] add Apache configuration templates\n* [x] allow sub-directories in `config` directory\n\n# Table of Contents\n\n* [Overview](#overview)\n* [Features of the `autoconf-template-perl` Utility](#features-of-the-autoconf-template-perl-utility)\n  * [Configuring Your Build](#configuring-your-build)\n  * [Why Autoconfiscate?](#why-autoconfiscate?)\n* [Quick Start](#quick-start)\n* [An Even Quicker Start](#an-even-quicker-start)\n* [Requirements](#requirements)\n* [Getting Started](#getting-started)\n  * [Automatically Creating A Manifest File](#automatically-creating-a-manifest-file)\n  * [Configuring `autoconf-template-perl`](#configuring-autoconf-template-perl)\n  * [`autoconf-template-perl` Options](#autoconf-template-perl-options)\n* [Project Source Tree](#project-source-tree)\n  * [Root Directory](#root-directory)\n  * [`autotools` Directory](#autotools-directory)\n  * [`config` Directory](#config-directory)\n  * [`resources` Directory](#resources-directory)\n  * [`src` Directory](#src-directory)\n* [Building and Deploying Your Application](#building-and-deploying-your-application)\n  * [Building Your Application](#building-your-application)\n  * [Checking Your Project Distribution](#checking-your-project-distribution)\n  * [Deploying Your Application](#deploying-your-application)\n  * [RPMs](#rpms)\n  * [Tarballs](#tarballs)\n  * [Standard Deployment Tree](#standard-deployment-tree)\n* [Adding Artifacts to Your Project](#adding-artifacts-to-your-project)\n* [Building From `.in` Files](#building-from-.in-files)\n  * [Automake Configuration Variables](#automake-configuration-variables)\n* [Building Perl Modules](#building-perl-modules)\n  * [Disabling Syntax Checking](#disabling-syntax-checking)\n  * [Perl Module Dependencies](#perl-module-dependencies)\n* [Building an RPM](#building-an-rpm)\n  * [Quick Start](#quick-start)\n  * [Building RPMs from CPAN Modules](#building-rpms-from-cpan-modules)\n  * [Signing an RPM](#signing-an-rpm)\n* [Building Documentation](#building-documentation)\n  * [README.md for Perl Modules](#readme.md-for-perl-modules)\n  * [Creating a Module Index](#creating-a-module-index)\n* [Unit Tests](#unit-tests)\n* [Advanced Topics](#advanced-topics)\n  * [Customizing Build Rules](#customizing-build-rules)\n  * [Customizing the `all` Target](#customizing-the-all-target)\n  * [Creating Your Own Configuration Options](#creating-your-own-configuration-options)\n  * [Customizing Your Stub Files](#customizing-your-stub-files)\n  * [Adding Files to the Distribution](#adding-files-to-the-distribution)\n  * [`configure` Options](#configure-options)\n  * [Perl Modules and RPMs](#perl-modules-and-rpms)\n  * [Building CPAN Distributions](#building-cpan-distributions)\n* [FAQs](#faqs)\n\n# Overview\n\nBuilding and packaging software is an important step in the software\ndevelopment process.  Writing good software can be a challenge but\nit's harder without good tools for building, packaging and deploying\nyour applications. One way to build, package and deploy software is\nthrough the use of a suite of tools known as the [GNU\nAutotools](https://en.wikipedia.org/wiki/GNU_Autotools).\n\nUsing this toolchain you can create a build and deploy mechanism based\non GNU `make`.  Building and deploying are then accomplished like\nthis:\n\n```\n./configure\nmake\nsudo make install\n```\n\nThis project will create the scaffolding for an\n[__autoconfiscated__](#why-autoconfiscate) Perl application without\nrequiring you to perform the tedious task of setting up your own build\ntree and `configure.ac`.  Using the autotools toolchain you can create\n*build rules* and specify *deployment targets* for all of your built\nartifacts.  Even if you are not familiar with the intricacies (and\nwonders) of autotools, you will be able to create a fairly\nsophisticated build environment for your application using this\nutility.\n\nIf you've ever wondered how software gets installed on a Linux system,\nthen you'll want to learn more about autoconfiscated\nprojects. Hopefully though, there is enough documentation here so you\ncan use this framework effectively.\n\n[Ok, I get it skip ahead to the Quick Start](#quick-start)\n\n[Back to Table of Contents](#table-of-contents)\n\n# Features of the `autoconf-template-perl` Utility\n\n* Organizes your applications and scripts into an __easily\n  recognizable and navigable tree structure__\n  * Perl modules\n  * Perl scripts\n  * CGI scripts\n  * Web application assets (`.html`, `.js`, `.css`, etc)\n* Creation of __deployment tarballs__ or __RPMs__\n* __Syntactic checking__ of Perl scripts and modules ( `make` )\n* __Best practice__ checking using `perlcritic` (`make check`)\n* Automatic __creation of all target directories__ during deployment\n* Identification of __Perl module dependencies__\n* Automatic creation of __unit test stubs__ for scripts and modules\n* __Variable substitution during builds__ from `configure` options\n* Creation of __man pages__ from your module or script POD\n* Creation of stub _modules_, _scripts_, _html files_, etc from\n  templates\n* Creation of an __RPM file__ for deployment on RedHat flavored systems\n* Creation of a CPAN distribution tarball\n\n[Back to Table of Contents](#table-of-contents) \n\n## Configuring Your Build\n\nAgain, the goal of this utility is to create a build and deploy system\nbased on GNU Autotools (`autoconf`, `automake`, and `make`). Reminders:\n\n* `configure` helps us configure the build and specify installation targets\n* `make` helps us build and install the artifacts that make up our\napplication\n\nWhen you run `./configure --help` you'll see a comprehensive guide to\nconfiguring your project.\n\n```\n...\nBy default, `make install' will install all the files in\n`/usr/local/bin', `/usr/local/lib' etc.  You can specify\nan installation prefix other than `/usr/local' using `--prefix',\nfor instance `--prefix=$HOME'.\n\nFor better control, use the options below.\n\nFine tuning of the installation directories:\n  --bindir=DIR            user executables [EPREFIX/bin]\n  --sbindir=DIR           system admin executables [EPREFIX/sbin]\n  --libexecdir=DIR        program executables [EPREFIX/libexec]\n  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]\n  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]\n  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]\n  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]\n  --libdir=DIR            object code libraries [EPREFIX/lib]\n  --includedir=DIR        C header files [PREFIX/include]\n  --oldincludedir=DIR     C header files for non-gcc [/usr/include]\n  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]\n  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]\n  --infodir=DIR           info documentation [DATAROOTDIR/info]\n  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]\n  --mandir=DIR            man documentation [DATAROOTDIR/man]\n  --docdir=DIR            documentation root [DATAROOTDIR/doc/my-project]\n  --htmldir=DIR           html documentation [DOCDIR]\n  --dvidir=DIR            dvi documentation [DOCDIR]\n  --pdfdir=DIR            pdf documentation [DOCDIR]\n  --psdir=DIR             ps documentation [DOCDIR]\n...\n```\nIn addition to the snippet of the guide\nabove, there other options of `configure` that will allow you to\ncontrol the behavior of the build and installation phases, making the\nbuild system particularly powerful and flexible.\n\n```\nOptional Features:\n  --disable-option-checking  ignore unrecognized --enable/--with options\n  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)\n  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]\n  --enable-silent-rules   less verbose build output (undo: \"make V=1\")\n  --disable-silent-rules  verbose build output (undo: \"make V=0\")\n  --enable-distcheck-hack enable distcheck hack\n  --disable-deps don't abort if dependencies missing\n  --disable-perldeps don't abort if dependencies missing\n  --enable-rpm-build-mode       configure RPM build mode (disables certain checks), default: disabled\n  --enable-perlcritic-mode       configure mode (disables certain checks), default: true\n\nOptional Packages:\n  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]\n  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)\n  --with-perl5libdir (defaults to DATAROOTDIR/perl5)\n  --with-perl5sharedir (defaults to perl5libdir/auto/share/dist/dist-name)\n  --with-perl-includes=DIR[:DIR:...]\n                          prepend DIRs to Perl's @INC\n  --with-apache-vhost-domain=name\n  --with-apache-vhost-dir=DIR\n  --with-apache-vhost-confdir=DIR, where Apache looks for virtual host configuration files\n  --with-apache-vhost-server=name, default: localhost\n  --with-apache-user=USER          user id that should own the web pages\n  --with-apache-group=GROUP        group that should own the web pages\n  --with-perlcritic-severity=severity\n  --with-license (defaults to GNU Public License)\n  --with-architecture (defaults to noarch)\n```\n\nUsing the options you provide to `configure` you can install your\nartifacts anywhere you'd like. The `autoconf-template-perl` utility,\nby convention, will install your artifacts as shown below:\n\n| Artifact | Source Directory | Installation Directory |\n| -------- | ---------------- | ---------------------- |\n| Perl script (`.pl`) | `src/main/perl/bin` | `bindir` |\n| Perl modules (`.pm`) | `src/main/perl/lib` | `perl5libdir` | \n| Perl CGI scripts (`.cgi`) | `src/main/perl/cgi-bin` | `apache-vhostdir/cgi-bin` | \n| Bash scripts (`.sh`) | `src/main/bash/bin` | `bindir` | \n| HTML files (`.html`) | `src/main/html/htdocs` | `apache-vhostdir/htdocs` |\n| CSS files (`.css`) | `src/main/css/htdocs` | `apache-vhostdir/htdocs/css` |\n| Image files (`.png`, etc) | `src/main/html/htdocs/image` | `apache-vhostdir/htdocs/img` |\n| Javascript files (`.js`) | `src/main/html/javascript` | `apache-vhostdir/htdocs/` |\n\n\u003e Note: `perl5libdir` defaults to `datadir/perl5`. To install your\n\u003e Perl modules in Perl's path use `--with-perl5libdir` without\n\u003e specifying a path\n\n[Back to Table of Contents](#table-of-contents) \n\n## Why Autoconfiscate?\n\nThe term\n[`autoconfisicate`](https://www.webster-dictionary.org/definition/autoconfiscate)\nis attributed to [Noah\nFriedman](https://savannah.gnu.org/users/friedman) to describe the\nprocess of setting up a build system that uses the GNU Autotools.\n\n\u003e There are a few reasons to autoconfiscate a package. You might be\nporting your package to a new platform for the first time, or you\nmight have outstripped the capabilities of an ad hoc system. Or, you\nmight be assuming maintenance of a package and you want to make it fit\nin with other packages that use the GNU Autotools. - https://www.oreilly.com/library/view/gnu-autoconf-automake/1578701902/1578701902_ch23lev1sec1.html\n\nAlthough you might not need to create a portable Perl application, GNU\nAutotools provide the framework of a complete build and packaging\nenvironment for your application.  Coupling that with the use of the\nRedhat Package Manager and you are on your way to automated builds\nthat are _organized_, _extensible_ and _scalable_.\n\n[Back to Table of Contents](#table-of-contents) \n\n# Quick Start\n\n1. Install this project from GitHub or CPAN (_Hint:_  _unless you want to\n   dive into the gory details of how this utility is built, install from [CPAN](https://metacpan.org/pod/Autoconf::Template)_)\n1. Create a `manifest.yaml` file that describes the project and the\n   assets you want to include (_they don't actually have to\n   exist!_). You can also use `autoconf-template-perl` to [_automagically_ create a\n   `manifest.yaml`](#automatically-creating-a-manifest-file) file from your project directory.\n   ```\n   project: foobar\n   description: The FooBar Project\n   author: Fred Flintstone\n   email: fred@openbedrock.org\n   perl:\n     bin:\n       - foo.pl\n       - bar.pl\n     lib:\n       - Foo.pm\n       - Foo/Bar.pm\n   ```\n1. run the `autoconf-template-perl` utility\n   ```\n   autoconf-template-perl -d . --create-missing\n   ```\n1. initialize the build system\n   ```\n   ./bootstrap\n   ```\n1. configure the project\n   ```\n   ./configure --localstatedir=/var --prefix=/usr --sysconfdir=/etc/\n   ```\n1. build the project\n   ```\n   make\n   ```\n1. install the project to `/tmp` or somewhere of your choosing\n   ```\n   make install DESTDIR=/tmp\n   ```\n\n\u003e As noted above, none of the assets listed above actually need to exist. The utility\n\u003e will create stubs for you. You can also create 0 length files to\n\u003e force creation of stub. [Perl scripts](#templates/stub.pl.tt) and\n\u003e [module stubs](#templates/stubs.pm.tt)  will be\n\u003e built from templates. Feel free to modify these as per your\n\u003e requirements and likes. :-)\n\nIf all goes well, you have installed a sample project that looks\nsomething like this:\n\n```\n/tmp\n|-- usr\n|   |-- bin\n|   |   |-- bar.pl\n|   |   `-- foo.pl\n|   `-- share\n|       |-- man\n|       |   |-- man1\n|       |   |   |-- bar.1man\n|       |   |   `-- foo.1man\n|       |   `-- man3\n|       |       |-- Foo.3man\n|       |       `-- Foo::Bar.3man\n|       `-- perl5\n|           |-- Foo\n|           |   `-- Bar.pm\n|           `-- Foo.pm\n`-- var\n    `-- www\n        |-- htdocs\n        |   |-- css\n        |   |-- img\n        |   `-- javascript\n        |-- log\n        |-- session\n        `-- spool\n```\n\nNext steps...take a look at the source tree created for you. First\nremove all of the built artifacts and files created by `configure`.\n\n```\nmake distclean\n```\n\n...and now inspect the source tree\n\n```\ntree foobar/ | less\n```\n\nThe source tree will contain all of your artifacts and a few extra\ngoodies:\n\n* Stub unit test files will be created in:\n  * `src/main/perl/bin/t`\n  * `src/main/perl/cgi-bin/t`\n  * `src/main/perl/lib/t`.\n* `.gitignore` file has been added to your project that will filter out\nfiles and directories you probably don't want to put under source\ncontrol.\n* a `.git` directory has been created with your name and email in the\n`config` file\n\nIf you are using `git` for source control, now is a good time to\ninitialize your repository and commit the Big Bang!\n\n```\nmake clean\ngit init\ngit add .\ngit commit -m 'Big Bang!'\n```\n\n[Back to Table of Contents](#table-of-contents) \n\n# An Even Quicker Start\n\nLet's create a project with:\n\n* a Perl script\n* a Perl module\n* a confguration file\n* a Bash script\n\nFirst create placeholders for the assets you'll have in your project and then create a manifest:\n\n```\nsudo cpanm -n -v Autoconf::Template\ntouch foo.pl\nmkdir Foo \u0026\u0026 touch Foo/Bar.pm\ntouch foo.sh\nautoconf-template-perl -n 'Me' --create-manifest -D 'the foo project' \\\n  -e 'me@example.org' -p foo \u003emanifest.yaml\n```\n\n...now create the project in a temporary direct - not the current directory!\n\n```\nmkdir /tmp/foo\nautoconf-template-perl -d /tmp\n```\n\n...see if it works?\n\n```\ncd /tmp\n./bootstrap\n./configure\nmake\nmake check\nmake dist\n```\n\n...commit the stub of your project\n\n```\nmake clean\ngit init\ngit add .\ngit commit -m 'Big Bang'\n```\n\n# Requirements\n\n* `autoconf`\n* `automake`\n* `make`\n* Perl modules (in addition to core modules)\n  ```\n  Capture::Tiny\n  Config::Inifiles\n  Date::Format\n  File::ShareDir\n  JSON\n  Log::Log4perl\n  Markdown::Render\n  Module::ScanDeps::Static\n  Readonly\n  Template\n  Term::ProgressBar\n  Text::ASCIITable::EasyTable\n  YAML\n  ```\n* ...and various other standard Linux utilities\n\n[Back to Table of Contents](#table-of-contents) \n\n# Getting Started\n\n`autoconf-template-perl` started out life as a simple template that\nrequired that you _fill in the blanks_ yourself.  It has since morphed\ninto a set of utilities for automatically creating the scaffolding of an\n_autoconfiscated_ Perl application. The resulting scaffolding is a\n__working__ starting point for your Perl application.  That's\nright...you should be able to build a deployment tarball for your\napplication after running the utilities that create the project build\ntree.\n\nIn order to create an _autoconfiscated_ project you will need to first install\nthis project from the GitHub repository or from CPAN.\n\nAfter installing this project, you should identify the artifacts needed\nby your project. Typically, this means you might have:\n\n* Perl modules (`.pm`)\n* Perl scripts (`.pl`)\n* CGI scripts (`.pl` or `.cgi`)\n* Configuration files (`.cfg`, `.json`, `.ini`, `.yaml`, etc)\n* Resources - additional files you might need to install somewhere\n* Web application artifacts (`.html`, `.js`, `.css`, `.png`, etc)\n\nOnce you have identified all of the artifacts that you'd like to include\nin your project, create a `manifest.yaml` file that looks something\nlike this:\n\n```\nproject: {project name}\ndescription: {description}\nauthor: {author's name}\nemail: {author's email address}\nperl:\n  bin:\n    - {list of .pl files}\n  lib:\n    - { list of .pm files }\n  cgi-bin:\n    - {list of .pl files that will be installed as .cgi files}\nresources:\n  - {list of files of any type}}\nhtml:\n  css:\n    - {list of .css files}\n  htdocs:\n    - { list of .html files }\n  javascript:\n    - { list of .js files}\n  image:\n    - { list of image files of any type}\n```\n\n* Files should be listed using their fully qualified pathname or a path\nrelative to the directory in which you run the\n`autoconf-template-perl` utility\n* None of the sections are required\n* If the file path begins with `~` (tilde) then the path will be\n  prepended with the `$HOME` environment variable (if it exists).\n* If the file listed does not exist, _that's ok_...the utility will\n  create the file from a set of stubs that were included with the\n  utility. Stubs exist for `.pm`, `.pl`, `.html`, `.cfg` and `.js`\n  files. These stubs are templates of the `Template::Toolkit` ilk. If\n  a stub does not exist for the file you listed, an empty file is\n  created (run `autoconf-template-perl --list-stubs` to see all stub\n  files and their locations).\n\n\u003e You can customize or use your stubs. See [Configuring\n\u003e `autoconf-template-perl`](#configuring-autoconf-template-perl)\n\nPerl modules, scripts and CGI scripts will be written to their target\ndirectories with and extension of `.pm.in` for modules and `.pl.in` for\nscripts. (See [Building from `.in` Files](#building-from-in-files) to\nunderstand why the framework uses `.in` files as source.)\n\nBash scripts will be written as `.sh.in` files.\n\n| Type | Extension in Build Tree | Extension Installed | \n| ---- | ----------------------- | ------------------- |\n| Perl modules | `.pm.in` | `.pm` |\n| Perl scripts | `.pl.in` | `.pl` | \n| Perl CGI scripts | `.pl.in` | `.cgi` |\n| Bash scripts | `.sh.in` | `.sh` |\n\nYour source files can have any extension when listed in the\nmanifest. The extension will be replaced using the convention described\nabove.\n\n\u003e Reminder: if the file in the manifest does not exist, the utility\n\u003e will try to find a template for the type of file you listed using\n\u003e the extension of your source file. If your extensions do not look\n\u003e like those in the table and you are trying to introduce a\n\u003e non-existent file to the project, it will be created as an empty\n\u003e file.\n\nCGI scripts will also be copied to their target directory as\n`.pl.in` files, but will have an extension of `.cgi` when\ninstalled.\n\nOnce you have created a manifest file, run the\n`autoconf-template-perl` utility to create your build tree.\n\n```\nautoconf-template-perl --destdir=/tmp --manifest=manifest.yaml\n```\n\n* `destdir` is the root of the target directory for your build\n  tree. This is a required argument.\n* `manifest` is the name of a YAML file that contains the manifest\n\nBy default, `autoconf-template-perl` will look for a file name\n`manifest.yaml`. Try `autoconf-template-perl -h` to see all the\navailable options.\n\nAfter running the utility, depending on what you have included in your\nmanifest, your build tree will look something like this:\n\n```\n|-- autom4te.cache\n|-- autotools\n|-- config\n|-- includes\n|-- resources\n`-- src\n    `-- main\n        |-- bash\n        |   `-- bin\n        |-- html\n        |   |-- css\n        |   |-- htdocs\n        |   `-- javascript\n        `-- perl\n            |-- bin\n            |   `-- t\n            |-- cgi-bin\n            `-- lib\n                `-- t\n```\n\n...and if all goes well, you can try your first build:\n\n```\n./configure\nmake\n```\n\n...if that succeeds, try installing the project and examine the\ndeployment tree structure:\n\n```\nmake install DESTDIR=/tmp/my-project\ntree /tmp/my-project | less\n```\n\n[Back to Table of Contents](#table-of-contents)\n\n## Automatically Creating A Manifest File\n\nTo create a `manifest.yaml` that contains your project assets, you use\nthe `--create-manifest` option of `autoconf-template-perl`. Assuming\nyour are in a directory that contains Perl scripts, modules and other\nassets you want to include in your project, creating a manifest is as\neasy as:\n\n```\nautoconf-template-perl --create-manifest --source-dir . \u003e manifest.yaml\n```\n\n`autoconf-template-perl` will look for these files:\n\n| File Type | Extension |\n| --------- | --------- |\n| Perl scripts and module | `.pm`, `.pl` |\n| Bash scripts | `.sh` |\n|  Web application artifacts | `.html`, `.css`, `.js`, `.png`, `.jpeg`, `.jpg` |\n| Configuration files | `.json`, `.yaml`, `.cfg`, `.ini` |\n\nAny other files in your source directory will be added to the\n`resources:` section of the manifest.\n\nNow edit the manifest and add paths to other artifacts or otherwise\ncustomize the manifest for your project. You can customize the\nmanifest by adding some options (the default `--source-dir` is the\ncurrent directory):\n\n```\nautoconf-template-perl --create-manifest \\\n  --project 'slate-industries-inventory' \\\n  --author 'Fred Flintstone' \\\n  --email 'fred@openbedrock.org' \\\n  --description 'quarry inventory app' \u003e manifest.yaml\n```\n\nRemember that your paths in the manifest can be absolute or relative\nto the directory where you will be running `autoconf-template-perl` to\ncreate your project.\n\nYou can also add the names of scripts or modules that do not exist but\nyou _plan_ to create. Use just the __relative path__ for those...for\nexample if I _plan_ to create a `Slate::Config` module, then list the\nfile in the manifest like this:\n\n```\nperl:\n  lib:\n    - Slate/Config.pm\n```\n\n`autoconf-template-perl` will then create a stub module for you from the stub\ntemplate for Perl modules.\n\nIf your files exist in a file hierarchy that you wish to preserve, use the\n`--strip-dir` option to strip the root of the hierarchy from files in\nyour manifest rather than the entire directory name. Normally, the\nfiles listed in the manifest will be copied to the __root__ of their\ntarget directory.  For example, any `.pl` files in your source\ndirectories (and below) will be copied to `src/main/perl/bin`. Suppose\nyou have files in your current directory like this:\n\n```\nbar/bar.pl\nbiz/biz.pl\nfoo/bar.pl\n```\n...and you want to preserve that hierarchy, set `--strip-dir` to the\ncurrent working directory when you create the project.\n\n```\nautoconf-template-perl  --strip-dir . -d .\n```\n\n[Back to Table of Contents](#table-of-contents) \n\n## Configuring `autoconf-template-perl`\n\n`autoconf-template-perl` can create a valid project with no options.\nAll you need to provide is a `manifest.yaml` file.  You can create\nyour own manifest or let `autoconf-template-perl` generate one for\nyou.\n\n```\nautoconf-template-perl --create-manifest --source-dir .\n```\n\n## `autoconf-template-perl` Options\n\n\u003e This may not be a complete list of current options. use\n\u003e `autoconf-template-perl -h` to see all options\n\n| Option | Description |\n| ------ | ----------- |\n| `h, --help`| help |\n| `a, --author name`|  author's name (default: \"anonymouse\")\n| `--add-version-numbers` | add version numbers to required modules, default: true |\n| `b, --bash`| build bash directories (default: true) |\n| `c, --create-missing`|  create any files in manifest that do not exist (default: false) |\n| `C, --create-manifest`| create a manifest file from the current directory |\n| `S, --create-stub`| filename  create a stub file |\n| `d, --destdir`| directory root for project directory |\n| `e, --email email`| author's email (default: rlauer6@comcast.net || anonymouse@example.com) |\n| `f, --force`| force overwrite of project directory |\n| `h, --html` | build html directories (default: true) |\n| `l, --log-level level`| logging level, error, warn, info, debug, trace  (default: error) |\n| `L, --list-stubs`| lists the stub templates available |\n| `m, --manifest` |  filename  name of the YAML manifest file |\n| `o, --output` | name of the output file for stubs |\n| `p, --project name` | project name (default: \"noname\") |\n| `r, --refresh`| refresh after  addition of script or module |\n| `R, --rpm-build`| enable or disable RPM spec file |\n| `s, --source-dir`| directory source directory for files in manifest or when creating manifest |\n|   | (default: pwd) |\n| `u, --unit-tests`| create unit test stubs (default: true) |\n| `v, --version` | report script version |\n\nThese options default to true, use `-no-{option}` to disable\n\n```\n--bash\n--html\n--rpm-build\n--unit-tests\n--add-version-numbers\n```\n\n[Back to Table of Contents](#table-of-contents)\n\n# Project Source Tree\n\nYour Perl application source tree is laid out in a _specific_, _organized\nhierarchy_ to create a standard layout that all of your team can navigate\neasily. It __will not__ reflect the way a project is eventually installed in\nthe target environment. See [Deploying Your\nProject](#deploying-your-project) for details regarding *where*\nartifacts are installed.\n\nThe source tree hierarchy is based on common patterns and best\npractices you'll see in many open source projects. Those practices\nhave been adapted for packaging Perl applications. Many of the\napplications I have written or maintained have included web\ncomponents. `autoconf-template-perl` recognizes the needs of those\ntypes of applications by creating directories and build instructions\nfor web applications as well.\n\n[Back to Table of Contents](#table-of-contents)\n\n## Root Directory\n\nThe root of the project will contain your `configure.ac` file which is\nused by `autoconf` to create your `configure` script.  The `configure`\nscript is then used to create the `Makefile` in all of your\nsubdirectories from the `Makefile.am` created automatically for you by\n`autoconf-template-perl`.\n\nThe root also contains a stub `ChangeLog`, `README.md` and other files\nyou can customize you might typically see on the _first page_ of your\n`git` repository..\n\n## `autotools` Directory\n\nThe `autotools` directory contains [`m4`\nmacros](https://en.wikipedia.org/wiki/M4_(computer_language)) used\nduring the configure phase. These should be considered source files\nunder source control (if you are using a source control system). You\ndon't need to know much about `m4` to use this utility. The project\ncontains and will create `m4` macros behind the curtains that do the\nthings needed to configure and build your project.\n\n## `config` Directory\n\nThis directory should contain the configuration files containing magic\nvalues (but hopefully not __secrets__) required by your\napplication. Typically configuration files might be `.ini`, `.cfg`,\n`yaml` or `.json` files. When you specify these files in your manifest, the\n`autoconf-template-perl` utility will rename them with a `.in`\nextension. See [Building From `.in`\nFiles](#building-from-in-files). It does this so that you can include\nvalues in the files that are populated when you configure the project\nfor a build by running `./configure` in the project root.\n\nYou can add new configuration files to your project at any time. To\nadd new configuration files after the initial project creation see\n[Adding Artifacts to Your Project](#adding-artifacts-to-your-project).\n\nConfiguration files are deployed to _`$(sysconfdir)/@PACKAGE@`_, defined when\nyou configure the project (typically `/etc/@PACKAGE@`).\n\n## `resources` Directory\n\nThis directory contains files in your project that will be installed\nto `$(datadir)/@PACKAGE@`. For example, if your project name is\n`foobar` and you configure your project like this:\n\n```\n./configure --prefix=/opt --sysconfdir=/etc/ --localstatedir=/var\n```\n...then your resources will be installed to `/opt/share/foobar`\n\nNew resources can be added to the project at any time by dropping the\nfile in the resources directory and running the\n`autoconf-template-perl` utility with the `--refresh` option.\n\n## `src` Directory\n\nThe `src` directory and all of the sub-directories  under `src` contain\nthe source files for the build. You may or may not have\nall of these directories in your build tree depending on what you\nincluded in the manifest.\n\n```\n src\n `-- main\n     |-- bash\n     |   `-- bin\n     |-- html\n     |   |-- css\n     |   |-- htdocs\n     |   |-- image\n     |   `-- javascript\n     `-- perl\n         |-- bin\n         |   `-- t\n         |-- cgi-bin\n         `-- lib\n             `-- t\n```\n\n[Back to Table of Contents](#table-of-contents)\n\n# Building and Deploying Your Application\n\n## Building Your Application\n\nIn general, the recipe for building your application looks like this:\n\n1. Configure the build with the options that determine the\n   installation location and other parameters that determine your\n   application or build environment\n   ```\n   ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \\\n       --with-perl5libdir --with-my-custom-option=foo\n   ```\n1. Run `make` to syntax check your Perl scripts and modules and create\n   your deployment files from your `.in` files\n1. Run `make check` if you want to run unit tests\n1. Run `make dist` to create distribution tarball for your application\n\nYou can also build an RPM after creating your distribution\ntarball. [Building RPMs](#building-an-rpm) is a more complicated subject that is discussed\nlater in this documenation.\n\n[Back to Table of Contents](#table-of-contents)\n\n## Checking Your Project Distribution\n\nChecking the project distribution before deployment involves several\nsteps, depending on how you have configured the project. By default\nthe distribution will go through the checks listed below when you run\n`make distcheck`\n\n* A tarball will be created from your project artifacts (`make dist`)\n* A [VPATH\n  build](https://www.gnu.org/software/automake/manual/html_node/VPATH-Builds.html)\n  will be initiated (`make`).\n  * building first proceeds with the substitution of Automake\n  variables for those files in the source tree with the `.in`\n  extension. The `.in` suffix is removed and a deployment file is\n  create (`.pl`, `.pm`, etc).\n  * Perl scripts and libraries will be syntax checked using `perl -wc`\n* Verification tests if any will be run (`make check`).\n  * unit tests found in the `t/` sub-directories of `perl/bin`, `perl/lib`\n    and `perl/cgi-bin`\n  * `perlcritic` at the severity level defined in your `Makefile.am`\n    specified in the `DISTCHECK_CONFIGURE_FLAGS` variable.\n* Installation of the project is done in a temporary (`make\n  install`)\n* The project will be uninstalled and build artifacts will be removed (`make\n  uninstall`, `make clean`)\n\nIf all of those steps succeed, your project is ready for\ndeployment. If it fails any of these steps you should check the FAQs\nregarding `distcheck` failures and correct the problem before\ndeployement. When `distcheck` fails, it is likely that taking your\ntarball to the target system and attempting an installation will be\n_first order broke_.\n\nPassing, does not mean your project will be successfully\ndeploy in any environment.  It simply indicates that, at least\nin your build environment, the package is complete and passes the tests\ndefined by the build system.  That includes whatever checks have been\ndone when you ran `./configure` which, tests for things like Perl modules\nand other Linux utilities (`prove`, `pod2man`, etc.). \n\nIf you have additional requirements for your application you can\nmodify the `configure.ac` file and use this example as a guide...\n\n```\nAC_PATH_PROG([POD2MAN],\n\t[pod2man])\n\nif test -z \"$POD2MAN\" ; then \n  AC_MSG_ERROR([pod2man found?])\nfi\n```\n\nIn the example above your `configure` script will check for the\n`pod2man` utility required for building man pages and create an\nAutomake variable (`@POD2MAN`) you can use in your `.in` files.\n\nFailure to find the `pod2man` utility will abort the\nconfiguration. If the item you are checking for is optional, you can\nuse `AC_MSG_WARN` instead of `AC_MSG_ERROR`.\n\nMuch more advanced checks are possible but require much more advanced\nknowledge of `autoconf`. Learn more about [writing\ntests](https://www.gnu.org/software/autoconf/manual/autoconf-2.60/html_node/Writing-Tests.html#Writing-Tests)\nfor your `configure.ac` file by visiting the Autoconf website.\n\n## Deploying Your Application\n\nHow you deploy your application depends on how you have packaged it.\nIf you have opted to use an RPM, deployment is done using `yum` or\n`rpm`. \n\n[Back to Table of Contents](#table-of-contents)\n\n## RPMs\n\nThe entire deployed application has been laid out within the\nRPM, so deployment is essentially done by `rpm` by copying the\ncontents of the RPM to the target system.  Some additional steps might\nbe performed in the `%post` section of the RPM if you are building\nPerl module dependencies at deployment time.\n\n[Back to Table of Contents](#table-of-contents)\n\n## Tarballs\n\nIf you are deploying to a target system from the distribution tarball,\nyou will need to _configure_, _build_ and _install_ the application. This is\ndone using the standard recipe shown below.\n\n```\ntar xfvz my-app-1.0.0.tar.gz\ncd my-app-1.0.0\n./configure\nmake\nsudo make install\n```\n\nYou might want to pass configuration options to `configure` instead of\nusing the defaults to control where all of your artifacts are\ndeployed.\n\nTry `./configure --help` to see a listing of all configuration\noptions.\n\n[Back to Table of Contents](#table-of-contents)\n\n## Standard Deployment Tree\n\nUsing the configuration options show below will result in your\napplication being installed in the locations shown in the table.\n\nThis hierarchy is (for the most part) based on the standard [Linux File System Hierarchy](https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard).\n```\n./configure --prefix=/usr --localstatedir=/var/ --sysconfdir=/etc\n```\n\n| Artifact | Source Location | Deployment Location | Config Option |\n| --------- | -------------- | ------------------- | ------------- |\n| Bash scripts | src/main/bash/bin/ | /usr/bin | `--bindir` |\n| Perl scripts | src/main/perl/bin/ | /usr/bin | `--bindir` |\n| Perl modules | src/main/perl/lib/ | `$Config{installsitelib}` | `--perl5libdir` |\n| Configuration files | config/ | /etc/@PACKAGE@ | `--sysconfdir`\n| Resource files | resources/ | /usr/share/@PACKAGE@/ | `--datadir` |\n| HTML files | src/main/html/htdocs | /var/www/htdocs | `--apache-vhostdir` |\n| CSS files | src/main/html/css | /var/www/htdocs/css | `--apache-vhostdir` |\n| Javscript files | src/main/html/javascript | /var/www/htdocs/javascript | `--apache-vhostdir` |\n| Image files | src/main/html/image | /var/www/htdocs/img | `--apache-vhostdir` |\n\n\u003e * @PACKAGE@ is the name of your project\n\u003e * `$Config{installsitelib}` is Perl's module site directory\n\u003e * Web application artifacts are all installed under `${apache_vhostdir}/htdocs`\n\n[Back to Table of Contents](#table-of-contents)\n\n# Adding Artifacts to Your Project\n\nAdding additional files and resources to your project can be done by\ndropping a new file in the target directory and refreshing\n(`--refresh`) the project. You can also use the `--create-stub` option\nto create files that have supported stub templates (`.pl`, `.pm`, `.cgi`, etc).\n\n```\ncp foo.txt my-project/resources/\ncd $PROJECT_HOME\nautoconf-template-perl --refresh\n```\n\nInside the project directory, this will add the new file to your\nproject. Outside the project or if you use the `--output` option the\nstub will be either written to STDOUT when `--output` is not provided\nor `-` or the file name provided in the option.\n\n```\nautoconf-template-perl --create-stub foo.pl\n```\n\nWhen you use the `--create-stub` option, `autoconf-template-perl` will\nautomatically do a refresh.\n\nIf you already have script or module and are not using the\n`--create-stub`option, copy the source file to the target\ndirectory as a `.in` file and then manually refresh the project.\n\n```\ncp foo.pl $PROJECT_HOME/src/main/perl/bin/foo.pl.in\ncd $PROJECT_HOME\nautoconf-template-perl --refresh\n```\n\nPerforming a refresh operation will regenerate the\n`Makefile.am` files to enable your new artifact to be built and\ninstalled when the project is deployed. Refreshing will also scan your\nPerl modules and scripts for new dependencies and regenerate files\nthat contain those dependencies.\n\n[Back to Table of Contents](#table-of-contents) \n\n# Building From `.in` Files\n\nWhen you specify configuration files, scripts and Perl modules in your\nmanifest, they are installed in their target source directories with a\n`.in` extension.  This is done because the various `Makefile.am` files\nspecify the file without the extension as the build target and use the `.in`\nfile as the source.\n\nFor example, a `.pl` file is built from a `.pl.in` file (similarly for\nother types of files with a `.in` extension). Depending on the file\ntype, the build recipe may be as simple as:\n\n```\n$(GCONFIG):\n    $(do_subst) $\u003c \u003e $@\n```\n\n...which simply takes your source file (`.cfg.in`) and uses `sed` to\nsubstitute values in your source that are associated with `automake`\nvariables.  These `automake` variables are the ones that are created\nby your `configure` script when you say something like `./configure\n--with-foobar=bar`. You can use them in your source files (`.in`)\nusing the convention `@variable-name@`.\n\nSo, for example, to specify the system configuration directory in one of\nyour configuration files (`my-app.cfg.in`), you might include something like this:\n\n```\ndb_config = @sysconfdir@/my-app/db-config.cfg\nlog_dir   = @localstatedir@/log/my-app.log\n```\n\nDuring the build, those variables surrounded by the `@` symbol will be\nreplaced by the `automake` variable's value.\n\n```\ndb_config = /etc/my-app/db-config.cfg\nlog_dir   = /var/log/my-app.log\n```\n\nWhy not just hard-code those paths? Well, as described in the\n[Overview](#overview), the beauty of using `autoconf` and\n`automake` is their ability to easily re-configure your project so that\nit can be installed anywhere.\n\n```\n./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc\nmake\nmake install DESTDIR=/tmp/foo\n```\n\nThe above statements would direct the install process to prefix your\nconfigured directories with `/tmp/foo` during the intallation phase\n(`make install`). In this manner, you can alter the installation paths\nfor different environments or for simply examining the deployment\nstructure without actually deploying to the intended targets.\n\nSee [Creating Your Own Configuration\nOptions](#creating-your-own-configuration-options)\n\n[Back to Table of Contents](#table-of-contents)\n\n## Automake Configuration Variables\n\nHere's a list of some of the `automake` configuration variables you\ncan use in any file that is built using `$(do_subst)` (config files,\nscripts, modules).\n\n| Variable Name | Description |\n| ------------- | ----------- |\n| `@ARCHITECTURE@` | architecture (noarch or X86_64) |\n| `@BUILD_DATE@` | build date |\n| `@LICENSE@` | license |\n| `@PACKAGE_DESCRIPTION@` | package description |\n| `@PACKAGE_NAME@` | package name |\n| `@PACKAGE_VERSION@` | package version |\n\n* Apache Site Directories\n\nThese directories are rooted by the configuration value\n(`--with-apache-vhostdir=`) made available by the `m4` macro\n[`autotools/apache_config.m4`](autotools/apache_config.m4).\n\nWithout modification, the directories below\nare set relative to the value you provided for `apache-vhostdir`. These\ndirectories are defined in `includes/apache-directories.inc`. Feel free to\nmodify them based on your needs.\n\nThese directories contain web application artifacts or are used by the\nweb application in some way. Note that descriptions are how these\ndirectories are _typcially_ used, however you can use or not use them\nas you please. Only a subsert of these directories are actualy created\nfor you when your web application is installed.\n\n| Variable Name | Description |\n| ------------- | ----------- |\n| `@apache_site_cachedir@` | cached assets |\n| `@apache_site_cgibindir@` | CGI scripts |\n| `@apache_site_configdir@` | configuration files |\n| `@apache_site_cssdir@` | CSS files |\n| `@apache_site_htdocsdir@` | HTML files|\n| `@apache_site_imgdir@` | Image files |\n| `@apache_site_javascriptdir@` | Javascript files |\n| `@apache_site_logdir@` | Log files |\n| `@apache_site_perl5libdir@` | Perl modules |\n| `@apache_site_reportsdir@` | Report files |\n| `@apache_site_sessiondir@` | Session files |\n| `@apache_site_spooldir@` | Spool files |\n| `@apache_site_workdir@` | A work dir? |\n| `@apache_sitedir@` | Same as `@apache_vhostdir@` ||\n| `@apache_vhostdir@` | root directory for web application |\n\n* Apache Domain and Virtual Server\n\nYou can potentially use these values in the table below to alter\nthe directories in the table above so that you might, for example\nsupport multiple applications in different virtual hosts or domains on\nthe same platform. In the default setup, defined in\n`includes/apache-directories.inc`, these values are not used. However\nif for example, you wanted to support a virtual host configuration you\nmight alter `apache_sitedir` in the `includes/apache-directories.inc`\nfile.\n\n```\n # Apache Virtual Host site directories\n apache_vhostdir           = @apache_vhostdir@\n apache_sitedir            = $(apache_vhostdir)/@apache_vhost_server@\n```\n\n...and then configure the project thusly...\n\n```\n./configure --with-apache-vhost-server=www.foobar.com --with-apache-vhostdir=/var/www/vhosts\n```\n...so that your web application might be installed in `/var/www/vhosts/www.foobar.com`\n\n| Variable Name | Description |\n| ------------- | ----------- |\n| `@apache_vhost_alias@` | possibly used for _ServerAlias_ directive in a _VirtualHost_ section of an Apache configuration file |\n| @apache_vhost_confdir@  | the directory where all the virtaul host configuration files reside\n|                         | examples: /etc/httpd/conf.d, /etc/apache2/sites-available, /usr/local/bin/conf/conf.d |\n| @apache_vhost_domain@  | the domain name of the website |\n|                         | examples: example.com | \n| @apache_vhost_server@ | the fully qualified domain name (including subdomain) of the website |\n|                     | examples: www.example.com, api.example.com |\n\n* Apache User/Group \n\nThese variable can be set when you configure the application or the m4\nmacro will create defaults based on the system flavor (RedHat vs\nDebian) you are building on.\n\n| Variable Name | Description |\n| ------------- | ----------- |\n| `@apache_user@` | the user that runs the apache server |\n|                 | examples: www-data, apache, nobody |\n| `@apache_group@` | the group the user that runs apache belongs to |\n|                  | examples: www-data, apache, nobody |\n\n* Miscellaneous Files\n\n| Variable Name | Description |\n| ------------- | ----------- |\n| `@bashrun@` | bash executable path |\n| `@bindir@` | scripts and binaries |\n| `@configure_input@` | the input to `configure` script |\n| `@datadir@` | data files |\n| `@libexecdir@` | scripts not meant for user consumption |\n| `@localstatedir@` | stateful files (typcially  `/var`) |\n| `@perl5libdir@` | Perl modules |\n| `@perlrun@` | Perl executable path |\n| `@prefix@` | prefix for file system hierarch (typicall `/usr/`) |\n| `@sysconfdir@` | Configuration files |\n\n*TODO:* _Provide templates for virtual host and Apache configurations_\n\n[Back to Table of Contents](#table-of-contents) \n\n# Building Perl Modules\n\nPerl is an interpretted language and thus Perl scripts do not need to\nbe built in the same ways C or C++ files require compilation and\nlinking to become executable. Perl scripts are compiled _on the fly_\nwhen you invoke the Perl interpretter either directly as in:\n\n```\nperl -I $HOME/lib/perl5 my-app.pl\n```\n...or implictly using the she-bang as the first line of your script to\ntell the shell how to run your script.\n\n```\n#!/usr/bin/env perl\n```\n\nSo what does _Building Perl Modules_ mean?\n\nIn the context of `autoconf-template-perl` building a Perl module\ndoes a few things:\n\n1. Replaces `automake` variables (`@variable-name@`) found in the\n   source files with their values that were set by `configure`\n1. Runs `perl -wc` on the module or script to check the syntax.\n1. Creates `man` pages from the pod contained in the module or script.\n\nWhen you build a Perl module or script from a `.pl.in` or `.pm.in`\nfile, the build recipe will first perform any required substitution of\n`automake` variables using `$(do_subst)`. \n\n\u003e `$(do_subst)` is defined in `configure` and is simply a series of\n`sed` statements that do text substitution\n\nThe `Makefile` recipe will then run `perl -wc` against the resulting\n`.pl` file. If the syntax checking fails, the build will stop.\n\nWhen the build recipe runs `perl -wc` it add additional Perl paths to\n`@INC` that might be needed to syntax check your script.  All files in\nthe `src/main/perl/lib` directory are built first, __in an order that\nguarantees that even modules contained in the project that are\ndependencies of other modules in the project are built before the\ndependent module__.\n\nThe order that `make` descends into your source tree is determined by the `SUBDIRS` variable in\n`src/main/perl/Makefile.am`.\n\n```\nSUBDIRS = . lib bin cgi-bin \n```\n\nNote that files in `lib` and `bin` are built prior to `cgi-bin`\nscripts. This is done because in most cases scripts in `bin` may depend\non modules you build in `lib`.  CGI scripts may depend on both Perl\nmodules and scripts.\n\nIf you have additional paths, other than those configured by Perl or\nthe build recipe, you can add them when you configure the project.\n\n```\n./configure --with-perl-includes=$HOME/lib/perl5\n```\n\nLaying out your build tree is not a mindless task and you should\nconsider the intradependencies of the components within the project\nwhen making those decisions. Of course, it's not rocket science\neither. ;-)\n\n[Back to Table of Contents](#table-of-contents)\n\n## Disabling Syntax Checking\n\nSyntax checking of Perl modules requires that all required Perl\nmodules are installed somewhere in Perl's `@INC` path. There may be\nsituations where you do not want to perform this kind of check.\nBuilding RPMs for example can resolve their own dependencies in the\ntarget environment when they are deployed. Your build system that\ncreates the RPM may not, and does not necessarily need the Perl\nmodules installed to build the RPM. To deal with this situation, there\nare two options you should consider.\n\nUse the `--disable-perldeps` option to `configure` to disable\nthe looking for required  Perl modules during execution of `configure`\nand the `--enable-rpm-build-mode` which\nwill turn off syntax checking of Perl scripts and modules during a `make`.\nSubstitution of `automake` variables will still occur however.\n\n[Back to Table of Contents](#table-of-contents)\n\n## Perl Module Dependencies\n\nAs discussed in previous sections, when your project is instantiated\n`autoconf-template-perl` will examine your source files and identify\nPerl module dependencies. Those dependencies are then used to create\nan `m4` macro used in the `configure` script to check your system for\nthose dependencies. When you manually add new Perl scripts or modules\nyou can run `autoconf-template-perl --refresh` to update that list of\ndependencies. If you use the `--create-stub` option to add new Perl\nmodules or scripts, the refresh is run automatically for\nyou. Refreshing your project does more than just update depdencies, it\nalso updates the list of assets in the `Makefile`s that are built or\ninstalled. Unless you refresh the project after you add a new file,\nthat file will be installed at deploy time.\n\nYou may not want `autoconf-template-perl` to alter your the list of\nrequirements if you have manually edited the requirement files. In\nthat case you use the `--no-dependencies` option when creating stubs\nor refreshing the project.\n\nIf you are maintaining the requirements list manually and you add a\nnew dependency, make sure you update the `m4` macro as well. Edit the\n`requires.json` or `requires.txt` file as needed and then run the\n`autoconf-ax-requirements-check` script to update the macro.\n\n```\nautoconf-ax-requirements-check -i requires.json --update\n```\n\nAfter this is executed, the three files that contain the Perl module\nrequirements will be updated.\n\n```\nrequires.txt\nrequires.json\nautotools/ax_requirements_check.m4\n```\n\nRe-run the `bootstrap` script. The next time you run `configure` the\nnew dependencies will be verified if dependency checking is enabled.\n\n[Back to Table of Contents](#table-of-contents) \n\n# Building an RPM\n\nThis section contains details regarding packaging your application as\nan RPM. This is a _potentially_ good way to package your Perl\napplications on RedHat systems.  It is probably *not* a good strategy if\nyou do not plan on using the _system_ provided `perl` (assuming the\ntarget environment even has such a thing).\n\n\u003e Recent versions of the Amazon Linux 2 Docker container have\n\u003e removed `perl` :-(\n\nWhile it is possible to use a vendored version of Perl and package\nyour application as an RPM, you are likely to run into dependency\nissues if you do not prevent the `rpmbuild` process from trying to\nfind your Perl dependencies. You may also find it a particularly\nfrustrating experience if your application uses Perl modules that do\nnot have RPM packages readily available (See [Building RPMs from\nCPAN Modules](#building-rpms-from-cpan-modules)).\n\nThe alternatives, using the `autoconf-template-perl` system, is to use\nthe tarball created by `make dist` to build your application directly\non the target system or in a Docker container.\n\nIn general, RPM building is done on RedHat flavored systems, however\nit is possible to build RPMs on Debian systems if you install the\n`rpm` package and other necessary utilities. Where you may get tripped\nup is if your `.spec` file includes a `BuildRequires` argument (which\nyour generated `.spec` from `autoconf-template-perl` in fact does). In\nthis case you can build RPMs without `rpmbuild` exiting by including\nthe `--nodeps` option to `rpmbuild`. See the discussion later in this\nsection discussing building RPMs in non-RedHat environments.\n\n## Quick Start\n\n\u003e RPMs are built using the instructions in a spec file (`.spec`). The\n\u003e default `.spec` file created for you has been somewhat customized so\n\u003e that it should work _out of the box_. That is, if haven't changed the basic\n\u003e structure of your project that was defined when you ran\n\u003e `autoconf-template-perl` the first time. If you don't know anything\n\u003e about RPMs or RPM spec files, you'll want to [learn\n\u003e more](https://docs.fedoraproject.org/en-US/package-maintainers/Packaging_Tutorial_GNU_Hello/)\n\u003e about packging applications using `rpmbuild`, especially if you run into any\n\u003e difficulties or want to customize your RPMs.\n\nAssuming you have your project in a state ready to build an RPM,\nfollow the quick start recipe below.\n\n1. Get the `rpm-build` package.\n   ```\n   sudo yum install -y rpm-build\n   ```\n   ...or \n   ```\n   sudo apt-get install rpm\n   ```\n1. Create RPM build directory and create a `.rpmmacros` file.\n   ```\n   test -d \"$HOME/rpmbuild\"  || mkdir $HOME/rpmbuild\n   echo -e \"%_topdir %{getenv:HOME}/rpmbuild \u003e$HOME/.rpmmacros\n   ```\n1. Build the tarball from your project directory and check the\n   distribution to make sure that all assets are present.\n   ```\n   make distcheck\n   ```\n1. Build the rpm.\n   ```\n   rpmbuild -tb $(ls -1t *.tar.gz | head -1)\n   ```\n\n[Back to Table of Contents](#table-of-contents)\n\n## Building RPMs from CPAN Modules\n\nThere have been multiple attempts to create scripts that package CPAN\nmodules as RPMs. The most recent and most robust of which appears to be `cpantorpm`.\n\n| Script | Notes | Repo | \n| ------ | ----- | ---- |\n| `cpantorpm` | loosely based on `cpan2rpm`| https://metacpan.org/dist/App-CPANtoRPM/view/bin/cpantorpm.pod |\n| `cpan2rpm` | | https://github.com/ekkis/cpan2rpm |\n| `cpanspec` | old and crufty | https://src.fedoraproject.org/rpms/cpanspec |\n\nIf you are going to package your application as an RPM you should\nbecome familiar with these tools.\n\n[Back to Table of Contents](#table-of-contents)\n\n## Signing an RPM\n\nOptionally sign the RPM. Make sure you have set `%_gpg_name` in your\n`.rpmmacros` file.\n\n\n```\nrpmbuild -tb $(ls -1t *.tar.gz | head -1) --sign\n```\n\n[Back to Table of Contents](#table-of-contents) \n\n# Building Documentation\n\nWhen you create your project source tree you can tell\n`autoconf-template-perl` to include the recipes for building\ndocumentation.\n\n`man` pages can be will be created from the pod in your `.pm`, `.pl`,\nand `.cgi` when you execute a build using `make`. You can also create\na `README.md` file for each Perl module in your `src/main/perl/lib`\ndirectories.  Use the `--man-pages` option to include the recipe for\nbuilding `man` pages in the `Makefile`s.\n\n[Back to Table of Contents](#table-of-contents)\n\n## README.md for Perl Modules\n\nUse the `--pod-to-readme` option to enable the creation of a\n`README.md` for your Perl modules.  The `README.md` files are __not__\nautomatically created during a build. Execute `make docs` in the\n`src/main/perl/lib` directory to create your `README.md` files. Each\nfiles will be created in a sub-directory whose name is the Perl module\npath.  Adding these files to your `git` repo gives you a convenient\nway to look at the module documentation.\n\n[Back to Table of Contents](#table-of-contents)\n\n## Creating a Module Index\n\nYou can create a module index in `src/main/perl/lib` that will allow\nyou to see all of your Perl modules in one place.  Links to their\n`README.md` files and the source for each module will be included in a\ntable. If you have pod embedded in the module, the index generator\nwill try to extract a short description of the module from the `=head\nDESCRIPTION` section of your pod.\n\n```\nautoconf-template-perl create-index \u003e src/main/perl/lib/README.md\n```\n\nYou can also use `make index` in the `src/main/perl/lib` directory to\nautomatically create your `README.md` file.\n\n[Back to Table of Contents](#table-of-contents)\n\n# Unit Tests\n\n`autoconf-template-perl` will create unit test stubs for you by\ndefault. Unit test stubs are just very simple Perl scripts that\nincorporate `Test::More`. You can disable their creation using the\n`--no-unit-tests` option.\n\nAdditional unit test stubs can be added at any time after project\ncreation. When `autoconf-template-perl` identifies a `.pl`, `.pm` or\n`.cgi` file during project creation, a unit test stub is created in a\nsub-directory of the source tree (e.g. `src/main/perl/bin/t`).  Unit\ntest are created with a `.t` extension. They are named with a 2-digit\nnumeric prefix, followed by the script name (in lower case) without\nthe extension.  Perl modules are named similiarly but have the '::'\nreplace with a dash ('-'). Examples:\n\n| Script/Module | Name Unit Test Name |\n| ------------- | ------------------- |\n|  `foo.pl`     | `t/00-foo.t` |\n| `Foo::Bar`    | `t/00-foo-bar.t` | \n\nUnit tests created after the initial project for a specific script or\nmodule will be named with a prefix one greater than the hightest test\nfor that file. To create `01-foo.pl`:\n\n`autoconf-template-perl --create-test-stub foo.pl`\n\nFor Perl scripts in your `src/main/cgi-bin` directory, use the `.cgi`\nextension for the filename which tells `autoconf-template-perl` to\nlook in that directory to create the next unit test for your CGI\nscript.\n\nUnit test stubs are created for `.pl`,\n`.pm`, and `.cgi` files. These stubs look something like this for\n`.pl` and `.cgi` files.\n\n```\n#!/usr/bin/env perl\n\nuse strict;\nuse warnings;\n\nuse Test::More tests =\u003e 1;\n\nsubtest 'debug' =\u003e sub {\n  ok(1);\n};\n\n__END__\n```\n...and something like this for `.pm` files:\n\n```\n package [% module_name %];\n # autogenerated from [% generator %] v[% version %] on [% timestamp %]\n # template: [% template_name %]\n \n use strict;\n use warnings;\n \n use Carp;\n use Data::Dumper;\n use English qw(-no_match_vars);\n use Log::Log4perl qw(:easy);\n \n use parent qw(Exporter Class::Accessor::Fast);\n \n __PACKAGE__-\u003efollow_best_practice;\n __PACKAGE__-\u003emk_accessors(\n   qw(\n    debug\n   )\n );\n \n our $VERSION = '@PACKAGE_VERSION@'; ## no critic (RequireInterpolation)\n \n ########################################################################\n sub new {\n ########################################################################\n   my ( $class, @args ) = @_;\n \n   my %options = ref $args[0] ? %{ $args[0] } : @args;\n \n   my $self = $class-\u003eSUPER::new( \\%options );\n \n   return $self;\n }\n \n 1;\n \n ## no critic (RequirePodSections)\n \n __END__\n \n =pod\n \n =head1 NAME\n \n =head1 SYNOPSIS\n \n =head1 DESCRIPTION\n \n =head1 METHODS AND SUBROUTINES\n \n =head1 SEE ALSO\n \n =head1 AUTHOR\n \n [% author %] - [% email %]\n \n =cut\n\n```\n\nUnit tests are run by executing `make check` which is also run\nwhenever you run `make distcheck` (See [Checking Your Project\nDistribution](#checking-your-project-distribution)).  All of the unit\ntests must pass for the distribution to be considered _working_.\n\n[Back to Table of Contents](#table-of-contents)\n\n# Advanced Topics\n\n## Customizing Build Rules\n\nIf you are familiar enough with `automake` and wish to customize some\naspect of the build, be aware that refreshing the project will normally\noverwrite your customizations. In order to make sure that a refresh\ndoes not lose your customizations, preface the custom section with a\ncomment that begins with two (2) comment characters.  End the\ncustomized section with another comment that starts with two hash\nmarks.  For example:\n\n```\n ## foo recipe\n \n foo: $(SOME_FOO_FILES)\n     do_something\n \n ## end of foo recipe\n```\n\nYou can customize any of the `Makefile.am` files that build your\nartifacts or the include files that specify the recipes for building\nPerl assets.\n\n* `includes/perl/lib/perl-modules.inc`\n* `includes/perl/bin/perl-bin.inc`\n* `includes/perl/cgi-bin/perl-cgi-bin.inc`\n* `includes/bash/bash-bin.inc`\n* `includes/bash/bash-scripts.inc`\n\nA typical use case might be if some modules are required by other\nmodules which need to be built first.\n\nSuppose module `Foo` is used as a base class for `Bar` and `Buz`:\n\n```\n ## dependencies\n FOO_MODULES = \\\n     Bar.pm.in \\\n     Buz.pm.in\n     USGN/Integration/HMSHost/PurchaseOrder.pm.in\n \n $(FOO): Foo.pm\n ## end of dependencies\n```\n\n[Back to Table of Contents](#table-of-contents)\n\n## Customizing the `all` Target\n\nIf you need to customize the `all` target, add a PHONY target like\n`ALL` to the list of dependencies in the existing `all` target.\nCreate your build rule for `ALL`.  For example:\n\n```\n .PHONY: ALL\n \n ## custom target\n ALL: foo.bar\n     cp $\u003c $$(basename $\u003c .bar).buz\n ## end custom target\n \n all: ALL\n```\n\n[Back to Table of Contents](#table-of-contents)\n\n## Creating Your Own Configuration Options\n\nThe instructions below are designed for those who want to dive a\nlittle deeper into `autoconf` and `automake`.  You might find it\nhelpful to follow along in the [GNU AutoMake documentation](https://www.gnu.org/software/automake/).\n\nOnce you've created your project and `autoconf-template-perl` has\ncreated your `configure.ac` file, executing `./configure --help` will\npresent you with the options available.\n\nAdding your own `configure` options to create\n`automake` variables you can use in source files is done manually by adding\nsome `m4` incantations to create in your `configure.ac` (the\n_automagic_ way is discussed a litle later).\n\n```\nAC_ARG_WITH(\n  [foo-bar],[  --with-foo-bar=[foo bar stuff]],\n  [foo_bar=$withval],\n  [foo_bar=[foo]]\n)\n\nAC_SUBST([foo_bar])\n```\n...and updating the `do_subst_command` in `configure.ac` by adding\nanother `sed` command.\n\n```\n  -e '\"'\"'s,[@]foo[@],$(foo),g'\"'\"' \\\n```\n\nBy adding these snippets you will create an `automake` variable you\ncan use in various ways. Most notably, you can use this is any source\nfile (`.in`) as `@variable-name@` and it will be resolved during the\nbuild phase.\n\n...but wait! There IS an __easier__ way!\n\nUse the `autoconf-ax-extra-opts` utility to add a new option. It will\nautomatically update an `m4` macro (`ax-extra-opts.m4`) and\n`configure.ac` for you.\n\n```\nautoconf-ax-extra-opts -o s3-bucket-name \\\n      -t \"bucket name\" \\\n      -d \"The bucket used store stuff\" \\\n      -D my-private-bucket-name\n```\n...then\n\n```\n./configure -h | grep s3\n--with-s3-bucket-name=bucket-name The bucket to store stuff in (default: my-private-bucket-name)\n```\n\nTo use this in a configuration file for example:\n\n```\n[s3]\nbucket_name = @s3_bucket_name@\n```\n\nDon't forget to commit the updated `autotools/ax_extra_opts.m4`\nmacro to your repository.\n\n[Back to Table of Contents](#table-of-contents)\n\n## Customizing Your Stub Files\n\nWhen files do not exist in your manifest or you want to use the\n`--create-stub` option to create a new script of module,\n`autoconf-template-perl` will create new files for you using a _stub_\ntemplate. You can create your own templates that\n`autoconf-template-perl` will use to create these stubs instead of the\nones that are provided in this distribution.\n\nAn `.autoconf-template-perlrc` file was created in you project\ndirectory when you created the project. Edit the file and replace the\npaths for the stub files you wish to customize.\n\n```\n[stubs]\n\ncgi  = /usr/local/share/perl/5.32.1/auto/share/Autoconf-Template/templates/stub.cgi\npm   = /usr/local/share/perl/5.32.1/auto/share/Autoconf-Template/templates/stub.pm\npl   = /usr/local/share/perl/5.32.1/auto/share/Autoconf-Template/templates/stub.pl\ncfg  = /usr/local/share/perl/5.32.1/auto/share/Autoconf-Template/templates/stub.cfg\njs   = /usr/local/share/perl/5.32.1/auto/share/Autoconf-Template/templates/stub.js\nhtml = /usr/local/share/perl/5.32.1/auto/share/Autoconf-Template/templates/stub.html\n```\n\nSome other options you can set in the configuration file include your\n_name_, _email address_ and _flags that determine whether certain source\ndirectories will be created for you_.  `autoconf-template-perl` will\nlook for this file in your home directory (`$HOME`) and the current\nworking directory, so for future project creations, you'll want to\nmove this to your `$HOME` directory after customization.\n\n```\n[global]\n\nauthor = \"Rob Lauer\"\nemail  = rlauer6@comcast.net\n\ncreate-missing = true\n\nhtml           = true\nbash           = true\nperl_bin       = true\nperl_lib       = true\nperl_cgi       = true\n```\n\n[Back to Table of Contents](#table-of-contents) \n\n## Adding Files to the Distribution\n\n* If you want to add files to be included in your distribution that\nshould __not__ be installed, add this snippet to `Makefile.am` in the\nroot of your project.\n\n```\ndist_noinst_DATA = \\\n   README.md \\\n   NEWS.md \\\n   README-BUILD.md \\\n   ChangeLog\n```\n\n* To add files that require building (`.pl`, `.pm`, `.sh`, and possibly\nconfiguration files) the easy way, follow these steps:\n\n1. Drop the file with a `.in` extension into the appropriate directory\n   ```\n   cp foo.pl $PROJECT_HOME/src/main/perl/bin/foo.pl.in\n   cp foo.cfg.in $PROJECT_HOME/config/foo.cfg.in\n   ```\n2. Re-run `autoconf-template-perl` in the root of the project using\n   the `--refresh` option.\n   ```\n   autoconf-template-perl --refresh\n   ```\n\n* Whenver you introduce new Perl module dependencies to the project,\nmake sure you run `autoconf-template-perl --refresh`. New dependencies\nwill be identified and added to the `m4` macro\n`autotools/ax_requirements_check.m4` so that `configure` will verify\ntheir existence in the target environment during the build.\n\n[Back to Table of Contents](#table-of-contents)\n\n## `configure` Options\n\nAlong with the standard `configure` options that allow you to alter the\ninstall paths there are additonal options specific to\n`autoconf-template-perl` that control the building of your project.\n\n| Option | Description |\n| ------ | ----------- |\n| `--enable-distcheck-hack` | enables flag that use the `DISTCHECK_CONFIGURE_FLAGS`  you might have set in your project root `Makefile.am` (see [FAQs](#faqs)) |\n| `--disable-deps` | don't abort if dependencies are missing, just warn |\n| `--enable-rpm-build-mode` |  disables dependency checking and other behaviors that are only relevant outside of an RPM build |'\n| `--disable-perldeps` | don't abort if Perl module dependencies are missing |\n| `--enable-perlcritic-mode` | run `perlcritic` during `make check` | \n| `--with-perlcritic-severity` | sets the severify level (1-5) that will break the build |\n| `--with-perl5libdir` | where to install Perl modules, default: `$Config{installib}` |\n|  `--with-perl-includes` | additional Perl module paths that will prepended to `@INC` |\n\n[Back to Table of Contents](#table-of-contents)\n\n* Apache Configuration Options\n\n| Option | Description |\n| ------ | ----------- |\n| `--with-apache-vhost-domain=name` | domain name used to set `@apache_vhost_domain@` |\n| `--with-apache-vhostdir=DIR` | root directory for web application |\n| `--with-apache-vhost-confdir=DIR` |  where Apache looks for virtual host configuration files (_not currently used_) |\n| `--with-apache-vhost-server=name` | fully qualified HTTP server name (_not currently_used) |\n| `--with-apache-user=USER`  |       user id that should own the web pages |\n| `--with-apache-group=GROUP`        group that should own the web pages |\n| `--with-license` | default: GNU Public License |\n| `--with-architecture` | architecture (`noarch`, `x86_64`) (default: noarch |\n\n[Back to Table of Contents](#table-of-contents) \n\n## Perl Modules and RPMs\n\nA reminder that our goal is to package a Perl application for\ndeployment and ensure that dependencies are satisfied one way or\nanother when the package is installed in the target environment.\n\nThere are several strategies available to ensure dependencies are\navailable when your application runs.\n\n\u003e Spoiler alert: `autoconf-template-perl` employs strategy #1.iii\n\n1. Don't package any dependencies, only package application artifacts.\n   1. Let the `rpmbuild` process identify dependencies and hope that\n     `yum` can find all the required dependencies as RPMs.\n   1. Kick the can down the road and prevent `rpmbuild` from\n      identifying dependencies so that `yum` does not attempt to pull\n      in RPMs that do not exist. Let another process (or person) worry\n      about installing Perl module dependencies in the target\n      environment, but don't let `yum` end up trying to install RPMs\n      that might not exist!\n   1. Build dependencies at the time of _deployment_ in a `%post`\n      section of the RPM package (_to be clear...in this strategy\n      dependencies themselves are __NOT__ packaged, but are built from\n      a manifest of required modules when the package is installed)\n1. Package dependencies inside your RPM\n   1. Prevent `rpmbuild` from identifying dependencies and build\n      dependencies yourself at the time you build your RPM\n\nEach of these strategies has its _pros_ and _cons_.\n\n| Strategy | Pros | Cons | \n| -------- | ---- | ---- |\n| 1.i | easy, no effort | RPM packages may not be available for all dependencies, some dependencies might not be identified by `rpmbuild` |\n| 1.ii | easy, no effort | requires support from SysAdmins or another step in deployment | \n| 1.iii | easy, some effort | may fail if building modules at time of deployment requires additional libraries or special installation or configuration instructions for CPAN modules |\n| 2.i | a complete RPM ready for deployment! | not supported by this utilty, lot's of effort, must be built in same environment as target |\n\nStrategy #1 is typically the way you build an RPM, letting `rpmbuild`\nfind your dependencies. In some cases you might add additional\ndependencies manually when `rpmbuild` fails to find them. This happens\noccassionally when your script or modules are using `require` in a way\nthat hides the module name from `rpmbuild`. You would them manually\nedit the `.spec` file and add a statement like `Requires:\nperl(Term::ANSIColor)`.\n\nWhile packaging your application as an RPM using strategy #1 is\n_easy_, you may encounter problems with missing RPMs. While all of the\ncore modules can usually be found as RPMs, there are many other\nmodules you may require that have not been packaged yet (or will never\nbe packaged unless you do it yoursef).  Of course, you [can build RPMs\nfrom CPAN yourself](#building-rpms-from-cpan) and store them in a\nprivate `yum` repository.\n\nBy default however, the `.spec` file created by this utility employs\nstrategy #1.iii. `autoconf-template-perl` prevents `rpmbuild` from\nincluding those dependencies by removing them when they are found by\n`rpmbuild`'s scanner. The spec file then includes a `%post` section\nthat executes the [`install-from-cpan`](install-from-cpan.in) script\nthat will install the required modules directly from CPAN using\n`cpanm`.  `autoconf-template-perl` identifies dependencies when your\nproject is being configured and then creates several files that list\nthose dependencies.\n\n| Dependency File | Description |\n| --------------- | ----------- |\n| `autotools/ax_requirements_check.m4` | `m4` macro that checks for  required modules |\n| `requirements.txt` | plain text file listing requirements |\n| `requiremetns.json` | requirements file in JSON format |\n\nThese files can be refreshed by running `autconf-tempalte-perl -r` in\nthe project's root directory.\n\nBuilding dependencies in the `%post` section ensures that dependencies\nare built __in the target deployment environment__. This becomes\nimportant when you are building Perl modules that use XS (compiled\nC/C++ subroutines).\n\nIn order to install a broad range of modules from CPAN a few\ndependencies have been added in the `Requires:` sections of the spec\nfile. These additional dependences (`gcc`, `make`, etc) are commonly\nrequired to build may Perl modules. Other utilities and libraries may\nalso be required to build your particular CPAN module. \n\n\u003e Some common libaries required include `openssl`, `libxml2`, `expat`\n\u003e and their `-devel` development RPMs as well.\n\nWhile building your modules in the `%post` section you may still run\ninto issues when the required Perl modules have additional\ndependencies not detected or known to `rpmbuild` (typically libraries\nlike `libxml2`, etc).  In that case you have two alternatives;\n\n1. Add the requirements to the list of those already in the spec file:\n   ```\n   Requires: gcc make\n   ```\n   ...or you can automatically add dependencies to your spec file when you\n   create your project using the `--rpm-requires` option.\n   ```\n   autoconf-template-perl -d . --rpm-requires libxml2 --rpm-requires libxml2-devel\n   ```\n1. _prevent dependency checking_ altogether and revert to (Strategy\n   #1), letting `yum` try resolve to the dependencies for your Perl\n   modules. This strategy will work if you know that all of your Perl\n   module dependencies can be satisfied from a `yum` repository you\n   have enabled.\n   \n   To employ this strategy and prevent the specfile from\n   blocking dependency checking (_the default_) use the\n   `--no-rpm-install-from-cpan` option when you build your project\n   with `autoconf-template-perl`. `rpmbuild` will then add the\n   dependencies to the package so that `yum` will attempt to satisfy\n   those dependencies from enabled repositories at install time.\n\nStrategy #1.ii usually takes the form of handing your dependency list\nto the _SysAdmins_ and asking them to add these dependencies using\nwhatever tools they use to install Perl modules.\n\n\u003e `autoconf-template-perl` will install your list of required modules\n\u003e when you run `make install`. The `requires.txt` file can be found in\n\u003e `@datadir@/@PACKAGE@/requires.txt` (typically\n\u003e `/usr/local/@PACKAGE@`). You can pass this file to the\n\u003e `install-from-cpan` script that is also installed for you. It will\n\u003e attempt to install of the required Perl modules using `cpanm`.\n\n\nAnother technique I have used in the past when creating Docker\ncontainers, is to create a base image that contains the required\ndependencies. In this manner, I separate the two resposibilities;\n__building the depdendencies__ and __building the application__.  Over\ntime I can refine the process of creating base images, learning from\nthe experience of building many CPAN modules. Here's an example of\ncreating a base image for some Perl modules that were required for an\napplication that required a specific version.\n\n```\nFROM amazonlinux:1\nRUN yum install -y epel-release\nRUN yum groupinstall -y --enablerepo epel 'Development Tools'\nRUN yum install -y --enablerepo epel v8 v8-devel 'perl(App::cpanminus)'\nRUN cpanm -v App::cpanminus\nRUN cpanm -v JavaScript::V8@0.09 \\\n    HTTP::Server::Simple \\\n    Class::Accessor::Fast \\\n    Readonly\n```\n\nBase image creation can be maintained and supported independently from\nthe application (perhaps even by different people). Ultimately\nhowever, from my application's perspective, this is still strategy\n#1.ii. I've kicked the can down the road, delegating the responsibility\nof dependency resolution to a different process.\n\nStrategy #2 _can_ work if you keep in mind a few things.\n\nFirst, you have to prevent `rpmbuild` from identifying Perl\ndependencies so that it does include the `Requires:` statements that\nwill cause `yum` to attempt resolution.\n\nSecond, you need to be aware that you are building what should be a\n_binary compatible RPM_ that will be deployed in your target\nenvironment. In other words, *your build environment must reflect your\ntarget environment*. You can't build your Perl modules on a system\nusing `perl` 5.36 and expect it work on a system that contains `perl`\n5.18. You _might_ have some luck building modules and RPMs on one\nplatorm and deploying on another _if you those modules do not require\nany binary library bindings_. Likewise you _might_ have some luck\nbuilding vanilla RPMs on Debian systems and deploying them to a RedHat\nflavored operating system. In general however, you are probably better\noff not attempting that trick.\n\nThe best strategy I have come up with these days is to create Docker\ncontainers that contain my Perl applications.  When building\ncontainers you can control all of the parameters and dependencies\nrequired for the build...and you can still couple a containerized\nbuild with the use of RPMs.\n\n[Back to Table of Contents](#table-of-contents) \n\n## Building CPAN Distributions\n\nIf your project implements Perl modules that you might want to\nupload to CPAN or you just want to create a packaged distribution for\nyourself you can do that using the tools in your generated project.\n\nIn order to build a CPAN distribution you should have\n[`make-cpan-dist`](https://github.com/rlauer6/make-cpan-dist)\ninstalled. This utility will create a CPAN distribution from a\nspecfication you supply as a YAML file.\n\nThe YAML file is _mostly_ built for you so all you need to do is run\n`make cpan` in the `cpan` directory of your project.\n\nSee the documentation for `make-cpan-dist` for information on how to\ncreate a `buildspec.yml` file.\n\n[Back to Table of Contents](#table-of-contents) \n\n# FAQs\n\n1. Do I need to be an Autotools expert to use this package?\n   * No, but it helps if you understand the basic concepts of\n     _autoconfiscation_, building open software using Autotools, and\n     using Linux utilities. If you find that you can't run this script\n     to create a project and create a distribution tarball that\n     [_works_](#checking-your-project-distribution), then please\n     report the issue - that's a bug.\n1. Why did you create this project when there are already a few very\n   good Perl packaging applications (`carton`, `Dist::Zilla`)?\n   * Those tools only solve a portion of the problems associated with\n     packaging an entire application. An application is usually\n     composed of more than just Perl modules. Artifacts for\n     applications must be inventoried, packaged and deployed in their\n     appropriate locations on the target environment. I was tutored\n     early on to respect the [Unix/Linux FSH File System Hierarchy](https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard)\n     as much as possible and there is no better tool (IMHO) than the\n     Autotools for helping to adhere to that advice.\n     \n     Over the years I have built project after project using my\n     template for creating Perl applications. The template was a good\n     accelerator starting a new project but I wanted something that\n     would get me going even faster.  The template still required a\n     lot of manual editing, cut 'n paste and revisitations to the\n     Automake documentation.  It was time to put my years of\n     experience using Autotools to the test and create a truly\n     automated way to create a new _autoconfiscated_ project that\n     worked immediately after the project was\n     created. `autoconf-template-perl` is the culmination of my\n     experience with Autotools and my experience writing Perl scripts\n     and modules.\n     \n     `autoconf-template-perl` is still a WIP, but should be usable to\n     get you started using Autotools without having to understand it completely.\n1. Why do I have to use a `.in` extension for my Perl scripts and\n   modules? (See [Building from `.in` Files](#building-from-in-files)).\n1. Why is `make distcheck` failing?\n   * [`make\n     distcheck`](https://www.gnu.org/software/automake/manual/html_node/Checking-the-Distribution.html)\n     should be run after you create a distribution to\n     ensure that the distribution actually works (See [Checking the\n     Project Distribution](#checking-your-project-distribution) for\n     more details).\n     \n     `distcheck` can fail for various reasons, the most common reason\n     being the tarball is missing an artifact required for building\n     the distribution. `autoconf-template-perl` __should__ account for\n     all of the artifacts it knows about when you created your project\n     or used the `--refresh` option. If you've added new artifacts\n     manually, you'll need to make sure they are included in the\n     distribution. See [Adding Artifacts to Your\n     Project](#adding-artifacts-to-your-project)\n   * It's also possible that `distcheck` will fail if built artifacts\n     are not cleaned up proplery during the `make clean` phase of the\n     check. In this case you may have failed to include some generated\n     files in the list of files to be removed (`CLEANFILES`). Again,\n     `autoconf-template-perl` __should__ account for all files that are\n     targets of a build rule.\n   * Lastly, there are situations where you may want to configure your\n     project in some way to avoid a situation that will cause `make\n     distcheck` to fail. You can add an `automake` variable to the\n     `Makefile.am` in the root of your project to pass configuration\n     options during `make distcheck`.  These will be passed to the\n     `configure` script.\n     ```\n     DISTCHECK_CONFIGURE_FLAGS = \n     ```\n1. What if I have other types of files I need to build (C/C++, e.g.)?\n   * `autconf-tempalte-perl` was built specifically for Perl\n     applications but could be expanded to include building other\n     types of applications (Python, C/C+). In fact, the original Perl\n     template for _autoconfiscation_ was based on an _autoconfiscated_\n     C application. Personally, I have not written a C program in over\n     20 years and don't intend on expanding this to building binaries\n     or libraries.  Python applications might be a target at some\n     point however (PRs welcome).\n1. I don't want  my RPM packages to install modules from CPAN, I have RPMs\n   for all my dependencies. How do I prevent the RPM from installing\n   dependencies from CPAN?\n   * When you create the project you can use the\n     `--no-rpm-install-from-cpan` option to disable installation of\n     dependencies in the `%post` section of the RPM spec file. If you\n     forgot to do that initially and later decide to disable that\n     feature, just refresh the project with that option.\n     ```\n     make distclean\n     autoconf-template-perl --no-rpm-install-from-cpan --refresh'\n     ./configure\n     make dist\n     rpmbuild -tb my-project-0.0.1.tar.gz\n     ```\n1. I created my project with `--no-html` (or `--no-bash`) and now I\n   want to add assets in those directories. How can I make sure the\n   build will recognize these?\n   * There are two ways to do this. The easy way is to use the\n     `--create-stub` option to create a new stub file in the\n     appropriate directory.\n     ```\n     autoconf-template-perl --create-stub index.html\n     ```\n     The extension of your stub filename will determine what directory\n     the file will be created in.  The file will be created in the\n     correct directory and the build system will be refreshed\n     automatically.  If you prefer to do this manually, create the new\n     directory,  move files into that directory\n     as needed and then run `autoconf-template-perl --refresh`.\n1. My source files are organized in sub-directories and I want to\n   deploy them that way. For example, I have HTML files in\n   sub-directories `foo/` and `bar/`.  So, the URLs for those might be\n   `http://www.example.com/foo/index.html`, and\n   `http://www.example.com/bar/index.html`. When the project was\n   created however, these files ended up in `src/main/html` and get\n   deployed to the root of my `DocumentRoot` directory.\n   * When creating the project source tree your manifest is used to\n     list each file. Make sure each file is listed in a sub-directory of a\n     common root directory.  Then use the `--strip-dir` option with\n     that root directory as the argument. See the discussion [here](#automatically-creating-a-manifest-file) for more information about `--strip-dir`.\n1. Where can get more documentation about Autotools?\n   * [Autotools](https://www.gnu.org/savannah-checkouts/gnu/automake/manual/html_node/Autotools-Introduction.html)\n   * [`automake`](https://www.gnu.org/software/automake/)\n   * [`make`](https://www.gnu.org/software/make/)\n   * [`autoconf`](https://www.gnu.org/software/autoconf/)\n   * [Autotools: A Practioner's Guide](https://www.amazon.com/Autotools-Practioners-Autoconf-Automake-Libtool/dp/1593272065)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frlauer6%2Fautoconf-template-perl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frlauer6%2Fautoconf-template-perl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frlauer6%2Fautoconf-template-perl/lists"}