diff options
-rw-r--r-- | comfignat.gpr.gp | 5 | ||||
-rw-r--r-- | comfignat.mk | 5 | ||||
-rw-r--r-- | manual.css | 50 | ||||
-rwxr-xr-x | manual.en.html | 479 |
4 files changed, 539 insertions, 0 deletions
diff --git a/comfignat.gpr.gp b/comfignat.gpr.gp index 7b632ae..e334f00 100644 --- a/comfignat.gpr.gp +++ b/comfignat.gpr.gp @@ -11,6 +11,11 @@ -- modified is included with the above copyright notice. +-- This file is part of Comfignat – common, convenient, command-line-controlled +-- compile-time configuration of software built with the GNAT tools. For more +-- information about Comfignat, see http://www.Rombobeorn.se/Comfignat/. + + -- This project file defines directory variables for use in build-controlling -- project files. It is not to be installed on the target system. -- diff --git a/comfignat.mk b/comfignat.mk index 8c0c603..b5f0bf5 100644 --- a/comfignat.mk +++ b/comfignat.mk @@ -11,6 +11,11 @@ # modified is included with the above copyright notice. +# This file is part of Comfignat – common, convenient, command-line-controlled +# compile-time configuration of software built with the GNAT tools. For more +# information about Comfignat, see http://www.Rombobeorn.se/Comfignat/. + + # This file contains generic Make code. It is designed to be included by other # makefiles, called containing makefiles, which add information specific to the # project at hand. Builds are controlled by GNAT project files which import the diff --git a/manual.css b/manual.css new file mode 100644 index 0000000..570c4ef --- /dev/null +++ b/manual.css @@ -0,0 +1,50 @@ +html { + background-color : white; + color : black; + font-family : sans-serif; +} + +p, ul, ol, dl, .example { + margin-top : 0.5em; + margin-bottom : 0.5em; +} + +pre, code { + font-family : monospace; +} + +pre { + white-space : pre-wrap; +} + +pre.make { + white-space : pre; +} + +.example { + display : table; + margin-left : 2em; + margin-right : 2em; + background-color : #EEEEEE; + padding : 0.2em; +} + +.file { + border-color : #DDDDDD; + border-width : thin; + border-style : solid; + padding : 0; +} + +.file > * { + margin : 0; + padding : 0.2em; +} + +.file > *:first-child { + background-color : #DDDDDD; + font-size : inherit; + font-variant : inherit; + font-style : inherit; + font-weight : bolder; +} diff --git a/manual.en.html b/manual.en.html new file mode 100755 index 0000000..414746e --- /dev/null +++ b/manual.en.html @@ -0,0 +1,479 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" +"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <!--#include virtual="/SSIfragment/indahed.shtml" --> + <link href="manual.css" rel="stylesheet" type="text/css" /> + <title>Comfignat</title> + <meta name="Author" xml:lang="sv" content="Björn Persson" /> +</head> + +<body> +<!--#include virtual="/SSIfragment/huvud.shtml" --> + +<h1>Comfignat</h1> + +<p>Comfignat is common, convenient, command-line-controlled compile-time +configuration of software built with the +<a href="http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/">GNAT tools</a> on +Unix-like operating systems. It consists of a makefile foundation to be +included by your makefile, and an abstract GNAT project file to be imported by +your project files. +Leveraging <a href="https://www.gnu.org/software/make/">GNU Make</a> and +<a href="http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Preprocessing-with-gnatprep.html">Gnatprep</a>, +Comfignat adds the flexibility that GNAT project files lack, so that programs +and libraries whose build systems are built around Comfignat can easily be +configured for all sorts of use cases. Comfignat also helps with configuration +and installation of files that GNAT project files don't handle, so that the +build system can install the whole software package, not just the compiled +files. At the same time Comfignat greatly reduces the amount of Make code that +needs to be written for every new project.</p> + +<h2>Features</h2> + +<ul> +<li><p>Users and distributions can build and install the software with the +traditional commands "<samp>make</samp>" and +"<samp>make install</samp>".</p></li> + +<li><p>All aspects of the build are fully configurable through directory +variables, program-name variables and options variables. These configuration +variables are compatible with the +<a href="https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html">GNU +Coding Standards</a>.</p></li> + +<li><p><var><a href="https://www.gnu.org/prep/standards/html_node/DESTDIR.html">DESTDIR</a></var> +is supported, so installation can be done to a staging directory or directly +to the target system.</p></li> + +<li><p>Configuration variables can be saved in a file and will then be used in +every subsequent Make invocation. This is convenient in particular for +developers who can configure debugging options or nonstandard paths in their +development environments.</p></li> + +<li><p>The build can be controlled entirely from a command prompt, which means +that it can be scripted. There is no need to edit or patch configuration files. +This is important in particular for distributions with automated build +systems.</p></li> + +<li><p>Users who build and install from source do not need to run a +configuration script. They can do any configuration they need directly in the +Make command.</p></li> + +<li><p>Directories projects are supported. A directories project is a +GNAT project file that defines directory variables for use by other project +files. If a directories project is provided, then Comfignat will configure the +project files to use the directory variables it defines.</p></li> + +<li><p>Out-of-tree building is supported. There can be several separate build +directories with different configurations.</p></li> + +<li><p>Multiarch operating systems are supported. Library instances built for +different architectures can coexist in a computer system if the system provides +a directories project that refers to different directories depending on the +target architecture.</p></li> + +<li><p>Relocatable binary packages can be built. Comfignat can be instructed to +convert the directory variables into relative pathnames and configure the +project files with those, so that the installed directory tree as a whole can +be moved to another location in the filesystem without breaking the project +files.</p></li> + +<li><p><a href="http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/The-GNAT-Make-Program-gnatmake.html">Gnatmake</a> +and <a href="http://docs.adacore.com/gprbuild-docs/html/gprbuild_ug.html">GPRbuild</a> +are both supported, which makes Comfignat suitable for both mixed-language +projects and pure Ada projects.</p></li> + +<li><p>The Make code that is needed to do all of this is generic, so that only +a minimal amount of Make code needs to be written for each project. An +uncomplicated project may need only two or three lines of Make code to build +and install the software itself. Test suites, documentation et cetera add to +this.</p></li> + +<li><p>Make is not a hard requirement. Comfignat uses some advanced features of +GNU Make that may not be supported by other clones and forks of Make. If a +system's native Make doesn't have those features and GNU Make isn't available, +then it's possible to bypass Make and run first Gnatprep and then Gnatmake or +GPRbuild manually. It's less convenient to build that way though, and some of +the features listed here are lost.</p></li> +</ul> + +<h2>Download</h2> + +<p>The code is available for download +<a href="https://www.xn--rombobjrn-67a.se/Comfignat/download">as a tarball</a>, +and is also browsable +<a href="https://gitorious.org/comfignat/comfignat/trees/master">on Gitorious</a>.</p> + +<h3>License</h3> + +<p>The following applies to all of Comfignat including this document:</p> + +<p>Copyright 2013 Björn Persson, Bjorn@Rombobjörn.se</p> + +<p>This material is provided as is, with absolutely no warranty expressed +or implied. Any use is at your own risk.</p> + +<p>Permission is hereby granted to use or copy these files +for any purpose, provided the above notices are retained on all copies. +Permission to modify the code and to distribute modified code is granted, +provided the above notices are retained, and a notice that the code was +modified is included with the above copyright notice.</p> + +<h2>Getting Started</h2> + +<p>This is the least that you have to do to use Comfignat:</p> + +<ul> +<li><p>Copy the files +<a href="comfignat.gpr.gp"><var>comfignat.gpr.gp</var></a>, +<a href="comfignat.mk"><var>comfignat.mk</var></a> and +<a href="INSTALL"><var>INSTALL</var></a> to your source tree.</p></li> + +<li><p>Write a GNAT project file to control the build. Import +"<samp>comfignat.gpr</samp>" (without "<samp>.gp</samp>") and use the variables +that the project <var>Comfignat</var> defines.</p> + <ul> + <li><p>Use <var>Comfignat.Objdir</var> for <var>Object_Dir</var>.</p></li> + + <li><p>If your project file builds a program, then use + <var>Comfignat.Stage_Bindir</var> for <var>Exec_Dir</var>, unless the program + is only intended to be executed by other programs and not run manually from a + command prompt, in which case it should be placed under + <var>Comfignat.Stage_Libexecdir</var>.</p></li> + + <li><p>If your project file builds a library, then use a subdirectory of + <var>Comfignat.Stage_Includedir</var> for <var>Library_Src_Dir</var>, + <var>Comfignat.Stage_Libdir</var> for <var>Library_Dir</var>, and a + subdirectory of <var>Comfignat.Stage_Libdir</var> for + <var>Library_ALI_Dir</var>.</p></li> + </ul> +</li> + +<li><p>If your project is a library, then write a project file for other +projects to import to use the library. Give it a filename that ends with +"<samp>.gpr.gp</samp>". It will be run through Gnatprep to generate the actual +project file without the "<samp>.gp</samp>" suffix. Make it import the project +file that the preprocessor symbol <var>Directories_GPR</var> specifies, but +only if <var>Directories_GPR</var> is defined. Do not import +<var>comfignat.gpr</var>. Use the symbol <var>Includedir</var> in the value of +<var>Source_Dirs</var>, and use <var>Libdir</var> for <var>Library_Dir</var> +and as part of <var>Library_ALI_Dir</var>.</p></li> + +<li><p>Write a makefile that includes <var>comfignat.mk</var>. The makefile +shall set the variable <var>build_GPRs</var> to the filename of the +build-controlling project file. For a library it shall also set the variable +<var>usage_GPRs</var> to the filename that the usage project file will have +after preprocessing. That's all that is required of the makefile. Everything +else is optional.</p></li> +</ul> + +<h3>Example</h3> + +<p>Here's a complete set of project files and makefile containing everything +that is necessary for building an uncomplicated shared library and installing +it where the user wants it:</p> + +<div class="example file"><h5><code>build_example.gpr</code></h5> +<pre class="gpr">with "comfignat.gpr"; + +library project Build_Example is + for Library_Name use "example"; + for Library_Kind use "dynamic"; + for Library_Version use "libexample.so.1"; + for Library_Interface use ("Example"); + for Object_Dir use Comfignat.Objdir; + for Library_Src_Dir use Comfignat.Stage_Includedir & "/example"; + for Library_Dir use Comfignat.Stage_Libdir; + for Library_ALI_Dir use Comfignat.Stage_Libdir & "/example"; +end Build_Example;</pre></div> + +<div class="example file"><h5><code>example.gpr.gp</code></h5> +<pre class="gpr">#if Directories_GPR'Defined then +with $Directories_GPR; +#end if; + +library project Example is + for Library_Name use "example"; + for Library_Kind use "dynamic"; + for Source_Dirs use ($Includedir & "/example"); + for Library_Dir use $Libdir; + for Library_ALI_Dir use $Libdir & "/example"; + for Externally_Built use "true"; +end Example;</pre></div> + +<div class="example file"><h5><code>Makefile</code></h5> +<pre class="make">include comfignat.mk + +build_GPRs = build_example.gpr +usage_GPRs = example.gpr</pre></div> + +<h2>How to Use Comfignat</h2> + +<h3>Where to Place Files</h3> + +<p>During the build, the files that will be installed are collected in a +directory structure under a staging directory whose name is held in the +variable <var>stagedir</var>. In the installation step that whole directory +structure is copied to the directory specified in <var>DESTDIR</var>, or to the +root directory if <var>DESTDIR</var> is empty. Compiled programs, libraries, +ALI files and needed library sources are written to the staging directory by +the GNAT tools if the build-controlling project files are written correctly. +Comfignat automatically stages usage project files. To get other files +installed, the makefile needs to either copy them to the appropriate directory +under the staging directory, or instruct the tools that generate those files to +write them there.</p> + +<p>Comfignat defines several directory variables to allow distributions and +installing users to control where in the filesystem different kinds of files +get installed and where applications write their files at run time. Variables +whose names begin with "<var>stage_</var>" point to the directories under the +staging directory where the files shall be written during the build. Variables +without the "<var>stage_</var>" prefix tell where the files will be in the +target system after installation, and are suitable for embedding in programs +where the directory names are needed at run time, and in usage project +files.</p> + +<p>Directory variables are available as Make variables to makefiles that +include <var>comfignat.mk</var>, as GNAT project variables to build project +files that import <var>comfignat.gpr</var>, and as preprocessor symbols to +usage project files that are preprocessed with Gnatprep. If the Make variable +<var>relocatable_package</var> is set to "<samp>true</samp>" on the command +line, then the variables for embedding will be relative to <var>bindir</var> in +build project files, and relative to <var>gprdir</var> in usage project +files.</p> + +<ul> +<li><p>Programs that can be run from a command prompt shall be placed in +<var>stage_bindir</var>. Build project files shall use +<var>Comfignat.Stage_Bindir</var>.</p></li> + +<li><p>Programs that are only to be run by other programs, not by users, shall +be placed under <var>stage_libexecdir</var>, +<var>Comfignat.Stage_Libexecdir</var> in build project files. If there are +several such programs they should probably be under a separate subdirectory. +Programs that need to invoke such programs shall have +<var>Comfignat.Libexecdir</var> compiled in.</p></li> + +<li><p>Idiosyncratic read-only architecture-independent data files shall be +placed under a separate subdirectory of <var>stage_datadir</var>. Programs +shall look for them under <var>Comfignat.Datadir</var>.</p></li> + +<li><p>Configuration files – host-specific data files that aren't modified in +the normal course of their use but may be modified by system administrators – +shall be placed under <var>stage_sysconfdir</var>. If there are several they +should probably be under a separate subdirectory. Programs shall look for them +under <var>Comfignat.Sysconfdir</var>.</p></li> + +<li><p>Idiosyncratic variable data files shall be placed under a separate +subdirectory of <var>stage_statedir</var>. Programs shall read and write them +under <var>Comfignat.Statedir</var>.</p></li> + +<li><p>If your program keeps cached data files that it can regenerate if they +are deleted, then those files shall be kept under a separate subdirectory of +<var>Comfignat.Cachedir</var>. You won't install cached files but you may want +to create the subdirectory under <var>stage_cachedir</var>.</p></li> + +<li><p>Log files shall be written under <var>Comfignat.Logdir</var>. You won't +install log files but you may want to create a separate subdirectory under +<var>stage_logdir</var> if your program writes its own log files.</p></li> + +<li><p>Ada specifications, C headers and other source files that are needed for +compilation of other software that uses your libraries shall be placed under +<var>Comfignat.Stage_Includedir</var> by build project files, usually under a +separate subdirectory. Usage project files shall get the directory from the +preprocessor symbol <var>Includedir</var>.</p></li> + +<li><p>Binary libraries shall be placed in <var>Comfignat.Stage_Libdir</var> +by build project files. Usage project files shall get the directory from the +preprocessor symbol <var>Libdir</var>.</p></li> + +<li><p>ALI files and other architecture-specific files shall usually be placed +under a separate subdirectory of <var>Comfignat.Stage_Libdir</var>.</p></li> + +<li><p>Comfignat puts usage project files in <var>stage_gprdir</var>.</p></li> + +<li><p>Locale-specific message catalogs shall be placed in the appropriate +subdirectories under <var>stage_localedir</var>. Programs shall look for them +under <var>Comfignat.Localedir</var>.</p></li> + +<li><p>Documentation in the Man format shall be placed in the appropriate +subdirectories under <var>stage_mandir</var>.</p></li> + +<li><p>Documentation in the Info format shall be placed in +<var>stage_infodir</var>.</p></li> + +<li><p>Other documentation files shall be placed under a separate subdirectory of +<var>stage_miscdocdir</var>.</p></li> +</ul> + +<h3>Directories Projects</h3> + +<p>A directories project is a GNAT project file that defines directory +variables for use by other project files. It may be defined by an operating +system and contain the standard directories on that system, or it may be +written by a system administrator to encode local policy. Comfignat configures +project files to use a directories project if the Make variable +<var>dirgpr</var> is set on the command line.</p> + +<p>A Comfignat-compatible directories project shall define the following +variables:</p> + +<dl> +<dt><var>Hardware_Platform</var></dt> +<dd>A short string, suitable for use in filenames, that identifies the current +target architecture.</dd> + +<dt><var>Bindir</var></dt> +<dd>The directory for programs that can be run from a command prompt.</dd> + +<dt><var>Libexecdir</var></dt> +<dd>The top-level directory for programs that are intended to be run by other +programs rather than by users.</dd> + +<dt><var>Includedir</var></dt> +<dd>The top-level directory for source files to be used in the compilation of +software using libraries.</dd> + +<dt><var>Libdir</var></dt> +<dd>The directory for binary libraries to be used by other software, and the +top-level directory for other architecture-specific files.</dd> +</dl> + +<p>Here's an example of what a directories project may look like:</p> + +<pre class="example gpr">abstract project System_Directories is + + type Platform_Type is ("i386", "x86_64", "ppc", "ppc64", "ia64"); + Hardware_Platform : Platform_Type := external ("HARDWARE_PLATFORM"); + + case Hardware_Platform is + when "i386" | "ppc" | "ia64" => + Lib := "lib"; + when "x86_64" | "ppc64" => + Lib := "lib64"; + end case; + Libdir := "/usr/" & Lib; + + Bindir := "/usr/bin"; + Libexecdir := "/usr/libexec"; + Includedir := "/usr/include"; + +end System_Directories;</pre> + +<p>This directories project belongs in a multiarch operating system where +libraries are kept in either <var>/usr/lib</var> or <var>/usr/lib64</var> +depending on which architecture they are compiled for. The directories project +sets <var>Libdir</var> to the right directory for the target architecture based +on an environment variable. A library project that uses this directories +project will therefore automatically adapt to the current target architecture, +so that 32-bit and 64-bit instances of the library can be installed in parallel +and the right library will be used in every build.</p> + +<h3>Options</h3> + +<p>Your software may have optional features or properties that can be enabled +or disabled at build time. Comfignat can help you define options for those. +Each option is represented as a Make variable whose value can be +"<samp>true</samp>" or "<samp>false</samp>", which installing users and +distributions are expected to override on the command line. The names of these +variables should be listed in the variable <var>options</var>. Each option +should also be assigned a default value, unless it shall be mandatory to always +set it on the command line. Comfignat will check that the variables listed in +<var>options</var> have valid Boolean values.</p> + +<p>Here's a makefile fragment that defines two options:</p> + +<pre class="example make">options = enable_frobnicator atomic_doodads +enable_frobnicator = false +atomic_doodads = true</pre> + +<p>Options listed in <var>options</var> will be conveyed as preprocessor +symbols to preprocessed files and as external variables to build project +files.</p> + +<h3>Build Tools and their Arguments</h3> + +<p>There are several options variables that let installing users and +distributions control which arguments the build tools are invoked with. They +have names that end with "<var>FLAGS</var>", and are documented in +<var>INSTALL</var>. The value of <var>GNATFLAGS</var> is a combination of the +other options variables and must not be modified in a way that disregards the +other variables. Apart from that restriction you can assign default values to +optional arguments in these variables, but be sure to do the assignments with +"<samp>?=</samp>" so that environment variables can override your defaults.</p> + +<p>The value of <var>Gnatprep_arguments</var> will be passed to Gnatprep when a +file is preprocessed, and <var>builder_arguments</var> will be passed to +GPRbuild or Gnatmake when a project is built. These variables are not meant to +be overridden by users. They may be used for preprocessor symbols, external +variables for project files or other arguments that are essential for the build +to work. Global default values for optional arguments should be set in the +options variables instead.</p> + +<p>The program-name variables <var>GNATPREP</var> and <var>GNAT_BUILDER</var> +allow installing users and distributions to control the commands that invoke +the build tools, for example to use a specific version or a wrapper. You can +set <var>GNAT_BUILDER</var> to "<samp>gnatmake</samp>" if you want to build +with Gnatmake instead of GPRbuild by default, but again be sure to do the +assignment with "<samp>?=</samp>" so that environment variables can override +your default.</p> + +<h3>Persistent Configuration</h3> + +<p>Those Make variables that installing users are expected to change can be +configured persistently. Run "<samp>make configure</samp>" with some variables +set on the command line. Those variables will then be saved in a file named +<var>comfignat_configuration.mk</var>, which will be loaded in all subsequent +Make invocations. Additional variables can be configured incrementally. The +configuration can be erased with "<samp>make unconfigure</samp>" or as a part +of "<samp>make distclean</samp>".</p> + +<p>The variables that can be configured are listed in the variable +<var>configuration_variables</var>. The variables listed in <var>options</var> +are included. You can make additional variables configurable by appending their +names to <var>configuration_variables</var>.</p> + +<h3>Separate Build Directories</h3> + +<p>Instead of building in the source tree you can use a separate build +directory. All generated files will then be written under the build directory +and the source tree will not be modified. You can have several build +directories with different configuration files in them. To set up a new build +directory, run "<samp>make configure builddir=/some/pathname</samp>". The +variable <var>builddir</var> will not be saved in the configuration; instead a +configuration file will be written in the specified directory. A makefile will +also be written in the build directory unless there is one already. This +generated makefile will delegate all commands to the main makefile in the +source directory so that Make can conveniently be invoked from the build +directory.</p> + +<p>If you use separate build directories, then you should do all your builds in +separate build directories and not build anything in the source directory. If +there are generated files with the same name both in the source directory and +in the build directory, then the wrong file may be used in some cases.</p> + +<p>If a build project file is preprocessed with Gnatprep, then the preprocessed +file will be in the build directory, so it can't refer to source directories +with pathnames relative to the project file or rely on the source files being +in the same directory as the project file. The preprocessor symbol +<var>Srcdir</var> must be used in the value of <var>Source_Dirs</var>. Its +value is the directory where <var>comfignat.mk</var> is, which is supposed to +be the root of the source tree. Here's an example:</p> + +<pre class="example gpr">for Source_Dirs use ($Srcdir & "/tools");</pre> + +<h3>Adjusting the Installation Instructions</h3> + +<p>After writing your makefile and project files, you should adapt the +installation instructions in <var>INSTALL</var> to your project. The file will +be useful to users as-is, but it will be more helpful if you edit it. Put the +title of your project in the heading, add information about optional features +and testing, and delete parts that don't apply to your project.</p> + +<!--#include virtual="/SSIfragment/giltig.shtml" --> + +</body> +</html> |