Rombobjörn

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Persson <bjorn@rombobjörn.se>2013-08-01 21:21:49 +0200
committerBjörn Persson <bjorn@rombobjörn.se>2013-08-01 21:21:49 +0200
commit06ddf1ce6c32e9bff1bb9b6b6edf14acd2cb0956 (patch)
treed4660778494fa44f33f17a386332947b8cab8d44
parent3a4102c2c7bfada49145ee6a5634645af8a31592 (diff)
Added the manual.
-rw-r--r--comfignat.gpr.gp5
-rw-r--r--comfignat.mk5
-rw-r--r--manual.css50
-rwxr-xr-xmanual.en.html479
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 &amp; "/example";
+ for Library_Dir use Comfignat.Stage_Libdir;
+ for Library_ALI_Dir use Comfignat.Stage_Libdir &amp; "/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 &amp; "/example");
+ for Library_Dir use $Libdir;
+ for Library_ALI_Dir use $Libdir &amp; "/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/" &amp; 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 &amp; "/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>