16.2. Administrative Files

Before you starting building a package for KSimpleApp, you should be familiar with some of the files used by the packaging system. Table 16.1 gives a summary of files and their purposes.


Table 16.1. Administrative Files in a KDE Package

FilenameDescription
configureConfiguration script used to configure the build environment.
configure.inSource for the script configure. This is prepared by the maintainer (you!) and processed by Autoconf to create the script configure.
config.hHolds the results of the tests run by the script configure. These results are specified by #define directives. You can include config.h in your source code to use these directives (thus, the results of the tests).
config.statusScript to remake the last successful build environment generated by the script configure.
config.cacheStores results of tests run by the script configure so that the package can be reconfigured quickly (without rerunning previously successful tests).
config.logContains debugging output from the script configure. You can consult this file to figure out why a test has failed.

16.2.1. Configuring the Top-Level Directory

To convert the kexample package to a package for KSimpleApp, you first need to edit configure.in and Makefile.am.

The file configure.in contains several macros, each of which corresponds to a set of tests run by configure. Autoconf expands these macros when converting configure.in to the script configure. You need to modify two macros called AM_INIT_AUTOMAKE and AC_OUTPUT.

The first of these specifies the name and version number of the package. Call the package ksimpleapp and give it version number 1.0 by changing the line


   1 
   2 AM_INIT_AUTOMAKE(kexample, 2.0pre) dnl searches for some needed programs
   3 

to read


   1 
   2 AM_INIT_AUTOMAKE(ksimpleapp, 1.0) dnl searches for some needed programs
   3 

Next, tell Autoconf which directories to compile source code in. In this example, only one directory exists, ksimpleapp, so change the lines


   1 
   2 AC_OUTPUT( \
   3        ./Makefile \
   4 
   5        kless/Makefile \
   6        )
   7 

to read


   1 
   2 AC_OUTPUT( \
   3          ./Makefile \
   4 
   5          ksimpleapp/Makefile \
   6          )
   7 

You also need to edit Makefile.am. This file is processed by Automake into Makefile.in, which is processed, in turn, into Makefile by Autoconf. Thankfully, this is a mostly transparent process. You will generally need to modify only one line in Makefile.am and then not worry about the other two files. The line to modify is


   1 
   2 SUBDIRS = kless
   3 

It should read


   1 
   2 SUBDIRS = ksimpleapp
   3 

The top-level directory is now configured. The changes you have made will be propagated when you type make Makefile.dist, but don't do that yet! You need to make some changes to the subdirectory kless. First off, change its name:


   1 
   2 mv kless ksimpleapp
   3 

The subdirectory kless, which you have renamed ksimpleapp, contains the source code, Makefile, and some support files for an application called kless.

16.2.2. Configuring the Subdirectories

Now prepare the subdirectory ksimpleapp for KSimpleApp:

  1. Delete the files kless.cpp, kless.h, and configure.in.in—you won't be needing them.

  2. Rename kless.desktop to ksimpleapp.desktop.

  3. Copy the source code for KSimpleApp to this directory. The necessary files are ksimpleapp.h, ksimpleapp.cpp, and main.cpp. (These files are part of the source code from Chapter 2.)

  4. Rename the files lom-app-kless.png and los-app-kless.png to lom-app-ksimpleapp.png and los-app-ksimpleapp.png, respectively. You can use the kless icon instead of drawing your own just for this example. When you distribute your application, you should create your own icons according to the KDE style guidelines in Chapter 6, "KDE Style Reference."

Now you need to configure the file Makefile.am. This file is read by automake when you run make Makefile.dist. Automake produces the file Makefile.in from it (from which Autoconf produces Makefile, as discussed previously).

Makefile.am contains a list of variable assignments and standard make rules. The standard make rules are copied directly to Makefile.in and then to Makefile. The assigned variables have special names that tell Automake how to create Makefile.in. For example, value assigned to the variable bin_PROGRAMS is the name of the application being created. Listing 16.1 shows an edited version of the Makefile.am found in the subdirectory kexample/kless. It has been edited to build KSimpleApp. (The original file was well commented; these comments have been removed here for brevity.)


Example 16.1. Makefile.am: An Automake Source File Used to Build KSimpleApp

   1 
   2  1: INCLUDES= $(all_includes)
   3  2:
   4  3: bin_PROGRAMS =     ksimpleapp
   5  4:
   6  5: ksimpleapp_SOURCES = ksimpleapp.cpp main.cpp
   7  6:
   8  7: ksimpleapp_METASOURCES = AUTO
   9  8:
  10  9: ksimpleapp_LDFLAGS = $(all_libraries) $(KDE_RPATH)
  11 10: ksimpleapp_LDADD = $(LIB_KDEUI)
  12 11:
  13 12: noinst_HEADERS = ksimpleapp.h
  14 13:
  15 14: messages:
  16 15:     $(XGETTEXT) --c++ -ki18n -x $(includedir)/kde.pot \
  17 16       $(ksimpleapp_SOURCES) &&mv messages.po ../po/ksimpleapp.pot
  18 17:
  19 18: kdelnkdir = $(kde_appsdir)/Utilities
  20 19: kdelnk_DATA = ksimpleapp.desktop
  21 10:
  22 21: KDE_ICON = ksimpleapp
  23 

The following variables should be assigned in Makefile.am.

INCLUDES—(Line 1) Include paths passed to the C++ compiler. Set this to $(all_includes) to get the KDE, Qt, and X11 include paths. Add other paths as needed (for example, to locate include files for a custom or other third-party library).

bin_PROGRAMS—(Line 3) The name of the binary to create. In this example, it is ksimpleapp.

ksimpleapp_SOURCES—(Line 5) The names of all the source files separated by spaces. Use the name assigned to bin_PROGRAMS as the first part of this and other variables (see subsequent items in this table). (Actually, the name assigned to bin_PROGRAMS needs to be converted a bit; all characters except letters and numbers should be converted to underscores. For example, if bin_PROGRAMS were set to my-program, the SOURCES variable would be my_program_SOURCES.)

ksimpleapp_METASOURCE—(Line 7) You should always set this to AUTO. Dependencies for *.moc files are automatically set up in Makefile. For this to work, you should include *.moc files in your C++ source code, the same as you've done throughout this book.

ksimpleapp_LDFLAGS—(Line 9) A list of paths to search for libraries. Set this to $(all_libraries) to add the search paths for the necessary KDE, Qt, and X libraries.

ksimpleapp_LADD—(Line 10) A list of libraries to link to. Setting this to $(LIB_KDEUI) links ksimpleapp to libkdeui, as well as to all the other libraries necessary to compile a basic KDE application. If you need libkfile, libkimgo, libkio, or libkab, you should add the variables—$(LIB_KFILE), $(LIB_KIMGIO), $(LIB_KIO), or $(LIB_KAB)—to this line. Be sure to separate the variable names with a space and place libraries in reverse order of dependence. For example, if library1 depends on library2, place library1 first in the list.

noinst_HEADERS—(Line 12) The header files listed here should not be installed along with the application.

kdelnkdir—(Line 18) The directory in which to install the ksimpleapp.desktop file. (Recall that the *.kdelnk files of KDE 1.x have been replaced with *.desktop files in KDE 2.0; this explains the name of this variable.)

kdelnk_DATA—(Line 19) The name of the .desktop file to install.

KDE_ICON—(Line 21) The root of the icon names. The icon names are lo32-app- ksimpleapp.png and lo16-app-ksimpleapp.png. The root is ksimpleapp. The prefixes are app for application, lom for "low color, medium sized," and los for "low color, small sized."

The last part of Makefile.am, which I haven't mentioned yet, is the target messages. This target (lines 14 and 15) follows the standard makefile conventions and is carried through unchanged by Automake and Autoconf to the final Makefile. When you run make messages, the string literals that have been passed to the function i18n() are extracted from all files listed in $(ksimpleapp_SOURCES) to the file ../po/ksimpleapp.pot. This file serves as a template for creating translations of the string literals. The option -x $(includedir)/kde.pot says to ignore strings that have been previously translated for global use by KDE applications. See Chapter 7, "Further KDE Compliance," for information on how to create and use translation (*.po) files.

16.2.3. Updating Administration Files

You may now update the administration files. First, make sure that the environment variables KDEDIR and QTDIR are set appropriately to the root KDE and Qt directories. Change directories to the top-level directory and type


   1 
   2 make -f Makefile.dist./configure

This performs the updates. You can now compile the application with make.

16.2.4. Creating Shared Libraries

The KDE package-management system you have been reading about makes the creation of shared libraries quite simple. To do this, create a subdirectory and copy the library's source code into it. Next, copy the file Makefile.am from the kless directory and modify it the same as you did for ksimpleapp, except for two things:

  1. Instead of assigning a value to the variable bin_PROGRAMS, set the variable lib_ LTLIBRARIES. For example:


       1 
       2 lib_LTLIBRARIES  = libkplotw.la
       3 

    tells automake that you are interested in creating a library called libkplotw.la.

  2. Add some linker flags:


       1 
       2 libkplotw_la_LDFLAGS = -version-info 0:2:0 $(all_libraries) -no-undefined
       3 

    Notice that an underscore has been substituted for the period in libkplotw.la. The option -version-info a:b:c says to create a library with the version number (a-c).c.b For example, this library would be created as libkplotw.so.0.0.2. The option -no-undefined says that no external symbols are needed by this library (it is needed to create a shared library).

16.2.5. Using Test Results

You can use the results of the tests run by the script configure in a source-code file by including the file config.h with the following statement:


   1 
   2 #include <config.h>
   3 

Then do either of the following:

  • Examine the macros defined in this file with preprocessor directives.

  • Use the macros directly.

The file config.h is created automatically by the script configure after the tests are run.

Let's examine the second method.

Add the statement #include <config.h> to the file ksimpleapp.cpp and change the following line:


   1 
   2 text = new QLabel (i18n("Hello!"), this);
   3 

to the lines


   1 
   2 QString qs (i18n("Hello from "));
   3 qs = qs + VERSION +"!";
   4 text = new QLabel (qs, this);
   5 

The identifier VERSION is a macro defined in config.h by the statement


   1 
   2 #define VERSION "1.0"
   3 

The string "1.0" comes, ultimately, from your declaration of the version in the call to AM_INIT_AUTOMAKE() in the file configure.in.

Other macros are defined that tell about the build environment. The file config.h in well commented and describes the purpose of each macro.

16.2.6. Make Targets

The makefiles that are generated by Automake/Autoconf contain several make targets that help make the development cycle more efficient. Several commonly used targets are listed in Table 16.2.


Table 16.2. Commonly Used Targets Included in Autogenerated Makefiles

TargetDescription
allBuild the entire package. This is the default target (that is, it is assumed if no target is specified).
installInstall the package. The target all is made if it hasn't been already.
uninstallRemove the package.
cleanRemove the build results (*.o files, executables, and so on) but not configuration results (config.cache, and so on).
distcleanPreparing the package for distribution removes both build results and results of configuration. You can still rebuild the package without having Automake, Perl, and Autoconf installed.
maintainer-cleanRemoves even more than distclean. You'll need to have Automake, Perl, and Autoconf to rebuild after making this target.

The targets all, install, and uninstall will be used by end users and generally, the others will be used only by the maintainer(s) of the package.