संकलन "विफल रहता है R_X86_64_32 के खिलाफ` .rodata.str1.8 'का उपयोग किसी साझा ऑब्जेक्ट को बनाते समय नहीं किया जा सकता है "


85

मैं एक वीपीएस में इस स्रोत कोड को मेकफाइल से संकलित करने की कोशिश कर रहा हूं, लेकिन यह काम नहीं कर रहा है। 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

यहाँ मेरा मेकफाइल है:

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

किसी को पता है कि क्या गलत है?


7
क्या आपने कोशिश की recompile with -fPIC?
जोआचिम इस्कसन

क्षमा करें, लेकिन मुझे यकीन नहीं है कि यह कैसे करना है। Google पर "-fPIC" के बारे में कुछ भी नहीं पा सकते हैं।
user1667191

4
कुछ इस तरह की कोशिश करेंCOMPILE_FLAGS=-c -O3 -w -DLINUX -fPIC -I../SDK/amx/
जोआचिम इस्कसन


10
अगर आप -fPIC के लिए गूगल सर्च करेंगे तो आपको कुछ नहीं मिलेगा। माइनस निकालें या उद्धरण चिह्नों का उपयोग करें "-fPIC" अन्यथा आप fPIC वाले सभी परिणामों को छोड़ देते हैं।
d00d

जवाबों:


119

कंपाइलर जो करने के लिए कहता है, वही करें -fPIC। यह जानने के लिए कि यह ध्वज क्या करता है और आपको इस मामले में इसकी आवश्यकता क्यों है, जीसीसी मैनुअल के कोड जनरेशन विकल्प देखें ।

संक्षेप में, शब्द स्थिति स्वतंत्र कोड (PIC) उत्पन्न मशीन कोड को संदर्भित करता है जो मेमोरी एड्रेस एग्नॉस्टिक है, अर्थात यह रैम में लोड होने के बारे में कोई धारणा नहीं बनाता है। केवल स्थिति स्वतंत्र कोड को साझा वस्तुओं (एसओ) में शामिल किया जाना चाहिए क्योंकि उनके पास रैम में गतिशील रूप से अपना स्थान बदलने की क्षमता होनी चाहिए।

अंत में, आप इसके बारे में विकिपीडिया पर भी पढ़ सकते हैं ।


3
क्या आप बता सकते हैं कि कैसे -fPIC के साथ घूमना है?
बेनी बोगोसल

13
@ बेनी बोगोसल: यह बहुत सरल है। आप बस लाइब्रेरी के -fPICसभी स्रोत फ़ाइलों (अनुवाद इकाइयों, उदा *.cppफ़ाइलों) के लिए सभी संकलक इनवॉइस में जोड़ते हैं । ऐसा करने का ठोस तरीका उस निर्माण प्रणाली पर निर्भर करता है जिसका आप उपयोग करते हैं। उदाहरण के लिए, CMake में आप जारी कर सकते हैं set_target_properties(${LIBRARY_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)। इस आदमी के मामले में (सादे पुराने मेक का उपयोग करके), उसे ऐसा करना होगा COMPILE_FLAGS+=-fPICक्योंकि वह इस चर का उपयोग अपने पुस्तकालय की सभी स्रोत फ़ाइलों के लिए संकलन झंडे के सेट को दर्शाने के लिए कर रहा है।
अलेक्जेंडर शुकेव

1
कॉन्फ़िगर करने के लिए -fPIC सक्षम करने के लिए: कॉन्फ़िगर करें - साझा करें, साझा करें, देखें stackoverflow.com/a/850464/440403
कैमिनो

50

मेरे मामले में यह त्रुटि हुई क्योंकि एक makeकमांड *.soएक LDFLAGSपर्यावरण चर द्वारा इंगित दूरस्थ निर्देशिका से साझा लाइब्रेरी ( फाइलें) लाने की उम्मीद कर रहा था । एक गलती में, केवल स्थिर पुस्तकालय ही वहां उपलब्ध थे ( *.laया *.aफाइलें)।

इसलिए, मेरी समस्या उस कार्यक्रम के साथ नहीं थी जिसे मैं संकलित कर रहा था लेकिन दूरस्थ पुस्तकालयों के साथ यह लाने की कोशिश कर रहा था। इसलिए, मुझे -fPICस्थानांतरण त्रुटि से बाधित संकलन में किसी भी ध्वज (कहते हैं ) को जोड़ने की आवश्यकता नहीं थी । इसके बजाय, मैंने दूरस्थ पुस्तकालय को फिर से जोड़ दिया ताकि साझा वस्तुएं उपलब्ध हो सकें।

मूल रूप से, यह भेस में एक फ़ाइल नहीं मिली त्रुटि है।

मेरे मामले में मुझे अपेक्षित कार्यक्रम के लिए मंगलाचरण --disable-sharedमें एक गलत स्विच को हटाना पड़ा configure, क्योंकि साझा और स्टैटिक लाइब्रेरी दोनों को डिफ़ॉल्ट के रूप में बनाया गया था।


मैंने देखा कि अधिकांश कार्यक्रम एक ही समय में दोनों प्रकार के पुस्तकालयों का निर्माण करते हैं, इसलिए मेरा संभवतः एक कोने का मामला है। सामान्य तौर पर, यह मामला हो सकता है कि आपको चूक के आधार पर साझा पुस्तकालयों को सक्षम करना होगा।

संकलित स्विच और चूक के साथ आपकी विशेष स्थिति का निरीक्षण करने के लिए, मैं उस सारांश को पढ़ूंगा जो ./configure --help | lessआमतौर पर अनुभाग वैकल्पिक सुविधाओं के साथ दिखाता है । मैंने अक्सर पाया कि यह रीडिंग इंस्टॉलेशन गाइड की तुलना में अधिक विश्वसनीय है जो कि अपडेट नहीं होती है जबकि डिपेंडेंसी प्रोग्राम विकसित होते हैं।


1
बिल्कुल सही, "यह भेस में एक फ़ाइल नहीं मिली त्रुटि है।" मेरे मामले में निर्भरता अभी तक स्थापित नहीं हुई थी।
लिट्टी

+1 मेरे मामले में, ओपनस्स्ल की एक नई प्रतिलिपि मैन्युअल रूप से बनाई गई थी और साझा पुस्तकालयों के बिना स्थापित की गई थी। जिस लाइब्रेरी को मैं बनाने की कोशिश कर रहा था, वह पहले से ही -fPIC के साथ संकलित थी। क्या ऐसा भी है कि संकलक इस त्रुटि को कम अस्पष्ट त्रुटि संदेश देने के लिए पहचान सकता है, उदाहरण के लिए "साझा पुस्तकालय libssl.so को खोजने की उम्मीद है, लेकिन केवल असंगत स्थिर पुस्तकालय /usr/local/ssl/lib-libssl.a मिला।" ?
रोहन माही

1
धन्यवाद। मेरे पास मेक-जे था और इस सॉफ्टवेयर पैकेज के लिए समानांतर निष्पादन की अनुमति नहीं थी।
माइकबरगमैन

मेरे मामले में, मेरे पास यह लाइन है "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

यह हमेशा संकलित झंडे के बारे में नहीं है, डिस्टेक का उपयोग करते समय मुझे जेंटू पर एक ही त्रुटि है।

कारण यह है कि distcc सर्वर पर एक हार्ड-प्रोफाइल प्रोफाइल का उपयोग किया जाता है और क्लाइंट पर प्रोफ़ाइल को कठोर किया जाता है। इस चर्चा की जाँच करें: https://forums.gentoo.org/viewtopic-p-7463994.html


10

-no-pieलिंकर चरण में विकल्प के साथ इसे फिक्स्ड करें :

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

4

बस परियोजना की सफाई ने इसे मेरे लिए हल कर दिया।

मेरा प्रोजेक्ट एक C ++ एप्लिकेशन है (साझा पुस्तकालय नहीं)। मुझे बहुत सी सफल बिल्ड्स के बाद यह त्रुटि आई।



0

मुझे https://stackoverflow.com/a/19365454/10593190 और XavierStuvw के उत्तर पर @ कैमिनो की टिप्पणी के समान समाधान मिल रहा है ।

मुझे यह काम करने के लिए मिला (ffmpeg स्थापित करने के लिए) बस $ ./configureबदले की शुरुआत से सभी उदाहरणों के साथ पूरी चीज़ को पुनः स्थापित करके $ ./configure --enable-shared(पहले पिछले प्रयास से .so फ़ाइलों सहित सभी फ़ोल्डर्स और फ़ाइलों को हटाना सुनिश्चित करें)।

जाहिर है इस वजह से काम करता है https://stackoverflow.com/a/13812368/10593190

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.