Помилка компіляції з “переміщення R_X86_64_32 проти` .rodata.str1.8 'не можна використовувати під час створення спільного об’єкта ”


84

Я намагаюся скомпілювати цей вихідний код із makefile у VPS, але він не працює. VPS - це 64-центрова ОС

Ось повна помилка

# make
gcc -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/amx/*.c
g++ -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/*.cpp
g++ -c -O3 -w -DLINUX -I../SDK/amx/ *.cpp
g++ -O2 -fshort-wchar -shared -o "TCP_V1.so" *.o
/usr/bin/ld: TCP-LINUX_V1.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be     used when making a shared object; recompile with -fPIC
TCP-LINUX_V1.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [all] Error 1

Ось мій файл make:

GPP=g++
GCC=gcc
OUTFILE="TCP_V1.so"

COMPILE_FLAGS=-c -O3 -w -DLINUX -I../SDK/amx/

all:
    $(GCC) $(COMPILE_FLAGS) ../SDK/amx/*.c
    $(GPP) $(COMPILE_FLAGS) ../SDK/*.cpp
    $(GPP) $(COMPILE_FLAGS) *.cpp
    $(GPP) -O2 -fshort-wchar -shared -o $(OUTFILE) *.o

Хтось знає, що не так?


6
Ви пробували recompile with -fPIC?
Йоахім Ісакссон

Вибачте, але я не знаю, як це зробити. Не можу знайти в Google нічого про "-fPIC".
user1667191

4
Спробуйте щось на кшталтCOMPILE_FLAGS=-c -O3 -w -DLINUX -fPIC -I../SDK/amx/
Йоахім Ісакссон


9
якщо ви шукаєте в Google -fPIC, ви точно не знайдете нічого. Видаліть мінус або використовуйте лапки "-fPIC", інакше ви опускаєте всі результати, що містять fPIC.
d00d

Відповіді:


119

Виконуйте те, що вам наказує компілятор, тобто перекомпілюйте -fPIC. Щоб дізнатись, що робить цей прапор і навіщо він потрібен у цьому випадку, див. Параметри генерації коду в посібнику GCC.

Коротше кажучи, термін незалежний від позиції код (PIC) відноситься до сформованого машинного коду, який є агностичним для адреси пам'яті, тобто не робить жодних припущень про те, де він був завантажений в оперативну пам'ять. Передбачається, що до спільних об'єктів (SO) повинен входити лише незалежний від позиції код, оскільки вони повинні мати можливість динамічно змінювати своє розташування в оперативній пам'яті.

Нарешті, ви також можете прочитати про це у Вікіпедії .


3
Не могли б ви пояснити, як перекомпілювати з -fPIC?
Бені Богосель

12
@ Бені Богосель: Це дуже просто. Ви просто додаєте -fPICдо всіх викликів компілятора для всіх вихідних файлів (одиниць перекладу, наприклад, *.cppфайлів) бібліотеки. Конкретний спосіб цього залежить від використовуваної вами системи складання. Наприклад, у CMake ви можете видавати set_target_properties(${LIBRARY_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON). У випадку з цим хлопцем (використовуючи звичайний старий Make), йому доведеться це зробити, COMPILE_FLAGS+=-fPICоскільки він використовує цю змінну для позначення набору прапорів компіляції для всіх вихідних файлів своєї бібліотеки.
Олександр Шукаєв

1
щоб увімкнути -fPIC за допомогою configure: configure --enable-shared, див. stackoverflow.com/a/850464/440403
camino

49

У моєму випадку ця помилка сталася, оскільки makeкоманда очікувала отримати спільні бібліотеки ( *.soфайли) з віддаленого каталогу, позначеного LDFLAGSзмінною середовища. Помилково, там були доступні лише статичні бібліотеки ( *.laабо *.aфайли).

Отже, моя проблема полягала не в програмі, яку я компілював, а в віддалених бібліотеках, які вона намагалася отримати. Отже, мені не потрібно було додавати жодного прапора (скажімо, -fPIC) до компіляції, перерваної помилкою переміщення. Швидше, я перекомпілював віддалену бібліотеку, щоб загальнодоступні об’єкти були доступні.

В основному це маскується помилка, яку не знайдено.

У моєму випадку мені довелося видалити неправильний --disable-sharedперемикач у configureвиклику необхідної програми, оскільки спільна та статична бібліотеки були побудовані за замовчуванням.


Я помітив, що більшість програм будують обидва типи бібліотек одночасно, тому моя, мабуть, наріжний випадок. Загалом, може трапитися так, що вам скоріше доведеться активувати спільні бібліотеки, залежно від типових значень.

Щоб перевірити вашу особливу ситуацію з перемикачами компіляції та за замовчуванням, я прочитав би підсумок, який відображається разом ./configure --help | less, як правило, у розділі Необов’язкові функції. Я часто виявляв, що це читання є більш надійним, ніж керівництво по установці, яке не оновлюється під час розвитку програм залежностей.


1
Ідеально, "це була замаскована помилка, яку не знайдено." У моєму випадку залежність ще не була встановлена.
Litty

+1 У моєму випадку нову копію openssl було створено вручну та встановлено без спільних бібліотек. Бібліотека, яку я намагався створити, вже була скомпільована з -fPIC. Чи є так чи інакше, що компілятор міг розпізнати цю помилку, щоб надати менш неясне повідомлення про помилку, наприклад "Очікується знайти спільну бібліотеку libssl.so, але знайдено лише несумісну статичну бібліотеку /usr/local/ssl/lib/libssl.a." ?
Rohan Mahy

1
Дякую. У мене був make -j, і паралельне виконання не дозволялося для цього програмного пакету.
MikeBergmann

У моєму випадку у мене є такий рядок "find_library (NGHTTP2_LIB NAMES libnghttp2.a libnghttp2.so libnghttp2.dylib)". і він лише забирав .a, пізніше я змінив його на find_library (NGHTTP2_LIB NAMES libnghttp2.so libnghttp2.a libnghttp2.dylib) ", і він почав працювати. Моє занепокоєння полягає в тому, чим він раніше працює для мене?
Наба Чінде

1
@NabaChinde Боюсь, у мене немає відповіді на ваше запитання ще й тому, що мені бракує контекстної інформації про ваші результати. Я, звичайно, закликаю розмістити окреме запитання, в якому ви пояснюєте свою робочу ситуацію та несподівану поведінку.
XavierStuvw

11

Це не завжди стосується прапорів компіляції, у мене однакова помилка на gentoo при використанні distcc.

Причина полягає в тому, що на сервері distcc використовується незагартований профіль, а на клієнтському - профіль. Перевірте це обговорення: https://forums.gentoo.org/viewtopic-p-7463994.html


9

Виправлено з -no-pieопцією на етапі компонування:

g++-8 -L"/home/pedro/workspace/project/lib" -no-pie ...

4

Просто очищення проекту вирішило це для мене.

Мій проект - це програма на C ++ (не спільна бібліотека). Я випадково отримав цю помилку після багатьох успішних збірок.



0

Я отримую таке саме рішення, як коментар @ camino на https://stackoverflow.com/a/19365454/10593190 та відповідь XavierStuvw .

Я змусив його працювати (для встановлення ffmpeg), просто перевстановивши все це з самого початку, $ ./configureзамінивши всі екземпляри на $ ./configure --enable-shared(спочатку обов’язково видаліть усі папки та файли, включаючи файли .so з попередньої спроби).

Очевидно, це працює, тому що https://stackoverflow.com/a/13812368/10593190 .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.