문제

정적 라이브러리 (파일)에 버전 번호를 저장하고 나중에 Linux에서 해당 버전을 확인하려면 어떻게해야합니까?

추신 : 쉘 유틸리티 만 사용하여 특별한 실행 가능없이 언제든지 파일 버전을 확인할 가능성이 필요합니다.

도움이 되었습니까?

해결책

어쩌면 다음과 같은 버전으로 문자열을 만들 수 있습니다.

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))

Notice with the MYLIB_CHECK_VERSION 매크로, 나는 당신이 원하는 버전보다 더 큰 특정 메이저 레브와 사소한 Rev를 원한다고 가정합니다. 응용 프로그램에 필요한 경우 변경하십시오.

그런 다음 호출 응용 프로그램에서 다음과 같은 것과 같은 것을 사용하십시오.

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 명령을 사용하여 버전 파일을 찾아 버전을 결정할 수 있습니다.

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

그것이 필요한 것을 얻을 수 있는지 확실하지 않지만 아카이브에 이와 같은 메타 데이터를 포함시키는 표준 방법은 없습니다. 어쩌면 아카이브를 위해이 "metafile"에 저장하려는 다른 정보를 찾을 수 있습니다.

여러번 man 1 ident 언급되었으므로 여기에 해당 방법을 사용하는 것에 대한 세부 사항이 있습니다.

ident RCS (개정 제어 시스템)와 함께 제공되는 명령이지만 CVS (동시 버전 시스템) 또는 전복을 사용하는 경우에도 사용할 수 있습니다.

당신은 이것 (Man Page에서 클로닝)처럼 사용할 것입니다.

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

그리고 FC는 FO로 컴파일 된 다음 명령

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 파일.

경고 : .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; }

그리고 FC는 FO로 컴파일 된 다음 명령

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)을 사용하는 경우 전체 개념이 의미가 없을 수 있습니다. 몇 가지 아이디어를 사용합니다 git 이 스레드를 참조하십시오 : CVS에서 GIT로 이동 : $ ID : $ 동등한? 해시는 버전 번호와 동일하지는 않지만. :)

GCC를 사용하는 경우 #INDEND 지시문을 사용할 수 있습니다.

#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