বাহ্যিক গ্রন্থাগারে সিএমকে লিঙ্ক করুন


126

একই সিএমকে প্রকল্পের মধ্যে নয় এমন বহিরাগত ভাগ করা লাইব্রেরির সাথে এক্সিকিউটেবলকে কীভাবে যুক্ত করতে সিএমকে পাবেন?

শুধু করা target_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so)ত্রুটি দেয়

make[2]: *** No rule to make target `res/mylib.so', needed by `GLBall'.  Stop.
make[1]: *** [CMakeFiles/GLBall.dir/all] Error 2
make: *** [all] Error 2
(GLBall is the executable)

আমি লাইব্রেরিটি বাইনারি দির অনুলিপি করার পরে bin/res

আমি ব্যবহার করার চেষ্টা করেছি find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)

যা দিয়ে ব্যর্থ হয় RESULT-NOTFOUND

উত্তর:


101

প্রথমে লাইব্রেরি অনুসন্ধানের পথ নির্ধারণ করুন:

LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/res)

এবং তারপর ঠিক কি

TARGET_LINK_LIBRARIES(GLBall mylib)

43
link_directoriesএমনকি এর নিজস্ব ডকুমেন্টেশনেও এর ব্যবহার নিরুত্সাহিত। আমি মনে করি find_libraryমূল প্রশ্নে ব্যর্থ কলটি সমাধান করা বা @ আন্দ্রে এর সমাধানটি ব্যবহার করা ভাল here
ফ্রেজার

4
আমি "আমদানিকৃত" লাইব্রেরি লক্ষ্যটিকে আরও শক্তিশালী বলে মনে করি, কারণ এটি নির্দিষ্ট লাইব্রেরির অবস্থানকে লক্ষ্যবস্তু করে, পরিবর্তে কেবল একটি বিশ্বব্যাপী অনুসন্ধানের পথ দেয়। আন্দ্রে এর উত্তর দেখুন।
লাকাটা

1
আপনার find_libraryএই পাথটিকে সর্বদা হার্ড কোডিংয়ের পরিবর্তে ব্যবহার এবং ব্যবহার করা উচিত , সিএফ। আমার উত্তর
usr1234567

121

এয়ারডোজারের উত্তরটি সঠিক এবং অনেক সময় পছন্দ হয়। আমি কেবল তার উত্তরের বিকল্প যুক্ত করতে চাই:

আপনি লিঙ্ক-ডিরেক্টরি পরিবর্তে একটি "আমদানি করা" লাইব্রেরি লক্ষ্য যুক্ত করতে পারেন। কিছুটা এইরকম:

# Your-external "mylib", add GLOBAL if the imported library is located in directories above the current.
add_library( mylib SHARED IMPORTED )
# You can define two import-locations: one for debug and one for release.
set_target_properties( mylib PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/res/mylib.so )

এবং তারপরে লিঙ্ক করুন যেন এই প্রকল্পটি আপনার প্রকল্প দ্বারা নির্মিত হয়েছিল:

TARGET_LINK_LIBRARIES(GLBall mylib)

যেমন একটি পদ্ধতির আপনি একটি সামান্য আরো নমনীয়তা দেবে: কটাক্ষপাত add_library () কমান্ড আমদানিকৃত লাইব্রেরি এর সাথে সম্পর্কিত অনেক লক্ষ্য-বৈশিষ্ট্য

আমি জানি না এটি "লিবের আপডেট সংস্করণ" দিয়ে আপনার সমস্যার সমাধান করবে কিনা।


2
সম্ভবত এটি হতে পারে add_library( mylib SHARED IMPORTED )বা আপনি কোনও add_library called with IMPORTED argument but no library typeত্রুটি পান
মারভিন

4
@ আন্ড্রে: আমি মনে করি IMPORTED_LOCATIONউদ্বোধনী বন্ধনীটি ভুল হওয়ার পরে
Ela782

5
আপনি যোগ করতে প্রয়োজন GLOBALপর IMPORTED: আপনার বর্তমান উপরে ডিরেক্টরিগুলি থেকে আমদানিকৃত লাইব্রেরি অ্যাক্সেস করতে চান তাহলেadd_library(breakpad STATIC IMPORTED GLOBAL)
রোমান Kruglov

@ আন্ডার ইমপোর্টটি শোধ করার জন্য ফাইলটি অন্তর্ভুক্ত থাকা ডিরেক্টরিটির পরিবর্তে ফাইলটির পাথের প্রয়োজন বলে মনে হচ্ছে
সোউসার

1
@ সোসার: হ্যাঁ, IMPORTED_LOCATION ফাইলের দিকে নির্দেশ করা উচিত ডিরেক্টরিতে নয়। আমি এটি স্থির করেছি, অনুমান লেখক কোনও অভিযোগ করবেন না।
Tsyvarev

64

আমি ধরে নিই যে আপনি foo নামক একটি লাইব্রেরিতে লিঙ্ক করতে চান , এর ফাইল নামটি সাধারণত কিছু লিঙ্ক foo.dllবা libfoo.so

1. আপনার গ্রন্থাগারটি
সন্ধান করতে হবে লাইব্রেরিটি সন্ধান করুন। আপনি যদি আপনার গ্রন্থাগারের পথটি জানেন তবে এটি একটি ভাল ধারণা। লাইব্রেরিটি নিখোঁজ হয়ে গেলে বা কোনও নতুন নাম পেলে সিএমকে ত্রুটিযুক্ত হবে। এটি প্রাথমিকভাবে ত্রুটি চিহ্নিত করতে এবং কোনও সমস্যার কারণ কী তা ব্যবহারকারীকে (নিজেই) এটি পরিষ্কার করতে সহায়তা করে।
একটি লাইব্রেরি foo সন্ধান এবং FOO_LIBব্যবহারের পথে সংরক্ষণ করতে

    find_library(FOO_LIB foo)

আসল ফাইলের নামটি সিএমকে নিজেই খুঁজে বের করবে। মনে হচ্ছে স্বাভাবিক স্থান পরীক্ষা করে /usr/lib, /usr/lib64এবং পাথ PATH

আপনি আপনার গ্রন্থাগারের অবস্থান ইতিমধ্যে জানেন know এটি যোগ করুন CMAKE_PREFIX_PATHযখন আপনি CMake, খুব কল তারপর CMake পাস মার্গে আপনার লাইব্রেরির দেখব।

কখনও কখনও আপনাকে ইঙ্গিত বা পথ প্রত্যয় যুক্ত করতে হবে, বিশদগুলির জন্য ডকুমেন্টেশন দেখুন: https://cmake.org/cmake/help/latest/command/find_library.html

২. লাইব্রেরিকে লিঙ্ক করুন ১ থেকে আপনার পুরো লাইব্রেরির নাম রয়েছে FOO_LIB। আপনি আপনার লক্ষ্য GLBallহিসাবে লাইব্রেরিটি লিঙ্ক করতে এটি ব্যবহার করুন

  target_link_libraries(GLBall PRIVATE "${FOO_LIB}")

আপনি যোগ করা উচিত PRIVATE, PUBLICঅথবা INTERFACEলক্ষ্য, cf. পর ডকুমেন্টেশন: https://cmake.org/cmake/help/latest/command/target_link_libraries.html

আপনি যদি এই ভিজিবিলিটি স্পেসিফায়ারগুলির মধ্যে একটি না যোগ করেন তবে এটি হয় সিএমকে সংস্করণ এবং নীতিমালাগুলির সেটের উপর নির্ভর করে PRIVATEবা এর মতো আচরণ করবে PUBLIC

৩. অ্যাড অন্তর্ভুক্ত রয়েছে (এই পদক্ষেপটি বাধ্যতামূলক নাও হতে পারে))
যদি আপনিও শিরোনাম ফাইল অন্তর্ভুক্ত করতে চান তবে find_pathঅনুরূপ ব্যবহার করুন find_libraryএবং একটি শিরোনাম ফাইল অনুসন্ধান করুন। তারপরে target_include_directoriesঅনুরূপ ডিরেক্টরি অন্তর্ভুক্ত করুন target_link_libraries

ডকুমেন্টেশন: https://cmake.org/cmake/help/latest/command/find_path.html এবং https://cmake.org/cmake/help/latest/command/target_incolve_directories.html

যদি বাহ্যিক সফ্টওয়্যার জন্য উপলব্ধ হয়, আপনি প্রতিস্থাপন find_libraryএবং find_pathদ্বারা করতে পারেন find_package


4
আইএমএইচও এটি সর্বোত্তম উত্তর। তবে, আমার সমস্যা হয়েছিল কারণ আমি "প্রোডাক্ট" এর পরে "ফাইন্ড_লিবারি" এবং "টার্গেট_লিঙ্ক_লাইবারি" "অ্যাড_এক্সেকটেটেবল" এর পরে কল করছিলাম না।
স্মুথওয়্যার

1
find_packageএই পদক্ষেপগুলি অনুসরণ করার চেয়ে অনেক সহজ
অ্যাক্টিভডিকে

2
আমার ধারণা আমি 2 ধাপটি বুঝতে পারি না a {FOO_LIB For /full/path/to/libfoo.dylib এর মতো হবে। কিভাবে এটি দরকারী? টার্গেট_লিঙ্ক_লাইব্রিজগুলি "-L / ফুল / পথ / থেকে-ফ্লু" তৈরি করছে না, সুতরাং সন্ধান_লাইবারি দরকারী কিছু ফিরিয়ে দিচ্ছে না, যা লাইব্রেরিটি ইতিমধ্যে যে স্থানে রয়েছে তা যাচাই করা ছাড়া। আমি কী মিস করছি?
লোকম্যাক

target_link_libraries(mylib "${FOO_LIB}")? লক্ষ্যটি mylibতার আসল টার্গেটের পরিবর্তে GLBall? আমার কাছে খুব একটা তাৎপর্য নেই
বার্সান

5

আরও একটি বিকল্প, আপনি অ্যাপস্টোরের সাথে কাজ করছেন এমন ক্ষেত্রে "এনটাইটেলমেন্টস" এবং অ্যাপল-ফ্রেমওয়ার্কের সাথে লিঙ্ক করার প্রয়োজন রয়েছে।

কাজ এনটাইটেলমেন্টের জন্য (যেমন GameCenter) আপনি প্রয়োজন একটি "লাইব্রেরি সাথে লিঙ্ক করুন বাইনারি" -buildstep আছে তারপর "GameKit.framework" সঙ্গে লিঙ্ক এবং। CMake "উদ্বুদ্ধ" A "নিম্ন স্তরের" কমান্ড মধ্যে উপর লাইব্রেরি, অত: পর Xcode নেই সত্যিই এটা সম্পর্কে জানেন, এবং যেমন আপনি হবে না GameKit কেপেবিলিটিস পর্দা সক্রিয় করুন।

সিএমকে ব্যবহার করার এবং "বাইনারিগুলির সাথে লিঙ্ক" থাকার একটি উপায়-বিল্ডস্টেপ হ'ল সিএমকেকের সাথে এক্সকোডেপ্রজ তৈরি করা এবং তারপরে 'অনুসন্ধান ও প্রতিস্থাপন' করতে 'সেড' ব্যবহার করা এবং এক্সকোডের পছন্দ মতো গেমকিট যুক্ত করা ...

স্ক্রিপ্টটি দেখতে দেখতে (এক্সকোড 6.3.1 এর জন্য)।

s#\/\* Begin PBXBuildFile section \*\/#\/\* Begin PBXBuildFile section \*\/\
    26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks \*\/ = {isa = PBXBuildFile; fileRef = 26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/; };#g

s#\/\* Begin PBXFileReference section \*\/#\/\* Begin PBXFileReference section \*\/\
    26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System\/Library\/Frameworks\/GameKit.framework; sourceTree = SDKROOT; };#g

s#\/\* End PBXFileReference section \*\/#\/\* End PBXFileReference section \*\/\
\
\/\* Begin PBXFrameworksBuildPhase section \*\/\
    26B12A9F1C10543B00A9A2BA \/\* Frameworks \*\/ = {\
        isa = PBXFrameworksBuildPhase;\
        buildActionMask = 2147483647;\
        files = (\
            26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks xxx\*\/,\
        );\
        runOnlyForDeploymentPostprocessing = 0;\
    };\
\/\* End PBXFrameworksBuildPhase section \*\/\
#g

s#\/\* CMake PostBuild Rules \*\/,#\/\* CMake PostBuild Rules \*\/,\
            26B12A9F1C10543B00A9A2BA \/\* Frameworks xxx\*\/,#g
s#\/\* Products \*\/,#\/\* Products \*\/,\
            26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/,#g

এটিকে "গেমসেন্টার.সেড" এ সংরক্ষণ করুন এবং তারপরে এটি "প্রয়োগ করুন" (এটি আপনার এক্সকোডেপ্রজকে পরিবর্তন করে!)

sed -i.pbxprojbak -f gamecenter.sed myproject.xcodeproj/project.pbxproj

আপনার প্রয়োজন অনুসারে আপনাকে স্ক্রিপ্ট-আদেশগুলি পরিবর্তন করতে হতে পারে।

সতর্কতা: প্রকল্পের ফর্ম্যাটটি পরিবর্তনের সাথে সাথে এটি বিভিন্ন এক্সকোড-সংস্করণে ভেঙে যাওয়ার সম্ভাবনা রয়েছে, (হার্ডকোডযুক্ত) অনন্য নম্বরটি সম্ভবত অনন্য দ্বারা নয় - এবং অন্যান্য লোকদের দ্বারা সমাধানগুলি আরও ভাল - যদি আপনার অ্যাপস্টোর + সমর্থন না করা হয় তবে এনটাইটেলমেন্ট (এবং স্বয়ংক্রিয় বিল্ডস), এটি করবেন না।

এটি সিএমকে বাগ, দেখুন http://cmake.org/Bug/view.php?id=14185 এবং http://gitlab.kitware.com/cmake/cmake/issues/14185


বিশেষত - বাহ্যিক গ্রন্থাগারের সাথে লিঙ্ক করতে চটকে পাওয়া সমস্যা নয় (উপরে বেশ কয়েকটি সমাধান রয়েছে)। এটি একটি স্বয়ংক্রিয় পদ্ধতিতে কাজ করা, যাতে এটি অ্যাপল অ্যাপস্টোর এবং এনটাইটেলমেন্টগুলির সাথে কাজ করে একটি চ্যালেঞ্জ। সুনির্দিষ্ট ক্ষেত্রে, উপরের সমাধানগুলি কাজ করে না কারণ এক্সকোড এইভাবে সংযুক্ত লাইব্রেরিগুলিকে 'দেখতে' দেবে না এবং এনটাইটেলমেন্টগুলি কেবল কাজ করবে না। আফাইক চ্যামেকটি 'অ্যাপস্টোরের সাথে সামঞ্জস্যপূর্ণ উপায়ে' এক্সকোডের যেভাবে প্রয়োজন হয় সেভাবে লিবারিগুলি যুক্ত করতে পারে না - আমাকে আলোকিত করতে নির্দ্বিধায়।
কলমিয়া

1
ওহ, দুঃখজনক সম্পূর্ণ ইস্যু ট্র্যাকারের লিঙ্কটি সম্পূর্ণরূপে, এতে বর্তমানে কোনও কমেন্ট নেই: gitlab.kitware.com/cmake/cmake/issues/14185
usr1234567

সমস্যাটি 5 মাস আগে সমাধান করা হয়েছিল, সুতরাং সিএমকের একটি সাম্প্রতিক সংস্করণ সহ এটি আর উপস্থিত হওয়া উচিত নয়। দেখুন gitlab.kitware.com/cmake/cmake/issues/14185
usr1234567
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.