<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <meta name="Author" content="David Faure" />
    <meta name="Generator" content="KWord/XEmacs" />

    <title>Makefile.am howto</title>
<style type="text/css">
 body {
  background-color: #FFFFFF;
  color: #000000;
 }
 code {color: #005500}
 h1 {text-align: center}
 div.c3 {font-size: 80%; text-align: center}
 hr.c2 {text-align: center}
</style>
  </head>

  <body>
      <h1>How to write a Makefile.am</h1>
<h2><a name="program">Makefile.am for a simple program</a></h2>
<code>
bin_PROGRAMS = kdialog<br/>
<br/>
kdialog_SOURCES = kdialog.cpp widgets.cpp ...<br/>
kdialog_LDADD = $(LIB_KIO)<br/>
kdialog_LDFLAGS = $(all_libraries) $(KDE_RPATH)<br/>
<br/>
AM_CPPFLAGS = $(all_includes)<br/>
<br/>
METASOURCES = AUTO
</code>

<p>bin means you want to create something that will install into the bin directory of KDE
<br/>
*_PROGRAMS means you want to compile a program. Use _SCRIPTS for scripts, etc.
<br/>
Then you can see the name of the program, which is what is used in the lines below to define what has to be done to create that program.
<br/>
*_SOURCES: There you list all the sources.
<br/>
*_LDADD: There you define which libraries the program links to. You can only use -lfoo, path/to/thelib.la (relative paths only), or the $(LIB_*) macros set by the kde build system.
<br/>
*_LDFLAGS: Finally you define the flags to be passed to the linker, in &lt;program&gt;_LDFLAGS. This can be -L flags (usually set by a configure check into a variable). $(all_libraries) contains all the -L flags necessary to find Qt and KDE, you must have it there. For programs you should use $(KDE_RPATH), it helps getting programs to find their libs without having to set LD_LIBRARY_PATH.
</p>

<p>
AM_CPPFLAGS: additional compilation flags. This must contain $(all_includes). This is also where other compile-time flags like -DWITHOUTBUGS and -I$(srcdir)/subdir go. IMPORTANT: insert -I directives before $(all_includes). This ensures that your own headers will be used, not some older installed version.
<br/>
You might find that many Makefile.am files in KDE still use INCLUDES though, that's the old name for it, but AM_CPPFLAGS is the recommended way nowadays.
</p>

<p>
There's also KDE_CXXFLAGS. Its role is to appended to the other flags, so it can undo one of the flags set by the build framework. This is the case for exceptions, which are disabled by default, so if you want to use exceptions you need to write KDE_CXXFLAGS = $(USE_EXCEPTIONS).
</p>

<p>
<code>METASOURCES = AUTO</code> is the magic line that makes the KDE build system take care of the moc files automatically. It is the recommended way if all your .cpp/.cc files include their .moc file (this is the best way since it gives faster compilation), or if you are compiling a single binary/library.
<br/>In case you have multiple binaries/libraries in the same directory, you might need to use the longer form of<br/>
<code>
libsomething_la_METASOURCES = myfile.moc myotherfile.moc<br/>
mybinary_METASOURCES = someotherfile.moc
</code>
</p>

<h2><a name="lib">Makefile.am for shared library</a></h2>
<p>
This is an example Makefile.am for a shared library.</p>
<code>
AM_CPPFLAGS = $(all_includes)<br/>
<br/>
lib_LTLIBRARIES = libkonq.la<br/>
libkonq_la_LIBADD = $(LIB_KPARTS)<br/>
libkonq_la_LDFLAGS = $(all_libraries) -version-info 6:0:2 -no-undefined<br/>
libkonq_la_SOURCES = popupmenu.cc knewmenu.cc ...<br/>
<br/>
METASOURCES = AUTO<br/>
</code>

<p>The lib_ prefix means that the library will be installed in lib/.<br/>
Then comes the name of the library, always followed by .la<br/>
Note how this becomes _la in the lines that refer to it.<br/>

<p>
*_LTLIBRARIES means &quot;LibTool libraries&quot;, i.e. it asks for libtool to handle them. You should always use this for libs.
<br/>
*_LIBADD is the list of libraries that this lib depends upon. Note that it's LDADD for programs and LIBADD for libs, since it's not exactly the same thing (a lib only remembers which libs it depends upon, it doesn't &quot;link them in&quot;).
<br/>
*_LDFLAGS contains the flags passed to the linker. $(all_libraries) for the -L flags as usual, but also the version number of the library (see info libtool / Versioning / Libtool versioning for details). -no-undefined is strongly recommended: it allows to check at link time that the library doesn't have undefined symbols. If any undefined symbol shows up, it means that either you forgot to implement a method, or a dependent library is missing in the LIBADD line.
<br/>
The rest is similar to the &quot;compiling a binary&quot; case.</p>

<h2><a name="plugin">Makefile.am for a plugin/module</a></h2>

<p>All dynamically opened piece of code (plugin, part, kdeinit module, applet, kioslave) can be called a &quot;DSO&quot; (Dynamic Shared Object) or more simply for our purposes a <i>module</i>.</p>
<p>All modules should be installed into the &quot;kde_module&quot; directory, which is usually &lt;kdeprefix&gt;/lib/kde3. Therefore the main difference with a shared library is that one should use
<br/>
<code>kde_module_LTLIBRARIES = something.la</code>

<p>For more details on the naming conventions and _LDFLAGS necessary for the various types of modules, please read kdelibs/NAMING (<a href="http://webcvs.kde.org/cgi-bin/cvsweb.cgi/~checkout~/kdelibs/NAMING">http://webcvs.kde.org/cgi-bin/cvsweb.cgi/~checkout~/kdelibs/NAMING</a> if you don't have the sources at hand)</p>

<h2><a name="install_data">Installing data</a></h2>
<p>To install header files:
<br/>
<code>include_HEADERS = foo.h bar.h</code>

<p>If the class uses a namespace, e.g. KParts, then the header file should be installed into kparts/foo.h
<br/>
To do that:
<br/>
<code>
kpartsincludedir = $(includedir)/kparts<br/>
kpartsinclude_HEADERS = foo.h bar.h
</code>

<p>The first line defines a new directory, the second line installs the files into it. The name before <i>dir</i> and <i>_HEADERS</i> must be the same, but other than that it doesn't matter much what it is.</p>

<p>To install data files into a standard directory, use &lt;dirname&gt;_DATA.
<br/>
For instance a Type=Service .desktop file should go into $(kde_servicesdir), therefore you should write
<br/>
<code>kde_services_DATA = foo.desktop</code>

<p>To install data files into a custom directory, you must first define it then use it:
<br/>
<code>
myappfoodir   = $(kde_datadir)/kmyapp<br/>
myappfoo_DATA = bar.desktop
</code>
<p>This installs bar.desktop into &lt;kdeprefix&gt;/share/apps/kmyapp.
</p>

<p>For a K menu entry use:<br/>
<code>somethingdir = $(kde_appsdir)/category[/subcategory]</code>
</p>

<h2><a name="icons">Icons</a></h2>

      <code>KDE_ICON = AUTO</code> installs the icons into the
      global KDE directories, whereas<br />
      <code>appicondir = $(kde_datadir)/myapp/icons<br />
      appicon_ICON = AUTO<br />
      </code> installs the icons into "myapp"'s specific directory
      (recommended when the icons are only needed by one
      application, to avoid cluttering the global dirs and codevent
      name clashes).</p>

      <p>For AUTO to work (and for the icon loading to work as
      well), you need to follow the naming convention:
      &lt;depth&gt;&lt;size&gt;-&lt;type&gt;-&lt;name&gt;.png<br />
       Where:<br />
      </p>

      <ul>
        <li>depth is hi or lo, for hicolor or locolor (the name of
        the icon theme in fact)</li>

        <li>size is 16, 22 or 32.</li>

        <li>type is 'app' for an application icon, 'mime' for a
        mimetype icon, 'action' for an menuitem/toolbar-button,
        'filesys' for some filesystem icons (dirs etc.), and
        'device' for the cdrom/floppy/harddisk/etc. icons.</li>
      </ul>
      You can find the same icon types in the icon chooser dialog. 

      <p>Note that this convention is for the sources only. Upon
      installation, the icon will be copied to the right directory,
      simply named &lt;name&gt;.png</p>

<h2><a name="docu">Documentation</a></h2>
      <code>KDE_LANG = en</code> (for the language of the
      documentation)<br />
       <code>KDE_DOCS = AUTO</code> if the directories are
      application names<br />
       <code>KDE_DOCS = myapp</code> to force a particular
      appname<br />
      </p>

<h2><a name="i18n">Translations</a></h2>
      To make your application translatable, you must use
      i18n() in the code, around the English strings that appear to
      the user. You must also define a <code>messages</code> target
      in your toplevel Makefile.am. A script runs every night, and
      calls all messages targets as they are, to create the .pot
      files that end up in the kde-i18n module. Then translators
      can create .po files that contain the translations of those
      messages.</p>

      <p>For applications not in CVS, run <code>make -f admin/Makefile.common package-messages</code>
      to generate the .pot file, and <code>cd po ; make merge</code>
      for the message merge (new .pot file with old .po file).
      IMPORTANT: you need to use a patched <code>gettext</code>, available
      from <a href="ftp://ftp.kde.org/pub/kde/devel/gettext-kde/">ftp.kde.org</a>,
      for proper support of contextual translations and plural handling.</p>

      <p>Let's now go back to the messages target. It should simply
      call <code>xgettext</code> on the sources that contain i18n - which is not
      equal to _SOURCES, as _SOURCES contains .ui and .skel files
      that do not work with xgettext. This why you usually use
      something like *.cpp *.h instead (make sure to include
      sub-directories, if any). So in the simple case a messages
      target will look like:</p>
      <code>messages: $(XGETTEXT) *.cpp *.h -o
      $(podir)/mypotfile.pot</code> 

      <p>mypotfile is the name of your main KInstance (for an
      application it's the first argument passed to KAboutData, and
      for components (parts and plugins), it's the name of the
      KInstance that you create).</p>

      <p>If you have .ui (Qt designer) or .rc (XML-UI) files, use
      <code>messages: rc.cpp</code> and the script will create
      rc.cpp from the ui and rc files _in the current directory_.
      If you have .ui or .rc files in subdirectories, you need to
      add something like <code>$(EXTRACTRC) */*.rc &gt;&gt;
      rc.cpp</code> to the messages target, before the <code>xgettext</code>
      call.</p>

      <p>Another special case is the "tips" file - an XML file
      containing tips shown to the user. In this case, use
      something like <code>messages: perl ./preparetips &gt;
      tips.cc $(XGETTEXT) *.cpp *.h tips.cc -o
      $(podir)/mypotfile.pot rm -f tips.cc</code> You can find the
      preparetips script under kdebase/ktip, for instance. (The
      name of the temporary tips.cc file doesn't matter,
      obviously).</p>

      <p>The last matter is the compilation and installation of .po
      files. Inside kde-i18n, Makefile.am files contain
      <code>KDE_LANG=language</code> and <code>POFILES=AUTO</code>,
      to mean that all the .po files in the directory are installed
      into that language.</p>

      <p>If you ship a separate application and you want it to
      install its own .po files, you'll usually have a po/
      subdirectory, and inside the Makefile.am will simply say
      <code>POFILES=AUTO</code>. In that case, the .po files are
      copied depending on their name as $(PACKAGE).mo (for instance
      de.po is installed under de/LC_MESSAGES/$(PACKAGE).mo and
      fr.po into fr/LC_MESSAGES/$(PACKAGE).mo).</p>

<h2><a name="qtonly">Qt-only program</a></h2>
      By default am_edit generates the "meta-unload" stuff
      [TODO an item for that], which requires kdecore. To disable
      this when building a Qt-only program, use<br />
       <code>KDE_OPTIONS = qtonly</code></p>

<h2><a name="nofinal">Disabling "final" compilation</a></h2>
      To prevent <a href="developer-faq.html#q56.3">--enable-final</a> from working in a specific directory,
      for instance to work on that directory when --enable-final was used for
      the whole module, you can either use
      <code>make no-final ; make no-final-install</code>
      or edit the Makefile.am and add
      <code>KDE_OPTIONS = nofinal</code></p>

    <p>Please send additional questions, responses or comments to
    <a href="mailto:faure@kde.org">faure@kde.org</a></p>
    <hr width="75%" noshade="noshade" class="c2" />

    <div class="c3">
      Last update: $Id: makefile_am_howto.html,v 1.4 2003/05/11 23:52:09 faure Exp $
    </div>
  </body>
</html>

