كيفية ربط ضد boost.system مع cmake
سؤال
ويمكنني استخدام cmake لدت MAKEFILE لترجمة ملف ج ++ التي تعتمد على مكتبة دفعة الملفات.
وخلال عملية الربط أحصل على الخطأ التالي:
Undefined symbols: "boost::system::get_generic_category()", referenced from: __static_initialization_and_destruction_0(int, int)in FaceRecognizer.cpp.o __static_initialization_and_destruction_0(int, int)in FaceRecognizer.cpp.o __static_initialization_and_destruction_0(int, int)in FaceRecognizer.cpp.o "boost::system::get_system_category()", referenced from: __static_initialization_and_destruction_0(int, int)in FaceRecognizer.cpp.o __static_initialization_and_destruction_0(int, int)in FaceRecognizer.cpp.o ld: symbol(s) not found collect2: ld returned 1 exit status make[2]: *** [src/ImageMarker] Error 1
ووالعمل من MAKEFILE أن يولد هذا الخطأ هو هذا السطر:
cd /Users/janusz/Documents/workspace/ImageMarker/Debug/src && /opt/local/bin/cmake -E cmake_link_script CMakeFiles/ImageMarker.dir/link.txt --verbose=1 /usr/bin/c++ -O3 -Wall -Wno-deprecated -g -verbose -Wl,-search_paths_first -headerpad_max_install_names -fPIC CMakeFiles/ImageMarker.dir/ImageMarker.cpp.o CMakeFiles/ImageMarker.dir/Image.cpp.o CMakeFiles/ImageMarker.dir/utils.cpp.o CMakeFiles/ImageMarker.dir/XMLWriter.cpp.o CMakeFiles/ImageMarker.dir/FaceRecognizer.cpp.o -o ImageMarker -L/opt/local/lib ../libTinyXml.a /opt/local/lib/libboost_filesystem-mt.dylib
وأظهر بعض غوغلينغ لي أن يبدو هذا الخطأ إلى أن تكون مشتركة على أجهزة ماكينتوش مع مكتبة نظام الملفات دفعة لأن لدي لربط ضد مكتبة boost.system أو تقديم مشروعي اعتمادا على مكتبة boost.system.
وكيف يمكنني اجبار cmake لربط ضد مكتبة بدون hardcoding مسار المكتبة؟
وهنا النتيجة من otool:
otool -L /opt/local/lib/libboost_filesystem-mt.dylib
/opt/local/lib/libboost_filesystem-mt.dylib:
/opt/local/lib/libboost_filesystem-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
/opt/local/lib/libboost_system-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.4.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0)
المحلول
في لينكس الأرقام CMake نفسها التي boost_filesystem يرتبط ضد boost_system. ومن الواضح أن عليك أن تخبر صراحة على نظام التشغيل Mac:
find_package(Boost COMPONENTS system filesystem REQUIRED)
#...
target_link_libraries(mytarget
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
)
نصائح أخرى
وهذه ليست "الجواب" على السؤال نشرها، ولكن الملاحظة على بلدي مربع أوبونتو.
لاستخدام يبس دفعة، عليك أن تكتب صراحة شيء من هذا القبيل:
find_package(Boost COMPONENTS regex system filesystem REQUIRED)
وبالإضافة إلى ذلك، تحتاج إلى ربطه بهذه الطريقة:
target_link_libraries(binary
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_REGEX_LIBRARY}
)
وولم بالطريقة التالية لا تعمل، على الأقل بالنسبة لي:
target_link_libraries(binary regex system filesystem)
ويأتي ذلك في أعقاب ما يقول مايك، ولكن ليس فقط على نظام التشغيل Mac.