linking OpenMP statically with GCC

匿名 (未验证) 提交于 2019-12-03 01:03:01

问题:

Given the following file print.cpp

#include <stdio.h> int main() {      printf("asdf\n"); } 

I can link this statically like this

g++ -static print.cpp 

or like this

g++ -static-libgcc -Wl,-Bstatic -lc print.cpp -o print 

But now let's add a little OpenMP and call the file print_omp.cpp

#include <omp.h> #include <stdio.h> int main() {      printf("%d\n", omp_get_num_threads()); } 

I can link this statically like this (I checked it with ldd)

g++ -fopenmp -static print_omp.cpp 

However, this does not work

g++ -fopenmp -static-libgcc -Wl,-Bstatic -lc print_omp.cpp -o print 

I have tried various combinations of -Wl,--whole-archive -lpthread -Wl,--no-whole-archive and -lgomp -lpthread but no luck (I get various problems linking to pthreads). Can someone explain how I can do this without using the -static option?

GCC says

On glibc-based systems, OpenMP enabled applications cannot be statically linked due to limitations of the underlying pthreads-implementation

However, since g++ -fopenmp -static print_omp.cpp works just fine this does not make sense to me.

Edit: I figured this out. The library GOMP comes with GCC whereas pthreads and libc come from GLIBC. So I can link GOMP statically like this

ln -s `g++ -print-file-name=libgomp.a` g++ foo.cpp -static-libgcc -static-libstdc++ -L. -o foo -O3 -fopenmp 

ldd shows

linux-vdso.so.1 =>  (0x00007fff71dbe000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc231923000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc23155c000) /lib64/ld-linux-x86-64.so.2 (0x00007fc231b5c000) 

However, if I the try this

ln -s `g++ -print-file-name=libpthread.a` g++ foo.cpp -static-libgcc -static-libstdc++ -L. -o foo -O3 -fopenmp 

It won't link. Pthreads and libc must be linked statically together. So once I add

ln -s `g++ -print-file-name=libc.a` g++ foo.cpp -static-libgcc -static-libstdc++ -L. -o foo -O3 -fopenmp 

ldd returns

not a dynamic executable 

回答1:

I really don't get why you may want to link only libgomp statically, but having separate compilation and linking commands may help. For instance assume main.cpp contains:

#include <omp.h> #include <stdio.h>  int main() {  #pragma omp parallel   {     printf("%d\n", omp_get_thread_num());   } } 

Then:

~/tmp$ ls main.cpp ~/tmp$ g++  -Wall -Werror -pedantic  -fopenmp main.cpp  -c ~/tmp$ ls main.cpp  main.o ~/tmp$ locate libgomp.a ${SOME_PATH_TO_LIBGOMP}/libgomp.a ~/tmp$ g++  -Wall -Werror -pedantic main.o -o main.x ${SOME_PATH_TO_LIBGOMP}/libgomp.a -pthread ~/tmp$ ls main.cpp  main.o  main.x ~/tmp$ ldd main.x     linux-gate.so.1 =>  (0xb7747000)     libstdc++.so.6 => /production/install/gnu/compiler/gcc/lib/libstdc++.so.6 (0xb765c000)     libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb75fa000)     libgcc_s.so.1 => /production/install/gnu/compiler/gcc/lib/libgcc_s.so.1 (0xb75de000)     libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb75c2000)     libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7413000)     /lib/ld-linux.so.2 (0xb7748000) 


回答2:

The most clean solution I've found for this is by modifying the libgomp.spec. Mine is at /usr/local/lib64/libgomp.spec. Change the content as follow:

*link_gomp: -l:libgomp.a %{static: -ldl } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!