سؤال

وكيف يمكنني تخزين رقم الإصدار في مكتبة ثابتة (file.a) وتحقق في وقت لاحق عن نسخته في لينكس؟

وP.S. أحتاج إمكانية للتحقق نسخة من ملف أي وقت دون أي قابل للتنفيذ الخاص باستخدام إلا عن طريق المرافق قذيفة.

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

المحلول

وربما كنت قد يخلق سلسلة مع إصدار مثل هذا:

char* library_version = { "Version: 1.3.6" };

وولتكون قادرة على التحقق من ذلك من قذيفة مجرد استخدام:

strings library.a | grep Version | cut -d " " -f 2

نصائح أخرى

وبالإضافة إلى توفير سلسلة ثابتة كما ذكر Puppe، بل هو ممارسة شائعة لتوفير ماكرو لاسترداد الاختيار إصدار من أجل التوافق. على سبيل المثال، يمكن أن يكون لديك وحدات الماكرو التالية (أعلن في ملف رأس ليتم استخدامها مع المكتبة الخاصة بك):

#define MYLIB_MAJOR_VERSION 1
#define MYLIB_MINOR_VERSION 2
#define MYLIB_REVISION 3
#define MYLIB_VERSION "1.2.3"
#define MYLIB_VERSION_CHECK(maj, min) ((maj==MYLIB_MAJOR_VERSION) && (min<=MYLIB_MINOR_VERSION))

وإشعار مع الماكرو MYLIB_CHECK_VERSION، أفترض أنك ترغب في مراجعة رئيسية محددة وأكبر مراجعة طفيفة من أو يساوي إلى الإصدار المطلوب. تتغير كما هو مطلوب للتطبيق الخاص بك.

وثم استخدامها من تطبيق الدعوة، وشيء من هذا القبيل:

if (! MYLIB_VERSION_CHECK(1, 2)) {
    fprintf(stderr, "ERROR: incompatible library version\n");
    exit(-1);
}

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

ويمكنك أيضا استخدام هذه المعلومات لإنشاء سلسلة ثابتة المخزنة داخل المكتبة، كما ذكر Puppe. ضع شيئا من هذا القبيل داخل المكتبة:

struct {
    const char* string;
    const unsigned major;
    const unsigned minor;
    const unsigned revision;
} mylib_version = {
    MYLIB_VERSION, MYLIB_MAJOR_VERSION, MYLIB_MINOR_VERSION, MYLIB_REVISION
};

وهذا سيخلق بنية تسمى mylib_version في مكتبتك. يمكنك استخدام هذا للقيام مزيد من التحقق من خلال خلق وظائف داخل المكتبة والوصول إلى تلك من تطبيق الدعوة، وما إلى ذلك.

وإنشاء إجابة جديدة تقوم على تحرير الخاص بك ... فقط لتجنب الارتباك:)

إذا كنت تبحث عن وسيلة غير رمز لحل المشكلة، قد تتمكن من محاولة هذا. انها (مرة أخرى) بديلا لنهج strings يحددها Puppe.

وربما يمكن أن مجرد لمس ملف يسمى version_1.2.3 وإضافته إلى الأرشيف. ثم، هل يمكن تحديد الإصدار من خلال النظر لملف النسخة باستخدام الأمر ع:

ar t libmylib.a | grep 'version_' | sed -e 's/^version_//'

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

تم ذكرها عدة مرات man 1 ident، حتى هنا تفاصيل حول استخدام هذا الأسلوب.

وident هو الأمر الذي يأتي مع RCS (نظام التحكم في مراجعة)، لكنها قد تكون متاحة أيضا إذا كنت تستخدم CVS (المتزامن إصدارات النظام)، أو التخريب.

ويمكنك أن استخدام مثل هذا (المستنسخة من الصفحة رجل):

#include <stdio.h>
static char const rcsid[] =
    "$Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp $";
int main() { return printf("%s\n", rcsid) == EOF; }

ويتم تصنيف f.c إلى f.o، ثم الأمر

ident f.c f.o

وإرادة الانتاج

   f.c:
       $Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp $
   f.o:
       $Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp $

إذا تم إضافة f.o الخاص بك إلى f.a مكتبة ثابت ثم ident f.a يجب أن تظهر إخراج مشابه. إذا كان لديك عدة بنيت بالمثل [a-z].o في az.a الخاص بك يجب أن تجد كافة السلاسل في ملف az.a.

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

إذا بدلا من ذلك كنت معتادا على (نظام التحكم في شفرة المصدر) SCCS ثم يمكنك استخدام man 1 what بدلا من ذلك، وأنها تبدو مثل هذا (فعلت مع وحدات الماكرو لإظهار المرونة وجدت):

#include <stdio.h>
#define VERSION_STR "5.4"
#define CONFIG "EXP"
#define AUTHOR "eggert"
static char const sccsid[] =
    "@(#) " CONFIG " v " VERSION_STR " " __DATE__ " " __TIME__ " " AUTHOR;
int main() { return printf("%s\n", sccsid) == EOF; }

ويتم تصنيف f.c إلى f.o، ثم الأمر

what f.c f.o

وإرادة الانتاج

   f.c:
       @(#) EXP v 5.4 1993/11/09 17:40:15 eggert
   f.o:
       @(#) EXP v 5.4 1993/11/09 17:40:15 eggert

وPS: كلا ident وwhat هي الأوامر التي تأتي مع أنظمة التحكم بالمصادر مركزية محددة. إذا كنت تستخدم نظام التحكم المصدر وزعت (مثل بوابة) مفهوم كله قد لا يكون له معنى. بالنسبة لبعض الأفكار باستخدام git نرى هذا الموضوع: الانتقال من CVS إلى بوابة: $ رقم: $ أي ما يعادل؟ على الرغم من أن التجزئة ليس هو نفس رقم الإصدار. :)

إذا كنت تستخدم دول مجلس التعاون الخليجي، يمكنك استخدام التوجيه #ident

#ident "Foo Version 1.2.3.4"
void foo(void){ /* foo code here */ }

للحصول على نسخة استخدام واحد فقط مما يلي:

strings -a foo.o | grep "Foo Version"
strings -a foo.a | grep "Foo Version"
strings -a foo.so | grep "Foo Version"

وهذا سوف يسمح لك لتجميع نسخة في المكتبة لديها القدرة على تجريد لاحقا من استخدام strip -R .comment your_file أو كليا حذف ذلك عن طريق تمرير -fno-ident (وهذا أيضا حذف التعليقات النسخة مترجم من الكائنات المترجمة)

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