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

📄 dealing-with-libraries.html

📁 linux下gnome编程
💻 HTML
📖 第 1 页 / 共 2 页
字号:
></TR></TABLE><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 3.6 Makefile.am for grumpalotbin_PROGRAMS=grumpalotgrumpalot_SOURCES=main.cgrumpalot_LDADD=libgrump.lagrumpalot_LDFLAGS=include_HEADERS=grump.hlib_LTLIBRARIES=libgrump.lalibgrump_la_SOURCES=grump.clibgrump_la_LDFLAGS=-version-info 0:0:0        </PRE></TD></TR></TABLE><P>          We'll have to run several commands to set things up and then          compile it all into the target grumpalot executable. All of          these commands should look familiar by now. If not, you          should probably go back and read this chapter again. It may          seem like a lot of typing, but think of all the wonderful          magic that goes on behind the scenes. It would take you          weeks of extra work to duplicate all that. To make things          even easier, GNOME projects often wrap all these commands up          into a single shell script for us, called autogen.sh. We'll          learn more about that in Section 3.5.4. Here are the          commands you need to compile the example, with the output of          the build tools snipped for clarity:        </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$ ./grumpalotOh, bother!...Go away!Be gone!Not again!Not again!Go away!        </PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN543">Exploring the Results</A></H2><P>          Let's see what libtool has done for us. First, it looks as          if libtool has created a .libs subdirectory, filled with          every possible incarnation of our libgrump library,          including libgrump.a, libgrump.la, and libgrump.so. Another          curious fact surfaces when we look at the .libs directory:          It also contains a grumpalot file! We have two          executables-one in the main directory, and one hidden away          with the library files. Let's snoop around and see if we can          figure out what's going on. We'll start with the file          command, a handy little utility that cracks open a file,          examines it, and prints out what it finds.        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">$ file grumpalotgrumpalot: Bourne shell script text$ file .libs/grumpalot.libs/grumpalot: ELF 32-bit LSB executable, Intel 80386, version 1, dynamically linked,not stripped        </PRE></TD></TR></TABLE><P>          It appears that libtool has generated some sort of wrapper          script around the real executable, which is in the .libs          directory. It does this to make sure the executable can          properly find and load the shared libraries, even though the          shared libraries haven't been installed yet. The wrapper          script performs a little fancy juggling of paths that          wouldn't normally be necessary with installed libraries;          it then invokes the executable in .libs for us. In most          cases,2 we can simply invoke the wrapper script as if it          were the real executable, passing all the normal command          line parameters to it.        </P><P>          Let's find out where the object code for our various grump_*          functions ended up. We can make use of another common UNIX          tool, nm, a utility for dumping the symbol tables of an          object file or executable into a legible ASCII format. The          output of nm can be voluminous, especially on larger binary          files, so we'll pipe the results through grep to filter out          the symbols we don't care about.        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">$ nm .libs/grumpalot | grep grump         U grump_a_lot_more         U grump_some$ nm .libs/libgrump.so | grep grump000008a4 T grump_a_lot_more00000880 T grump_some        </PRE></TD></TR></TABLE><P>          The nm utility uses a handful of single-letter codes to          characterize each symbol. The documentation for nm contains          a pretty good description of what they all mean. In our          case, the libgrump symbols in the binary executable          grumpalot are undefined (U). This is normal for any symbols          imported from a library into an executable or another          library, where the symbols are referenced but not          implemented. In libgrump itself, the symbols are marked with          a T, which means that nm found their implementations inside          the text (or code) section of the library file. The          addresses indicate exactly where in the code section the          symbols reside. You can find out more about nm by typing          info binutils at the command line of a GNU-equipped system          and then going into the nm documentation.        </P><P>          Next we'll see how things change with static libraries. We          can do this with the --disable-shared flag. We'll have to          clean out the old object files to make sure everything          recompiles correctly.        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">$ ./configure --disable-shared$ make clean &#38;&#38; make all$ file grumpalotgrumpalot: ELF 32-bit LSB executable, Intel 80386, version 1,dynamically linked, not stripped$ nm grumpalot | grep grump08048634 T grump_a_lot_more08048620 T grump_some        </PRE></TD></TR></TABLE><P>          Things are a lot simpler this time. The .libs directory          contains only static libraries. The .so files are gone, as          is the .libs/grumpalot executable. As we see by the file          command, the top-level grumpalot is now the real executable.          libtool puts the executable in the .libs directory only when          it's creating shared libraries.        </P><P>          Finally, to ease our minds we verify that the libgrump          functions are linked directly into the executable. Notice          how much larger the symbol addresses are when they are          statically linked into the executable. The reason is that          the symbols have absolute addresses when they reside in          the executable but relative addresses when inside the shared          library. The relative addresses make it possible to load          shared libraries into different parts of an executable's          memory. If a shared library tries to load itself into an          area of memory that's already taken, the library loader can          dynamically relocate it to another area.        </P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN555">A Note about Version Numbers</A></H2><P>          The path to creating new versions of shared libraries can be          a twisted, precarious maze. You have to juggle          distribution versions with library versions. The main          software package might go through major alterations without          a single change to the supporting libraries, and vice          versa. It's dangerous to mix package version numbers with          library versions because the two are not synony-          mous. Package versions are fairly arbitrary, and mostly for          the end user's benefit. Shared-library versions, however,          refer to very specific changes in functionality. The dynamic          library loader uses this version number to determine which          implementation of the library to load. If you have only one          libgrump.so file, the choice is easy. On UNIX, however, it's          possible to have many versions of the same library in the          same directory at the same time. The library version number          is the loader's only hope for finding the correct library          for a given application.        </P><P>          You can set the version for a library with an _LDFLAGS          primary in your Makefile.am file, with the -version-info          flag:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">libgrump_la_LDFLAGS=-version-info 5:1:2        </PRE></TD></TR></TABLE><P>          The three numbers stand for CURRENT:REVISION:AGE, or C:R:A          for short.  The libtool script typically tacks these three          numbers onto the end of the name of the .so file it          creates. The formula for calculating the file numbers on          Linux and Solaris is (C - A).(A).(R), so the example given          here would create the file libgrump.so.3.2.1. Other          operating systems might use a different library file name          convention; libtool takes care of the details.        </P><P>          As you release new versions of your library, you will update          the library's C:R:A. Although the rules for changing these          version numbers can quickly become confusing, a few simple          tips should help keep you on track. The libtool          documentation goes into greater depth.        </P><P>          In essence, every time you make a change to the library and          release it, the C:R:A should change. A new library should          start with 0:0:0. Each time you change the public interface          (i.e., your installed header files), you should increment          the CURRENT number. This is called your interface          number. The main use of this interface number is to tag          successive revisions of your API.        </P><P>          The AGE number is how many consecutive versions of the API          the current implementation supports. Thus if the CURRENT          library API is the sixth published version of the          interface and it is also binary compatible with the fourth          and fifth versions (i.e., the last two), the C:R:A might be          6:0:2. When you break binary compatibility, you need to set          AGE to 0 and of course increment CURRENT.        </P><P>          The REVISION marks a change in the source code of the          library that doesn't affect the interface-for example, a          minor bug fix. Anytime you increment CURRENT, you should          set REVISION back to 0.        </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="generating-makefiles.html">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="adding-gnome.html">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Generating Makefiles</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="gnome-build.html">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Adding GNOME</TD></TR></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

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