将OpenMP与GCC静态链接

时间:2014-05-26 12:16:03

标签: gcc openmp static-linking

给出以下文件print.cpp

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

我可以像这样静态链接

g++ -static print.cpp

或者像这样

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

但现在让我们添加一点OpenMP并调用print_omp.cpp文件

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

我可以像这样静态链接(我用ldd检查了<)>

g++ -fopenmp -static print_omp.cpp

然而,这不起作用

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

我尝试了-Wl,--whole-archive -lpthread -Wl,--no-whole-archive和-lgomp -lpthread的各种组合,但没有运气(我遇到了链接到pthreads的各种问题)。有人可以解释如何在不使用-static选项的情况下执行此操作吗?

GCC says

  

在基于glibc的系统上,由于底层pthreads-implementation的限制,启用OpenMP的应用程序无法静态链接

但是,由于g++ -fopenmp -static print_omp.cpp工作正常,这对我来说没有意义。

编辑: 我想出了这个。图书馆GOMP附带GCC,而pthreads和libc来自GLIBC。所以我可以像这样静态链接GOMP

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

ldd显示

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)

但是,如果我试试这个

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

它不会链接。 Pthreads和libc必须静态链接。所以一旦我添加

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

ldd返回

not a dynamic executable

2 个答案:

答案 0 :(得分:3)

我真的不明白为什么你可能只想静态地链接libgomp,但是有单独的编译和链接命令可能有所帮助。例如,假设main.cpp包含:

#include <omp.h>
#include <stdio.h>

int main() { 
#pragma omp parallel
  {
    printf("%d\n", omp_get_thread_num());
  }
}

然后:

~/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)

答案 1 :(得分:1)

我发现的最干净的解决方案是修改/usr/local/lib64/libgomp.spec。我在*link_gomp: -l:libgomp.a %{static: -ldl } 。更改内容如下:

class