স্ট্যাটিক লাইব্রেরিগুলিকে অন্যান্য স্ট্যাটিক লাইব্রেরিতে সংযুক্ত করা


138

আমার কাছে কোডের একটি ছোট অংশ রয়েছে যা অনেকগুলি স্ট্যাটিক লাইব্রেরির উপর নির্ভর করে (a_1-a_n)। আমি সেই কোডটি একটি স্ট্যাটিক লাইব্রেরিতে প্যাকেজ করতে এবং এটি অন্য লোকের কাছে উপলব্ধ করতে চাই।

আমার স্ট্যাটিক লাইব্রেরি, এটি এক্স বলতে যাক, সূক্ষ্ম সংকলন করে।

আমি একটি সাধারণ নমুনা প্রোগ্রাম তৈরি করেছি যা এক্স থেকে কোনও ফাংশন ব্যবহার করে, তবে আমি যখন এটির সাথে এক্সের সাথে লিঙ্ক করার চেষ্টা করি, তখন আমি লাইব্রেরি a_1 - a_n থেকে অনুপস্থিত চিহ্নগুলি সম্পর্কে অনেক ত্রুটি পেয়েছি।

এমন কি কোনও উপায় আছে যে আমি একটি নতুন স্ট্যাটিক লাইব্রেরি তৈরি করতে পারি, যেটিতে এক্স রয়েছে এবং এক্স দ্বারা প্রয়োজনীয় সমস্ত কার্যকারিতা রয়েছে (a_1 - a_n থেকে নির্বাচিত বিট), যাতে আমি লোকদের তাদের প্রোগ্রামের সাথে লিঙ্ক করার জন্য কেবল ওয়াই বিতরণ করতে পারি?


হালনাগাদ:

আমি কেবল আর দিয়ে সবকিছু ছুঁড়ে ফেলেছি এবং একটি মেগা-লিবিব তৈরি করেছি, তবে এটি প্রচুর পরিমাণে প্রতীকের প্রয়োজন সহ শেষ হয় (সমস্ত .o ফাইলগুলি প্রায় 700 এমবি, তবে, একটি স্ট্যাটিকালি লিঙ্কযুক্ত এক্সিকিউটেবল 7 হয় মেগাবাইট)। আসলে যা প্রয়োজন কেবল তা অন্তর্ভুক্ত করার জন্য কি কোনও দুর্দান্ত উপায় নেই?


এটি বেশ কয়েকটি সি / সি ++ লাইব্রেরিকে এক সাথে কীভাবে যুক্ত করতে পারে তার সাথে নিবিড়ভাবে সম্পর্কিত বলে মনে হচ্ছে ?

উত্তর:


76

স্ট্যাটিক লাইব্রেরিগুলি অন্যান্য স্ট্যাটিক লাইব্রেরির সাথে লিঙ্ক করে না। এই কাজ করার একমাত্র উপায় আপনার লাইব্রেরিয়ানকে / আর্কাইভার টুল (যেমন ব্যবহার করা আরবী ভাষায় একাধিক লাইব্রেরি concatenating দ্বারা একটি একক নতুন স্ট্যাটিক গ্রন্থাগার তৈরি করতে লিনাক্স)।

সম্পাদনা: আপনার আপডেটের প্রতিক্রিয়া হিসাবে, কেবলমাত্র যে চিহ্নগুলি প্রয়োজন তা কেবলমাত্র চয়ন করতে আমি জানতে পারি তা হ'ল .o ফাইলগুলির উপসেট থেকে ম্যানুয়ালি লাইব্রেরি তৈরি করা them এটি কঠিন, সময়সাপেক্ষ এবং ত্রুটির প্রবণ। এটি করতে সহায়তার জন্য আমি কোনও সরঞ্জাম সম্পর্কে সচেতন নই (তাদের উপস্থিতি নেই বলে মনে হয় না) তবে এটি তৈরি করার জন্য এটি একটি আকর্ষণীয় প্রকল্প তৈরি করবে।


হাই নিল, আমি প্রশ্নটি আপডেট করেছি - আপনি কেবলমাত্র .o ফাইলগুলি অন্তর্ভুক্ত করার কোনও উপায় জানেন?
জেসন সুন্দরাম

আপডেট - যদি আপনি নিজেকে এটি করতে ইচ্ছুক দেখতে পান তবে এক ধাপ পিছনে যান এবং অন্য কিছু অনুসরণ করুন (যদি না জন নোয়েলার উল্লেখ না করে আপনি ভিজুয়াল স্টুডিও ব্যবহার করছেন)। আমি এই পদ্ধতির মধ্যে অনেক সময় ডুবেছি এবং দরকারী কিছু পাই নি।
জেসন সুন্দরাম

জিএনইউ এলডি সরঞ্জাম একটি বিকল্প সরবরাহ -rকরে যা আউটপুটকে এলডি-র জন্য একটি ইনপুট হিসাবে ব্যবহার করতে পারে। আপনি যদি একবার লিঙ্ক করেন তবে আপনার স্থান পরিবর্তনযোগ্য হওয়া উচিত আপনার লাইব্রেরিগুলি সারোগেট করা যেতে পারে। (এটি চেষ্টা করে দেখুন)।
হার্পার

49

আপনি যদি ভিজুয়াল স্টুডিও ব্যবহার করছেন তবে হ্যাঁ, আপনি এটি করতে পারেন।

ভিজ্যুয়াল স্টুডিও সহ লাইব্রেরি বিল্ডার সরঞ্জাম আপনাকে কমান্ড লাইনে লাইব্রেরিতে যোগদানের অনুমতি দেয়। যদিও ভিজ্যুয়াল এডিটরটিতে এটি করার কোনও উপায় আমি জানি না।

lib.exe /OUT:compositelib.lib  lib1.lib lib2.lib

5
ভিএস ২০০৮-এ, লাইব্রেরিয়ান / জেনারেলের অধীনে কম্পোজিটেলিবের প্রজেক্টের বৈশিষ্ট্যগুলিতে, আপনি যদি [x] লিঙ্ক লাইব্রেরি নির্ভরতাগুলি পরীক্ষা করে থাকেন, তবে lib1 এবং lib2 কমপোজিটেলিবের নির্ভরতা হলে এটি আপনার পক্ষে এটি করবে। কিছুটা বগি মনে হচ্ছে, আমি প্রতিটি বিল্ড কনফিগারেশনে চেকবক্সটি আলাদাভাবে সেট করব, একবার 'সমস্ত কনফিগারেশন'-এ নয়।
স্পাইকএক্সএফ

2
ভিএস ২০১৫ আইডিই - আপনি লাইব্রেরিয়ান / জেনারেলের অধীনে "অতিরিক্ত নির্ভরতা" ব্যবহার করেন না যে আপনার প্রকল্পটি যে লাইব্রেরিটি তৈরি করছে তার সাথে সরাসরি অতিরিক্ত লাইব্রেরি যুক্ত হবে?
ডেভিডবাক

@ ডেভিডবাক আমি গত দু'দিন ধরে এটি বের করার চেষ্টা করছি এবং দৃশ্যত এই বিকল্পটি অপ্রচলিত এবং কিছু করে না?
মন্টাল্ডো

20

লিনাক্স বা মিংডাব্লু তে, জিএনইউ সরঞ্জামচেন সহ:

ar -M <<EOM
    CREATE libab.a
    ADDLIB liba.a
    ADDLIB libb.a
    SAVE
    END
EOM
ranlib libab.a

যদি আপনি মুছে না থাকেন liba.aএবং libb.a, আপনি একটি "পাতলা সংরক্ষণাগার" তৈরি করতে পারেন:

ar crsT libab.a liba.a libb.a

উইন্ডোজে, এমএসভিসি সরঞ্জামচেন সহ:

lib.exe /OUT:libab.lib liba.lib libb.lib

জেনে ভাল লাগল, কিন্তু আসলেই ওপি'র সমস্যাটি সমাধান করা যায় না, কারণ আপনি libb.a থেকে সমস্ত যৌথ lib- তে অন্তর্ভুক্ত করছেন, যদি আপনাকে libb থেকে কয়েকটি মডিউল প্রয়োজন হয় তবে এটি খুব বড় হয়ে উঠতে পারে।
এলমার জান্ডার

1
@ এলমারজান্ডার তবে আপনি ব্যবহার করতে পারেন ar crsT, যা অনুলিপি না করে "সিমলিংকিং" এর মতো কিছু করে, তারপরে আপনার কেবলমাত্র একটি অনুলিপি তথ্য প্রেরণ করতে হবে।
তারকা উজ্জ্বল

পাতলা আর্কাইভগুলি উল্লেখযোগ্যভাবে লিনাক্স কার্নেল v4.19 এ ব্যবহার করা হয়েছে: unix.stackexchange.com/questions/5518/…
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

10

একটি স্ট্যাটিক লাইব্রেরি হ'ল .oঅবজেক্ট ফাইলগুলির সংরক্ষণাগার । এগুলি ar(ইউনিক্স ধরে ধরে) নিয়ে বের করুন এবং সেগুলি একটি বড় লাইব্রেরিতে প্যাক করুন।


6

বিকল্প Link Library Dependenciesহিসাবে প্রকল্পের বৈশিষ্ট্যগুলিতে ভিজ্যুয়াল স্টুডিওতে লাইব্রেরিগুলিকে লিঙ্ক করার আরও একটি উপায় রয়েছে।

  1. আপনি অন্যান্য লাইব্রেরির সাথে একত্রিত হতে চান এমন লাইব্রেরির (এক্স) প্রকল্পটি খুলুন।
  2. আপনি এক্স (রাইট ক্লিক, Add Existing Item...) এর সাথে সম্মিলিত অন্যান্য লাইব্রেরি যুক্ত করুন ।
  3. তাদের ওয়েবসাইটের যান এবং নিশ্চিত করুন Item TypeনেইLibrary

এটি এক্সের অন্যান্য লাইব্রেরিগুলিকে অন্তর্ভুক্ত করবে যেন আপনি দৌড়েছিলেন

lib /out:X.lib X.lib other1.lib other2.lib

হাই, আমি ইন্টেল আইপিপি ব্যবহার করছি এবং আমি আমার নিজস্ব ফাংশনগুলি তৈরি করেছি যা আমি চাই যে সমস্তগুলি একটি (স্ট্যাটিক) লাইবে আবৃত হোক। তবুও আমি যখন lib তৈরি করি এবং তারপরে অন্য কম্পিউটারে প্রজেক্টটি প্রেরণ করি যা আমি কেবল আমার তৈরি lib ব্যবহার করে প্রজেক্টটি সংকলন করতে সক্ষম হতে চাই আমি ইন্টেল আইপিপি লাইব্রেরির একটি .h ফাইলের প্রয়োজনীয়তা বলতে ত্রুটি পাই। কোন ধারণা?
রই

lib ফাইল সাধারণত পর্যাপ্ত হয় না। আপনি যদি এটি ব্যবহার করতে চান তবে আপনাকে হেডার ফাইলগুলিও অন্তর্ভুক্ত করতে হবে। তবে এই থ্রেডটি এখানে লিঙ্কিং সম্পর্কে কথা বলে এবং আপনার সমস্যাটি সংকলনের পর্যায়ে রয়েছে it's
ইপ্পো

ঠিক আছে. আপনাকে সাহায্য করতে আমার আরও তথ্যের প্রয়োজন হবে। বিল্ড আউটপুটটি দেখুন বা লগ করুন এবং হারিয়ে যাওয়া .h ফাইলটিতে কী অভিযোগ করছে তা দেখুন। আমি এটি cl.exe মনে হয়। যদি কেসটি হয় তবে এটি আপনাকে সংকলিত .cpp / .cc / .c ফাইলের নাম দেবে যা হেডার ব্যবহার করে। .Cpp ফাইলটির নাম কী এবং এটি কোন প্রকল্পের অন্তর্ভুক্ত?
ইপ্পো

আমি তাই বিভ্রান্ত. আমি এটি পড়ার আগে, এটি কখনও কাজ করেছে বলে মনে হয় নি (এটি আমার প্রকল্পগুলি ইতিমধ্যে কনফিগার করা আছে)। তবে এখন আমি এটি পড়েছি এবং আমার প্রকল্পগুলি পুনরায় সেট করেছি, এটি দৃশ্যত কাজ করছে। চিত্রে যান! :(
মর্দাচাই

1
@ মোর্দাচাই নীচে এই হাইকু আপনার অভিজ্ঞতার নিখুঁত বর্ণনা করেছেন: গতকাল এটি কাজ করেছে আজ এটি উইন্ডোজ কাজ করছে না এমন হয়
এপ্পো

5

আপনি বিশ্রামটি পড়ার আগে দ্রষ্টব্য: এখানে প্রদর্শিত শেল স্ক্রিপ্টটি অবশ্যই ব্যবহার করা নিরাপদ নয় এবং ভালভাবে পরীক্ষা করা হয়েছে। আপনার নিজের ঝুঁকিতে ব্যবহার করুন!

সেই কাজটি সম্পাদনের জন্য আমি বাশ স্ক্রিপ্ট লিখেছিলাম। ধরুন আপনার লাইব্রেরিটি lib1 এবং আপনার যেটি থেকে কিছু চিহ্ন অন্তর্ভুক্ত করা দরকার তা হল lib2। স্ক্রিপ্টটি এখন একটি লুপে চলেছে, যেখানে এটি প্রথমে lib1 থেকে কোন পূর্বনির্ধারিত প্রতীকগুলি lib2 তে পাওয়া যাবে তা পরীক্ষা করে। এরপরে এটি lib2 এর সাথে সম্পর্কিত অবজেক্ট ফাইলগুলি বের করে ar, তাদের কিছুটা নাম পরিবর্তন করে এবং তাদেরকে lib1 এ রাখে। এখন আরও বেশি নিখোঁজ প্রতীক থাকতে পারে, কারণ আপনি যে লাইব 2 থেকে অন্তর্ভুক্ত করেছেন সেগুলিতে lib2 থেকে অন্য স্টাফের প্রয়োজন আছে, যা আমরা এখনও অন্তর্ভুক্ত করি নি, তাই লুপটি আবার চালানো দরকার। লুপের কিছু পাসের পরে যদি আর কোনও পরিবর্তন হয় না, যেমন lib2 থেকে কোনও অবজেক্ট ফাইল lib1 এ যুক্ত হয় না, লুপটি থামতে পারে।

দ্রষ্টব্য, অন্তর্ভুক্ত চিহ্নগুলি এখনও অপরিবর্তিত হিসাবে রিপোর্ট করা হয়েছে nm, সুতরাং লুপটি থামানো যায় কিনা তা নির্ধারণ করার জন্য আমি অবজেক্ট ফাইলগুলিতে নজর রাখছি, যেগুলি lib1 এ যুক্ত হয়েছিল themselves

#! /bin/bash

lib1="$1"
lib2="$2"

if [ ! -e $lib1.backup ]; then
    echo backing up
    cp $lib1 $lib1.backup
fi

remove_later=""

new_tmp_file() {
    file=$(mktemp)
    remove_later="$remove_later $file"
    eval $1=$file
}
remove_tmp_files() {
    rm $remove_later
}
trap remove_tmp_files EXIT

find_symbols() {
    nm $1 $2 | cut -c20- | sort | uniq 
}

new_tmp_file lib2symbols
new_tmp_file currsymbols

nm $lib2 -s --defined-only > $lib2symbols

prefix="xyz_import_"
pass=0
while true; do
    ((pass++))
    echo "Starting pass #$pass"
    curr=$lib1
    find_symbols $curr "--undefined-only" > $currsymbols
    changed=0
    for sym in $(cat $currsymbols); do
        for obj in $(egrep "^$sym in .*\.o" $lib2symbols | cut -d" " -f3); do
            echo "  Found $sym in $obj."
            if [ -e "$prefix$obj" ]; then continue; fi
            echo "    -> Adding $obj to $lib1"
            ar x $lib2 $obj
            mv $obj "$prefix$obj"
            ar -r -s $lib1 "$prefix$obj"
            remove_later="$remove_later $prefix$obj"
            ((changed=changed+1))
        done
    done
    echo "Found $changed changes in pass #$pass"

    if [[ $changed == 0 ]]; then break; fi
done

আমি সেই স্ক্রিপ্টটির নাম রেখেছি libcomp, তাই আপনি এটিকে কল করতে পারেন, উদাহরণস্বরূপ

./libcomp libmylib.a libwhatever.a

যেখানে ইচ্ছামত যেখানে আপনি প্রতীক অন্তর্ভুক্ত করতে চান। যাইহোক, আমি মনে করি প্রথমে পৃথক ডিরেক্টরিতে সমস্ত অনুলিপি করা সবচেয়ে নিরাপদ। আমি আমার স্ক্রিপ্টকে এতটা বিশ্বাস করব না (তবে এটি আমার পক্ষে কাজ করেছে; আমি তার সাথে আমার সংখ্যার লাইব্রেরিতে libgsl.a অন্তর্ভুক্ত করতে পারি এবং সেই -lgsl সংকলক সুইচটি ছেড়ে দিতে পারি)।

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