⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adding-gnome.html

📁 linux下gnome编程
💻 HTML
📖 第 1 页 / 共 3 页
字号:
>          This command will place the grumpalot executable file in the          /home/jsheets/wga/bin directory, any libraries in          /home/jsheets/wga/lib, and any include files in          /home/jsheets/wga/include. When you're done experimenting,          you can run make uninstall or rm -rf /home/jsheets/wga.        </P><P>          Listing 3.15 shows the Makefile.am file for case 2, in which          we want to link the two grump source files into a library,          then statically link that library into grumpalot. Although          this may at first seem a little silly-why don't we just          compile them into the executable like we did in case 1?-you          may someday have to do this in your own project. If you          have a lot of files in your project, you might want to          divide some of them up into separate directories to keep          things organized and reduce the clutter.        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.15 Makefile.am for Case 2 of GNOME Grump ExampleINCLUDES = $(GNOME_INCLUDEDIR)bin_PROGRAMS = grumpalotgrumpalot_SOURCES = main.cgrumpalot_LDADD = $(GNOME_LIBDIR) $(GNOMEUI_LIBS) \  libGrump.lanoinst_LTLIBRARIES = libGrump.lalibGrump_la_SOURCES = grump.c grump_more.clibGrump_la_LIBADD = $(GNOME_LIBDIR) $(GNOMEUI_LIBS)        </PRE></TD></TR></TABLE><P>          Unfortunately, GNU make, and thus automake, has a limitation          that prevents us from targeting source files outside the          current directory. If we were to move grump.c and          grump_more.c to a subdirectory, we would have to create an          additional Makefile.am file for that subdirectory and then          compile those files into a library. Then we could pull that          temporary helper library into our main executable by adding          it to the grump_LDADD variable in our main Makefile.am          file. This is exactly what we'll do in case 2, except          without the subdirectory. Our grump_LDADD line will look          like this:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">grump_LDADD = $(GNOME_LIBDIR) $(GNOMEUI_LIBS) \  libGrump.la        </PRE></TD></TR></TABLE><P>          We name libGrump.la explicitly, without the implicit -l          flag, so that the linker will not mistakenly try to link          against libGrump.so. We don't have to do anything else to          set up the static link. The linker will link libGrump.la          into our binary file. Our case 2 grumpalot program won't          require any external libraries. automake knows this because          we told it to use the noinst target for the library;          consequently, the generated makefile will not bother          generating any dynamic .so libraries.        </P><P>          With case 3, we create a dynamic library rather than a          static one. This brings up a handful of new concerns. We now          have to install the library, since the executable loads it          during runtime. We also have to install any header files          that define the library's interface. If we didn't install          the headers, other people would be unable to use our library          because they wouldn't know which functions it contained;          more to the point, the compiler needs the header file to          satisfy the #include "grump.h" statement in main.c (or it          would if the grump library were distributed separately from          the main executable). Finally, we should set the library          version number as we discussed in Section 3.4.5 to make sure          the loader grabs the right library. This is a simple matter          of adding the -version-info option to          libGrump_la_LDFLAGS. See Listing 3.16 for the case 3          Makefile.am file.        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.16 Makefile.am for Case 3 of GNOME Grump ExampleINCLUDES = $(GNOME_INCLUDEDIR)bin_PROGRAMS = grumpalotgrumpalot_SOURCES = main.cgrumpalot_LDADD = $(GNOME_LIBDIR) $(GNOMEUI_LIBS) \  -lGrump -L$(top_builddir)/.libslib_LTLIBRARIES = libGrump.lalibGrump_la_SOURCES = grump.c grump_more.clibGrump_la_LDFLAGS = -version-info 0:0:0libGrump_la_LIBADD = $(GNOME_LIBDIR) $(GNOMEUI_LIBS)libgrumpdir = $(includedir)libgrump_HEADERS = grump.h        </PRE></TD></TR></TABLE><P>          First let's figure out how to make our library shared rather          than static. As it turns out, the main thing we have to do          is change our noinst_LTLIBRARIES automake variable to          lib_LTLIBRARIES. This change tells automake that we want our          package's libraries installed in $(libdir). Since we are          installing libraries, libtool takes the liberty of          generating dynamic .so libraries in addition to the static          .a and .la libraries it generated in case 2. Furthermore, it          puts these new .so files in the .libs subdirectory rather          than in the same directory as the grumpalot executable. For          this reason we must add an -L option to grump_LDADD:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">grump_LDADD = $(GNOME_LIBDIR) $(GNOMEUI_LIBS) \  -lGrump -L$(top_builddir)/.libs        </PRE></TD></TR></TABLE><P>          We provide this as a relative path off of $(top_builddir) so          that make can find the .libs directory even if          administrators perform their builds in directories outside          of the source tree. This makes it possible to build more          than one set of executables with different configure          options, simultaneously, off of the same source tree. If you          use relative paths inside your source tree, or mistakenly          use $(top_srcdir), to refer to your object and library          files, you will break this functionality. The linker will          end up looking for your object files inside the source          tree rather than inside your build tree, where they will          reside.        </P><P>          To see what it's like to build a package outside its source          tree, you can create a build directory outside the source          tree, cd into it, and invoke the configure script from that          directory. configure will create Makefile files inside the          build directory (the Makefile.am and Makefile.in files will          still land in the source tree). When you run the resulting          Makefile, it will create all the object files, libraries,          and executables inside the current directory path, in the          build directory tree. To see how this works, run all the          commands up to and including autoconf inside the source          tree, just as you always have. Then type in the following          commands (assuming that the myapp subdirectory is the root          of your source tree):        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">$ cd ..$ mkdir build$ cd build$ ../myapp/configure$ make$ ./grumpalot        </PRE></TD></TR></TABLE><P>          The dynamically linked grumpalot executable should now          reside inside the build directory. If you wanted to test a          static build of grumpalot without pulverizing the current          dynamic build, you could create a new directory-          buildstatic, for example-and then invoke configure from          there, with the --disable-shared option. Presto! You now          have two copies of grumpalot on your system-one that          dynamically links to libGrump.so, and one that is statically          linked to libGrump.a-and both of them arise from the same          Makefile.am.        </P><P>          If you're following along diligently and trying each example          at the keyboard as you go, you probably came across a          problem in trying to run the dynamically linked case 3          grumpalot executable. Chances are, you got an error that          looks something like this:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">$ ./grumpalot./grumpalot: error in loading shared librarieslibGrump.so.0: cannot open shared object file: No such file or directory        </PRE></TD></TR></TABLE><P>          The problem is that libGrump.so.0 is tucked away in the          .libs directory, where your system's loader can't find          it. Rather than permanently adding temporary .libs          directories to your loader's search path for each project          you're testing, you can set the LD_LIBRARY_PATH environment          variable to a colon-separated list of extra library          paths. To run our case 3 grumpalot executable in the bash          shell, for example, you can invoke it like this, in the same          directory as grumpalot:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">$ LD_LIBRARY_PATH=.libs ./grumpalot        </PRE></TD></TR></TABLE><P>          This is only a problem if you try running grumpalot from          inside the build tree, prior to installing it. If you've          already installed grump with the make install target, things          should work fine, as long as you installed it into a path          that your system's dynamic link loader knows.        </P><P>          Our final concern for case 3 is how to install grump.h into          the include directory. We can do this in two lines in our          Makefile.am file:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">libgrumpdir = $(includedir)libgrump_HEADERS = grump.h        </PRE></TD></TR></TABLE><P>          The first line creates the arbitrarily named $(libgrumpdir)          variable, and sets it to point to $(includedir). This will          install all files listed in $(libgrump_HEADERS) into          $(includedir). This is good enough for our purposes in case          3. In some projects, however, you may not want all your          include files to go into the same directory. You can use a          similar approach to place header files into subdirectories          of $(includedir), or anywhere else for that matter. For          example, if our grump source tree had header files in the          subdirectories grump, grump/net, and grump/gui, we could          mirror this layout on the target system by adding something          like this to our Makefile.am file:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">libgrumpdir = $(includedir)/grumplibgrump_HEADERS = grump.hlibgrumpnetdir = $(includedir)/grump/netlibgrumpnet_HEADERS = grump-net.hlibgrumpguidir = $(includedir)/grump/guilibgrumpgui_HEADERS = grump-gui.h        </PRE></TD></TR></TABLE><P>          automake would see to it that the corresponding directories          were created and that the include files ended up in the          proper install location.        </P><P>          Our final case is a combination of cases 2 and 3, in which          we have both static and dynamic libaries in the same          project. The case 4 Makefile.am file has the same structure          as the one in case 3, except for a few additions (see          Listing 3.17). Most notably, we must add a          noinst_LTLIBRARIES target to build a new static library from          the grump_more.c source file. We'll call this new library          libGrumpMore.la. The _SOURCES and _LIBADD primaries for          libGrumpMore.la are almost identical to the ones we used for          the static library in case 2, except that we are linking          only one source file into it.        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.17 Makefile.am for Case 4 of GNOME Grump ExampleINCLUDES = $(GNOME_INCLUDEDIR)bin_PROGRAMS = grumpalotgrumpalot_SOURCES = main.cgrumpalot_LDADD = $(GNOME_LIBDIR) $(GNOMEUI_LIBS) \  -lGrump -L$(top_builddir)/.libsnoinst_LTLIBRARIES = libGrumpMore.lalib_LTLIBRARIES = libGrump.lalibGrump_la_DEPENDENCIES = libGrumpMore.lalibGrump_la_SOURCES = grump.clibGrump_la_LDFLAGS = -version-info 0:0:0libGrump_la_LIBADD = $(GNOME_LIBDIR) $(GNOMEUI_LIBS) \  libGrumpMore.lalibGrumpMore_la_SOURCES = grump_more.clibGrumpMore_la_LIBADD = $(GNOME_LIBDIR) $(GNOMEUI_LIBS)libgrumpdir = $(includedir)libgrump_HEADERS = grump.h        </PRE></TD></TR></TABLE><P>          The library targets will need a little work to convert them          from case 3 to case 4, but not much. First we remove          grump_more.c from libGrump_la_SOURCES, since it now resides          in the libGrumpMore.la library.  Next we add libGrumpMore.la          to libGrump_la_LIBADD, just as we added the static          libGrump.la to grump_LDADD in case 2. As a result, the          linker will statically link libGrumpMore.la into          libGrump.la so that we end up with only one distributable          library.        </P><P>          Our final tweak addresses a timing issue with the order of          compilation. We must make sure that our makefile creates          libGrumpMore.la before it tries to create          libGrump.la. Simply adding libGrumpMore.la to the          libGrump.la link line is not enough to generate a dependency          check. We must state the dependency explicitly, or we will          have no guarantee that libGrumpMore.la will exist when          libGrump.la needs it. We can do this with automake's          _DEPENDENCIES primary:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">libGrump_la_DEPENDENCIES = libGrumpMore.la        </PRE></TD></TR></TABLE><P>          The _DEPENDENCIES primary simply adds its contents to the          list of dependencies for the libGrump.la target in the          makefile, forcing make to build our libGrumpMore.la file          first.        </P></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLEWIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="dealing-with-libraries.html">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="graphics.html">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Dealing with Libraries</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="gnome-build.html">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Graphics</TD></TR></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -