2010-05-03 3 views
16

मेरे पास एक ऐसा प्रोग्राम है जो साझा लाइब्रेरी पर निर्भर करता है, यह निर्देशिका संरचना के अंदर गहराई से खोजने की अपेक्षा करता है। मैं उस साझा लाइब्रेरी को बाहर और बेहतर स्थान पर ले जाना चाहता हूं। ओएस एक्स पर, यह install_name_tool के साथ किया जा सकता है। मैं लिनक्स के बराबर नहीं ढूंढ पा रहा हूं।किसी प्रोग्राम को बनाने के बाद साझा लाइब्रेरी के फ़ाइल नाम को मैं कैसे बदल सकता हूं?

संदर्भ के लिए, readelf -d myprogram निम्नलिखित दूसरे शब्दों में बयान उत्पादन बाहर थूक:

Dynamic section at offset 0x1e9ed4 contains 30 entries: 
    Tag  Type       Name/Value 
0x00000001 (NEEDED)      Shared library: [this/is/terrible/library.so] 
0x00000001 (NEEDED)      Shared library: [libGL.so.1] 
0x00000001 (NEEDED)      Shared library: [libGLU.so.1] 
0x00000001 (NEEDED)      Shared library: [libstdc++.so.6] 
(continues in an uninteresting fashion) 

(और अनुरोध के द्वारा, ldd myprogram :)

linux-gate.so.1 => (0x0056a000) 
    this/is/terrible/library.so => not found 
    libGL.so.1 => /usr/lib/mesa/libGL.so.1 (0x0017d000) 
    libGLU.so.1 => /usr/lib/libGLU.so.1 (0x00a9c000) 
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00710000) 
    (etc, etc) 

और मैं शुद्धिपत्र करने के लिए "चाहते हैं यह/है/भयानक/लाइब्रेरी.सो "साझा"/पुस्तकालय.सो "होना"। ध्यान दें कि, यदि प्रोग्राम अपने "निर्मित" स्थान में छोड़ा गया है, जहां सापेक्ष पथ यह// भयानक/लाइब्रेरी है। वास्तव में मौजूद है, तो ldd इसे ढूंढने में सक्षम है, जैसा कि आप उम्मीद करेंगे।

मुझे RPATH के बारे में पता है और यह वह नहीं है जिसे मैं ढूंढ रहा हूं, मुझे वैश्विक स्तर पर खोज पथ बदलने की आवश्यकता नहीं है।

+0

तो आप कह रहे हैं कि "यह/है/भयानक /" पथ rpath के रूप में सेट नहीं है? क्या यह लाइब्रेरी के सोनम का हिस्सा है? मुझे नहीं लगता कि लिनक्स पर install_name है। –

+0

हां, यह सोनीम का हिस्सा होगा, जो लिंकर द्वारा प्रस्तुत किया गया था जब मूल लिंक के आधार पर इसे लिंक किया गया था। – ZorbaTHut

+0

क्या आप 'ldd।/Yourprogram' आउटपुट भी पोस्ट कर सकते हैं? –

उत्तर

5

HT - यह सहायक हो सकता है।

एचटी एक्जिक्यूटिव के लिए एक फ़ाइल संपादक/दर्शक/विश्लेषक है। लक्ष्य डीबगर की निम्न-स्तरीय कार्यक्षमता और आईडीई की प्रयोज्यता को जोड़ना है। हम सभी (हेक्स-) संपादन सुविधाओं और सबसे महत्वपूर्ण फ़ाइल प्रारूपों के समर्थन को लागू करने की योजना बना रहे हैं।

मुझे ज़ोरबाथट के समाधान से कुछ अलग नहीं मिला, लेकिन शायद अलग-अलग लंबाई के साथ एक नाम रखना संभव है और अभी भी बाइनरी वैध रखें।

gelf - यह भी उपयोगी हो सकता है।

जीईएलएफ मैनिपुलेट के लिए एक सामान्य, ईएलएफ कक्षा-स्वतंत्र एपीआई है- ईएलएफ ऑब्जेक्ट फाइलों में आईएनजी। जीईएलएफ 32-बिट और 64-बिट ईएलएफ प्रारूप ऑब्जेक्ट फ़ाइलों को संभालने के लिए एक एकल, सामान्य अंतर- चेहरा प्रदान करता है।

+0

अच्छा। एचटी मेरे लिए व्यावहारिक नहीं है क्योंकि मुझे सीएलआई समाधान की आवश्यकता है। खुद पूरी तरह व्यावहारिक दिखता है - यह मानते हुए कि यह काम करता है - मुझे बस इसके चारों ओर वास्तविक कोड लिखना होगा। अब तक का सबसे अच्छा जवाब। – ZorbaTHut

+7

अपडेट: patchelf (http://nixos.org/patchelf.html) अब जाने का तरीका प्रतीत होता है। –

+0

patchelf (वर्तमान में) में यह सुविधा नहीं है। यह आपको निर्भरता को पूरी तरह से हटाने की अनुमति देता है, या RPATH सेट करता है (जो एक साझा lib के नाम को बदलने से अलग है) – hraban

-3

आप साझा पुस्तकालयों के लिए खोज पथ बदलने के लिए LD_LIBRARY_PATH का उपयोग कर सकते हैं। यदि आपका प्रोग्राम आपके उदाहरण शो जैसे किसी विशेष सापेक्ष पथ पर निर्भर करता है, तो आपको अभी भी उस निर्देशिका संरचना की आवश्यकता होगी। दूसरे शब्दों में आप आप अपने कार्यक्रम के पुनर्निर्माण कर सकते हैं /home/user/dev/project/this/is/terrible/library.so से /usr/local/lib/this/is/terrible/library.so लेकिन नहीं करने के लिए /usr/local/lib/library.so

को lib स्थानांतरित कर सकते हैं, तो सापेक्ष पथ यह lib के लिए उपयोग करता है बदल सकते हैं।

http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

+0

मेरे मामले में मदद नहीं करता है। मैं एक प्रोग्राम ले रहा हूं जो पहले से ही बनाया गया है, फिर इसे अन्य लोगों के सिस्टम पर तैनात करने की कोशिश कर रहा है। सबसे पहले, मैं अपने सिस्टम पर LD_LIBRARY_PATH के साथ मक नहीं करना चाहता हूं। दूसरा, जैसा कि आप उल्लेख करते हैं, वह वास्तव में इस// भयानक/उपसर्ग से छुटकारा नहीं पाता है, केवल मुझे इसके सामने एक और उपसर्ग जोड़ने की अनुमति देता है। मेरा प्रोग्राम केवल उस निर्देशिका संरचना पर निर्भर करता है क्योंकि वह डीएलएल की तलाश में है - यही वही है जो मैं बदलने की कोशिश कर रहा हूं :) – ZorbaTHut

7

पर लिनक्स में साझा libs पर कुछ अधिक जानकारी पोस्ट कर रहा है एक अस्थायी, भयानक, hacky समाधान नहीं है।

लाइब्रेरी निर्भरताओं को ईएलएफ ब्लॉक में संग्रहीत किया जाता है जिसे डीपेंड ब्लॉक कहा जाता है। उस ब्लॉक का प्रारूप पहचानकर्ता/स्ट्रिंगपोइंटर जोड़े की एक बड़ी सरणी है, जिसमें स्ट्रिंगपोइंटर बाइनरी में स्थित मानक सी नल-टर्मिनेटेड स्ट्रिंग को इंगित करता है।

आप देखते हैं कि यह कहां जा रहा है, है ना?

हाँ, जब तक आपको जिस नए पथ की आवश्यकता है वह पुराने पथ से बड़ा नहीं है, आप बस बाइनरी में सीधे पहुंच सकते हैं और एक साधारण स्ट्रिंग को प्रतिस्थापित कर सकते हैं। सुनिश्चित करें कि बाइट्स को जोड़ना या निकालना न भूलें या आप संपूर्ण बाइनरी को तोड़ देंगे। यदि आप इसके बारे में अधिक सुरक्षित होना चाहते हैं, तो आप वास्तव में ईएलएफ संरचना को पार कर सकते हैं ताकि यह सुनिश्चित किया जा सके कि आपके पास सही स्थान है - अभी मैं केवल यह सुनिश्चित करने के लिए जांच कर रहा हूं कि स्रोत स्ट्रिंग बिल्कुल एक बार दिखाई दे।

ईएलएफ में चेकसम शामिल है, लेकिन जाहिर है कि कोई लोडर नहीं है जो वास्तव में इसे सत्यापित करता है, इसलिए यह "सुरक्षित" है - यद्यपि गन्दा - अनदेखा करना।

"असली समाधान" एक उपयोगिता होगी जो ईएलएफ संरचना के निम्न स्तर के सामान्यीकृत हेरफेर की अनुमति देगी। जैसा कि मैं कह सकता हूं, कुछ विशेष मामलों को छोड़कर किसी भी चीज के लिए ऐसी कोई उपयोगिता मौजूद नहीं है (आरपीएटीएच, ज्यादातर।) मुझे यह जानने का नाटक नहीं है कि ऐसी उपयोगिता कितनी मुश्किल होगी।

मुझे बिल्कुल इसका बेहतर समाधान पसंद आएगा, लेकिन अब तक, यह काम प्रतीत होता है।

+1

जब मैंने हेक्स-एडिटिंग ईएलएफ ब्लॉक के बारे में सोचा तो मुझे क्रिंग किया गया, लेकिन मुझे लगता है कि यह काम करेगा। यदि ऐप इंस्टॉल हो जाने पर एक बार स्थानांतरित नहीं किया जाएगा तो आप "साझा/लाइब्रेरी.एसओ" और "यह/है/भयानक/लाइब्रेरी.एसओ" सिमलिंक कर सकते हैं। हालांकि, मैं सही पथ के साथ पुन: निर्माण की सिफारिश करता हूं और आपके प्रोग्राम के उपयोगकर्ताओं को एक अधिक उपयोगकर्ता के अनुकूल समाधान के रूप में पैच/अपडेट जारी करता हूं। – bta

+0

"पुनर्निर्माण" के साथ वास्तविक समस्या यह है कि मैं रनटाइम से अजीब आवश्यकताओं के साथ अपने बिल्ड सिस्टम लेआउट को प्रदूषित नहीं करना चाहता हूं, और इसी तरह मैं बिल्डटाइम से अजीब आवश्यकताओं के साथ अपने रनटाइम लेआउट को प्रदूषित नहीं करना चाहता हूं। यह एक संगतता मुद्दा नहीं है, यह सिर्फ यह सुनिश्चित कर रहा है कि मेरे और मेरे उपयोगकर्ता दोनों खुश हैं। – ZorbaTHut

+0

मुझे नहीं लगता कि सीसी के लिए एक और तर्क के साथ आपके ऐप को फिर से कैसे बनाया जाए आपके निर्माण वातावरण को प्रदूषित करेगा।लेकिन मुझे लगता है कि आपको बेहतर पता होना चाहिए :-) – Stan

6

हम उपयोग कर सकते हैं patchelf:

patchelf --replace-needed liboriginal.so.1 libreplacement.so.1 my-program 

हम भी निर्भरता निकाल सकते हैं:

patchelf --remove-needed libfoo.so.1 my-program 

निर्भरता जोड़ें:

patchelf --add-needed libfoo.so.1 my-program 

या जहां खोज करने के लिए पथ बदल पुस्तकालयों के लिए (rpath):

patchelf --set-rpath /path/to/lib:/other/path my-program 
संबंधित मुद्दे