সিএমকে ব্যবহার করে এক্সিকিউটেবলের মতো একই ফোল্ডারে কীভাবে ডিএলএল ফাইলগুলি অনুলিপি করবেন?


100

আমরা আমাদের এসভিএন-তে আমাদের উত্সের ভিজ্যুয়াল স্টুডিও ফাইলগুলি তৈরি করার জন্য সিএমকে ব্যবহার করি। এখন আমার সরঞ্জামটির জন্য নির্বাহযোগ্য হিসাবে একই ফোল্ডারে কিছু ডিএলএল ফাইল থাকা দরকার। DLL ফাইলগুলি উত্সের পাশাপাশি একটি ফোল্ডারে রয়েছে।

আমি কীভাবে আমার CMakeLists.txtএই পরিবর্তন করতে পারি যে উত্পন্ন ভিজ্যুয়াল স্টুডিও প্রকল্পটি হয় ইতিমধ্যে প্রকাশিত / ডিবাগ ফোল্ডারগুলিতে নির্দিষ্ট ডিএলএল ফাইলগুলি ধারণ করবে বা সংকলনের পরে সেগুলি অনুলিপি করবে?

উত্তর:


126

আমি add_custom_commandপাশাপাশি এটি অর্জন করতে ব্যবহার করব cmake -E copy_if_different...। সম্পূর্ণ তথ্য চালানোর জন্য

cmake --help-command add_custom_command
cmake -E


সুতরাং আপনার ক্ষেত্রে যদি আপনার নিম্নলিখিত ডিরেক্টরি কাঠামো থাকে:

/CMakeLists.txt
/src
/libs/test.dll

এবং কমান্ডটি প্রযোজ্য যেখানে আপনার সিএমকে লক্ষ্য MyTest, তখন আপনি নিজের সিএমকেলিস্ট.সেক্সটটিতে নিম্নলিখিতগুলি যুক্ত করতে পারেন:

add_custom_command(TARGET MyTest POST_BUILD        # Adds a post-build event to MyTest
    COMMAND ${CMAKE_COMMAND} -E copy_if_different  # which executes "cmake - E copy_if_different..."
        "${PROJECT_SOURCE_DIR}/libs/test.dll"      # <--this is in-file
        $<TARGET_FILE_DIR:MyTest>)                 # <--this is out-file path


আপনি যদি কেবল /libs/ডিরেক্টরিটির সম্পূর্ণ বিষয়বস্তু অনুলিপি করতে চান তবে ব্যবহার করুন cmake -E copy_directory:

add_custom_command(TARGET MyTest POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_directory
        "${PROJECT_SOURCE_DIR}/libs"
        $<TARGET_FILE_DIR:MyTest>)


আপনার যদি কনফিগারেশনের উপর নির্ভর করে বিভিন্ন dlls অনুলিপি করতে হয় (রিলিজ, ডিবাগ, উদাহরণস্বরূপ) তবে আপনার সাথে সম্পর্কিত কনফিগারেশন সহ উপ-ডিরেক্টরিতে নাম থাকতে পারে:, /libs/Releaseএবং /libs/Debug। তারপরে আপনাকে add_custom_commandকলটিতে dll যাওয়ার পথে কনফিগারেশন টাইপটি ইনজেক্ট করতে হবে :

add_custom_command(TARGET MyTest POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_directory
        "${PROJECT_SOURCE_DIR}/libs/$<CONFIGURATION>"
        $<TARGET_FILE_DIR:MyTest>)

4
ভবিষ্যতে অন্য কাউকে সহায়তা করার ক্ষেত্রে আমার ক্ষেত্রে কী কাজ করেছে তার জন্য দ্রুত দ্রষ্টব্য: আমার কাছে একটি স্ট্যাটিক লাইব্রেরি প্রকল্প রয়েছে যা মূল নির্বাহযোগ্য optionচ্ছিকভাবে এর সাথে লিঙ্ক করে, এবং সেই লাইব্রেরির যুক্ত করা হলে একটি ডিএলএল অনুলিপি করা দরকার। সুতরাং সেই লাইব্রেরির সিএমকেলিস্ট.টেক্সট ফাইলটিতে আমি ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>লক্ষ্য গন্তব্যের জন্য ব্যবহার করেছি । অন্যথায় এটি এটি লাইব্রেরি নির্মাণের পথে অনুলিপি করে, যা অকেজো।
অ্যাবারেন্ট ওল্ফ

install()বাইনারিগুলিকে একত্রিত করা কি চামেকের নির্দেশনার লক্ষ্য নয় ? না কি চট করে LIBRARYজিনিস? আমি সত্যিই টুলচেন জানি না।
স্যান্ডবুর্গ

4
$<TARGET_FILE_DIR:MyTest>- এটা কি? কীভাবে তথ্য প্রিন্ট করা যায়, এর অর্থ কী
ilw

আমি কমান্ডটি সংহত করার সময় আমি কিছু মিস না করি তবে এই পদ্ধতিটি যোগ করা লাইব্রেরিগুলির জন্য কাজ করে না IMPORTED_LIBRARIES। এটি কোনও বিল্ড তৈরি না করে পোস্ট-বিল্ড কমান্ড চালাতে না পারার অভিযোগ করে।
তাজালুমেন

4
আমার ক্যামকে টেস্টিং এবং প্রোডিংয়ের পরে: আপনি যদি IMPORTEDগ্রন্থাগারগুলি ব্যবহার করছেন এবং ডিএলএলগুলি স্থানান্তরিত করতে চান তবে আপনার একটি ভেরিয়েন্ট কমান্ড ব্যবহার করা দরকার। আপনি আপনার করে তাহলে IMPORTEDযেমন গ্রন্থাগার MyImportedLibআপনি ব্যবহার করেন COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:MyImportedLib> $<TARGET_FILE_DIR:MyTest>আপনি তাদের সব একটি কাস্টম কমান্ড যেমন মধ্যে আবদ্ধ প্রয়োজন একাধিক পোস্ট বিল্ড কমান্ড চালানোর জন্য নোটadd_custom_command(TARGET MyTest POST_BUILD COMMAND #your first command# COMMAND #Your second command#)
Tzalumen

24

আমি এই লাইনগুলিকে আমার শীর্ষ-স্তরের সিএমকেলিস্ট.সেক্সট ফাইলটিতে রেখেছি। সিএমকে দ্বারা সংকলিত সমস্ত লাইব্রেরি এবং এক্সিকিউটেবলগুলি বিল্ড ডিরেক্টরিটির শীর্ষ স্তরে স্থাপন করা হবে যাতে এক্সিকিউটেবলগুলি গ্রন্থাগারগুলি খুঁজে পেতে পারে এবং সবকিছু চালানো সহজ হয়।

set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

নোট করুন যে এটি প্রকল্পের উত্স ডিরেক্টরি থেকে পূর্বনির্ধারিত বাইনারিগুলি অনুলিপি করার জন্য ওপি'র সমস্যার সমাধান করে না।


7

আমার প্রোগ্রামটি একটি উইন্ডোজ বিল্ড করার চেষ্টা করার সময় আমি আজ এই সমস্যাটি পেয়েছি। এই সমস্ত উত্তর আমাকে সন্তুষ্ট না করায় এবং আমি নিজেই কিছু গবেষণা চালিয়েছি। তিনটি মূল সমস্যা ছিল:

  • আমি চেয়েছিলাম ডিবাগ বিল্ডসগুলিকে লাইব্রেরির ডিবাগ সংস্করণগুলির সাথে যুক্ত করতে হবে এবং মুক্তির বিল্ডগুলি যথাক্রমে লাইব্রেরির রিলিজ বিল্ডগুলির সাথে যুক্ত হতে হবে।

  • এগুলি ছাড়াও, আমি চেয়েছিলাম ডিএলএল ফাইলগুলির সঠিক সংস্করণগুলি (ডিবাগ / রিলিজ) আউটপুট ডিরেক্টরিতে অনুলিপি করা উচিত।

  • এবং আমি জটিল এবং ভঙ্গুর স্ক্রিপ্ট না লিখে এগুলি অর্জন করতে চেয়েছিলাম।

গিথুবে কিছু সিএমকে ম্যানুয়াল এবং কয়েকটি মাল্টিপ্লাটফর্ম প্রকল্পগুলি ব্রাউজ করার পরে আমি এই সমাধানটি পেয়েছি:

"লাইব্রেরি" বৈশিষ্ট্য সহ আপনার গ্রন্থাগারটিকে লক্ষ্য হিসাবে ঘোষণা করুন, এর ডিবাগটি উল্লেখ করুন এবং .lib এবং .dll ফাইলগুলি প্রকাশ করুন।

add_library(sdl2 SHARED IMPORTED GLOBAL)
set_property(TARGET sdl2 PROPERTY IMPORTED_IMPLIB_RELEASE "${SDL_ROOT_PATH}/lib/SDL2.lib")
set_property(TARGET sdl2 PROPERTY IMPORTED_LOCATION_RELEASE "${SDL_ROOT_PATH}/bin/SDL2.dll")
set_property(TARGET sdl2 PROPERTY IMPORTED_IMPLIB_DEBUG "${SDL_ROOT_PATH}/lib/SDL2d.lib")
set_property(TARGET sdl2 PROPERTY IMPORTED_LOCATION_DEBUG "${SDL_ROOT_PATH}/bin/SDL2d.dll")

আপনার প্রকল্পের সাথে যথারীতি এই লক্ষ্যটিকে লিঙ্ক করুন

target_link_libraries(YourProg sdl2 ...)

পূর্ববর্তী বিল্ডের পরে যদি কোনওভাবে পরিবর্তন করা হয়ে থাকে তবে dll ফাইলটিকে তার গন্তব্যে অনুলিপি করতে কাস্টম বিল্ড স্টেপ তৈরি করুন

add_custom_command ( TARGET YourProg POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
    $<TARGET_FILE:sdl2> $<TARGET_FILE_DIR:YourProg>
)

5

স্বীকৃত উত্তরের একটি সংযোজন, পৃথক উত্তর হিসাবে যুক্ত হয়েছে যাতে আমি কোড ফর্ম্যাটিং পাই:

যদি আপনি একই প্রকল্পে আপনার ঘর তৈরি করছেন তবে সেগুলি সাধারণত রিলিজ, ডিবাগ ইত্যাদি ডিরেক্টরিতে থাকে। এগুলি সঠিকভাবে অনুলিপি করতে আপনাকে ভিজ্যুয়াল স্টুডিও পরিবেশের ভেরিয়েবলগুলি ব্যবহার করতে হবে। যেমন:

"${PROJECT_BINARY_DIR}/your_library/\$\(Configuration\)/your_library.dll"

উত্স এবং

"${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/your_library.dll"

গন্তব্য জন্য। পালানোর বিষয়টি খেয়াল করুন!

কনফিগারেশনের জন্য আপনি সিএমকে CMAKE_BUILD_TYPE ভেরিয়েবলটি ব্যবহার করতে পারবেন না কারণ এটি ভিএস প্রকল্পের উত্পাদনের সময় সমাধান হয়েছে এবং সর্বদা পূর্বনির্ধারিত যাই হোক।


8
গৃহীত উত্তরের শেষ অংশটি ক্লিনার সিএমকে ব্যবহার করে এটিকে সম্বোধন করে$<CONFIGURATION>
চক ক্লাঞ্চ

4

আপনি ফাইন্ড_লাইবারি কমান্ডটি ব্যবহার করতে পারেন:

find_library(<some_var> NAMES <name_of_lib> PATHS "<path/to/lib>")

উদাহরণস্বরূপ একটি সংজ্ঞায়িত EXECUTABLE_PATH সহ:

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

আপনার কার্যকর করার মতো প্রয়োজনীয় .dll ফাইলগুলি আপনি সরাতে পারেন

file(COPY ${<some_var>}
    DESTINATION ${EXECUTABLE_OUTPUT_PATH})

2

এটি তাদের একটির জন্য দরকারী

SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
    ${PROJECT_SOURCE_DIR}/lib CACHE
    PATH "Directory where all the .lib files are dumped." FORCE)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY
    ${PROJECT_SOURCE_DIR}/bin CACHE
    PATH "Directory where .exe and .dll files are dumped." FORCE)

1

আপনার সম্ভবত কাস্টম লক্ষ্য যুক্ত করা এবং এটি আপনার নির্বাহযোগ্য লক্ষ্যগুলির মধ্যে একটির উপর নির্ভরশীল করা দরকার।

উপরের ফাংশনটি ব্যবহার করে ফাইল অনুলিপি করতে:

COMMAND ${CMAKE_PROGRAM} -E copy_if_different ${CMAKE_BINARY_DIR}/path/to/file.dll ${CMAKE_BINARY_DIR}/where/to/put/file.dll`

0

আমি একজন সিএমকে শিক্ষানবিশ, তবুও আমি আমার অভিজ্ঞতা ভাগ করে নিতে চাই। আমার ক্ষেত্রে আমার একটি ইনস্টল-পরবর্তী অনুলিপিটি প্রয়োজন ছিল যাতে আমার সমস্ত বাইনারি থাকে CM

find_package( dependency REQUIRED )
if( MSVC ) 
    # If done properly and if the dependency has a correct config file, IMPORTED_LOCATION_RELEASE should be defined
    get_target_property( DEP_SHARED_LIB_PATH dependency IMPORTED_LOCATION_RELEASE )
    # Create a bin directory in the install folder
    add_custom_command(TARGET BGS POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory  ${CMAKE_INSTALL_PREFIX}/bin/)
    # Copy the shared lib file
    add_custom_command(TARGET BGS POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${DEP_SHARED_LIB_PATH} ${CMAKE_INSTALL_PREFIX}/bin/)
endif()

অবশ্যই ভাগ করে নেওয়া লাইব্রেরিটি কীভাবে নির্মিত / ইনস্টল করা হয়েছিল তার উপর নির্ভর করে IMPORTED_LOCATION_RELEASE এর বৈকল্পিক থাকতে পারে। IMPORTED_LOCATION_DEBUG হতে পারে।

সেই সম্পত্তির নাম পাওয়ার আরও ভাল উপায় হতে পারে, আমি জানি না।


0

বিল্ড ব্যবহারের সময় ফাইলগুলি সরানো install

পদক্ষেপ 9- এ সিএমকে অফিসিয়াল টিউটোরিয়ালটি অনুসরণ করার চেষ্টা করে আমার এই সমস্যাটি হয়েছিল । আমি যে ফাইলটি স্থানান্তর করতে চেয়েছিলাম এটির অবস্থান:

src
 |_build
    |_Debug
       - `MathFunctions.dll`

এই জায়গাটিই আমি ফাইলটি রাখতে চেয়েছিলাম:

src
 |_build
    |_install
         |_bin
             - `MathFunctions.dll`

যেহেতু এই ডিএলএলটি একটি ভাগ করা লাইব্রেরি হিসাবে তৈরি হয়েছিল, তাই আমি যা করেছি তা হ'ল এই লাইনটি উপCMakeLists.txt - ডিরেক্টরিতে লাইব্রেরির উত্স কোডটি অন্তর্ভুক্ত করা ছিলsrc/Mathfunctions/CMakeLists.txt

install(FILES ${PROJECT_BINARY_DIR}/$<CONFIG>/MathFunctions.dll
DESTINATION bin)

আপনার উত্তরগুলির জন্য ধন্যবাদ আমি এই সম্পর্কে ভাবতে পারি। শুধুমাত্র একটি লাইন, তাই আমি মনে করি ঠিক আছে। $<CONFIG>দুইটি মানের থাকতে পারে ডিবাগ বা রিলিজ জলবিদ্যুৎ প্রকল্প কীভাবে নির্মিত হয় উপর নির্ভর করে মূল প্রশ্ন প্রয়োজনীয়।

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