2007年9月21日 星期五

share/static library experience sharing

一般gcc compile 預設都是使用share library (libXXX.so.X), 除非compile時, gcc 加上 -static 或是直接將.a (libXXX.a) 和.o (object files)放在一起來link成execution file

如何看static library 的成員API 有哪些
# strings libpcap.a | grep pcap_findalldevs
pcap_findalldevs
pcap_findalldevs
pcap_findalldevs

Show the member symbols/variables/functions of shared library
# nm /usr/local/src/library/libpcap/libpcap-0.9.7/libpcap.so.0.9.7 | grep pcap_findalldevs
000052c0 T pcap_findalldevs

nm can show the shared library (libXXX.so.a.b.c) and static library (libYYY.a)

More verbose command with options
with -l, it will show the symbols/variables/functions appearing place(file name and line number) originally
with -o, it will print out the symbols/variables/functions belong to which library

show the symbols of the static library
# nm -o -l /usr/lib/libeXosip2.a 2> /dev/null | grep eXosip_init
/usr/lib/libeXosip2.a:eXconf.o:00001800 T eXosip_init /usr/local/src/sip/libeXosip2-3.0.3-3/src/eXconf.c:616

show the symbols of the shared library
# nm -o -l /usr/lib/libeXosip2.so.4.2.0 2> /dev/null | grep eXosip_init
/usr/lib/libeXosip2.so.4.2.0:0000c4ce T eXosip_init /usr/local/src/sip/libeXosip2-3.0.3-3/src/eXconf.c:616

If you have ever used to strip the static/shared library, all the symbols (functions/variables) inside the file will be deleted.
# strip /usr/lib/libeXosip2.a
# strip /usr/lib/libeXosip2.so.4.2.0

The type is displayed as a letter;
lowercase means that the symbol is local,
uppercase means that the symbol is global (external).

Typical symbol types include
T (a normal definition in the code section),
D (initialized data section),
B (uninitialized data section),
U (undefined; the symbol is used by the library but not defined by the library),
W (weak; if another library also defines this symbol, that definition overrides this one)



如何看某一個程式使用哪些shared library
# ldd zip
libc.so.6 => /lib/i686/libc.so.6 (0x42000000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xb7fee000)


Question: 下面這樣的程式編譯, 不是只要用到 static library 就可以了嗎? 為什麼還要用到 dynamic library?

# cat aaa.c
#include
#include

void main()
{
char errbuf[1024];
pcap_if_t *devices = NULL;
pcap_findalldevs(&devices, errbuf);
printf("ok\n");


# gcc -o aaa -lpcap aaa.c
aaa.c: In function `main':
aaa.c:5: warning: return type of `main' is not `int'
aaa.c:10:2: warning: no newline at end of file
/tmp/cc6CFwvH.o: In function `main':
/tmp/cc6CFwvH.o(.text+0x2f): undefined reference to `pcap_findalldevs' ==> 未定義 pcap_findalldevs, 因為libpcap.so.0 沒有包含這個API
collect2: ld returned 1 exit status

>>> libpcap static/shared library compiling procedures
# ./configure --prefix=/home/userName/usr --exec-prefix=/home/userName/usr --enable-yydebug

( DON'T set this parameter, --enable-optimizer-dbg, cause it will result the "dflag" variable in the optimize.c nondefined. And later if we compile other program will due to linking error...

my examples:
compile NSAT program...
g++ -Wall -O6 -funroll-loops -ansi -fPIC -DLINUX functions.o pidalloc.o nsat.o progress.o AuditSet.o SockSet.o Distributed.o Logging.o mod/binfo.o mod/bo.o mod/ftp.o mod/rpc.o mod/snmp.o mod/www.o mod/xp_icmp_addrmask.o mod/xp_icmp_timestamp.o mod/xp_pcap_iface.o mod/xp_utils.o mod/xp_icmp_echo.o mod/xp_logic_tree.o mod/xp_pkt_exams.o mod/xp_icmp_infr.o mod/xp_udp_probe.o libmix++/net/net.o libmix++/misc/misc.o libmix++/misc/exclude.o -o ../nsat -L/usr/X11R6/lib -L/home/userName/usr/lib -lX11 -lrpcsvc -lpcap
/home/userName/usr/lib/libpcap.so: undefined reference to `dflag'
)


make all
# make install
會編譯出來 libpcap.a static library
# make shared
# make install-shared
會編譯出來 libpcap.so.0.9.7 shared library

要真正編譯之前, 需要先到/usr/local/lib or /usr/lib 下面建立soft link 如下
ln -sf ./libpcap.so.0.9.7 ./libpcap.so

之後再去編譯程式就ok了

Or
{
# tar xvfz libpcap-1.0.0.tar.gz cd libpcap-1.0.0
# ./configure --prefix=/usr
# make shared all
# make install-shared install
# ln -sf /usr/lib/libpcap.so.1.0.0 /usr/lib/libpcap.so
# ln -sf /usr/lib/libpcap.so.1.0.0 /usr/lib/libpcap.so.1
}

[root@localhost src]# cat aaa.c
#include
#include

int main()
{
char errbuf[1024];
pcap_if_t *devices = NULL;
pcap_findalldevs(&devices, errbuf);
printf("ok\n");
return 0;
}
[root@localhost src]# gcc -o aaa -lpcap -L/usr/local/lib aaa.c
# ls aaa -la
-rwxr-x--- 1 root root 11769 Sep 21 17:45 aaa

成功編譯出 aaa 程式

How to use ldconfig to add the /usr/lib to the system permanently?
Use the following command to add the library path
PATH="$PATH:/sbin" ldconfig -n /usr/lib


openssl 編完 make install 之後秀出來的message, 告知我們如何做share library linking
* you link with static (archive) libraries. If you are truly
paranoid about security, you should use static libraries.
* you use the GNU libtool code during linking
(http://www.gnu.org/software/libtool/libtool.html)
* you use pkg-config during linking (this requires that
PKG_CONFIG_PATH includes the path to the OpenSSL shared
library directory), and make use of -R or -rpath.
(http://www.freedesktop.org/software/pkgconfig/)
* you specify the system-wide link path via a command such
as crle(1) on Solaris systems.
* you add the OpenSSL shared library directory to /etc/ld.so.conf
and run ldconfig(8) on Linux systems.

We can show all the searched directories that
# ldconfig -Nv | grep ":" | sed 's/:.*//'


* you define the LD_LIBRARY_PATH, LIBPATH, SHLIB_PATH (HP),
DYLD_LIBRARY_PATH (MacOS X) or PATH (Cygwin and DJGPP)
environment variable and add the OpenSSL shared library
directory to it.

One common tool to check the dynamic dependencies of an executable
or dynamic library is ldd(1) on most UNIX systems.

See any operating system documentation and manpages about shared
libraries for your version of UNIX. The following manpages may be
helpful: ld(1), ld.so(1), ld.so.1(1) [Solaris], dld.sl(1) [HP],
ldd(1), crle(1) [Solaris], pldd(1) [Solaris], ldconfig(8) [Linux],
chatr(1) [HP].
cp libcrypto.pc /tmp/newopenssl/lib/pkgconfig
chmod 644 /tmp/newopenssl/lib/pkgconfig/libcrypto.pc
cp libssl.pc /tmp/newopenssl/lib/pkgconfig
chmod 644 /tmp/newopenssl/lib/pkgconfig/libssl.pc
cp openssl.pc /tmp/newopenssl/lib/pkgconfig
chmod 644 /tmp/newopenssl/lib/pkgconfig/openssl.pc

沒有留言: