Statically linked executables?

How do I make a statically linked an executable? So far I have tried the following:

1.) Supply -Bstatic to the linking phase of compilation:
application builds fine, but is not statically linked. Instead it depends on shared libraries not avaliable on my target machine.
2.) Supply -Bstatic during linking and during the building of each executable.
results in the following errors:
/opt/pgi/linux86-64/6.0/lib/libstd.a(locale_impl.o)(.text+0x25): In function std::_STLP_mutex_base::_M_acquire_lock( (void))': : undefined reference to pthread_mutex_lock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(locale_impl.o)(.text+0x35): In function std::_STLP_mutex_base::_M_release_lock( (void))': : undefined reference to pthread_mutex_unlock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(locale_impl.o)(.text+0x67): In function std::_STLP_mutex_indirect::_M_initialize( (void))': : undefined reference to pthread_mutex_init’
/opt/pgi/linux86-64/6.0/lib/libstd.a(locale_impl.o)(.text+0x93): In function std::_STLP_mutex_indirect::_M_destroy( (void))': : undefined reference to pthread_mutex_destroy’
/opt/pgi/linux86-64/6.0/lib/libstd.a(monetary.o)(.text+0x25): In function std::_STLP_mutex_base::_M_acquire_lock( (void))': : undefined reference to pthread_mutex_lock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(monetary.o)(.text+0x35): In function std::_STLP_mutex_base::_M_release_lock( (void))': : undefined reference to pthread_mutex_unlock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(monetary.o)(.text+0x67): In function std::_STLP_mutex_indirect::_M_initialize( (void))': : undefined reference to pthread_mutex_init’
/opt/pgi/linux86-64/6.0/lib/libstd.a(monetary.o)(.text+0x93): In function std::_STLP_mutex_indirect::_M_destroy( (void))': : undefined reference to pthread_mutex_destroy’
/opt/pgi/linux86-64/6.0/lib/libstd.a(numpunct.o)(.text+0x25): In function std::_STLP_mutex_base::_M_acquire_lock( (void))': : undefined reference to pthread_mutex_lock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(numpunct.o)(.text+0x35): In function std::_STLP_mutex_base::_M_release_lock( (void))': : undefined reference to pthread_mutex_unlock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(collate.o)(.text+0x25): In function std::_STLP_mutex_base::_M_acquire_lock( (void))': : undefined reference to pthread_mutex_lock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(collate.o)(.text+0x35): In function std::_STLP_mutex_base::_M_release_lock( (void))': : undefined reference to pthread_mutex_unlock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(dll_main.o)(.text+0x25): In function std::_STLP_mutex_base::_M_acquire_lock( (void))': : undefined reference to pthread_mutex_lock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(dll_main.o)(.text+0x35): In function std::_STLP_mutex_base::_M_release_lock( (void))': : undefined reference to pthread_mutex_unlock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(num_get.o)(.text+0x25): In function std::_STLP_mutex_base::_M_acquire_lock( (void))': : undefined reference to pthread_mutex_lock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(num_get.o)(.text+0x35): In function std::_STLP_mutex_base::_M_release_lock( (void))': : undefined reference to pthread_mutex_unlock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(num_put.o)(.text+0x25): In function std::_STLP_mutex_base::_M_acquire_lock( (void))': : undefined reference to pthread_mutex_lock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(num_put.o)(.text+0x35): In function std::_STLP_mutex_base::_M_release_lock( (void))': : undefined reference to pthread_mutex_unlock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(time_facets.o)(.text+0x25): In function std::_STLP_mutex_base::_M_acquire_lock( (void))': : undefined reference to pthread_mutex_lock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(time_facets.o)(.text+0x35): In function std::_STLP_mutex_base::_M_release_lock( (void))': : undefined reference to pthread_mutex_unlock’
/opt/pgi/linux86-64/6.0/lib/libstd.a(ctype.o)(.text+0x27): In function std::_STLP_mutex_indirect::_M_initialize( (void))': : undefined reference to pthread_mutex_init’
/opt/pgi/linux86-64/6.0/lib/libstd.a(ctype.o)(.text+0x53): In function std::_STLP_mutex_indirect::_M_destroy( (void))': : undefined reference to pthread_mutex_destroy’

Hi CEPman,

Adding “-Bstatic” to the link line should work for most cases (it’s not valid with “-fpic” or “-mcmodel=medium”), so something else is going on. The second case is most likely missing “-lpthread” and is why your getting the undefined reference errors.

Could you post the following:

  1. The command line you use to link the files (omit the objects files if it’s very long or if your concerned about privacy).
  2. Add “-v” to you link line, and post the command passed to the linker (/usr/bin/ld).
  3. The output of the command "ldd "

This should help us narrow down where the problem is coming from.

Thanks,
Mat

Here are the results from case 1:

g77 -c -fno-globals -g -o SLAP/dir.o SLAP/dir.f
...
g77 -c -fno-globals -g -o SLAP/domn.o SLAP/domn.f
/opt/pgi/linux86-64/6.0/bin/pgCC  -g  -I. -I./IonicModels -D LINUX  -DMEMFEM -D_DEBUG -c  -o dludcmp.o dludcmp.c
...
/opt/pgi/linux86-64/6.0/bin/pgCC  -g  -I. -I./IonicModels -D LINUX  -DMEMFEM -D_DEBUG -c  -o IonicModels/LRdModel.o IonicModels/LRdModel.cc

All of which compile fine. Here is the linking command an subequent output:

/opt/pgi/linux86-64/6.0/bin/pgCC -o memfem  -g  -I. -I./IonicModels -D LINUX  -DMEMFEM -D_DEBUG <object files> -lm -lblas -lg2c  -Bstatic -v


/usr/bin/ld /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.3/crtbegin.o -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 <object files> -o memfem -L/opt/pgi/linux86-64/6.0/lib -L/usr/lib64 -L/usr/lib64/gcc-lib/x86_64-suse-linux/3.3.3 -rpath /opt/pgi/linux86-64/6.0/lib -lm -lblas -lg2c -Bstatic -lstd -lC -lc -lnspgc -lpgc -lm -lgcc -lc -lgcc /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.3/crtend.o /usr/lib64/crtn.o

Our compilers are running on AMD Opterons using EM64T.

The command exists successfully, but the binary is not statically linked:

$ bpsh $NODES ./memfem
./memfem: error while loading shared libraries: libg2c.so.0: cannot open shared object file: No such file or directory

The binary needs to run on a Beowolf cluster where every node has only the basic glibc libraries loaded into a filesystem mounted in memory. To run on the cluster, all binaries need to be statically linked.

Perhaps there is some confusion: In what ways does -Bstatic for pgCC differ from -static in g++? -static in g++ works just fine.

Case 2 surprises me, because
a.) my application doesn’t use pthreads (unless -lblas, -m or -g2c use pthreads wthout my knowledge)
b.) The only difference between case 1 and case 2 is that I put -Bstatic, a linking flag, on the follwing lines like so:

/opt/pgi/linux86-64/6.0/bin/pgCC  -g  -Bstatic -I. -I./IonicModels -D LINUX  -DMEMFEM -D_DEBUG -c  -o dludcmp.o dludcmp.c
...
/opt/pgi/linux86-64/6.0/bin/pgCC  -g  -Bstatic -I. -I./IonicModels -D LINUX  -DMEMFEM -D_DEBUG -c  -o IonicModels/LRdModel.o IonicModels/LRdModel.cc

c.) Uing -static with g++ works just fine. That means that if my library does depend on pthreads indirectly, why does gcc succeed where pgCC fails?

Hi CEPman,

“-Bstatic” is order dependant and needs to be put before all libraries that are to be statically linked. The g2c library is being dynamically linked since it appears before “-Bstatic”. Try the following command:

/opt/pgi/linux86-64/6.0/bin/pgCC -o memfem -g  -I. -I./IonicModels -D LINUX  -DMEMFEM -D_DEBUG <object files> -Bstatic -lm -lblas -lg2c  -v

I believe the difference between g++ and pgCC here is that pgCC will leave “-Bstatic” where you put it while g++ moves “-static” before all the libraries. The advantage to the pgCC method is that you can mix “-Bstatic” with “-Bdynamic” to specify exactly which libraries to include statically and which to include dynamically.

As for case 2, this is strange to me as well. “-Bstatic” is a linker flag and the compiler simply passes it along. So compiling with “-Bstatic” shouldn’t effect anything. Hopefully it’s a moot point and the above solution works for you.

Thanks,
Mat

Hi Mat,

When I added -Bstatic as the first flag to my linking command, I got the same errors as case 2. It turns out that adding -Bstatic to my compilation commands had a side effect of adding -Bstatic much eariler in my linking command, due to the way my Makefile is constructed.

When I link pthreads to my application, everything compiles fine. I still don’t know why my application suddenly depends on pthreads, but at least I can test the program now.

Thank you for all your help.