سؤال

أحاول إنشاء تطبيق Mac في Xcode الذي يحتوي على بعض تطبيقه في مكتبة ديناميكية.

أضفت هدفا جديدا (مكتبة ديناميكية) إلى مشروع Xcode Cocoa الخاص بي وبعد القتال مع الأطر مع الأطر والرؤوس المدبرة، تحتوي على تجميع Dynlib - وتشغيل بنجاح من المصحح.

عند تشغيل مستقل ولكن من الواضح أن Dynlib في المكان الخطأ. "المكتبة غير محملة: /usr/local/lib/testlib.dynlib". على Windows - منصبي أكثر المعتادة - يمكن وضع DLLs في نفس المجلد مثل EXE، وفي أي مكان على مسار النظام.

أفضل أن أبحث عن تطبيقي للبحث عن Dynlib في مكان ما في حزمة تطبيقه (ويبدو أن بعض المستندات تأكيد هذا النهج الصحيح)، لكنني لا أعرف كيف.

هل من الممكن تكوين المشروع في Xcode بحيث يتم نسخ Dylib بالفعل إلى حزمة التطبيق، في مكان سيبحث فيه التطبيق عنه؟


يبدو أنني لا أحتاج إلى استخدام Otool لإعادة ضبط مسار البحث. إذا قمت بتحرير المعلومات المستهدفة -> Build -> النشر -> دليل التثبيت الذي يمكنني تغييره، من داخل Xcode، المسار الذي ستنظر فيه Dyld إلى DYLIB. افتراضيا لمشروع مكتبة ديناميكي جديد، تم ضبط المسار على /usr/local/lib. وبعد التي تغيرت إليها ./ - otool يؤكد ذلك ./ هو الآن حيث ستبحث Dyld عن هذه الوحدة الديناميكية المحددة. لسوء الحظ. / لا يبدو أنه يشير فعليا إلى أي دليل في حزمة طلبي :(

لذلك، أسئلتي (التي لم تتم الإجابة عليها في مؤشر الترابط الآخر) الآن هي: 1. كيف يمكنني إدخال مغزى نسبيا المسار في المعلومات المستهدفة -> ... -> إعداد دليل التثبيت، و 2. كيف يمكنني الحصول على Xcode لنسخ هدف DYLIB تلقائيا في مجلد Bundle Bound's Bunder في الموقع النسبي؟

هل كانت مفيدة؟

المحلول

أخيرا. وجد بعض الوثائق الرسمية. وبعد من الممكن القيام بذلك تماما داخل Xcode.

كنت في منتصف الطريق لتعديل إعداد الدليل المثبت في المكتبة: يحتاج إلى أن يكون: @executable_path/../Frameworks

ثم كنت بحاجة إلى إضافة خطوة "نسخ ملفات" إلى المكتبة لتنسخها بالفعل إلى مجلد الأطر.

بسيط. تلقائي

نصائح أخرى

أعتقد أنك لا نسخ المكتبة الديناميكية في حزمة التطبيق في وقت الترجمة.

يبحث التطبيق عن نقطة في نظام الملفات، ولكنه يفعل هذا فقط بعد عدم العثور عليه داخل حزمة التطبيق. تحتاج إلى استخدام otool أمر لتعديل الثنائي بعد تجميعه (باستخدام برنامج نصي بناء).

ستجد لك الإجابة في السؤال الذي سبق طرحه:كيف يمكنني إنشاء مكتبة ديناميكية في Xcode.

حظ سعيد.

بعد الكثير من الأبحاث التي حصلت عليها، كنت أحاول أن أحسب بعض OpenCV Dylib مع طلبي لأنني كنت أتلقى "المكتبة غير محملة: ...." خطأ.

يحتوي Dylibs على اسم تثبيت يشير إلى المكان الذي قمت بتثبيته عندما فعلت ذلك في المرة الأولى (يقوم macports بتثبيتها على / opt / lib / lib /). لديهم أيضا الطريق إلى Dylib الأخرى التي يحتاجون إليها للعمل. على سبيل المثال، إذا كان لديك Dylib يسمى "Libopencv_core.2.4.8.dylib" يمكنك التحقق من اسم التثبيت والمسارات إلى Dylibs الأخرى التي تستخدمها مع هذا الأمر:

otool -L libopencv_core.2.4.8.dylib

إخراج الأمر هو:

libopencv_core.2.4.8.dylib:
/opt/local/lib/libopencv_core.2.4.dylib (compatibility version 2.4.0, current version 2.4.8)
/opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

1- السطر الأول: اسم الملف الذي تقوم بالتحقق منه.

2- السطر الثاني: تثبيت اسم Dylib الذي تقوم بالتحقق منه. (macports تثبيتها في / opt / local / lib /)

3- السطر الثالث: المسار إلى Dylibs الأخرى التي تحتاج إلى العمل ليست في جميع أنظمة OSX. (تقوم Macports بتثبيتها في / opt / lib / lib / وكنت لديك لأنك مثبت سابقا، ولهذا السبب إذا قمت بتوزيع تطبيقك على أجهزة Mac الأخرى التي تحصل عليها خطأ "لم يتم العثور على المكتبة")

4 و 5 - الخطوط 4 و 5: Dylibs داخل جميع أنظمة ماكوسكس. لا تحتاج إلى نسخها في مشروعك.

الآن نحن نعرف هذا، أهدافنا هي:

1- تغيير جميع المسارات داخل Dylibs (تثبيت الأسماء والمسارات إلى Dylibs الأخرى اللازمة) لأننا سنضع Dylibs داخل التطبيق في دليل "الأطر"، وعند نقل التطبيق أو نسخه إلى Mac الأخرى نريد أن نبحث Dylibs عن بعضها البعض داخل مجلد "الأطر" داخل دليل التطبيق لدينا: المسار الذي نستخدمه هو:

@executable_path/../Frameworks/nameOFTheDylib.dylib

(لاحظ النقطتين مهمة حقا!)

2- نسخة إلى xcode جميع dylibs التي نحتاجها، ولكن ليس كل ديليبس داخل مجلد / opt / local / lib، فقط تلك التي نحتاجها: (كلهم أكثر من اللازم، ربما 500 ميغابايت) سنحتاج إلى متابعة روابط من Dylibs نحن نعلم أننا نحتاجها (عادة 4 أو 5) و Dylibs المضمنة لأن هؤلاء 4 أو 5 بحاجة إليهم للعمل.

نعم أخيرا فعلت ذلك بهذه الطريقة:

أ) تغيير المسارات:

1- نسخ جميع ملف / opt / local / lib إلى سطح المكتب.

2- قم بإزالة جميع الملفات داخل مجلد LIB غير المحفوظات .dylib.

3-ضع هذا البرنامج النصي داخل مجلد LIB (مع Dylibs) لقد نسخنا للتو في سطح المكتب:

(انسخ هذا النص في TextEdit وحفظه كما oneameyouprefer.sh)

#!/bin/bash
echo empieza el script

EXECFILE=${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}
OLDLIBPATH="/opt/local/lib/"
NEWLIBPATH="@executable_path/../Frameworks/"
ACTUALPATH=`pwd`
# space separated list of libraries
for TARGET in ${ACTUALPATH}/* ; do
TARGET=$(basename $TARGET)
    if [ ${TARGET: -6} == ".dylib" ]
    then
        echo otool -DX ${TARGET}
        TARGETID=`otool -DX ${TARGET}`
        echo ${TARGETID}

        echo install_name_tool -id ${NEWLIBPATH}${TARGET} ${TARGET}
        echo `install_name_tool -id ${NEWLIBPATH}${TARGET} ${TARGET}`

        for DYLIB in ${ACTUALPATH}/* ; do
        DYLIB=$(basename $DYLIB)
            if [ ${DYLIB: -6} == ".dylib" ]
            then
                echo install_name_tool -change ${TARGETID} ${NEWLIBPATH}${TARGET} ${DYLIB}
                echo `install_name_tool -change ${TARGETID} ${NEWLIBPATH}${TARGET} ${DYLIB}`
            else
                if [ ${DYLIB: -3} == ".sh" ]
                then
                    echo soyYo
                else
                    echo mkdir ${ACTUALPATH}/eliminadas/
                    echo `mkdir ${ACTUALPATH}/eliminadas/`
                    echo mv ${DYLIB} ${ACTUALPATH}/eliminadas
                    echo `mv ${TARGET} ${ACTUALPATH}/eliminadas`
                fi
            fi
        done
    else
if [ ${TARGET: -3} == ".sh" ] || ![ -h ${TARGET} ]
        then
            echo noMeElimino
        else
            echo mkdir ${ACTUALPATH}/eliminadas/
            echo `mkdir ${ACTUALPATH}/../eliminadas/`
            echo mv ${TARGET} ${ACTUALPATH}/eliminadas/${TARGET}
            echo `mv ${TARGET} ${ACTUALPATH}/../eliminadas`
        fi
    fi
done

echo finaliza el script

4- تنفيذ ذلك:

cd Desktop/lib
sudo ./theNameYouPrefer.sh

من المهم حقا تشغيله أثناء سودو، لأن Dylibs يمكن حماية الكتابة.

في هذه المرحلة، يجب أن يكون لديك جميع مسارات Dylibs تغيرت. يمكنك التحقق من ذلك في بعض Dylibs مع الأمر:

otool -L theDylibYouPrefer.dylib

ب) حدد فقط Dylibs اللازمة، وليس كل مجلد LIB:

1-إعادة تسمية مجلد lib إلى lib2: lib =====> lib2

2- قم بإنشاء مجلد آخر (مع الاسم الذي تفضله، على سبيل المثال ExamplidFolder) في سطح المكتب، بجانب مجلد Lib2.

3- نسخة داخل Examplidder هي Dylibs الهامة التي تعرف أنك ستحتاج إليها بالتأكيد، في حالتي هي: libopencv_core.2.8.8.8.8.8.8.8.8.dylib، libopencv_imgproc.2.4.8.dylib، libopencv_objdetect. 2.4.8.dylib.

4- النصي: انسخه داخل المثال، بجانب dylibs الهامة. أنا لا أعرف الكثير عن البرامج النصية، لذلك هذا واحد أكثر قذرة قليلا:

#!/bin/bash
echo empieza el script

EXECFILE=${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}
OLDLIBPATH="/opt/local/lib/"
NEWLIBPATH="@executable_path/../Frameworks/"
ACTUALPATH=`pwd`
# space separated list of libraries
for TARGET in ${ACTUALPATH}/* ; do
TARGET=$(basename $TARGET)
    if [ ${TARGET: -6} == ".dylib" ]
    then
        echo otool -DX ${TARGET}
        TARGETID=`otool -L ${TARGET}`
echo ${TARGETID}

echo :::::::::::::::::::::::::::

ELIM=`echo ${TARGETID} | sed 's/([^)]*)/UUU/g'`
echo $ELIM
#echo ${TARGETID} | sed 's/([^)]*)/UUU/g'
ELIM=`echo $(awk '{gsub("@executable_path/../Frameworks/", "");print}' <<< ${ELIM})`
echo $ELIM

ELIM=`echo $(awk '{gsub(" UUU", "");print}' <<< ${ELIM})`
echo $ELIM

ELIM=`echo $(awk '{gsub(":", "");print}' <<< ${ELIM})`
echo $ELIM

IFS=' ' read -a ARRAY <<< $ELIM

for element in ${ARRAY[@]}
do
    echo $element
    if [[ ${element} == */* ]]
    then
        echo "NO FRAMEWORK";
    else
        echo `mkdir ${ACTUALPATH}/../copy`
        echo `cp ${ACTUALPATH}/../lib2/${element} ${ACTUALPATH}/${element}`
    fi
done


    else
if [ ${TARGET: -3} == ".sh" ] || ![ -h ${TARGET} ]
        then
            echo noMeElimino
        else
            echo mkdir ${ACTUALPATH}/eliminadas/
            echo `mkdir ${ACTUALPATH}/../eliminadas/`
            echo mv ${TARGET} ${ACTUALPATH}/eliminadas/${TARGET}
            echo `mv ${TARGET} ${ACTUALPATH}/../eliminadas`
        fi
    fi
done

echo finaliza el script

5- تنفيذ هذا البرنامج النصي عدة مرات، حتى تقدر أن عدد الملفات داخل المثال لا يتغير.

6- ديليبس تحتاجها هي جميعها داخل المثال! في حالتي، حصلت على 61 ديليبي. (تذكر عندما بدأنا وضعت هناك 4 Dylibs)

7- آخر شيء تحتاج إلى القيام به هو إسقاط مجلد "الأطر" في Xcode. بعد ذلك تذكر أن تذهب إلى "بناء مراحل" وإضافة مرحلة "نسخ ملفات": "محرر" => "إضافة مرحلة البناء" => "إضافة مرحلة بناء ملفات النسخ" وداخل المرحلة "نسخ الملفات" انقر فوق Plus أيقونة وإضافة هناك جميع dylibs تجد في مجلد "frameWroks". الوجهة التي تحتاجها هي الأطر.

وهذا هو، لقد حصلت عليه بهذه الطريقة أكثر أو أقل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top