Difference between revisions of "Development/Tutorials/KDE3/Makefile.am"

Jump to: navigation, search
m (Text replace - "<code ini>" to "<syntaxhighlight lang="ini">")
m (Text replace - "</code>" to "</syntaxhighlight>")
 
(2 intermediate revisions by one user not shown)
Line 9: Line 9:
  
 
== Makefile.am for a simple program ==
 
== Makefile.am for a simple program ==
<code bash># Notice the bin_ prefix.
+
<syntaxhighlight lang="bash"># Notice the bin_ prefix.
 
bin_PROGRAMS = kdialog
 
bin_PROGRAMS = kdialog
  
Line 19: Line 19:
  
 
METASOURCES = AUTO
 
METASOURCES = AUTO
</code>
+
</syntaxhighlight>
  
 
=== bin ===
 
=== bin ===
Line 45: Line 45:
  
 
=== KDE_CXXFLAGS ===
 
=== KDE_CXXFLAGS ===
There is also KDE_CXXFLAGS.  It is always appended to the end of the other flags used in the build, so it can undo one of the flags set by the KDE build framework.  This is the case for exception handling support, which is disabled by default.  If you want to use exception handling you need to write <code bash>KDE_CXXFLAGS = $(USE_EXCEPTIONS)</code>
+
There is also KDE_CXXFLAGS.  It is always appended to the end of the other flags used in the build, so it can undo one of the flags set by the KDE build framework.  This is the case for exception handling support, which is disabled by default.  If you want to use exception handling you need to write <syntaxhighlight lang="bash">KDE_CXXFLAGS = $(USE_EXCEPTIONS)</syntaxhighlight>
  
 
=== METASOURCES ===
 
=== METASOURCES ===
 
METASOURCES = AUTO 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.
 
METASOURCES = AUTO 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.
  
In case you have multiple binaries/libraries in the same directory, you might need to use the longer form of <code bash>libfoo_la_METASOURCES = myfile.moc myotherfile.moc
+
In case you have multiple binaries/libraries in the same directory, you might need to use the longer form of <syntaxhighlight lang="bash">libfoo_la_METASOURCES = myfile.moc myotherfile.moc
mybinary_METASOURCES = someotherfile.moc</code>
+
mybinary_METASOURCES = someotherfile.moc</syntaxhighlight>
  
 
== Makefile.am for shared libraries ==
 
== Makefile.am for shared libraries ==
Line 57: Line 57:
 
Here is an example Makefile.am for a simple library.
 
Here is an example Makefile.am for a simple library.
  
<code bash>AM_CPPFLAGS = $(all_includes)
+
<syntaxhighlight lang="bash">AM_CPPFLAGS = $(all_includes)
  
 
lib_LTLIBRARIES = libkonq.la
 
lib_LTLIBRARIES = libkonq.la
Line 65: Line 65:
 
libkonq_la_SOURCES = popupmenu.cc knewmenu.cpp ...
 
libkonq_la_SOURCES = popupmenu.cc knewmenu.cpp ...
  
METASOURCES = AUTO</code>
+
METASOURCES = AUTO</syntaxhighlight>
  
 
=== lib ===
 
=== lib ===
Line 89: Line 89:
 
All dynamically opened pieces of code (including plugins, KParts, kdeinit modules, Kicker applets and KIOSlaves) can be called a "DSO" (Dynamic Shared Object) or more simply for our purposes, a module.
 
All dynamically opened pieces of code (including plugins, KParts, kdeinit modules, Kicker applets and KIOSlaves) can be called a "DSO" (Dynamic Shared Object) or more simply for our purposes, a module.
  
All modules should be installed into the "kde_module" directory, which is usually {{path|$KDEPREFIX/lib/kde3}}.  Therefore the main difference with a shared library is that one should use <code bash>kde_module_LTLIBRARIES = something.la</code> (Note that the library name doesn't have to start with lib).  For more details on the naming conventions and _LDFLAGS necessary for the various types of modules, please read [http://websvn.kde.org/*checkout*/branches/KDE/3.5/kdelibs/NAMING kdelibs/NAMING].
+
All modules should be installed into the "kde_module" directory, which is usually {{path|$KDEPREFIX/lib/kde3}}.  Therefore the main difference with a shared library is that one should use <syntaxhighlight lang="bash">kde_module_LTLIBRARIES = something.la</syntaxhighlight> (Note that the library name doesn't have to start with lib).  For more details on the naming conventions and _LDFLAGS necessary for the various types of modules, please read [http://websvn.kde.org/*checkout*/branches/KDE/3.5/kdelibs/NAMING kdelibs/NAMING].
  
 
== Sharing code with convenience libraries ==
 
== Sharing code with convenience libraries ==
Line 99: Line 99:
 
To define a convenience library:
 
To define a convenience library:
  
<code># Just as bin_ means install to /bin and lib_ means
+
<syntaxhighlight lang="text"># Just as bin_ means install to /bin and lib_ means
 
# install to lib/, noinst_ means not to install at all.
 
# install to lib/, noinst_ means not to install at all.
 
noinst_LTLIBRARIES = libcommon.la
 
noinst_LTLIBRARIES = libcommon.la
Line 110: Line 110:
 
# Then you can use the convenience lib:
 
# Then you can use the convenience lib:
 
mylib_la_LIBADD = libcommon.la
 
mylib_la_LIBADD = libcommon.la
myprogram_LDADD = libcommon.la</code>
+
myprogram_LDADD = libcommon.la</syntaxhighlight>
  
This is also the way that you can compile source files in subdirectories.  Automake does ''not'' allow <code bash>foo_SOURCES = subdir/bar.cc</code>
+
This is also the way that you can compile source files in subdirectories.  Automake does ''not'' allow <syntaxhighlight lang="bash">foo_SOURCES = subdir/bar.cc</syntaxhighlight>
  
 
You have to define a convenience library inside of {{path|subdir}}, and use that from the toplevel directory.
 
You have to define a convenience library inside of {{path|subdir}}, and use that from the toplevel directory.
Line 120: Line 120:
 
This is an example Makefile.am for an automated test program.
 
This is an example Makefile.am for an automated test program.
  
<code bash>METASOURCES = AUTO
+
<syntaxhighlight lang="bash">METASOURCES = AUTO
  
 
check_PROGRAMS = mytestprog.cpp
 
check_PROGRAMS = mytestprog.cpp
Line 129: Line 129:
 
mytestprog_LDADD = ../libcommon.la
 
mytestprog_LDADD = ../libcommon.la
  
AM_CPPFLAGES = -I$(srcdir)/.. $(all_includes)</code>
+
AM_CPPFLAGES = -I$(srcdir)/.. $(all_includes)</syntaxhighlight>
  
 
A common way of adding automated tests to your application is to create a subdirectory called {{path|tests}}. Add tests to the SUBDIRS line in parent Makefile.am and create a Makefile.am in the new {{path|tests}} directory. Use [http://websvn.kde.org/*checkout*/branches/KDE/3.5/kdesdk/scripts/create_makefile create_makefile] (from kdesdk/scripts) to create the new Makefile, and now when you type <tt>make check</tt> the test program will be compiled (due to check_PROGRAMS) and run (due to TESTS). If the test program returns a non-zero value, make prints out an error message and stops. If the test program shouldn't run automatically (e.g. because it's interactive), omit the TESTS line.
 
A common way of adding automated tests to your application is to create a subdirectory called {{path|tests}}. Add tests to the SUBDIRS line in parent Makefile.am and create a Makefile.am in the new {{path|tests}} directory. Use [http://websvn.kde.org/*checkout*/branches/KDE/3.5/kdesdk/scripts/create_makefile create_makefile] (from kdesdk/scripts) to create the new Makefile, and now when you type <tt>make check</tt> the test program will be compiled (due to check_PROGRAMS) and run (due to TESTS). If the test program returns a non-zero value, make prints out an error message and stops. If the test program shouldn't run automatically (e.g. because it's interactive), omit the TESTS line.
Line 137: Line 137:
 
In case your test program needs command-line arguments, use a check-local target to launch it instead of TESTS:
 
In case your test program needs command-line arguments, use a check-local target to launch it instead of TESTS:
  
<code>check-local: mytestprog
+
<syntaxhighlight lang="text">check-local: mytestprog
         ./mytestprog $(srcdir)/datafile</code>
+
         ./mytestprog $(srcdir)/datafile</syntaxhighlight>
  
 
This is Makefile syntax, the second line needs to start with a tab.
 
This is Makefile syntax, the second line needs to start with a tab.
Line 148: Line 148:
 
To install header files:
 
To install header files:
  
<code bash>include_HEADERS = foo.h bar.h</code>
+
<syntaxhighlight lang="bash">include_HEADERS = foo.h bar.h</syntaxhighlight>
  
 
If the class uses a namespace, e.g. KParts, then the header file should be installed into {{path|kparts/foo.h}}
 
If the class uses a namespace, e.g. KParts, then the header file should be installed into {{path|kparts/foo.h}}
Line 154: Line 154:
 
To do that:
 
To do that:
  
<code bash>kpartsincludedir = $(includedir)/kparts
+
<syntaxhighlight lang="bash">kpartsincludedir = $(includedir)/kparts
kpartsinclude_HEADERS = foo.h bar.h</code>
+
kpartsinclude_HEADERS = foo.h bar.h</syntaxhighlight>
  
 
The first line defines a new directory, the second line installs the files into it. The name before dir and _HEADERS must be the same, but other than that it doesn't matter much what it is.
 
The first line defines a new directory, the second line installs the files into it. The name before dir and _HEADERS must be the same, but other than that it doesn't matter much what it is.
Line 164: Line 164:
 
For instance a Type=Service .desktop file should go into $(kde_servicesdir), therefore you should write:
 
For instance a Type=Service .desktop file should go into $(kde_servicesdir), therefore you should write:
  
<code bash>kde_services_DATA = foo.desktop</code>
+
<syntaxhighlight lang="bash">kde_services_DATA = foo.desktop</syntaxhighlight>
  
 
To install data files into a custom directory, you must first define it, then you can use it:
 
To install data files into a custom directory, you must first define it, then you can use it:
  
<code bash>myappfoodir = $(kde_datadir)/kmyapp
+
<syntaxhighlight lang="bash">myappfoodir = $(kde_datadir)/kmyapp
myappfoo_DATA = bar.desktop</code>
+
myappfoo_DATA = bar.desktop</syntaxhighlight>
  
 
This installs bar.desktop into {{path|$KDEPREFIX/share/apps/kmyapp}}.
 
This installs bar.desktop into {{path|$KDEPREFIX/share/apps/kmyapp}}.
  
For a K Menu entry use: <code bash>xdg_apps_DATA = kmyapp.desktop</code>
+
For a K Menu entry use: <syntaxhighlight lang="bash">xdg_apps_DATA = kmyapp.desktop</syntaxhighlight>
  
 
=== Icons ===
 
=== Icons ===
  
To install icons for all KDE applications to use, you can use <code bash>KDE_ICON = AUTO</code>
+
To install icons for all KDE applications to use, you can use <syntaxhighlight lang="bash">KDE_ICON = AUTO</syntaxhighlight>
  
 
However, if you only need to use icons in one application, you should install the icons into the application's specific directory by doing the following:
 
However, if you only need to use icons in one application, you should install the icons into the application's specific directory by doing the following:
  
<code bash>appicondir = $(kde_datadir)/myapp/icons
+
<syntaxhighlight lang="bash">appicondir = $(kde_datadir)/myapp/icons
appicon_ICON = AUTO</code>
+
appicon_ICON = AUTO</syntaxhighlight>
  
 
For <tt>AUTO</tt> to work (and for the icon loading to work), you need to follow this icon naming convention: '''themesize'''-'''type'''-'''name'''.png (extension can also be .svgz, see below).
 
For <tt>AUTO</tt> to work (and for the icon loading to work), you need to follow this icon naming convention: '''themesize'''-'''type'''-'''name'''.png (extension can also be .svgz, see below).
Line 214: Line 214:
 
<syntaxhighlight lang="ini">[Desktop Entry]
 
<syntaxhighlight lang="ini">[Desktop Entry]
 
Encoding=UTF-8
 
Encoding=UTF-8
Hidden=true</code>
+
Hidden=true</syntaxhighlight>
  
 
Now you should edit Makefile.am and add:
 
Now you should edit Makefile.am and add:
  
<code bash>install-data-local: uninstall.desktop
+
<syntaxhighlight lang="bash">install-data-local: uninstall.desktop
 
$(mkinstalldirs) $(DESTDIR)/$(kde_datadir)/kmyapp
 
$(mkinstalldirs) $(DESTDIR)/$(kde_datadir)/kmyapp
 
$(INSTALL_DATA) $(srcdir)/uninstall.desktop $(DESTDIR)
 
$(INSTALL_DATA) $(srcdir)/uninstall.desktop $(DESTDIR)
$(kde_datadir)/kmyapp/oldfilename.desktop</code>
+
$(kde_datadir)/kmyapp/oldfilename.desktop</syntaxhighlight>
  
 
where {{path|$(kde_datadir)/kmyapp}} is just an example, it should be replaced with the directory where the .desktop was installed to.  Don't forget to prepend $(DESTDIR).
 
where {{path|$(kde_datadir)/kmyapp}} is just an example, it should be replaced with the directory where the .desktop was installed to.  Don't forget to prepend $(DESTDIR).
Line 231: Line 231:
 
=== Qt Designer UI files ===
 
=== Qt Designer UI files ===
  
To compile Qt Designer UI files, use <code>foo_SOURCES = mydialog.ui</code>
+
To compile Qt Designer UI files, use <syntaxhighlight lang="text">foo_SOURCES = mydialog.ui</syntaxhighlight>
  
 
=== DCOP stubs and skeletons ===
 
=== DCOP stubs and skeletons ===
  
To compile a DCOP stub (the client side, calling methods) or skeleton (the "server" side, where the object is implemented), use <code>foo_SOURCES = client.stub obj.skel</code>
+
To compile a DCOP stub (the client side, calling methods) or skeleton (the "server" side, where the object is implemented), use <syntaxhighlight lang="text">foo_SOURCES = client.stub obj.skel</syntaxhighlight>
  
 
This works if the header file is in the current directory.  Otherwise you need to specify where it is, for example:
 
This works if the header file is in the current directory.  Otherwise you need to specify where it is, for example:
  
<code>KDesktopIface_DIR = $(top_srcdir)/kdesktop
+
<syntaxhighlight lang="text">KDesktopIface_DIR = $(top_srcdir)/kdesktop
foo_SOURCES = KDesktopIface.stub</code>
+
foo_SOURCES = KDesktopIface.stub</syntaxhighlight>
  
 
=== Generated sources ===
 
=== Generated sources ===
  
 
To generate sources yourself (e.g. with a Perl script), use
 
To generate sources yourself (e.g. with a Perl script), use
<code>generated.cpp $(srcdir)/myscript $(srcdir)/mydata
+
<syntaxhighlight lang="text">generated.cpp $(srcdir)/myscript $(srcdir)/mydata
 
$(PERL) $(srcdir)/myscript $(srcdir)/mydata -o $@
 
$(PERL) $(srcdir)/myscript $(srcdir)/mydata -o $@
  
CLEANFILES = generated.cpp</code>
+
CLEANFILES = generated.cpp</syntaxhighlight>
  
(Note the Makefile syntax, the second line needs to start with a tab).  For generated .cpp files only, this is sufficient, simply add the generated .cpp file to a _SOURCES line.  For a generated header file, you might have to ensure that it is compiled first, either with proper dependencies like: <code>foo.lo: myheader.h</code> or with <code>target_COMPILE_FIRST = myheader.h</code>
+
(Note the Makefile syntax, the second line needs to start with a tab).  For generated .cpp files only, this is sufficient, simply add the generated .cpp file to a _SOURCES line.  For a generated header file, you might have to ensure that it is compiled first, either with proper dependencies like: <syntaxhighlight lang="text">foo.lo: myheader.h</syntaxhighlight> or with <syntaxhighlight lang="text">target_COMPILE_FIRST = myheader.h</syntaxhighlight>
  
 
In case there are a large number of compiled files, you can still use variables, to list them only once in CLEANFILES and target_COMPILE_FIRST, but you still need to write a two-line rule for each file.
 
In case there are a large number of compiled files, you can still use variables, to list them only once in CLEANFILES and target_COMPILE_FIRST, but you still need to write a two-line rule for each file.
Line 258: Line 258:
 
In the normal case you need only list the subdirectories to add to the build:
 
In the normal case you need only list the subdirectories to add to the build:
  
<code>SUBDIRS = foo bar</code>
+
<syntaxhighlight lang="text">SUBDIRS = foo bar</syntaxhighlight>
  
The current directory "." is implicitly last, so that the current directory compiles after all the subdirectories.  To compile some subdirectories after the current directory, insert "." explicitly, like the following: <code>SUBDIRS = mylib . myplugins</code>
+
The current directory "." is implicitly last, so that the current directory compiles after all the subdirectories.  To compile some subdirectories after the current directory, insert "." explicitly, like the following: <syntaxhighlight lang="text">SUBDIRS = mylib . myplugins</syntaxhighlight>
  
To automatically compile all subdirectories, use <code>SUBDIRS = $(AUTODIRS)</code>
+
To automatically compile all subdirectories, use <syntaxhighlight lang="text">SUBDIRS = $(AUTODIRS)</syntaxhighlight>
  
 
To compile a subdirectory optionally, you need to use the Automake Conditional feature.  The Makefile.am will look like this:
 
To compile a subdirectory optionally, you need to use the Automake Conditional feature.  The Makefile.am will look like this:
  
<code>if compile_KOPAINTER
+
<syntaxhighlight lang="text">if compile_KOPAINTER
 
KOPAINTERDIR = kopainter
 
KOPAINTERDIR = kopainter
 
endif
 
endif
  
SUBDIRS = foo bar $(KOPAINTERDIR)</code>
+
SUBDIRS = foo bar $(KOPAINTERDIR)</syntaxhighlight>
  
The Automake Conditional will be either true or false depending on whether the configure script found whatever feature it was looking for.  To use it in the Makefile.am you need to declare it in your configure.in.in file:  <code>AM_CONDITIONAL(compile_KOPAINTER, ...)</code>
+
The Automake Conditional will be either true or false depending on whether the configure script found whatever feature it was looking for.  To use it in the Makefile.am you need to declare it in your configure.in.in file:  <syntaxhighlight lang="text">AM_CONDITIONAL(compile_KOPAINTER, ...)</syntaxhighlight>
  
The second argument is the test, for instance <code bash>test "$foo" = "yes"</code>
+
The second argument is the test, for instance <syntaxhighlight lang="bash">test "$foo" = "yes"</syntaxhighlight>
  
 
Normally you would have run the test in question in the configure.in.in to define the value of foo before setting the AM_CONDITIONAL.  An abbreviated example from {{path|kdemultimedia/juk}}:
 
Normally you would have run the test in question in the configure.in.in to define the value of foo before setting the AM_CONDITIONAL.  An abbreviated example from {{path|kdemultimedia/juk}}:
  
<code bash>have_musicbrainz=no
+
<syntaxhighlight lang="bash">have_musicbrainz=no
 
KDE_CHECK_HEADER(tunepimp/tp_c.h, have_musicbrainz=yes)
 
KDE_CHECK_HEADER(tunepimp/tp_c.h, have_musicbrainz=yes)
AM_CONDITIONAL(link_lib_MB, test "x$have_musicbrainz" = xyes)</code>
+
AM_CONDITIONAL(link_lib_MB, test "x$have_musicbrainz" = xyes)</syntaxhighlight>
  
 
== Toplevel directories ==
 
== Toplevel directories ==
Line 286: Line 286:
 
The previous section is only for subdirectories of toplevel directories (toplevel directories are like kdebase/libkonq or kdenetwork/kopete, i.e. a directory below the module).  The toplevel directories of a KDE source module are handled in a special way: they are automatically detected, so you don't need a SUBDIRS line there.  However you might want to have some control on the ordering, in case of dependencies, so you can write something like this in the Makefile.am.in file for the module:
 
The previous section is only for subdirectories of toplevel directories (toplevel directories are like kdebase/libkonq or kdenetwork/kopete, i.e. a directory below the module).  The toplevel directories of a KDE source module are handled in a special way: they are automatically detected, so you don't need a SUBDIRS line there.  However you might want to have some control on the ordering, in case of dependencies, so you can write something like this in the Makefile.am.in file for the module:
  
<code>COMPILE_AFTER_kcontrol = kdm kdesktop
+
<syntaxhighlight lang="text">COMPILE_AFTER_kcontrol = kdm kdesktop
COMPILE_BEFORE_konqueror = libkonq</code>
+
COMPILE_BEFORE_konqueror = libkonq</syntaxhighlight>
  
If you want configure to optionally skip a toplevel directory, use this in the configure.in.in code (in the module): <code>DO_NOT_COMPILE = "$DO_NOT_COMPILE foobar"</code>
+
If you want configure to optionally skip a toplevel directory, use this in the configure.in.in code (in the module): <syntaxhighlight lang="text">DO_NOT_COMPILE = "$DO_NOT_COMPILE foobar"</syntaxhighlight>
  
 
{{tip|This is also useful to skip toplevel directories locally at configure time.  Simply export DO_NOT_COMPILE with the list of dirs to skip}}
 
{{tip|This is also useful to skip toplevel directories locally at configure time.  Simply export DO_NOT_COMPILE with the list of dirs to skip}}
Line 295: Line 295:
 
== Documentation ==
 
== Documentation ==
  
For the language of the documentation: <code>KDE_LANG = en</code>
+
For the language of the documentation: <syntaxhighlight lang="text">KDE_LANG = en</syntaxhighlight>
  
If the directories are the application names (e.g. kdebase/doc/kdm will install as "kdm") then you can use the autodetection: <code>KDE_DOCS = AUTO</code>
+
If the directories are the application names (e.g. kdebase/doc/kdm will install as "kdm") then you can use the autodetection: <syntaxhighlight lang="text">KDE_DOCS = AUTO</syntaxhighlight>
  
You can also force a particular installation directory: <code>KDE_DOCS = kcontrol/mouse</code>
+
You can also force a particular installation directory: <syntaxhighlight lang="text">KDE_DOCS = kcontrol/mouse</syntaxhighlight>
  
 
== Translation Support ==
 
== Translation Support ==
Line 305: Line 305:
 
To make your application translatable, you must use <tt>i18n()</tt> in the code, around the English strings that appear to the user. You must also define a messages 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 l10n module. Then translators can create .po files that contain the translations of those messages.
 
To make your application translatable, you must use <tt>i18n()</tt> in the code, around the English strings that appear to the user. You must also define a messages 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 l10n module. Then translators can create .po files that contain the translations of those messages.
  
For applications not in SVN, run <code bash>make -f admin/Makefile.common package-messages</code> to generate the .pot file and <code bash>make merge</code> for the message merge (new .pot file with old .po file).
+
For applications not in SVN, run <syntaxhighlight lang="bash">make -f admin/Makefile.common package-messages</syntaxhighlight> to generate the .pot file and <syntaxhighlight lang="bash">make merge</syntaxhighlight> for the message merge (new .pot file with old .po file).
  
 
{{note|You need to use a patched gettext program, available from [ftp://ftp.kde.org/pub/kde/devel/gettext-kde/ ftp.kde.org] for proper support of contextual translations and plural handling.}}
 
{{note|You need to use a patched gettext program, available from [ftp://ftp.kde.org/pub/kde/devel/gettext-kde/ ftp.kde.org] for proper support of contextual translations and plural handling.}}
Line 311: Line 311:
 
The messages target in the Makefile.am should simply call <tt>xgettext</tt> on the sources that contain translatable text.  This is not the same as the _SOURCES value, since _SOURCES contains .ui and .skel files that do not work with <tt>xgettext</tt>. This is 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:
 
The messages target in the Makefile.am should simply call <tt>xgettext</tt> on the sources that contain translatable text.  This is not the same as the _SOURCES value, since _SOURCES contains .ui and .skel files that do not work with <tt>xgettext</tt>. This is 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:
  
<code>messages:
+
<syntaxhighlight lang="text">messages:
         $(XGETTEXT) *.cpp *.h -o $(podir)/mypotfile.pot</code>
+
         $(XGETTEXT) *.cpp *.h -o $(podir)/mypotfile.pot</syntaxhighlight>
  
 
{{note|Just as with other Makefile rules, the second line must begin with a tab.  Also, the name of the .pot file must be ''unique'' across KDE, so it is best to use an application name or module name as the prefix, such as kofficefilters.pot.}}
 
{{note|Just as with other Makefile rules, the second line must begin with a tab.  Also, the name of the .pot file must be ''unique'' across KDE, so it is best to use an application name or module name as the prefix, such as kofficefilters.pot.}}
Line 318: Line 318:
 
The file name you use for the .pot file is the name of your main KInstance (for a application, it is the first argument passed to KAboutData, and for components/modules it's the name of the KInstance that you create).
 
The file name you use for the .pot file is the name of your main KInstance (for a application, it is the first argument passed to KAboutData, and for components/modules it's the name of the KInstance that you create).
  
If you have .ui (Qt Designer), .rc (XML-GUI) or .kcfg (KConfigXT) files, add <code>messages: rc.cpp</code> and the script will create rc.cpp from the ui, rc, and kcfg files in the current directory.  If you have .ui, .rc or .kcfg files in subdirectories, you need to add something like <code>$(EXTRACTRC) */*.rc >> rc.cpp</code> to the messages target, before the xgettext call (don't forget to start the line with a tab).
+
If you have .ui (Qt Designer), .rc (XML-GUI) or .kcfg (KConfigXT) files, add <syntaxhighlight lang="text">messages: rc.cpp</syntaxhighlight> and the script will create rc.cpp from the ui, rc, and kcfg files in the current directory.  If you have .ui, .rc or .kcfg files in subdirectories, you need to add something like <syntaxhighlight lang="text">$(EXTRACTRC) */*.rc >> rc.cpp</syntaxhighlight> to the messages target, before the xgettext call (don't forget to start the line with a tab).
  
 
Another special case is the "tips" file &mdash; an XML file containing tips shown to the user.  In this case, use something like  
 
Another special case is the "tips" file &mdash; an XML file containing tips shown to the user.  In this case, use something like  
  
<code>messages:
+
<syntaxhighlight lang="text">messages:
 
         perl ./preparetips > tips.cc
 
         perl ./preparetips > tips.cc
 
         $(XGETTEXT) *.cpp *.h tips.cc -o $(podir)/mypotfile.pit
 
         $(XGETTEXT) *.cpp *.h tips.cc -o $(podir)/mypotfile.pit
         rm -f tips.cc</code>
+
         rm -f tips.cc</syntaxhighlight>
  
 
You can find the preparetips script under kdebase/ktip, for instance.  The name of the temporary tips.cc file doesn't matter.
 
You can find the preparetips script under kdebase/ktip, for instance.  The name of the temporary tips.cc file doesn't matter.
  
The last matter is the compilation and installation of .po files.  Inside l10n, 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.
+
The last matter is the compilation and installation of .po files.  Inside l10n, Makefile.am files contain <syntaxhighlight lang="text">KDE_LANG = language</syntaxhighlight> and <syntaxhighlight lang="text">POFILES = AUTO</syntaxhighlight> to mean that all the .po files in the directory are installed into that language.
  
If you ship a separate application and you want it to install its own .po files, you'll usually have a {{path|po/}} subdirectory, and inside the Makefile.am will simply say <code>POFILES = AUTO</code>
+
If you ship a separate application and you want it to install its own .po files, you'll usually have a {{path|po/}} subdirectory, and inside the Makefile.am will simply say <syntaxhighlight lang="text">POFILES = AUTO</syntaxhighlight>
  
 
In that case, the .po files are copied depending on their name as $(PACKAGE).mo (for instance, de.po is installed under {{path|de/LC_MESSAGES/$(PACKAGE).mo}}).
 
In that case, the .po files are copied depending on their name as $(PACKAGE).mo (for instance, de.po is installed under {{path|de/LC_MESSAGES/$(PACKAGE).mo}}).
Line 337: Line 337:
 
== Qt only programs ==
 
== Qt only programs ==
  
By default the build system assumes you're building a KDE application, so it might do things which require kdecore (e.g. using klocale.h when compiling Qt Designer .ui files).  To disable this when building a Qt-only program, use <code>KDE_OPTIONS = qtonly</code>
+
By default the build system assumes you're building a KDE application, so it might do things which require kdecore (e.g. using klocale.h when compiling Qt Designer .ui files).  To disable this when building a Qt-only program, use <syntaxhighlight lang="text">KDE_OPTIONS = qtonly</syntaxhighlight>
  
 
== Disabling "final" compilation ==
 
== Disabling "final" compilation ==
  
To prevent the --enable-final configure option from working in a specific directory (for instance, to work on the directory when --enable-final was used for the whole module), you can either use <code bash>make no-final ; make no-final-install</code> or edit the Makefile.am and add <code>KDE_OPTIONS = nofinal</code>
+
To prevent the --enable-final configure option from working in a specific directory (for instance, to work on the directory when --enable-final was used for the whole module), you can either use <syntaxhighlight lang="bash">make no-final ; make no-final-install</syntaxhighlight> or edit the Makefile.am and add <syntaxhighlight lang="text">KDE_OPTIONS = nofinal</syntaxhighlight>
  
 
== Things to avoid ==
 
== Things to avoid ==
Line 360: Line 360:
 
# You can also use the [http://websvn.kde.org/*checkout*/branches/KDE/3.5/kdesdk/scripts/create_makefile create_makefile] script (from kdesdk/scripts, installed as part of kdesdk).
 
# You can also use the [http://websvn.kde.org/*checkout*/branches/KDE/3.5/kdesdk/scripts/create_makefile create_makefile] script (from kdesdk/scripts, installed as part of kdesdk).
  
To use the create_makefile script, simply type <code bash>create_makefile subdir</code> in the parent directory of {{path|subdir}}.  This will create {{path|subdir/Makefile}} from {{path|subdir/Makefile.am}}.  There is also a create_makefiles script which works recursively down a directory tree.
+
To use the create_makefile script, simply type <syntaxhighlight lang="bash">create_makefile subdir</syntaxhighlight> in the parent directory of {{path|subdir}}.  This will create {{path|subdir/Makefile}} from {{path|subdir/Makefile.am}}.  There is also a create_makefiles script which works recursively down a directory tree.
  
 
== Questions? ==
 
== Questions? ==

Latest revision as of 21:52, 29 June 2011

Ktip.png
 
Tip
Note: This page deals with content related to KDE 3. If you are developing for KDE 4, this information might not be valid anymore.


Contents

[edit] Introduction

Original Author: David Faure (faure@kde.org)

This is the Makefile.am HOWTO (English version). Makefile.am is a file used to describe how to build KDE programs. Usually each subdirectory in a KDE module has a Makefile.am. As you may guess from the name, it is supposed to be similar to a Makefile, but it processed first by the KDE build system, then by the autotools to generate the final Makefile.

This is the build system for KDE 3. KDE 4 uses a different build system, CMake.

[edit] Makefile.am for a simple program

# Notice the bin_ prefix.
bin_PROGRAMS = kdialog
 
kdialog_SOURCES = kdialog.cpp widgets.cpp
kdialog_LDADD = $(LIB_KIO)
kdialog_LDFLAGS = $(all_libraries) $(KDE_RPATH)
 
AM_CPPFLAGS = $(all_includes)
 
METASOURCES = AUTO

[edit] bin

bin means that you want to create something that will install into the bin directory of KDE. *_PROGRAMS means you want to compile a program. Use _SCRIPTS for scripts, etc. 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.

[edit] _SOURCES

You list all of the source files that need to be compiled for each of the PROGRAMS you have listed. Don't include header files or other files that don't need processed in the build procedure.

[edit] _LDADD

This variable is used for each program to define the libraries that the program links to. You can use three types of libraries references:

  1. A library reference as you would pass it to gcc. (Like -lfoo)
  2. A relative path to a Libtool library (Like ../path/to/thelib.la).
  3. A library macro set by the KDE build system. (Like $(LIB_KIO)). It is recommended to use the macro version if set by the KDE build system.

If a library (A) depends on another library (B), you don't need to specify the dependency library (B). But if you do, (e.g. because the dependencies on A might change), make sure you specify A before B. So usually libtool .la libraries are first, then $(LIB_*), then -lfoo if any.

[edit] _LDFLAGS

This defines any flags that need to be passed to the linker. Note that the flags do not get passed to the linker by using _LDADD! These can be -L flags (to change the library search path, usually set by configure into a variable). $(all_libraries) contains all the -L flags necessary to find Qt and KDE, so you must have it there. For programs you should also add $(KDE_RPATH), it helps to get installed programs to find their libraries without having to set LD_LIBRARY_PATH.

[edit] AM_CPPFLAGS

These specify additional compilation flags. This must contain $(all_includes). This is also where other compile-time flags like -DWITHOUTBUGS and -I$(srcdir)/subdir go.
noframe
 
Note
Insert -I directives before $(all_includes). This ensures that your own headers will be used, not some older installed version.

Note that $(srcdir) and . (the build directory) are always included automatically. You may find that Makefile.am files in KDE still use INCLUDES (the old name for AM_CPPFLAGS), but AM_CPPFLAGS is the recommended way to add include paths and other compilation flags.

[edit] KDE_CXXFLAGS

There is also KDE_CXXFLAGS. It is always appended to the end of the other flags used in the build, so it can undo one of the flags set by the KDE build framework. This is the case for exception handling support, which is disabled by default. If you want to use exception handling you need to write
KDE_CXXFLAGS = $(USE_EXCEPTIONS)

[edit] METASOURCES

METASOURCES = AUTO 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.

In case you have multiple binaries/libraries in the same directory, you might need to use the longer form of
libfoo_la_METASOURCES = myfile.moc myotherfile.moc
mybinary_METASOURCES = someotherfile.moc

[edit] Makefile.am for shared libraries

Here is an example Makefile.am for a simple library.

AM_CPPFLAGS = $(all_includes)
 
lib_LTLIBRARIES = libkonq.la
 
libkonq_la_LIBADD = $(LIB_KPARTS)
libkonq_la_LDFLAGS = $(all_libraries) -version-info 6:0:2 -no-undefined
libkonq_la_SOURCES = popupmenu.cc knewmenu.cpp ...
 
METASOURCES = AUTO

[edit] lib

The lib_ prefix means that the library will be installed in /lib. Then comes the name of the library, always followed by .la (which stands for Libtool archive). Note that this becomes _la in the lines that refer to it.

[edit] _LTLIBRARIES

means "LibTool libraries". In other words, it lets the autotools know that libraries should be handled using the libtool program. You should always use this for libraries.

[edit] _LIBADD

This is the list of libraries that this library depends on. Note that it is LDADD for programs and LIBADD for libraries, since it's not exactly the same thing. A library only remembers which other libraries it depends on, it doesn't link them into the final library. See LDADD for recommendations about how to order dependencies.

[edit] _LDFLAGS

This contains the list of flags passed to the linker. $(all_libraries) is required as usual, but also the version number of the library (see [info:/libtool/Libtool%20versioning info:/libtool/Libtool versioning (Konqueror link only)] for more details). The -no-undefined flag is strongly recommended, as it allows the build system to check at link time that the library has no undefined symbols. If any undefined symbols show up, it means that you either forgot to implement a method, or that a dependant library is missing in the LIBADD line.

The rest of the lines are similar to the compiling a binary case.

[edit] Makefile.am for a plugin or module

All dynamically opened pieces of code (including plugins, KParts, kdeinit modules, Kicker applets and KIOSlaves) can be called a "DSO" (Dynamic Shared Object) or more simply for our purposes, a module.

All modules should be installed into the "kde_module" directory, which is usually $KDEPREFIX/lib/kde3. Therefore the main difference with a shared library is that one should use
kde_module_LTLIBRARIES = something.la
(Note that the library name doesn't have to start with lib). For more details on the naming conventions and _LDFLAGS necessary for the various types of modules, please read kdelibs/NAMING.

[edit] Sharing code with convenience libraries

If you are compiling the same source file with the same option into two shared libraries, or into two programs, which are in the same directory, and using the same compilation options, then that's fine, you can list it in both _SOURCES lines. It will in fact be compiled only once, and the object file will be used by both targets.

However, if you are using the same source file in a library and a program, or if you are sharing it between different directories, then you can't list it in both _SOURCES lines. This is because a library and a program need different compilation options (-fPIC), and in case of different directories, because automake doesn't support source files in other dirs. Instead, you should put the shared source files in either a shared library (installed) or in a convenience library. The latter is a static library (*.a on Unix), which isn't installed as is. The targets (shared libs or programs) that "link" to the convenience library will in fact incorporate the object files from it.

To define a convenience library:

# Just as bin_ means install to /bin and lib_ means
# install to lib/, noinst_ means not to install at all.
noinst_LTLIBRARIES = libcommon.la
libcommon_la_SOURCES = dirk.cpp coolo.cpp ...
 
# no need for LIBADD or LDFLAGS, strictly speaking, but it can help
# if e.g. this code needs $(LIBJPEG), all users of this convenience
# lib won't have to specify it.
 
# Then you can use the convenience lib:
mylib_la_LIBADD = libcommon.la
myprogram_LDADD = libcommon.la
This is also the way that you can compile source files in subdirectories. Automake does not allow
foo_SOURCES = subdir/bar.cc

You have to define a convenience library inside of subdir, and use that from the toplevel directory.

[edit] Makefile.am for automated tests

This is an example Makefile.am for an automated test program.

METASOURCES = AUTO
 
check_PROGRAMS = mytestprog.cpp
TESTS = mytestprog
 
mytestprog_SOURCES = mytestprog.cpp
mytestprog_LDFLAGS = $(all_libraries) $(KDE_RPATH)
mytestprog_LDADD = ../libcommon.la
 
AM_CPPFLAGES = -I$(srcdir)/.. $(all_includes)

A common way of adding automated tests to your application is to create a subdirectory called tests. Add tests to the SUBDIRS line in parent Makefile.am and create a Makefile.am in the new tests directory. Use create_makefile (from kdesdk/scripts) to create the new Makefile, and now when you type make check the test program will be compiled (due to check_PROGRAMS) and run (due to TESTS). If the test program returns a non-zero value, make prints out an error message and stops. If the test program shouldn't run automatically (e.g. because it's interactive), omit the TESTS line.

Note that the test program needs to link to a library (either shared or convenience lib) containing the code it's testing. Don't link to a program, KPart, plugin (or other module).

In case your test program needs command-line arguments, use a check-local target to launch it instead of TESTS:

check-local: mytestprog
        ./mytestprog $(srcdir)/datafile

This is Makefile syntax, the second line needs to start with a tab.

[edit] Installing data

[edit] Header files

To install header files:

include_HEADERS = foo.h bar.h

If the class uses a namespace, e.g. KParts, then the header file should be installed into kparts/foo.h

To do that:

kpartsincludedir = $(includedir)/kparts
kpartsinclude_HEADERS = foo.h bar.h

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

[edit] Data files

To install data files into a standard directory (not a directory path, see below for that), use dirname_DATA.

For instance a Type=Service .desktop file should go into $(kde_servicesdir), therefore you should write:

kde_services_DATA = foo.desktop

To install data files into a custom directory, you must first define it, then you can use it:

myappfoodir = $(kde_datadir)/kmyapp
myappfoo_DATA = bar.desktop

This installs bar.desktop into $KDEPREFIX/share/apps/kmyapp.

For a K Menu entry use:
xdg_apps_DATA = kmyapp.desktop

[edit] Icons

To install icons for all KDE applications to use, you can use
KDE_ICON = AUTO

However, if you only need to use icons in one application, you should install the icons into the application's specific directory by doing the following:

appicondir = $(kde_datadir)/myapp/icons
appicon_ICON = AUTO

For AUTO to work (and for the icon loading to work), you need to follow this icon naming convention: themesize-type-name.png (extension can also be .svgz, see below).

Where:

  • Theme is hi, lo, or cr for hicolor, locolor, or crystal. The crystal theme is the KDE default, but icons installed there will not be picked up in other desktop environments. Use hicolor for that.
  • Size is 16, 22, or 32 for locolor. For hicolor and crystal the size can be 16, 22, 32, 48, 64, or 128, or sc. sc stands for scalable, and the icon should be in SVG format, compressed with GZip, and ending in .svgz instead of .png. The 22x22 size is the default toolbar icon size.
  • Type is one of the following:
    • 'app' for an application icon.
    • 'mime' for a mimetype icon.
    • 'action' for a menu item, toolbar button, or other KAction.
    • 'filesys' for a filesystem icon (directories, etc.)
    • or 'device' for the cdrom/floppy/hard disk/etc. icons.

You can find the same icon types in the icon chooser dialog as well.

Examples:

  • cr32-app-konqueror.png: Application icon.
  • cr32-action-insert_frame.png: Toolbar button. Note the use of the underscore, as no hyphen is allowed in the name.
  • cr16-action-insert_frame.png: Menu item.
noframe
 
Note
This convention applies to the source files only. Upon installation, the icon will be copied to the right directory, simply named name.png

[edit] Uninstalling a .desktop file

If you rename or delete a .desktop file, you might want to "uninstall" the old file, i.e. to overwrite it at install time with a file that says "deleted" in order to provide a smoother migration for people installing from sources.

The first step is to add a file called uninstall.desktop to your sources. It can be shared among subdirectories if needed. It should contain the following lines:

[Desktop Entry]
Encoding=UTF-8
Hidden=true

Now you should edit Makefile.am and add:

install-data-local: uninstall.desktop
	$(mkinstalldirs) $(DESTDIR)/$(kde_datadir)/kmyapp
	$(INSTALL_DATA) $(srcdir)/uninstall.desktop $(DESTDIR)
	$(kde_datadir)/kmyapp/oldfilename.desktop

where $(kde_datadir)/kmyapp is just an example, it should be replaced with the directory where the .desktop was installed to. Don't forget to prepend $(DESTDIR).

noframe
 
Note
The Makefile.am sample is another instance of Makefile formatting, therefore the lines under install-data-local: need to start with tabs

[edit] Other types of source files

[edit] Qt Designer UI files

To compile Qt Designer UI files, use
foo_SOURCES = mydialog.ui

[edit] DCOP stubs and skeletons

To compile a DCOP stub (the client side, calling methods) or skeleton (the "server" side, where the object is implemented), use
foo_SOURCES = client.stub obj.skel

This works if the header file is in the current directory. Otherwise you need to specify where it is, for example:

KDesktopIface_DIR = $(top_srcdir)/kdesktop
foo_SOURCES = KDesktopIface.stub

[edit] Generated sources

To generate sources yourself (e.g. with a Perl script), use

generated.cpp $(srcdir)/myscript $(srcdir)/mydata
	$(PERL) $(srcdir)/myscript $(srcdir)/mydata -o $@
 
CLEANFILES = generated.cpp
(Note the Makefile syntax, the second line needs to start with a tab). For generated .cpp files only, this is sufficient, simply add the generated .cpp file to a _SOURCES line. For a generated header file, you might have to ensure that it is compiled first, either with proper dependencies like:
foo.lo: myheader.h
or with
target_COMPILE_FIRST = myheader.h

In case there are a large number of compiled files, you can still use variables, to list them only once in CLEANFILES and target_COMPILE_FIRST, but you still need to write a two-line rule for each file.

[edit] Adding subdirectories to the build

In the normal case you need only list the subdirectories to add to the build:

SUBDIRS = foo bar
The current directory "." is implicitly last, so that the current directory compiles after all the subdirectories. To compile some subdirectories after the current directory, insert "." explicitly, like the following:
SUBDIRS = mylib . myplugins
To automatically compile all subdirectories, use
SUBDIRS = $(AUTODIRS)

To compile a subdirectory optionally, you need to use the Automake Conditional feature. The Makefile.am will look like this:

if compile_KOPAINTER
KOPAINTERDIR = kopainter
endif
 
SUBDIRS = foo bar $(KOPAINTERDIR)
The Automake Conditional will be either true or false depending on whether the configure script found whatever feature it was looking for. To use it in the Makefile.am you need to declare it in your configure.in.in file:
AM_CONDITIONAL(compile_KOPAINTER, ...)
The second argument is the test, for instance
test "$foo" = "yes"

Normally you would have run the test in question in the configure.in.in to define the value of foo before setting the AM_CONDITIONAL. An abbreviated example from kdemultimedia/juk:

have_musicbrainz=no
KDE_CHECK_HEADER(tunepimp/tp_c.h, have_musicbrainz=yes)
AM_CONDITIONAL(link_lib_MB, test "x$have_musicbrainz" = xyes)

[edit] Toplevel directories

The previous section is only for subdirectories of toplevel directories (toplevel directories are like kdebase/libkonq or kdenetwork/kopete, i.e. a directory below the module). The toplevel directories of a KDE source module are handled in a special way: they are automatically detected, so you don't need a SUBDIRS line there. However you might want to have some control on the ordering, in case of dependencies, so you can write something like this in the Makefile.am.in file for the module:

COMPILE_AFTER_kcontrol = kdm kdesktop
COMPILE_BEFORE_konqueror = libkonq
If you want configure to optionally skip a toplevel directory, use this in the configure.in.in code (in the module):
DO_NOT_COMPILE = "$DO_NOT_COMPILE foobar"
Ktip.png
 
Tip
This is also useful to skip toplevel directories locally at configure time. Simply export DO_NOT_COMPILE with the list of dirs to skip


[edit] Documentation

For the language of the documentation:
KDE_LANG = en
If the directories are the application names (e.g. kdebase/doc/kdm will install as "kdm") then you can use the autodetection:
KDE_DOCS = AUTO
You can also force a particular installation directory:
KDE_DOCS = kcontrol/mouse

[edit] Translation Support

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 messages 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 l10n module. Then translators can create .po files that contain the translations of those messages.

For applications not in SVN, run
make -f admin/Makefile.common package-messages
to generate the .pot file and
make merge
for the message merge (new .pot file with old .po file).
noframe
 
Note
You need to use a patched gettext program, available from ftp.kde.org for proper support of contextual translations and plural handling.

The messages target in the Makefile.am should simply call xgettext on the sources that contain translatable text. This is not the same as the _SOURCES value, since _SOURCES contains .ui and .skel files that do not work with xgettext. This is 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:

messages:
        $(XGETTEXT) *.cpp *.h -o $(podir)/mypotfile.pot
noframe
 
Note
Just as with other Makefile rules, the second line must begin with a tab. Also, the name of the .pot file must be unique across KDE, so it is best to use an application name or module name as the prefix, such as kofficefilters.pot.

The file name you use for the .pot file is the name of your main KInstance (for a application, it is the first argument passed to KAboutData, and for components/modules it's the name of the KInstance that you create).

If you have .ui (Qt Designer), .rc (XML-GUI) or .kcfg (KConfigXT) files, add
messages: rc.cpp
and the script will create rc.cpp from the ui, rc, and kcfg files in the current directory. If you have .ui, .rc or .kcfg files in subdirectories, you need to add something like
$(EXTRACTRC) */*.rc >> rc.cpp
to the messages target, before the xgettext call (don't forget to start the line with a tab).

Another special case is the "tips" file — an XML file containing tips shown to the user. In this case, use something like

messages:
        perl ./preparetips > tips.cc
        $(XGETTEXT) *.cpp *.h tips.cc -o $(podir)/mypotfile.pit
        rm -f tips.cc

You can find the preparetips script under kdebase/ktip, for instance. The name of the temporary tips.cc file doesn't matter.

The last matter is the compilation and installation of .po files. Inside l10n, Makefile.am files contain
KDE_LANG = language
and
POFILES = AUTO
to mean that all the .po files in the directory are installed into that language. 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
POFILES = AUTO

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).

[edit] Qt only programs

By default the build system assumes you're building a KDE application, so it might do things which require kdecore (e.g. using klocale.h when compiling Qt Designer .ui files). To disable this when building a Qt-only program, use
KDE_OPTIONS = qtonly

[edit] Disabling "final" compilation

To prevent the --enable-final configure option from working in a specific directory (for instance, to work on the directory when --enable-final was used for the whole module), you can either use
make no-final ; make no-final-install
or edit the Makefile.am and add
KDE_OPTIONS = nofinal

[edit] Things to avoid

Do NOT use the following constructs:

  •  %.foo: %.bar rules. They are not portable.
  • $< in a custom rule. It's not portable. $@ is, however.
  • BUILT_SOURCES. Automake doesn't support it properly, it makes $(BUILT_SOURCES) a dependency on Makefile, so e.g. they are regenerated when you call make clean twice.
  • Obviously, don't call gcc or ld yourself.

[edit] Turning Makefile.am into a Makefile

When you change a Makefile.am, if there is already a Makefile generated from it you can simply run make and the Makefile will automatically be re-generated.

If there is no Makefile created yet, you have two choices.

  1. Run make -f Makefile.cvs at the toplevel of the module, and re-run configure to regenerate all Makefiles.
  2. You can also use the create_makefile script (from kdesdk/scripts, installed as part of kdesdk).
To use the create_makefile script, simply type
create_makefile subdir
in the parent directory of subdir. This will create subdir/Makefile from subdir/Makefile.am. There is also a create_makefiles script which works recursively down a directory tree.

[edit] Questions?

If you're still stuck, there's several things you can do:

  • Email the kde-devel mailing list with your question.
  • You can use the Discussion tab of this wiki to request clarification of a point.
  • Never forget that the source code for KDE is available online. It can be instructive to see how other software projects use Makefile.am.
  • You can also ask in the #kde-devel chatroom in irc.kde.org

This page was last modified on 29 June 2011, at 21:52. This page has been accessed 14,580 times. Content is available under Creative Commons License SA 3.0 as well as the GNU Free Documentation License 1.2.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal