Я использую LLD8 LLVM для замены GNU-LD для повышения скорости соединения. Но когда я делаю .so файл, в режиме выпуска возникает странная ошибка. После оптимизации я воспроизвел эту проблему на простом примере.
test.h:
#ifndef TEST_H
#define TEST_H
inline int func(){
static __thread int i = 1;
return i;
}
void handle();
#endif
test.cpp
#include <iostream>
#include <stdio.h>
#include "test.h"
void handle() {
std::cout << func() << std::endl;
}
main.cpp
#include "test.h"
void x(){
handle();
}
Следующие cmds скопированы из make V = 1 stdout в моем проекте, я сохраняю эти cmds в скрипт и компилирую мой пример файла
скомпилировать lib:
$dpath/bin/g++ -DLT_OBJDIR=\".libs/\" -I. -I$dpath/include/ -w -std=gnu++11 -g -O2 -D_GLIBCXX_USE_CXX11_ABI=0 -D_NO_EXCEPTION -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -Wall -Werror -Wextra -Wunused-parameter -Wformat -Wconversion -Wno-deprecated -Wno-invalid-offsetof -finline-functions -fno-strict-aliasing -mtune=core2 -Wno-psabi -Wno-sign-compare -Wno-literal-suffix -DGCC_52 -DUSE_POSIX_FALLOCATE -DSUPPORT_SSE4_2 -DHAVE_SCHED_GETCPU -DHAVE_REALTIME_COARSE -DHAVE_FALLOCATE -c test.cpp -fPIC -DPIC -o .libs/test.o
ссылка lib
ar cru .libs/lib.a .libs/test.o
ranlib .libs/lib.a
компилировать файлы
$dpath/bin/g++ -DLT_OBJDIR=\".libs/\" -I. -I$dpath/include -std=gnu++11 -g -O2 -D_GLIBCXX_USE_CXX11_ABI=0 -D_NO_EXCEPTION -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -Wall -Werror -Wextra -Wunused-parameter -Wformat -Wconversion -Wno-deprecated -Wno-invalid-offsetof -finline-functions -fno-strict-aliasing -mtune=core2 -Wno-psabi -Wno-sign-compare -Wno-literal-suffix -DGCC_52 -DUSE_POSIX_FALLOCATE -DSUPPORT_SSE4_2 -DHAVE_SCHED_GETCPU -DHAVE_REALTIME_COARSE -DHAVE_FALLOCATE -c main.cpp -fPIC -DPIC -o .libs/main.o
ссылка так
$dpath/bin/ld.lld -shared -nostdlib .libs/main.o -l:lib.a -L./.libs -L/usr/lib64 -L$glib/gcc/x86_64-unknown-linux-gnu/5.2.0 -L$glib/gcc -L$glib/../lib64 -L$glib -L$dpath/lib/libstdc++.so --allow-shlib-undefined -soname server.so.0 -o ./server.so.0.0.0
наконец я получил эту ошибку
ld.lld: error: can't create dynamic relocation R_X86_64_DTPOFF32 against symbol: func()::i in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in ./.libs/lib.a(test.o)
>>> referenced by test.cpp:6
>>> test.o:(handle()) in archive ./.libs/lib.a
как вы видели, я уже передал -fPIC в своих cmds, поэтому я передаю -znotext в lld
но я получил еще одну ошибку
ld.lld: error: relocation R_X86_64_DTPOFF32 cannot be used against symbol func()::i; recompile with -fPIC
>>> defined in ./.libs/lib.a(test.o)
>>> referenced by test.cpp:6`enter code here`
>>> test.o:(handle()) in archive ./.libs/lib.a
Эта ошибка появляется только когда я компилирую свой проект в режиме выпуска, когда я удаляю -O2, он хорошо связывается.
Но когда я использую so / bin, который связан в режиме отладки, для запуска тестовых сценариев, я получаю множество необъяснимых дампов ядра вокруг кодов, которые используют статические tls для функций.
Задача ещё не решена.
Других решений пока нет …