📄 adding-gnome.html
字号:
</PRE></TD></TR></TABLE><P> The gnome-config script is a very handy interface for retrieving package information and compile parameters. It is fairly consistent, but not always so. You should always test your invocation syntax on the command line before putting it into a makefile, and be prepared for gnome-config's behavior to change in subtle ways between major releases of gnome-libs. </P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN603">GNOME Makefile Variables</A></H2><P> As if gnome-config didn't already make life easy enough, the GNOME_INIT macro in gnome.m4 defines a handful of shrink-wrapped variables that you can use in your Makefile.am files without any other preparation on your part, aside from including GNOME_INIT in your configure.in file. </P><P> Some of these variables concern GNOME libraries that we won't cover in this book, such as zvt, the virtual terminal library used by the gnome-terminal application, and gnorba, the CORBA helper library used by gnome-libs. The four variables that are most interesting to us concern libgnome and libgnomeui. The contents of these four variables arise from calling gnome-config on the gnome and gnomeui modules with different options. Here is the relevant code from the GNOME_INIT macro, cleaned up a little for clarity: </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">AC_PATH_PROG(GNOME_CONFIG, gnome-config)GNOME_LIBS="`$GNOME_CONFIG --libs-only-l gnome`"GNOMEUI_LIBS="`$GNOME_CONFIG --libs-only-l gnomeui`"GNOME_LIBDIR="`$GNOME_CONFIG --libs-only-L gnomeui`"GNOME_INCLUDEDIR="`$GNOME_CONFIG --cflags gnomeui`"AC_SUBST(GNOME_LIBS)AC_SUBST(GNOMEUI_LIBS)AC_SUBST(GNOME_LIBDIR)AC_SUBST(GNOME_INCLUDEDIR) </PRE></TD></TR></TABLE><P> You can probably get a good idea of what each variable is useful for, just by looking at the gnome-config command for each one. We'll see how and where to use them in Makefile.am files in Section 3.5.5. If you're interested in digging around behind the scenes to see how all the various options are generated and where the contents come from, take a look at the gnome-config.in file in the gnome-libs package. </P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN609">autogen.sh</A></H2><P> As we saw in the libtool example in Section 3.4.3, all these tools can lead to quite a long series of command invocations, each of which needs to be called in the right order, with the right parameters. Developers have enough tech support problems that result from buggy code without worrying about debugging the install process for each new user that comes along. To cut down on this excess traffic, and to make it easier for themselves, the GNOME developers created a template build script, called autogen.sh, to make sure everything is called in the right order. Also, it's simply more convenient to have to run only one command. </P><P> The autogen.sh script runs everything for you, up to but not including the make command. The install procedures for nearly all packages properly modified for GNOME look identical: </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">$ tar xzf <package>.tar.gz$ cd <package>$ ./autogen.sh$ make$ make install </PRE></TD></TR></TABLE><P> The master autogen.sh script resides in the macros directory with the GNOME m4 files. Each distribution typically has a thin wrapper autogen.sh script in the top-level directory, next to the configure.in file. In this wrapper script you can add some additional checks before calling the master autogen.sh. Most wrapper scripts look something like Listing 3.8. </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.8 Sample autogen.sh Wrapper Script from Gnome-games#!/bin/sh# Run this to generate all the initial makefiles, etc.srcdir=`dirname $0`test -z "$srcdir" && srcdir=.PKG_NAME="Gnome Games"(test -f $srcdir/configure.in \ && test -d $srcdir/gnomine \ && test -d $srcdir/same-gnome) || {' echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" echo " top-level gnome directory" exit 1}. $srcdir/macros/autogen.sh </PRE></TD></TR></TABLE><P> The master autogen.sh script does various things. It checks for the existence of the autoconf and automake tools-although it doesn't specifically check the current version of them, so an out-of-date version of autoconf or automake can still cause problems-as well as the GNU gettext library. It then embarks on a recursive search, starting with the top-level directory, looking for all configure.in files in the package. It does this in case you have multiple subprojects in your distribution. Normally you'll have only one configure.in file, in the top directory, but just in case, autogen.sh checks for more. This check is necessary because you must run autoconf separately on each configure.in file. If you run autoconf on only the top-level directory, the sublevel configure.in files will end up being ignored. </P><P> The autogen.sh script makes good use of grep, on each iteration looking in your configure.in file for certain macros and responding accordingly. For example, if it finds AM_GNU_GETTEXT or AM_GNOME_GETTEXT, it will run gettextize to set things up for internationalization (see Section 4.6). If autogen.sh spies an AM_PROG_LIBTOOL macro, it will run libtoolize for you. If it sees AM_CONFIG_HEADER, it will run autoheader. Next it runs automake and autoconf, with the proper parameters. Finally, it runs configure for you, passing along any parameters you gave to autogen.sh. To top things off, it adds a message to remind you that you still have to run make. </P><P> This is a good example of clever build scripting. Take a look at the master version of autogen.sh when you have a chance. </P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN619">Some Grumpy GNOME Examples</A></H2><P> We've covered quite a lot of ground in this chapter. The GNOME build environment is extremely complex and covers many different strata, including over a dozen scripts of various types. It is time now to tie everything together and see if we can come up with a few practical test cases that you can use in your own development efforts. </P><P> In this section we will cover four build topologies, four ways of building and installing the same set of source files (see Figure 3.3). Since we already have working sample code from Section 3.4.3, we'll recycle that for our GNOME examples, adding a few minor touches as we go. Our four build cases all use the same code base, but they differ in the way they link the libraries together: </P><DIVCLASS="FIGURE"><ANAME="AEN623"></A><P><B>Figure 3-3. Four Grumpy Library Cases</B></P><DIVCLASS="MEDIAOBJECT"><P><IMGSRC="figures/3f3.png"></IMG></P></DIV></DIV><P></P><UL><LI><P> Case 1: Binary executable; no libraries </P></LI><LI><P> Case 2: Binary executable; one statically linked library </P></LI><LI><P> Case 3: Binary executable; one dynamically linked library </P></LI><LI><P> Case 4: Binary executable; one dynamically linked library, one statically linked library </P></LI></UL><P> We won't change much of the original grump example. First we'll split grump.c into two separate files, one for each function. This is important for the fourth build case, in which we create two libraries, one from each file, grump.c and grump_more.c. We'll also change the #include statement in grump.h to pull in gnome.h rather than stdlib.h (this works because gnome.h in turn includes stdlib.h). Finally, to make use of gnome.h we will change our printf( ) statements to g_print( ) statements. Technically, since g_print( ) is part of GLib, not gnome-libs, we aren't really making good use of gnome.h, but for purposes of demonstration, g_print( ) is fine. </P><P> You can use the same techniques to set up most, if not all, of your full-blooded GNOME applications. Listings 3.9 through 3.12 contain the source code for the four files in our example. Listing 3.13 contains our configure.in file. These five files will remain the same throughout all four cases; only the Makefile.am files will change. </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.9 grump.h for GNOME Grump Example# include <gnome.h>void grump_some( );void grump_a_lot_more( ); </PRE></TD></TR></TABLE><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.10 grump.c for GNOME Grump Example# include "grump.h"void grump_some( ){ g_print("Oh, bother!...\n\n");} </PRE></TD></TR></TABLE><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.11 grump_more.c for GNOME Grump Example# include "grump.h"void grump_a_lot_more( ){ int i, index; char *grumps[5] = { "Aargh!", "Be gone!", "Sigh...", "Not again!", "Go away!" }; for (i = 0; i < 5; i++) { index = (5.0 * rand( ) / (RAND_MAX + 1.0)); g_print("%s\n", grumps[index]); }} </PRE></TD></TR></TABLE><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.12 main.c for GNOME Grump Example# include "grump.h"int main(int argc, char *argv[]){ grump_some( ); grump_a_lot_more( );} </PRE></TD></TR></TABLE><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.13 configure.in for GNOME Grump ExampleAC_INIT(grump.c)AM_INIT_AUTOMAKE(myapp, 0.0.1)AC_PROG_CCAC_HEADER_STDCAM_PROG_LIBTOOLGNOME_INITAC_OUTPUT([Makefile]) </PRE></TD></TR></TABLE><P> In case 1, whose Makefile.am is outlined in Listing 3.14, we'll link all three .c files directly into the grumpalot executable. We'll pass GNOME's compile flags to gcc in automake's global $(INCLUDES) variable. automake will add the contents of $(INCLUDES) to the compile line for every .c file we list in that Makefile.am file. We want our final executable target, grumpalot, to be installed in $(bindir), so we'll assign it to bin_PROGRAMS. Finally, we'll list the source files under the _SOURCES primary, and the flags we want to send to the linker in the _LDADD primary. </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.14 Makefile.am for Case 1 of GNOME Grump ExampleINCLUDES = $(GNOME_INCLUDEDIR)bin_PROGRAMS = grumpalotgrumpalot_SOURCES = main.c grump.c grump_more.cgrumpalot_LDADD = $(GNOME_LIBDIR) $(GNOMEUI_LIBS) </PRE></TD></TR></TABLE><P> To configure and compile the GNOME version of our grumpalot program, we follow the same series of commands we used for the one in Section 3.4.3: </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">$ libtoolize$ aclocal$ touch NEWS README AUTHORS ChangeLog$ automake --add-missing --gnu$ autoconf$ ./configure$ make </PRE></TD></TR></TABLE><P> If you also run make install, the makefile will copy the grumpalot executable into the bin directory of whatever prefix you pass in to the configure script. The default prefix is /usr/local, but you probably don't want to in- stall this experimental grumpalot project into that directory, especially if you don't have root privileges on the system you're working on. You can set things up to install grumpalot into your home directory with the following command (substituting the path to your own home directory): </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">$ ./configure --prefix=/home/jsheets/wga </PRE></TD></TR></TABLE><P
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -