C / C ++. كيفية استخدام موارد التطبيق المدمجة عند العمل في دول مجلس التعاون الخليجي على نظام Linux

أردت استخدام موارد لينكس المضمنة بطريقة أو بأخرى ، علاوة على ذلك ، تلقائيًا. بشكل عام ، المهمة هي:


  1. يوجد برنامج مشروع Eclipse في C ++.
  2. نظام التشغيل: Linux Ubuntu. المترجم: G ++
  3. يستخدم المشروع بيانات من ملفات خارجية: سلاسل الترجمة ، استعلامات SQL ، الصور ، الأصوات ، إلخ.
  4. يجب تضمين جميع الموارد في الملف القابل للتنفيذ ، لأنه من المخطط توزيع البرنامج على أنه قابل للنقل.
  5. بالإضافة إلى ذلك ، أريد أن تكون العملية تلقائية قدر الإمكان ، بسبب الكسل.

بادئ ذي بدء ، وفر البحث في المنتديات عدة طرق ممكنة لحل المشكلة. من بين أولئك الذين تبين أنهم الأكثر --format=binary ، بدت لي الفكرة لاستخدام --format=binary "- --format=binary " الخاصة --format=binary " ld ". وعد المنتدى المشاركات فريق من النموذج:

 g++ -Wl,--format=binary -Wl,my.res -Wl,--format=default 

سيتم ربط ملف "my.res" بالتطبيق وإنشاء حرفين - _binary_my_res_start و _binary_my_res_end ، للإشارة ، على التوالي ، إلى بداية ونهاية نفس البيانات التي كانت موجودة في الملف المرتبط. لذلك ، يمكن الوصول إلى البيانات من C ++ بشيء من هذا القبيل:
 extern const uint8_t my_res_start[] asm("_binary_my_res_start"); extern const uint8_t my_res_end[] asm("_binary_my_res_end"); 

ولكن كان هناك. نكتب كل شيء كما ينبغي ، والمترجم ليست سعيدة. الرمز «_binary_my_res_start» ، كما ترى ، لا يمكن العثور عليه. حسنا ، لا شيء ، nm لمساعدتنا. نكتب الأمر التالي:

 nm MyProgramm |grep -w -o -P -e '_binary_[\w\d_]+' 

ونحن نحصل على:

 _binary__home_unknown_workspace_MyProgramm_res_my_res_sql_end _binary__home_unknown_workspace_MyProgramm_res_my_res_sql_start 

اتضح أن اسم الرمز يتضمن المسار الكامل له ، والذي قد يؤدي في المستقبل إلى الحاجة إلى إعادة كتابة مستمرة لملف الرأس الذي يحتوي على روابط إلى الموارد. يتم حل المشكلة إذا تمت إضافة البرنامج النصي التالي إلى حدث PostBuild في إعدادات مشروع Eclipse:

 #!/bin/bash OUTPUT=$1/resources.h printf '#ifndef __RESOURCES_H__\n' > "$OUTPUT" printf '#define __RESOURCES_H__\n\n' >> "$OUTPUT" printf '#include <inttypes.h>\n\n' >> "$OUTPUT" SYMBOLS=$(nm NewsParser |grep -w -o -P -e '_binary_[\w\d_]+') >> "$OUTPUT" VAR_SIZES_LIST='' for SYMBOL in $SYMBOLS do VAR_NAME=$(echo $SYMBOL | grep -o -P -e 'res_[\w\d_]+'|cut -c 5-) if [[ -z $(echo $SYMBOL|grep _size) ]] then printf '\textern const uint8_t '$VAR_NAME'[]\tasm("'$SYMBOL'");\n\n' >> "$OUTPUT" else START_VAR=$(echo $VAR_NAME|rev|cut -c 5-|rev)'start' END_VAR=$(echo $VAR_NAME|rev|cut -c 5-|rev)'end' VAR_SIZES_LIST=$VAR_SIZES_LIST$(printf '\\tconst uint64_t '$VAR_NAME'\\t=\\t'$END_VAR' - '$START_VAR';\\n\\n') fi done printf "$VAR_SIZES_LIST" >> "$OUTPUT" printf '#endif\n' >> "$OUTPUT" printf 'File '$OUTPUT' is generated.\n' 

كيفية إضافة البرنامج النصي "update_resource.sh" ، الموجود في جذر المشروع ، إلى حدث PostBuild في إعدادات مشروع Eclipse.


حسنا. سيكون ملف الرأس الآن جديدًا في كل مرة ، ويمكنك الوصول إلى البيانات بأسماء المتغيرات التي لن تتغير إلا إذا قمت بإعادة تسمية ملف المورد نفسه. بالإضافة إلى ذلك ، يحسب هذا البرنامج النصي حجم كل مورد. لم يكن فقط أخذ المؤشر إلى البداية من المؤشر إلى النهاية مشكلة كبيرة ، ولكنه مع ذلك أكثر ملاءمة.

لكن هذا ، في الوقت الحالي ، ليس كل شيء. بعد كل شيء ، تتحول إضافة كل مورد جديد إلى مشروع إلى شكل م. ويمكن أيضًا حل هذه المشكلة بمساعدة برنامج نصي ، فقط في مرحلة الربط:

 FLAGS=$1 OUTPUT_FLAG=$2 OUTPUT_PREFIX=$3 OUTPUT=$4 INPUTS=$5 RESOURCE_PATH=$6 RESOURCES='' for res_file in $(ls $RESOURCE_PATH/*) do RESOURCES=$RESOURCES' '-Wl,$res_file echo ' '$res_file'   ' done g++ $FLAGS $OUTPUT_FLAG $OUTPUT_PREFIX$OUTPUT $INPUTS -Wl,--format=binary $RESOURCES -Wl,--format=default 

كيفية استبدال استدعاء الرابط القياسي بنص مخصص في إعدادات مشروع Eclipse.


  • يتم وضع علامة باللون الأحمر في الصورة ، حيث يوجد المسار إلى البرنامج النصي "link.sh" بدلاً من الأمر القياسي للاتصال بالرابط ، في جذر المشروع.
  • اللون الأخضر في الصورة هو المكان الذي يتم فيه إضافة رابط آخر إلى معلمات linker المعتادة ، والتي تخبر البرنامج النصي بموقع الدليل بالموارد.
  • بالإضافة إلى ذلك ، من المهم عدم نسيان التفاف المعلمات المتبقية بعلامات اقتباس مزدوجة حتى لا يتم قطع مسافات بطريق الخطأ بالترتيب الخاطئ الذي ينتظره البرنامج النصي.


ممتاز. الآن ستقع جميع الملفات الموجودة في الدليل الفرعي "res" في الموارد أثناء كل تجميع.

Source: https://habr.com/ru/post/ar468399/


All Articles