Biên dịch không thành công với "định vị lại R_X86_64_32 chống lại" .rodata.str1.8 'không thể được sử dụng khi tạo một đối tượng chia sẻ "


84

Tôi đang cố gắng biên dịch mã nguồn này từ makefile trong VPS, nhưng nó không hoạt động. VPS là hệ điều hành 64 Cent

Đây là toàn bộ lỗi

# 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

Đây là makefile của tôi:

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

Có ai biết chuyện gì không?


6
Bạn đã thử recompile with -fPIC?
Joachim Isaksson

Xin lỗi nhưng tôi không biết chắc cách thực hiện việc này. Không thể tìm thấy bất cứ điều gì về "-fPIC" trên google.
dùng1667191

4
Hãy thử một cái gì đó giống nhưCOMPILE_FLAGS=-c -O3 -w -DLINUX -fPIC -I../SDK/amx/
Joachim Isaksson


9
nếu bạn tìm kiếm google cho -fPIC chắc chắn bạn sẽ không tìm thấy gì. Loại bỏ dấu trừ hoặc sử dụng dấu ngoặc kép "-fPIC" nếu không bạn bỏ qua tất cả các kết quả có chứa fPIC.
d00

Câu trả lời:


119

Làm những gì trình biên dịch yêu cầu bạn làm, tức là biên dịch lại với -fPIC. Để tìm hiểu chức năng của cờ này và lý do bạn cần nó trong trường hợp này, hãy xem Tùy chọn tạo mã của sổ tay GCC.

Nói tóm lại, thuật ngữ mã độc lập vị trí (PIC) dùng để chỉ mã máy được tạo ra là mã bất khả tri địa chỉ bộ nhớ, tức là không đưa ra bất kỳ giả định nào về nơi nó được tải vào RAM. Chỉ mã độc lập vị trí mới được đưa vào các đối tượng dùng chung (SO) vì chúng phải có khả năng thay đổi động vị trí của chúng trong RAM.

Cuối cùng, bạn cũng có thể đọc về nó trên Wikipedia .


3
Bạn có thể giải thích cách biên dịch lại với -fPIC không?
Beni Bogosel

12
@Beni Bogosel: Điều này rất đơn giản. Bạn chỉ cần thêm -fPICvào tất cả các lệnh gọi trình biên dịch cho tất cả các tệp nguồn (đơn vị dịch, ví dụ: *.cpptệp) của thư viện. Cách cụ thể để làm điều đó phụ thuộc vào hệ thống xây dựng mà bạn sử dụng. Ví dụ, trong CMake, bạn có thể phát hành set_target_properties(${LIBRARY_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON). Trong trường hợp của anh chàng này (sử dụng Make cũ đơn giản), anh ta sẽ phải làm gì COMPILE_FLAGS+=-fPICvì anh ta đang sử dụng biến này để biểu thị tập hợp các cờ biên dịch cho tất cả các tệp nguồn trong thư viện của anh ta.
Alexander Shukaev

1
để cho phép -fPIC sử dụng cấu hình: cấu hình enable-chia sẻ, xem stackoverflow.com/a/850464/440403
camino

49

Trong trường hợp của tôi, lỗi này xảy ra do một makelệnh mong đợi tìm nạp các thư viện được chia sẻ ( *.sotệp) từ một thư mục từ xa được chỉ ra bởi một LDFLAGSbiến môi trường. Do nhầm lẫn, ở đó chỉ có các thư viện tĩnh ( *.lahoặc *.acác tệp).

Do đó, vấn đề của tôi không nằm ở chương trình tôi đang biên dịch mà với các thư viện từ xa, nó đang cố gắng tìm nạp. Vì vậy, tôi không cần thêm bất kỳ cờ nào (giả sử -fPIC) vào quá trình biên dịch bị gián đoạn bởi lỗi chuyển vị trí. Đúng hơn, tôi đã biên dịch lại thư viện từ xa để các đối tượng được chia sẻ có sẵn.

Về cơ bản, đó là lỗi không tìm thấy tệp do ngụy trang.

Trong trường hợp của tôi, tôi đã phải loại bỏ một --disable-sharedcông tắc đặt sai vị trí trong lệnh configuregọi cho chương trình cần thiết, vì cả thư viện được chia sẻ và thư viện tĩnh đều được xây dựng như mặc định.


Tôi nhận thấy rằng hầu hết các chương trình xây dựng cả hai loại thư viện cùng một lúc, vì vậy tôi có lẽ là một trường hợp khó. Nói chung, có thể có trường hợp bạn phải bật thư viện chia sẻ, tùy thuộc vào giá trị mặc định.

Để kiểm tra tình huống cụ thể của bạn với các công tắc biên dịch và mặc định, tôi sẽ đọc phần tóm tắt hiển thị cùng ./configure --help | less, thường là trong phần Tính năng tùy chọn. Tôi thường thấy rằng cách đọc này đáng tin cậy hơn các hướng dẫn cài đặt không được cập nhật trong khi các chương trình phụ thuộc phát triển.


1
Tuyệt vời, "đó là lỗi không tìm thấy tệp do ngụy trang." Trong trường hợp của tôi, phần phụ thuộc vẫn chưa được cài đặt.
Litty

+1 Trong trường hợp của tôi, một bản sao mới hơn của openssl được tạo theo cách thủ công và được cài đặt mà không có thư viện được chia sẻ. Thư viện tôi đang cố gắng xây dựng đã được biên dịch bằng -fPIC. Dù sao thì trình biên dịch có thể nhận ra lỗi này để đưa ra thông báo lỗi ít khó hiểu hơn, ví dụ: "Dự kiến ​​tìm thấy thư viện được chia sẻ libssl.so, nhưng chỉ tìm thấy thư viện tĩnh không tương thích /usr/local/ssl/lib/libssl.a." ?
Rohan Mahy,

1
Cảm ơn. Tôi đã có một make -j và thực thi song song không được phép đối với gói phần mềm này.
MikeBergmann

Trong trường hợp của tôi, tôi có dòng này "find_library (NGHTTP2_LIB NAMES libnghttp2.a libnghttp2.so libnghttp2.dylib)". và nó chỉ chọn .a, sau đó tôi đã đổi nó thành find_library (NGHTTP2_LIB NAMES libnghttp2.so libnghttp2.a libnghttp2.dylib) "và nó bắt đầu hoạt động. Mối quan tâm của tôi là, nó dùng để làm việc gì trước đây đối với tôi?
Naba Chinde

1
@NabaChinde Tôi e rằng tôi không có câu trả lời cho câu hỏi của bạn vì tôi thiếu thông tin bối cảnh về kết quả của bạn. Tôi chắc chắn sẽ khuyến khích đăng một câu hỏi riêng trong đó bạn giải thích tình hình làm việc và hành vi không mong muốn của mình.
XavierStuvw

11

Không phải lúc nào cũng có các cờ biên dịch, tôi cũng gặp lỗi tương tự trên gentoo khi sử dụng distcc.

Lý do là trên máy chủ distcc đang sử dụng một hồ sơ chưa được làm cứng và trên máy khách, hồ sơ được làm cứng. Kiểm tra cuộc thảo luận này: https://forums.gentoo.org/viewtopic-p-7463994.html


9

Đã sửa nó với -no-pietùy chọn trong giai đoạn trình liên kết:

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

4

Đơn giản chỉ cần làm sạch dự án đã giải quyết nó cho tôi.

Dự án của tôi là một ứng dụng C ++ (không phải là một thư viện được chia sẻ). Tôi ngẫu nhiên gặp lỗi này sau rất nhiều lần xây dựng thành công.


2

Tôi đã từng gặp vấn đề tương tự. Hãy thử biên dịch lại bằng -fPICcờ.


0

Tôi nhận được giải pháp tương tự như nhận xét của @ camino trên https://stackoverflow.com/a/19365454/10593190câu trả lời của XavierStuvw .

Tôi đã làm cho nó hoạt động (để cài đặt ffmpeg) bằng cách chỉ cần cài đặt lại toàn bộ từ đầu với tất cả các trường hợp được $ ./configurethay thế bằng $ ./configure --enable-shared(trước tiên hãy đảm bảo xóa tất cả các thư mục và tệp bao gồm cả tệp .so từ lần thử trước).

Rõ ràng điều này hoạt động vì https://stackoverflow.com/a/13812368/10593190 .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.