Статическая связь OpenMP с GCC
Учитывая следующий файл 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
вариант?
В системах на основе glibc приложения с поддержкой OpenMP не могут быть статически связаны из-за ограничений базовой реализации pthreads
Тем не менее, так как 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
лдд шоу
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
лдд возвращается
not a dynamic executable
2 ответа
Я действительно не понимаю, почему вы можете ссылаться только на 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)
Самым чистым решением, которое я нашел для этого, является изменение libgomp.spec
, Мой в /usr/local/lib64/libgomp.spec
, Измените содержимое следующим образом:
*link_gomp: -l:libgomp.a %{static: -ldl }