Static Linking on AIX

本文详细描述了在使用IBM Visual Age 5 for AIX 5.1环境中,进行C++程序静态链接遇到的问题及解决方案。包括无法静态链接libc、Zlib和Oracle OCI库,以及如何通过特定选项和系统文件解决这些问题,实现程序的静态链接。

转自:http://blog.firetree.net/2005/07/21/static-linking-on-aix/

 

Static Linking on AIX

I’ve spent the last several hours trying to link a C++ program statically on our ageing AIX machine. As I’ve come to expect from IBM’s compiler – nothing’s ever that simple. What did I expect? They don’t even provide a man page, and the linker always kicks out thousands of irrelevant warnings by design.

The system is running IBM VisualAge 5 on AIX 5.1. I said it was ageing.

Always finish with -bdynamic

Dynamic linking (-bdynamic) is the default for AIX’s xlC compiler. The documentation says that the -bstatic option turns on static linking. OK, but try using this option and you get dozens of ‘undefined symbol’ errors for symbols that should be defined in libc:

ld: 0711-317 ERROR: Undefined symbol: errno
ld: 0711-317 ERROR: Undefined symbol: _exit
ld: 0711-317 ERROR: Undefined symbol: open

 

Apparently, you can’t link  libc statically. Here’s the relevant quote, hidden away on page 102 of  some blasted PDF:

 

To avoid possible problems with unresolved linker errors when linking the C library, you must add the -bdynamic option to the end of any compilation sections that use the -bstatic option.

Note: Actually the documentation says you can statically link libc, but you might not want to. That said, I’ve not been able to make it work. See below for the secret.

ranlib libz.a

I had trouble with linking Zlib of all things. I got these six severe errors:

ld: 0711-212 SEVERE ERROR: Symbol .__divus, found in the global symbol table
        of archive /lib/libz.a, was not defined in archive member libz.so.1.
ld: 0711-212 SEVERE ERROR: Symbol __divus, found in the global symbol table
        of archive /lib/libz.a, was not defined in archive member libz.so.1.
ld: 0711-212 SEVERE ERROR: Symbol .__mulh, found in the global symbol table
        of archive /lib/libz.a, was not defined in archive member libz.so.1.
ld: 0711-212 SEVERE ERROR: Symbol __mulh, found in the global symbol table
        of archive /lib/libz.a, was not defined in archive member libz.so.1.
ld: 0711-212 SEVERE ERROR: Symbol .__quous, found in the global symbol table
        of archive /lib/libz.a, was not defined in archive member libz.so.1.
ld: 0711-212 SEVERE ERROR: Symbol __quous, found in the global symbol table
        of archive /lib/libz.a, was not defined in archive member libz.so.1.

AIX’s libz.a is at fault. Simply running ranlib on it fixes the problem. You have to make a copy first, since the current one may be in use and therefore locked:

# cd /lib
# cp libz.a libz.a.new
# ranlib libz.a.new
# mv libz.a libz.a.old && mv libz.a.new libz.a

Oracle OCI Library

So how on earth do you link Oracle’s OCI library statically on AIX? Here are the errors:

ld: 0711-317 ERROR: Undefined symbol: pw_wait
ld: 0711-317 ERROR: Undefined symbol: pw_post
ld: 0711-317 ERROR: Undefined symbol: pw_config
ld: 0711-317 ERROR: Undefined symbol: aix_ora_pw_version3_required
ld: 0711-317 ERROR: Undefined symbol: ksmsgl_
ld: 0711-317 ERROR: Undefined symbol: kcbkclx_

Naturally there’s no documentation provided by Oracle, but digging around in the OCI examples reveals the following two options:

  -bI:$(ORACLE_HOME)/lib/pw-syscall.exp
  -bI:$(ORACLE_HOME)/lib/ksms.imp

The -bI option isn’t even mentioned in IBM’s ‘documentation’ for xlC. However, I think it just points to a file that lists symbols to import. I don’t have the inclination to explore that further right now.

UPDATE!!

I’ve belatedly discovered that Oracle provide a (little known) static library:libclntst9.a. (For Oracle 10, the library would be libclntst10.a and so on.) Naturally you’d imagine that you can simply add that to your link line as -lclntst. Well, nearly. You need to include a few other libraries too. On Linux the link line is:

-lclntst9 -lnsl -ldl -lm

For Solaris, you need a few more libraries:

-lclntst9 -lnsl -lsocket -lgen -ldl -laio -lkstat -lm

Thanks to Josh Chu on the Oracle Forums.

static libc

A bit of exploration in the man page for ld reveals the following:

To link a program using the libc.a library as a non-shared library, enter:

cc -o pgm pgm.o -bnso -bI:/lib/syscalls.exp

However this comes with the following warning:

Any application that is statically linked is NOT binary portable from any fix or release level to any other fix or release level.

nso stands for no shared objects, so this sounds promising. However, the file/lib/syscalls.exp is not to be found on my system, so I suppose I’ll never know whether this works or not.

 

COMMENT · RSS · TRACKBACK

  1. michael said,

    19 January, 2006 @ 23:29

    did you ever get/find a copy of /lib/syscalls.exp ???????

  2. alex said,

    24 January, 2006 @ 23:19

    michael: No, I’m afaid not. We looked through all of the system packages, but the file was nowhere to be found. Perhaps it’s only to be found on a more recent version of AIX. I’m still stuck on v5.1.

    Frankly, I wasn’t that bothered about statically linking libc. The calls interface to libc is probably more stable than the OS-level interface, so why would you want to statically link it? My goal was binary portability, which is probably better served by dynamically linked libc.

    I suppose there may be paranoid security reasons for wanting to statically link…

  3. Jonas said,

    26 January, 2006 @ 14:29

    FYI: I just managed to link libc statically using the example above. The system is running AIX 4.3.3.

  4. Sébastien said,

    31 January, 2006 @ 15:51

    On my system, it seems like the /lib/syscalls.exp file comes from the bos.adt.syscalls fileset :

    ls -l /lib/syscalls.exp
    lrwxrwxrwx  1  bin  bin  21 Sep  2 19:52 /lib/syscalls.exp@ -> /usr/lib/syscalls.imp
    
    lslpp -w /usr/lib/syscalls.exp
    File                    Fileset            Type
    -----------------------------------------------------
    /usr/lib/syscalls.exp   bos.adt.syscalls   Symlink
    

    Hope this’ll help

  5. alex said,

    21 February, 2006 @ 16:21

    UPDATE!!

    I’ve added some extra text about Oracle’s libclntst.a static library.

  6. Blaise said,

    16 June, 2006 @ 10:53

    I’ve the same problem. The hint to install bos.adt.syscalls helped!

  7. Yogesh said,

    30 June, 2007 @ 08:40

    Thanks, Nice artical .. i am able to compile static binaries with this informetion.

Leave a Comment

gezi@ubuntu:~/study/pubilc/camerademo6/curl-8.7.1$ ./configure --host=arm-linux-gnueabi --prefix=/home/gezi/study/pubilc/camerademo6/curl_arm --with-openssl checking whether to enable maintainer-specific portions of Makefiles... no checking whether make supports nested variables... yes checking whether to enable debug build options... no checking whether to enable compiler optimizer... (assumed) yes checking whether to enable strict compiler warnings... no checking whether to enable compiler warnings as errors... no checking whether to enable curl debug memory tracking... no checking whether to enable hiding of library internal symbols... yes checking whether to enable c-ares for DNS lookups... no checking whether to disable dependency on -lrt... (assumed no) checking whether to enable ECH support... no checking for path separator... : checking for sed... /bin/sed checking for grep... /bin/grep checking that grep -E works... yes checking for arm-linux-gnueabi-ar... /usr/bin/arm-linux-gnueabi-ar checking for a BSD-compatible install... /usr/bin/install -c checking for arm-linux-gnueabi-gcc... arm-linux-gnueabi-gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... yes checking for suffix of object files... o checking whether the compiler supports GNU C... yes checking whether arm-linux-gnueabi-gcc accepts -g... yes checking for arm-linux-gnueabi-gcc option to enable C11 features... none needed checking whether arm-linux-gnueabi-gcc understands -c and -o together... yes checking how to run the C preprocessor... arm-linux-gnueabi-gcc -E checking for stdio.h... yes checking for stdlib.h... yes checking for string.h... yes checking for inttypes.h... yes checking for stdint.h... yes checking for strings.h... yes checking for sys/stat.h... yes checking for sys/types.h... yes checking for unistd.h... yes checking for stdatomic.h... yes checking if _Atomic is available... yes checking for a sed that does not truncate output... (cached) /bin/sed checking for code coverage support... no checking whether build environment is sane... yes checking for arm-linux-gnueabi-strip... arm-linux-gnueabi-strip checking for a race-free mkdir -p... /bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking whether make supports the include directive... yes (GNU style) checking dependency style of arm-linux-gnueabi-gcc... gcc3 checking curl version... 8.7.1 checking for httpd... no checking for apache2... no checking for apachectl... no checking for apxs... no configure: httpd/apache2 not in PATH, http tests disabled configure: apxs not in PATH, http tests disabled checking for nghttpx... no checking for caddy... no checking build system type... x86_64-pc-linux-gnu checking host system type... arm-unknown-linux-gnueabi checking for grep that handles long lines and -e... (cached) /bin/grep checking for egrep... /bin/grep -E checking if OS is AIX (to define _ALL_SOURCE)... no checking if _THREAD_SAFE is already defined... no checking if _THREAD_SAFE is actually needed... no checking if _THREAD_SAFE is onwards defined... no checking if _REENTRANT is already defined... no checking if _REENTRANT is actually needed... no checking if _REENTRANT is onwards defined... no checking for special C compiler options needed for large files... no checking for _FILE_OFFSET_BITS value needed for large files... 64 checking how to print strings... printf checking for a sed that does not truncate output... (cached) /bin/sed checking for fgrep... /bin/grep -F checking for ld used by arm-linux-gnueabi-gcc... /usr/arm-linux-gnueabi/bin/ld checking if the linker (/usr/arm-linux-gnueabi/bin/ld) is GNU ld... yes checking for BSD- or MS-compatible name lister (nm)... /usr/bin/arm-linux-gnueabi-nm -B checking the name lister (/usr/bin/arm-linux-gnueabi-nm -B) interface... BSD nm checking whether ln -s works... yes checking the maximum length of command line arguments... 1572864 checking how to convert x86_64-pc-linux-gnu file names to arm-unknown-linux-gnueabi format... func_convert_file_noop checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop checking for /usr/arm-linux-gnueabi/bin/ld option to reload object files... -r checking for arm-linux-gnueabi-file... no checking for file... file configure: WARNING: using cross tools not prefixed with host triplet checking for arm-linux-gnueabi-objdump... arm-linux-gnueabi-objdump checking how to recognize dependent libraries... pass_all checking for arm-linux-gnueabi-dlltool... no checking for dlltool... no checking how to associate runtime and link libraries... printf %s\n checking for arm-linux-gnueabi-ar... /usr/bin/arm-linux-gnueabi-ar checking for archiver @FILE support... @ checking for arm-linux-gnueabi-strip... (cached) arm-linux-gnueabi-strip checking for arm-linux-gnueabi-ranlib... arm-linux-gnueabi-ranlib checking command to parse /usr/bin/arm-linux-gnueabi-nm -B output from arm-linux-gnueabi-gcc object... ok checking for sysroot... no checking for a working dd... /bin/dd checking how to truncate binary pipes... /bin/dd bs=4096 count=1 checking for arm-linux-gnueabi-mt... no checking for mt... mt checking if mt is a manifest tool... no checking for dlfcn.h... yes checking for objdir... .libs checking if arm-linux-gnueabi-gcc supports -fno-rtti -fno-exceptions... no checking for arm-linux-gnueabi-gcc option to produce PIC... -fPIC -DPIC checking if arm-linux-gnueabi-gcc PIC flag -fPIC -DPIC works... yes checking if arm-linux-gnueabi-gcc static flag -static works... yes checking if arm-linux-gnueabi-gcc supports -c -o file.o... yes checking if arm-linux-gnueabi-gcc supports -c -o file.o... (cached) yes checking whether the arm-linux-gnueabi-gcc linker (/usr/arm-linux-gnueabi/bin/ld) supports shared libraries... yes checking whether -lc should be explicitly linked in... no checking dynamic linker characteristics... GNU/Linux ld.so checking how to hardcode library paths into programs... immediate checking whether stripping libraries is possible... yes checking if libtool supports shared libraries... yes checking whether to build shared libraries... yes checking whether to build static libraries... yes checking whether to build shared libraries with -version-info... yes checking whether to build shared libraries with -no-undefined... no checking whether to build shared libraries with -mimpure-text... no checking whether to build shared libraries with PIC... yes checking whether to build static libraries with PIC... no checking whether to build shared libraries only... no checking whether to build static libraries only... no checking for arm-linux-gnueabi-windres... no checking for windres... no checking for inline... inline checking if cpp -P is needed... yes checking if cpp -P works... yes checking if compiler is DEC/Compaq/HP C... no checking if compiler is HP-UX C... no checking if compiler is IBM C... no checking if compiler is Intel C... no checking if compiler is clang... no checking if compiler is GNU C... yes checking compiler version... gcc '700' (raw: '7') checking if compiler is SGI MIPSpro C... no checking if compiler is SGI MIPS C... no checking if compiler is SunPro C... no checking if compiler is Tiny C... no checking whether build target is a native Windows one... no checking if compiler accepts some basic options... yes configure: compiler options added: -Werror-implicit-function-declaration checking if compiler optimizer assumed setting might be used... yes checking if compiler accepts optimizer enabling options... yes configure: compiler options added: -O2 checking if compiler accepts strict warning options... yes configure: compiler options added: -Wno-system-headers checking if compiler halts on compilation errors... yes checking if compiler halts on negative sized arrays... yes checking if compiler halts on function prototype mismatch... yes checking if compiler supports hiding library internal symbols... yes checking whether build target supports WIN32 file API... no checking whether build target supports WIN32 crypto API... no checking for good-to-use Darwin CFLAGS... no checking whether to link macOS CoreFoundation, CoreServices, and SystemConfiguration frameworks... no checking to see if the compiler supports __builtin_available()... no checking whether to support http... yes checking whether to support ftp... yes checking whether to support file... yes checking whether to support ldap... yes checking whether to support ldaps... yes checking whether to support rtsp... yes checking whether to support proxies... yes checking whether to support dict... yes checking whether to support telnet... yes checking whether to support tftp... yes checking whether to support pop3... yes checking whether to support imap... yes checking whether to support smb... yes checking whether to support smtp... yes checking whether to support gopher... yes checking whether to support mqtt... no checking whether to build documentation... yes checking whether to provide built-in manual... yes checking whether to enable generation of C code... yes checking whether to use libgcc... no checking if X/Open network library is required... no checking for gethostbyname... yes checking whether build target is a native Windows one... (cached) no checking for proto/bsdsocket.h... no checking for connect in libraries... yes checking for sys/types.h... (cached) yes checking for sys/time.h... yes checking for monotonic clock_gettime... yes checking for clock_gettime in libraries... no additional lib required checking for sys/types.h... (cached) yes checking for sys/time.h... (cached) yes checking for raw monotonic clock_gettime... yes checking for arm-linux-gnueabi-pkg-config... no checking for pkg-config... /usr/bin/pkg-config checking for zlib options with pkg-config... found checking for zlib.h... yes configure: found both libz and libz.h header checking for BrotliDecoderDecompress in -lbrotlidec... no checking for brotli/decode.h... no checking for ZSTD_createDStream in -lzstd... no checking for zstd.h... no checking for lber.h... no checking for ldap.h... no checking for ldap_ssl.h... no checking for LDAP libraries... cannot find LDAP libraries configure: WARNING: Cannot find libraries for LDAP support: LDAP disabled checking whether to enable IPv6... yes checking if struct sockaddr_in6 has sin6_scope_id member... yes checking if argv can be written to... no configure: WARNING: the previous check could not be made default was used checking if GSS-API support is requested... no checking whether to enable Windows native SSL/TLS... no checking whether to enable Secure Transport... no checking whether to enable Amiga native SSL/TLS (AmiSSL v5)... no checking for arm-linux-gnueabi-pkg-config... /usr/bin/pkg-config checking for openssl options with pkg-config... found configure: pkg-config: SSL_LIBS: "-lssl -lcrypto" configure: pkg-config: SSL_LDFLAGS: "" configure: pkg-config: SSL_CPPFLAGS: "" checking for HMAC_Update in -lcrypto... no checking for HMAC_Init_ex in -lcrypto... no checking OpenSSL linking with -ldl... no checking OpenSSL linking with -ldl and -lpthread... no checking for SSL_set_quic_use_legacy_codepoint... no configure: OpenSSL version does not speak QUIC API configure: OPT_OPENSSL: yes configure: OPENSSL_ENABLED: configure: error: --with-openssl was given but OpenSSL could not be detected
10-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值