2009-10-28 12 views
7

मैं एक स्थिर पुस्तकालय (file.a) में संस्करण संख्या कैसे संग्रहीत कर सकता हूं और बाद में लिनक्स में इसके संस्करण की जांच कर सकता हूं?एक स्थिर पुस्तकालय में संस्करण संख्या को कैसे स्टोर करें?

पीएस मुझे केवल किसी भी विशेष निष्पादन योग्य के बिना खोल उपयोगिताओं का उपयोग करके फ़ाइल के संस्करण की जांच करने की संभावना है।

+0

नीचे दिए गए समाधान (दो लिखने के रूप में) दोनों साझा पुस्तकालयों के लिए भी उपलब्ध हैं। –

+0

बस आपके संपादन के आधार पर एक और जवाब जोड़ा गया ... उम्मीद है कि मदद करता है। – jheddings

उत्तर

8

हो सकता है कि आप इस तरह के संस्करण के साथ एक स्ट्रिंग बना सकते हैं:

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

और खोल से यह जांच करने के लिए सक्षम होने के लिए बस का उपयोग करें:

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

आप निश्चित रूप से, 'कॉन्स्ट चार लाइब्रेरी_वर्जन [] = "1.3.6" बना सकते हैं;' पॉइंटर के लिए जगह को सहेजने के लिए। और आप लाइब्रेरी के हेडर में वैरिएबल घोषित करेंगे (या लाइब्रेरी के साथ वितरित हेडर में)। –

+0

कृपया मेरे प्रश्न को दोबारा जांचें - इसे अपडेट किया गया था – Pirks

+1

शैल – Puppe

8

इसके अलावा एक स्थिर स्ट्रिंग प्रदान करने के लिए जैसा कि 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 
}; 

यह एक struct अपने पुस्तकालय में mylib_version कहा जाता है पैदा करेगा। आप इस का उपयोग कर सकते हैं अपने पुस्तकालय के अंदर कार्यों बनाने और बुला आवेदन से उन तक पहुँचने, आदि

+1

MYLIB_VERSION_CHECK के साथ एकमात्र मुद्दा यह है कि यह संकलित समय पर मूल्यांकन किया जाता है, और एक अच्छा अनुकूलक चेक को हटा देगा अगर सबकुछ ठीक है, और बिना शर्त रूप से printf() को कॉल करेगा - आपका मतलब है fprintf (stderr, ...), है ना? - और बाहर निकलें()। मुझे लगता है कि निरंतर अभिव्यक्ति का उपयोग करने के बजाय तर्क को एम्बेड करने वाले फ़ंक्शन को कॉल करना बेहतर होगा। –

+0

हाँ, यहां अच्छे अंक ... मैंने बाद में इस पोस्ट के लिए लाइब्रेरी में जानकारी एम्बेड करने के लिए अपनी पोस्ट संपादित की। स्पष्टीकरण के लिए धन्यवाद। – jheddings

+0

कृपया मेरे प्रश्न को दोबारा जांचें - इसे – Pirks

3

आपके संपादन के आधार एक नया उत्तर बनाकर आगे सत्यापन करने के लिए ... बस भ्रम :)

हैं से बचने के लिए आप समस्या को हल करने के लिए एक गैर-कोड तरीका ढूंढ रहे हैं, आप इसे आजमा सकते हैं। यह Pupp द्वारा परिभाषित strings दृष्टिकोण के लिए एक विकल्प है (फिर भी)।

शायद आप version_1.2.3 नामक फ़ाइल को स्पर्श कर सकते हैं और इसे संग्रह में जोड़ सकते हैं। उसके बाद, आप ar आदेश का उपयोग संस्करण फ़ाइल की तलाश द्वारा संस्करण का निर्धारण कर सकते हैं:

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

मुझे यकीन है कि अगर है कि तुम क्या जरूरत है आप मिल जाएगा नहीं कर रहा हूँ, लेकिन वहाँ इस तरह मेटाडाटा एम्बेड करने के लिए कोई मानक पद्धति है, एक संग्रह में। शायद आपको अन्य जानकारी मिल जाएगी जो आप संग्रह के लिए इस "मेटाफाइल" में स्टोर करना चाहते हैं।

+0

अपडेट किया गया था ** 'मैन 1 पहचान' ** के बारे में कैसे? –

+0

यह विधि संस्करण नियंत्रण के लिए अच्छा नहीं है। –

+0

@ vitaly.v.ch लिनक्सक्स के अलावा कुछ भी उपलब्ध नहीं है। – MarcusJ

0

कई बार man 1 ident का उल्लेख किया गया है, इसलिए यहां उस विधि का उपयोग करने के बारे में विवरण हैं।

ident एक आदेश है जो आरसीएस (संशोधन नियंत्रण प्रणाली) के साथ आता है, लेकिन यदि आप सीवीएस (समवर्ती संस्करण प्रणाली) या सबवर्जन का उपयोग कर रहे हैं तो भी उपलब्ध हो सकता है।

आप इसे इस तरह का प्रयोग करेंगे (आदमी पेज से क्लोन):

#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; } 

और एफसी के लिए, फिर कमांड

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 को एक समान आउटपुट दिखाना चाहिए। यदि आपके az.a में आपके समान [a-z].o निर्मित हैं, तो आपको az.a फ़ाइल में अपने सभी तारों को ढूंढना चाहिए।

कैवेट: सिर्फ इसलिए कि वे .a फ़ाइल में हैं, इसका मतलब यह नहीं है कि उन्हें आपकी प्रोग्राम फ़ाइल में शामिल किया जाएगा। जब तक कार्यक्रम उन्हें संदर्भित नहीं करता है तब तक लिंकर को शामिल करने की आवश्यकता नहीं होती है। इसलिए आपको आमतौर पर स्ट्रिंग को वापस करने के लिए प्रत्येक मॉड्यूल में एक विधि होनी चाहिए, और ऐप को उस विधि को कॉल करने की आवश्यकता है। अधिकांश लिंकर्स को मनाने के तरीके हैं कि यह वास्तव में संदर्भित किए बिना एक आवश्यक प्रतीक है, लेकिन यह लिंकर पर निर्भर करता है, और इस उत्तर के दायरे से बाहर है।

आप 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; } 

और एफसी के लिए, फिर कमांड

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 
में संकलित किया गया है

पीएस: ident और what दोनों आदेश हैं जो विशिष्ट केंद्रीकृत स्रोत नियंत्रण प्रणाली के साथ आते हैं। यदि आप एक वितरित स्रोत नियंत्रण प्रणाली (जैसे गिट) का उपयोग कर रहे हैं तो पूरी अवधारणा समझ में नहीं आ सकती है। git का उपयोग कर कुछ विचारों के लिए यह धागा देखें: Moving from CVS to git: $Id:$ equivalent? हालांकि हैश एक संस्करण संख्या के समान नहीं है। :)

0

आप जीसीसी का उपयोग कर रहे हैं, तो आप #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 (यह संकलित वस्तुओं से संकलक संस्करण टिप्पणियों को भी छोड़ देगा)

संबंधित मुद्दे