লাইব্রেরির পাথের পছন্দ কীভাবে নির্দিষ্ট করবেন?


95

আমি একটি সি ++ প্রোগ্রাম g++এবং ব্যবহার করে সংকলন করছি ld। আমার একটি .soলাইব্রেরি আছে যা আমি লিঙ্ক করার সময় ব্যবহার করতে চাই। যাইহোক, একই নামের একটি লাইব্রেরি রয়েছে /usr/local/lib, এবং ldএক আমি সরাসরি উল্লেখ করছি উপর লাইব্রেরির নির্বাচন করা হয়। আমি এটা কিভাবে ঠিক করবো?

নীচের উদাহরণগুলির জন্য, আমার লাইব্রেরি ফাইলটি /my/dir/libfoo.so.0। আমি চেষ্টা করেছি যে কাজ করে না:

  • আমার জি ++ কমান্ডটি g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
  • /my/dirআমার $PATHen` ভেরিয়েবলের শুরু বা শেষে যোগ করা
  • /my/dir/libfoo.so.0g ++ এ যুক্তি হিসাবে যুক্ত করা হচ্ছে

4
আর কি কি libfoo.*ফাইল বিদ্যমান এবং যেখানে - .soW / O .0, .aইত্যাদি ইত্যাদি?
অ্যালেক্স মার্টেলি

উত্তর:


94

আপনার নতুন লাইব্রেরিটি যেখানে পাথ যুক্ত করুন LD_LIBRARY_PATH(ম্যাকের এটির কিছুটা আলাদা নাম আছে ...)

আপনার -L/my/dir -lfooসলিউশনটি বিকল্পগুলি ব্যবহার করে কাজ করা উচিত , রানটাইমের সময় আপনার লাইব্রেরির অবস্থানের দিকে নির্দেশ করতে LD_LIBRARY_PATH ব্যবহার করুন।

LD_LIBRARY_PATH ব্যবহার করে যত্নশীল - সংক্ষেপে (লিঙ্ক থেকে):

.. প্রভাবগুলি ..:
সুরক্ষা : মনে রাখবেন যে এলডি_লিবিআরআরএআইপিএটিএলে উল্লিখিত ডিরেক্টরিগুলি স্ট্যান্ডার্ড লোকেশনের আগে অনুসন্ধান করা হবে! এইভাবে, কোনও দুষ্টু ব্যক্তি কোনও ভাগ করা লাইব্রেরির একটি সংস্করণ যাতে দূষিত কোড রয়েছে তা লোড করতে আপনার অ্যাপ্লিকেশনটি পেতে পারে! সেটুইড / সেটজিড এক্সিকিউটেবলগুলি সেই পরিবর্তনশীলটিকে অবহেলা করার এক কারণ!
কর্মক্ষমতা: লিংক লোডারকে উল্লিখিত সমস্ত ডিরেক্টরি সন্ধান করতে হবে, যতক্ষণ না এটি ভাগ করা লাইব্রেরি যেখানে থাকে সেই ডিরেক্টরিটি খুঁজে না পায় - সমস্ত ভাগ করা লাইব্রেরির জন্য অ্যাপ্লিকেশনটির সাথে লিঙ্কযুক্ত! এর অর্থ প্রচুর সিস্টেম কল () খোলার জন্য, এটি "ENOENT (এ জাতীয় কোনও ফাইল বা ডিরেক্টরি নেই)" দিয়ে ব্যর্থ হবে! যদি पथটিতে অনেকগুলি ডিরেক্টরি থাকে তবে ব্যর্থ কলগুলির সংখ্যা রৈখিকভাবে বৃদ্ধি পাবে এবং আপনি এটি অ্যাপ্লিকেশনটির শুরু হওয়ার সময় থেকেই বলতে পারেন। ডিরেক্টরিগুলির কিছু (বা সমস্ত) যদি কোনও এনএফএস পরিবেশে থাকে তবে আপনার অ্যাপ্লিকেশনগুলির প্রারম্ভকালীন সময়টি সত্যই দীর্ঘতর হতে পারে - এবং এটি পুরো সিস্টেমকে ধীর করে দিতে পারে!
অসঙ্গতি: এটি সবচেয়ে সাধারণ সমস্যা। LD_LIBRARY_PATH কোনও অ্যাপ্লিকেশনকে একটি ভাগ করা লাইব্রেরি লোড করতে বাধ্য করে যা এর সাথে লিঙ্ক করা হয়নি এবং এটি সম্ভবত মূল সংস্করণের সাথে সামঞ্জস্যপূর্ণ নয়। এটি হয় খুব সুস্পষ্ট হতে পারে, যেমন অ্যাপ্লিকেশন ক্র্যাশ হয়ে যায়, বা এটি ভুল ফলাফল হতে পারে, যদি বাছাই করা লাইব্রেরিটি মূল সংস্করণটি যা করত তেমন না করে। বিশেষত পরেরটি কখনও কখনও ডিবাগ করা শক্ত।

বা

লিঙ্কারের জন্য জিসিসি-র মাধ্যমে আরপিথ বিকল্পটি ব্যবহার করুন - রানটাইম লাইব্রেরি অনুসন্ধানের পথটি স্ট্যান্ডার্ড দির (জিসিসি বিকল্প) সন্ধানের পরিবর্তে ব্যবহৃত হবে:

-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)

এটি একটি অস্থায়ী সমাধানের জন্য ভাল। লিঙ্কার প্রথমে স্ট্যান্ডার্ড ডিরেক্টরিগুলি অনুসন্ধান করার আগে লাইব্রেরির জন্য LD_LIBRARY_PATH অনুসন্ধান করে।

আপনি যদি স্থায়ীভাবে LD_LIBRARY_PATH আপডেট করতে না চান তবে আপনি ফ্লাই অন কমান্ড লাইনে এটি করতে পারেন:

LD_LIBRARY_PATH=/some/custom/dir ./fooo

লাইব্রেরি লিঙ্কার (উদাহরণ) ব্যবহার সম্পর্কে যা জানে তা আপনি পরীক্ষা করতে পারেন:

/sbin/ldconfig -p | grep libpthread
        libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0

এবং আপনার অ্যাপ্লিকেশনটি কোন লাইব্রেরি ব্যবহার করছে তা পরীক্ষা করতে পারেন:

ldd foo
        linux-gate.so.1 =>  (0xffffe000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb7f9e000)
        libxml2.so.2 => /usr/lib/libxml2.so.2 (0xb7e6e000)
        librt.so.1 => /lib/librt.so.1 (0xb7e65000)
        libm.so.6 => /lib/libm.so.6 (0xb7d5b000)
        libc.so.6 => /lib/libc.so.6 (0xb7c2e000)
        /lib/ld-linux.so.2 (0xb7fc7000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7c2a000)
        libz.so.1 => /lib/libz.so.1 (0xb7c18000)

23
LD_LIBRARY_PATHরানটাইম অনুসন্ধান করা হয়, সংকলন সময় আপনি সেট করতে চান LIBRARY_PATH। দেখুন gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html
Bjoern Dahlgren

4
আপনি যদি গ্রন্থাগারটি সিস্টেম লাইব্রেরি থেকে সম্পূর্ণ পৃথক পৃথক হন, অর্থাত্ সর্বদা ব্যবহারযোগ্য এটি দয়া করে আরপিথ সমাধানটি ব্যবহার করুন। LD_LIBRARY_PATH পরীক্ষার জন্য একটি হ্যাক এবং সঠিকভাবে সম্পাদনযোগ্য কাজ করার প্রয়োজন হবে না।
ব্যবহারকারী 2746401

4
ম্যাকের জন্য এটির DYLD_LIBRARY_PATH
সিবাইন্ডার

এখানে একটি সম্পূর্ণ নমুনা কমান্ড (সি এর জন্য) দেওয়া হয়েছে যা এই উত্তরের উপর ভিত্তি করে কাজ করে:gcc myFile.c -o myFile.o -l myLibraryBaseName -Wl,-rpath,locationOfMyLibrary -L locationOfMyLibrary
জেট ব্লু

25

এটি একটি পুরানো প্রশ্ন, তবে কেউ এটি উল্লেখ করেছে বলে মনে হয় না।

আপনি ভাগ্যবান হচ্ছিলেন যে জিনিসটি একেবারে সংযুক্ত ছিল।

আপনার পরিবর্তন দরকার ছিল

g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp

এটি:

g++ -g -Wall -o my_binary -L/my/dir bar.cpp -lfoo

আপনার লিঙ্কারটি সমাধান করতে হবে এমন প্রতীকগুলির উপর নজর রাখে। এটি যদি প্রথম গ্রন্থাগারটি পড়ে থাকে তবে এর কোনও প্রয়োজনীয় চিহ্ন নেই, তাই এটি এতে থাকা প্রতীকগুলিকে উপেক্ষা করে। আপনার লিঙ্কারে যেগুলিতে সন্ধানের চিহ্ন রয়েছে সেগুলির সাথে লিংকগুলি নির্দিষ্ট করুন যাতে তাদের লিঙ্ক করা প্রয়োজন।

এছাড়াও, -lfooএটি নির্দিষ্ট করা হিসাবে একটি ফাইল প্রয়োজন হিসাবে libfoo.aবা libfoo.soপ্রয়োজন হিসাবে অনুসন্ধান করে তোলে । না libfoo.so.0। সুতরাং হয় lnনাম বা লাইব্রেরিটির নামকরণকে প্রশংসাপত্র হিসাবে।

জিসিসি ম্যান পৃষ্ঠাটি উদ্ধৃত করতে:

-l library
   ...
   It makes a difference where in the command you 
   write this option; the linker searches and processes 
   libraries and object files in the order they are 
   specified.  Thus, foo.o -lz bar.o searches library z 
   after file foo.o but before bar.o.  If bar.o refers 
   to functions in z, those functions may not be loaded.

সরাসরি g++কমান্ড লাইনে ফাইল যুক্ত করা উচিত ছিল, যদি না এটি অবশ্যই আগে রেখে দেওয়া bar.cppহত, যার ফলে লিঙ্কারটিকে প্রয়োজনীয় চিহ্নগুলির অভাবের কারণে এড়ানো হবে, কারণ কোনও চিহ্নের প্রয়োজন হয়নি।


22

গ্রন্থাগারের নিখুঁত পথ নির্দিষ্ট করে কাজ করা উচিত:

g++ /my/dir/libfoo.so.0  ...

আপনি -lfooএকবার নিখুঁত পথ যোগ করার পরে কি অপসারণের কথা মনে আছে ?


4
এই সমাধানটি আমার পক্ষেও দুর্দান্ত কাজ করেছে - ডিসট্রো ডেভলপমেন্ট প্যাকেজ ব্যতীত অন্য কোনও কিউটি 5 এর সংস্করণের সাথে লিঙ্ক দেওয়ার চেষ্টা করা। ধন্যবাদ
16'9

@সংস্করণীকৃত প্রতীকগুলির জন্য এই কাজটি কীভাবে করবেন ? সর্বনিম্ন উদাহরণ: github.com/cirosantilli/cpp-cheat/blob/…
Ciro Santilli 冠状 冠状 病 六四 事件

11

বিকল্প হিসাবে, আপনি এনভায়রনমেন্ট ভেরিয়েবলগুলি ব্যবহার করতে পারেন LIBRARY_PATHএবং CPLUS_INCLUDE_PATHযা যথাক্রমে CPATH-L এবং -I বিকল্পগুলি উল্লেখ না করে কোথায় লাইব্রেরি সন্ধান করতে হবে এবং কোথায় শিরোনামগুলি সন্ধান করতে হবে (কাজটিও করবে) indicate

সম্পাদনা: এর CPATHসাথে -Iএবং CPLUS_INCLUDE_PATHসাথে শিরোনাম অন্তর্ভুক্ত -isystem


আপনি দয়া করে ব্যবহারের জন্য উদাহরণ যোগ করতে পারেন?
হানা খলিল

export LIBRARY_PATH = /path/to/libআপনি যে
সংকলনটি

0

যদি কেউ উইন্ডোজে ডিএলএল নিয়ে কাজ করতে ব্যবহৃত হয় এবং লিনাক্স / কিউটিতে .so সংস্করণ নম্বরগুলি এড়িয়ে যেতে চান, তবে CONFIG += pluginসংস্করণ সংখ্যাগুলি বেরিয়ে যাবে। .So এর নিখুঁত পথ ব্যবহার করার জন্য, লিঙ্কারে এটি দেওয়া ভাল কাজ করে, যেমন মিঃ ক্লাটচো উল্লেখ করেছেন mentioned

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.