IT이야기

__DA 사용방법TE__와 __TIME__의 매크로가 2개의 정수로 정의되어 있습니다.그러면 스트링화?

cyworld 2022. 5. 27. 21:22
반응형

__DA 사용방법TE__와 __TIME__의 매크로가 2개의 정수로 정의되어 있습니다.그러면 스트링화?

컴파일 시 코드에 자동 버전을 제공하기 위한 정수로 __ DATE ____ TIME __ 를 사용합니다.

#define STRINGIZER(arg)     #arg
#define STR_VALUE(arg)      STRINGIZER(arg)

#define DATE_as_int_str useD(__DATE__) // What can be done ?
#define TIME_as_int_str useT(__TIME__) // What can be done ?

#define VERSION 1.4

#define COMPLETE_VERSION STR_VALUE(VERSION) "." DATE_as_int_str "." TIME_as_int_str

COMPLETE_VERSION의 문자열로서const unsigned char [].

const unsigned char completeVersion[] = ?? COMPLETE_VERSION;

1.4.1432.2234를 출력합니다.

생각할 수 있는 솔루션 중 하나는 다음과 같습니다: convert-date-to-unsigned-int.

컴파일 시간 convertint-date-and-time-string-to-just-integers-in-c에서는 확장 및 문자열화 방법을 참조할 수 있습니다.

C++ 컴파일러를 사용하여 버전 문자열을 포함하는 오브젝트 파일을 작성할 수 있다면 원하는 대로 할 수 있습니다.여기서 유일한 마법은 C++에서는 식을 사용하여 어레이를 정적으로 초기화할 수 있지만 C에서는 그렇지 않다는 것입니다.표현식은 컴파일 시 완전히 계산 가능해야 하지만 이러한 표현식은 계산 가능하므로 문제 없습니다.

버전 문자열을 한 번에 1바이트씩 구축하면 원하는 것을 얻을 수 있습니다.

// source file version_num.h

#ifndef VERSION_NUM_H

#define VERSION_NUM_H


#define VERSION_MAJOR 1
#define VERSION_MINOR 4


#endif // VERSION_NUM_H

// source file build_defs.h

#ifndef BUILD_DEFS_H

#define BUILD_DEFS_H


// Example of __DATE__ string: "Jul 27 2012"
//                              01234567890

#define BUILD_YEAR_CH0 (__DATE__[ 7])
#define BUILD_YEAR_CH1 (__DATE__[ 8])
#define BUILD_YEAR_CH2 (__DATE__[ 9])
#define BUILD_YEAR_CH3 (__DATE__[10])


#define BUILD_MONTH_IS_JAN (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n')
#define BUILD_MONTH_IS_FEB (__DATE__[0] == 'F')
#define BUILD_MONTH_IS_MAR (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r')
#define BUILD_MONTH_IS_APR (__DATE__[0] == 'A' && __DATE__[1] == 'p')
#define BUILD_MONTH_IS_MAY (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y')
#define BUILD_MONTH_IS_JUN (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n')
#define BUILD_MONTH_IS_JUL (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l')
#define BUILD_MONTH_IS_AUG (__DATE__[0] == 'A' && __DATE__[1] == 'u')
#define BUILD_MONTH_IS_SEP (__DATE__[0] == 'S')
#define BUILD_MONTH_IS_OCT (__DATE__[0] == 'O')
#define BUILD_MONTH_IS_NOV (__DATE__[0] == 'N')
#define BUILD_MONTH_IS_DEC (__DATE__[0] == 'D')


#define BUILD_MONTH_CH0 \
    ((BUILD_MONTH_IS_OCT || BUILD_MONTH_IS_NOV || BUILD_MONTH_IS_DEC) ? '1' : '0')

#define BUILD_MONTH_CH1 \
    ( \
        (BUILD_MONTH_IS_JAN) ? '1' : \
        (BUILD_MONTH_IS_FEB) ? '2' : \
        (BUILD_MONTH_IS_MAR) ? '3' : \
        (BUILD_MONTH_IS_APR) ? '4' : \
        (BUILD_MONTH_IS_MAY) ? '5' : \
        (BUILD_MONTH_IS_JUN) ? '6' : \
        (BUILD_MONTH_IS_JUL) ? '7' : \
        (BUILD_MONTH_IS_AUG) ? '8' : \
        (BUILD_MONTH_IS_SEP) ? '9' : \
        (BUILD_MONTH_IS_OCT) ? '0' : \
        (BUILD_MONTH_IS_NOV) ? '1' : \
        (BUILD_MONTH_IS_DEC) ? '2' : \
        /* error default */    '?' \
    )

#define BUILD_DAY_CH0 ((__DATE__[4] >= '0') ? (__DATE__[4]) : '0')
#define BUILD_DAY_CH1 (__DATE__[ 5])



// Example of __TIME__ string: "21:06:19"
//                              01234567

#define BUILD_HOUR_CH0 (__TIME__[0])
#define BUILD_HOUR_CH1 (__TIME__[1])

#define BUILD_MIN_CH0 (__TIME__[3])
#define BUILD_MIN_CH1 (__TIME__[4])

#define BUILD_SEC_CH0 (__TIME__[6])
#define BUILD_SEC_CH1 (__TIME__[7])


#if VERSION_MAJOR > 100

#define VERSION_MAJOR_INIT \
    ((VERSION_MAJOR / 100) + '0'), \
    (((VERSION_MAJOR % 100) / 10) + '0'), \
    ((VERSION_MAJOR % 10) + '0')

#elif VERSION_MAJOR > 10

#define VERSION_MAJOR_INIT \
    ((VERSION_MAJOR / 10) + '0'), \
    ((VERSION_MAJOR % 10) + '0')

#else

#define VERSION_MAJOR_INIT \
    (VERSION_MAJOR + '0')

#endif

#if VERSION_MINOR > 100

#define VERSION_MINOR_INIT \
    ((VERSION_MINOR / 100) + '0'), \
    (((VERSION_MINOR % 100) / 10) + '0'), \
    ((VERSION_MINOR % 10) + '0')

#elif VERSION_MINOR > 10

#define VERSION_MINOR_INIT \
    ((VERSION_MINOR / 10) + '0'), \
    ((VERSION_MINOR % 10) + '0')

#else

#define VERSION_MINOR_INIT \
    (VERSION_MINOR + '0')

#endif



#endif // BUILD_DEFS_H

// source file main.c

#include "version_num.h"
#include "build_defs.h"

// want something like: 1.4.1432.2234

const unsigned char completeVersion[] =
{
    VERSION_MAJOR_INIT,
    '.',
    VERSION_MINOR_INIT,
    '-', 'V', '-',
    BUILD_YEAR_CH0, BUILD_YEAR_CH1, BUILD_YEAR_CH2, BUILD_YEAR_CH3,
    '-',
    BUILD_MONTH_CH0, BUILD_MONTH_CH1,
    '-',
    BUILD_DAY_CH0, BUILD_DAY_CH1,
    'T',
    BUILD_HOUR_CH0, BUILD_HOUR_CH1,
    ':',
    BUILD_MIN_CH0, BUILD_MIN_CH1,
    ':',
    BUILD_SEC_CH0, BUILD_SEC_CH1,
    '\0'
};


#include <stdio.h>

int main(int argc, char **argv)
{
    printf("%s\n", completeVersion);
    // prints something similar to: 1.4-V-2013-05-09T15:34:49
}

이것은 당신이 요청한 형식이 아닙니다만, 저는 여전히 당신이 어떻게 일, 시간을 정수에 매핑하기를 원하는지 완전히 이해할 수 없습니다.원하는 끈을 어떻게 만들지는 분명하다고 생각합니다.

단답(질문 버전): (형식 3.33.20150710).182906)

사용하세요makefile 라이선스:

MAJOR = 3
MINOR = 33
BUILD = $(shell date +"%Y%m%d.%H%M%S")
VERSION = "\"$(MAJOR).$(MINOR).$(BUILD)\""
CPPFLAGS = -DVERSION=$(VERSION)

program.x : source.c
       gcc $(CPPFLAGS) source.c -o program.x

않는다면makefile, , , , , , , , , , , , , , , , , , , , , , , 등으로 .

gcc source.c -o program.x -DVERSION=\"2.22.$(date +"%Y%m%d.%H%M%S")\"

단답(권장 버전): (형식 150710).182906)

사용하다double전전: :

Make File(Make File(파일 만들기):

VERSION = $(shell date +"%g%m%d.%H%M%S")
CPPFLAGS = -DVERSION=$(VERSION)
program.x : source.c
      gcc $(CPPFLAGS) source.c -o program.x

또는 간단한 bash 명령어:

$ gcc source.c -o program.x -DVERSION=$(date +"%g%m%d.%H%M%S")

힌트: 아직 마음에 안 들어makefile아니면 아주 작은 테스트 프로그램 때문일까요?음음음:

 export CPPFLAGS='-DVERSION='$(date +"%g%m%d.%H%M%S")

your ~/.profile 할 때는 컴파일을 해 주세요.gcc $CPPFLAGS ...


장황한 답변:

이 질문이 더 오래된 건 알지만, 제가 할 일이 좀 있어요.베스트 프랙티스는 항상 오류(또는 망각)의 원인이 될 수 있는 것을 자동화하는 것입니다.

버전 번호를 만들어 주는 기능에 익숙해졌습니다., 이 하는 것이 .float 번호는 같이 할 수 printf("%13.6f\n", version()); '하다, 하다, 하다, 하다' 이런 거 요.150710.150411( 「 ( 2 ) DOT 」 ) 。

하 、 、 、 제 、 요 、 제는 。majortime을 수 "major.minor.date.time"이더 .) 을 이용하다), 를 날짜+시간으로 할 수 major.datetime = 1.150710150411

본론으로 들어갑시다. 경우 을 사용하면 합니다.-DVERSION, 보다도, use서서직만만만만만도만만만만만만만만만만 a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a 。makefile.


3가지 형식의 컴파일 및 결과:

make 사용:

beco> make program.x
gcc -Wall -Wextra -g -O0 -ansi -pedantic-errors -c -DVERSION="\"3.33.20150710.045829\"" program.c -o program.o
gcc  program.o -o program.x

실행 중:

__DATE__: 'Jul 10 2015'
__TIME__: '04:58:29'
VERSION: '3.33.20150710.045829'

-DVERSION 사용:

beco> gcc program.c -o program.x -Wall -Wextra -g -O0 -ansi -pedantic-errors -DVERSION=\"2.22.$(date +"%Y%m%d.%H%M%S")\"

실행 중:

__DATE__: 'Jul 10 2015'
__TIME__: '04:58:37'
VERSION: '2.22.20150710.045837'

빌트인 기능 사용:

beco> gcc program.c -o program.x -Wall -Wextra -g -O0 -ansi -pedantic-errors

실행 중:

__DATE__: 'Jul 10 2015'
__TIME__: '04:58:43'
VERSION(): '1.11.20150710.045843'

소스 코드

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 #define FUNC_VERSION (0)
  6 #ifndef VERSION
  7   #define MAJOR 1
  8   #define MINOR 11
  9   #define VERSION version()
 10   #undef FUNC_VERSION
 11   #define FUNC_VERSION (1)
 12   char sversion[]="9999.9999.20150710.045535";
 13 #endif
 14 
 15 #if(FUNC_VERSION)
 16 char *version(void);
 17 #endif
 18 
 19 int main(void)
 20 {
 21 
 22   printf("__DATE__: '%s'\n", __DATE__);
 23   printf("__TIME__: '%s'\n", __TIME__);
 24 
 25   printf("VERSION%s: '%s'\n", (FUNC_VERSION?"()":""), VERSION);
 26   return 0;
 27 }
 28 
 29 /* String format: */
 30 /* __DATE__="Oct  8 2013" */
 31 /*  __TIME__="00:13:39" */
 32
 33 /* Version Function: returns the version string */
 34 #if(FUNC_VERSION)
 35 char *version(void)
 36 {
 37   const char data[]=__DATE__;
 38   const char tempo[]=__TIME__;
 39   const char nomes[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
 40   char omes[4];
 41   int ano, mes, dia, hora, min, seg;
 42 
 43   if(strcmp(sversion,"9999.9999.20150710.045535"))
 44     return sversion;
 45 
 46   if(strlen(data)!=11||strlen(tempo)!=8)
 47     return NULL;
 48 
 49   sscanf(data, "%s %d %d", omes, &dia, &ano);
 50   sscanf(tempo, "%d:%d:%d", &hora, &min, &seg);
 51   mes=(strstr(nomes, omes)-nomes)/3+1;
 52   sprintf(sversion,"%d.%d.%04d%02d%02d.%02d%02d%02d", MAJOR, MINOR, ano, mes, dia, hora, min, seg);
 53 
 54   return sversion;
 55 }
 56 #endif

되므로 주의하시기 바랍니다.MAJOR<=9999 ★★★★★★★★★★★★★★★★★」MINOR<=9999물론 이 값은 절대 오버플로하지 않도록 설정했습니다. ,, 을, 을, 용을 double더 완전 자동이므로 설정할 필요가 ).MAJOR ★★★★★★★★★★★★★★★★★」MINOR★★★★★★★★★★★★★★★★★★)

지금 위의 프로그램은 조금 과하다. 삭제되도록 것이 .VERSION.-DVERSIONGCC에 위해 GCC ( 잊어버리지)되는 솔루션makefile.

, 여기 있습니다.makefile


Make File 소스:

  1   MAJOR = 3
  2   MINOR = 33
  3   BUILD = $(shell date +"%Y%m%d.%H%M%S")
  4   VERSION = "\"$(MAJOR).$(MINOR).$(BUILD)\""
  5   CC = gcc
  6   CFLAGS = -Wall -Wextra -g -O0 -ansi -pedantic-errors
  7   CPPFLAGS = -DVERSION=$(VERSION)
  8   LDLIBS =
  9   
 10    %.x : %.c
 11          $(CC) $(CFLAGS) $(CPPFLAGS) $(LDLIBS) $^ -o $@

DUBLE을 사용한 더 나은 버전

지금까지, 「고객이 선호하는」솔루션을 소개했습니다.다음은 저의솔루션입니다.

(a) makefile 또는 (b) gcc를 사용하여 직접 컴파일:

(a) Make File:

   VERSION = $(shell date +"%g%m%d.%H%M%S")
   CC = gcc
   CFLAGS = -Wall -Wextra -g -O0 -ansi -pedantic-errors 
   CPPFLAGS = -DVERSION=$(VERSION)
   LDLIBS =
   %.x : %.c
         $(CC) $(CFLAGS) $(CPPFLAGS) $(LDLIBS) $^ -o $@

(b) 또는 간단한 bash 명령어:

 $ gcc program.c -o program.x -Wall -Wextra -g -O0 -ansi -pedantic-errors -DVERSION=$(date +"%g%m%d.%H%M%S")

소스 코드(더블 버전):

#ifndef VERSION
  #define VERSION version()
#endif

double version(void);

int main(void)
{
  printf("VERSION%s: '%13.6f'\n", (FUNC_VERSION?"()":""), VERSION);
  return 0;
}

double version(void)
{
  const char data[]=__DATE__;
  const char tempo[]=__TIME__;
  const char nomes[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
  char omes[4];
  int ano, mes, dia, hora, min, seg;
  char sversion[]="130910.001339";
  double fv;

  if(strlen(data)!=11||strlen(tempo)!=8)
    return -1.0;

  sscanf(data, "%s %d %d", omes, &dia, &ano);
  sscanf(tempo, "%d:%d:%d", &hora, &min, &seg);
  mes=(strstr(nomes, omes)-nomes)/3+1;
  sprintf(sversion,"%04d%02d%02d.%02d%02d%02d", ano, mes, dia, hora, min, seg);
  fv=atof(sversion);

  return fv;
}

주의: 이 이중 함수는 매크로 VERSION을 정의하는 것을 잊은 경우에만 있습니다.「 」를 하는 경우makefile해 주세요.alias gcc gcc -DVERSION=$(date +"%g%m%d.%H%M%S")이 기능을 완전히 삭제할 수 있습니다.


음, 바로 그겁니다.버전 관리를 쉽게 셋업할 수 있는 매우 깔끔한 방법!

'다'는 안 되다이전 답변과 비슷하지만 빌드 월을 계산했습니다(빌드 월을 계산하면#if단, 할 수 , 「삼원식」, 「삼원식」을 사용할 수 있습니다.

또한 설명서에 따르면 컴파일러가 하루 중 시간을 알 수 없는 경우 이러한 문자열에 물음표가 표시됩니다.그래서 이 케이스에 대한 테스트를 추가하여 이 경우 여러 매크로에서 잘못된 값(99)을 반환하도록 했습니다.

#ifndef BUILD_DEFS_H

#define BUILD_DEFS_H


// Example of __DATE__ string: "Jul 27 2012"
// Example of __TIME__ string: "21:06:19"

#define COMPUTE_BUILD_YEAR \
    ( \
        (__DATE__[ 7] - '0') * 1000 + \
        (__DATE__[ 8] - '0') *  100 + \
        (__DATE__[ 9] - '0') *   10 + \
        (__DATE__[10] - '0') \
    )


#define COMPUTE_BUILD_DAY \
    ( \
        ((__DATE__[4] >= '0') ? (__DATE__[4] - '0') * 10 : 0) + \
        (__DATE__[5] - '0') \
    )


#define BUILD_MONTH_IS_JAN (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n')
#define BUILD_MONTH_IS_FEB (__DATE__[0] == 'F')
#define BUILD_MONTH_IS_MAR (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r')
#define BUILD_MONTH_IS_APR (__DATE__[0] == 'A' && __DATE__[1] == 'p')
#define BUILD_MONTH_IS_MAY (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y')
#define BUILD_MONTH_IS_JUN (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n')
#define BUILD_MONTH_IS_JUL (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l')
#define BUILD_MONTH_IS_AUG (__DATE__[0] == 'A' && __DATE__[1] == 'u')
#define BUILD_MONTH_IS_SEP (__DATE__[0] == 'S')
#define BUILD_MONTH_IS_OCT (__DATE__[0] == 'O')
#define BUILD_MONTH_IS_NOV (__DATE__[0] == 'N')
#define BUILD_MONTH_IS_DEC (__DATE__[0] == 'D')


#define COMPUTE_BUILD_MONTH \
    ( \
        (BUILD_MONTH_IS_JAN) ?  1 : \
        (BUILD_MONTH_IS_FEB) ?  2 : \
        (BUILD_MONTH_IS_MAR) ?  3 : \
        (BUILD_MONTH_IS_APR) ?  4 : \
        (BUILD_MONTH_IS_MAY) ?  5 : \
        (BUILD_MONTH_IS_JUN) ?  6 : \
        (BUILD_MONTH_IS_JUL) ?  7 : \
        (BUILD_MONTH_IS_AUG) ?  8 : \
        (BUILD_MONTH_IS_SEP) ?  9 : \
        (BUILD_MONTH_IS_OCT) ? 10 : \
        (BUILD_MONTH_IS_NOV) ? 11 : \
        (BUILD_MONTH_IS_DEC) ? 12 : \
        /* error default */  99 \
    )

#define COMPUTE_BUILD_HOUR ((__TIME__[0] - '0') * 10 + __TIME__[1] - '0')
#define COMPUTE_BUILD_MIN  ((__TIME__[3] - '0') * 10 + __TIME__[4] - '0')
#define COMPUTE_BUILD_SEC  ((__TIME__[6] - '0') * 10 + __TIME__[7] - '0')


#define BUILD_DATE_IS_BAD (__DATE__[0] == '?')

#define BUILD_YEAR  ((BUILD_DATE_IS_BAD) ? 99 : COMPUTE_BUILD_YEAR)
#define BUILD_MONTH ((BUILD_DATE_IS_BAD) ? 99 : COMPUTE_BUILD_MONTH)
#define BUILD_DAY   ((BUILD_DATE_IS_BAD) ? 99 : COMPUTE_BUILD_DAY)

#define BUILD_TIME_IS_BAD (__TIME__[0] == '?')

#define BUILD_HOUR  ((BUILD_TIME_IS_BAD) ? 99 :  COMPUTE_BUILD_HOUR)
#define BUILD_MIN   ((BUILD_TIME_IS_BAD) ? 99 :  COMPUTE_BUILD_MIN)
#define BUILD_SEC   ((BUILD_TIME_IS_BAD) ? 99 :  COMPUTE_BUILD_SEC)


#endif // BUILD_DEFS_H

다음의 테스트 코드를 사용하면, 상기의 동작은 양호합니다.

printf("%04d-%02d-%02dT%02d:%02d:%02d\n", BUILD_YEAR, BUILD_MONTH, BUILD_DAY, BUILD_HOUR, BUILD_MIN, BUILD_SEC);

그러나 이러한 매크로를 문자열화 매크로와 함께 사용하려고 하면 리터럴 표현이 문자열화됩니다.컴파일러가 식을 리터럴 정수값으로 줄인 후 문자열화하도록 하는 방법을 모르겠습니다.

매크로를 , 는 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」로 불만을 합니다.error: initializer element is not constant매크로로는 할 수 .따라서 이러한 매크로에서는 원하는 작업을 수행할 수 없습니다.

현시점에서는 새로운 include 파일을 생성하는 Python 스크립트가 최선이라고 생각합니다.원하는 포맷으로 원하는 것을 미리 계산할 수 있습니다.Python을 원하지 않으시면 AWK 스크립트나 C 프로그램을 작성하실 수 있습니다.

하거나 Python으로 파일을 수 .#define'나'나 '나'나 '나'나 '나'나 '나'나.그런 다음 빌드하기 전에 이 프로그램을 실행해야 합니다.

괜찮으시다면 여기에 하나 쓰고 출처를 알려드리겠습니다.

운이 좋으면 빌드 도구(IDE 등)에 외부 명령을 실행할 수 있는 기능이 있을 수 있습니다.그러면 외부 도구에서 빌드별로 포함 파일을 자동으로 다시 쓰도록 할 수 있습니다.

Python: Python을 사용하다.「 」라고 하는 .build_num.h이 할 때마다 빌드 또, 「 번호」는 「빌드 번호」라고 써 있습니다.#define이 프로그램이 실행되는 년, 월, 날짜, 시간, 분 및 초의 값을 지정합니다., ,가 붙어있어요.#define 번호의 , 풀 「」 「」 「」 「」 「」 「」 「」VERSION ★★★★★★★★★★★★★★★★★」COMPLETE_VERSION 할지시간부터 요.(날짜와 시각의 번호를 어떻게 알고 싶은지 몰라서, 날짜와 시각의 연결 자리수만을 선택했습니다.이것은 간단하게 변경할 수 있습니다.)

에 됩니다.build_num.h이 경우 빌드 번호를 합니다.build_num.h파일이 존재하지 않습니다. 1번으로 하다마찬가지로 메이저버전 번호와 마이너버전 번호를 구분하여 파일이 존재하지 않으면 기본적으로 버전 0.1로 설정됩니다.

import time

FNAME = "build_num.h"

build_num = None
version_major = None
version_minor = None

DEF_BUILD_NUM = "#define BUILD_NUM "
DEF_VERSION_MAJOR = "#define VERSION_MAJOR "
DEF_VERSION_MINOR = "#define VERSION_MINOR "

def get_int(s_marker, line):
    _, _, s = line.partition(s_marker) # we want the part after the marker
    return int(s)

try:
    with open(FNAME) as f:
        for line in f:
            if DEF_BUILD_NUM in line:
                build_num = get_int(DEF_BUILD_NUM, line)
                build_num += 1
            elif DEF_VERSION_MAJOR in line:
                version_major = get_int(DEF_VERSION_MAJOR, line)
            elif DEF_VERSION_MINOR in line:
                version_minor = get_int(DEF_VERSION_MINOR, line)
except IOError:
    build_num = 1
    version_major = 0
    version_minor = 1

assert None not in (build_num, version_major, version_minor)


with open(FNAME, 'w') as f:
    f.write("#ifndef BUILD_NUM_H\n")
    f.write("#define BUILD_NUM_H\n")
    f.write("\n")
    f.write(DEF_BUILD_NUM + "%d\n" % build_num)
    f.write("\n")
    t = time.localtime()
    f.write("#define BUILD_YEAR %d\n" % t.tm_year)
    f.write("#define BUILD_MONTH %d\n" % t.tm_mon)
    f.write("#define BUILD_DATE %d\n" % t.tm_mday)
    f.write("#define BUILD_HOUR %d\n" % t.tm_hour)
    f.write("#define BUILD_MIN %d\n" % t.tm_min)
    f.write("#define BUILD_SEC %d\n" % t.tm_sec)
    f.write("\n")
    f.write("#define VERSION_MAJOR %d\n" % version_major)
    f.write("#define VERSION_MINOR %d\n" % version_minor)
    f.write("\n")
    f.write("#define VERSION \"%d.%d\"\n" % (version_major, version_minor))
    s = "%d.%d.%04d%02d%02d.%02d%02d%02d" % (version_major, version_minor,
            t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)
    f.write("#define COMPLETE_VERSION \"%s\"\n" % s)
    f.write("\n")
    f.write("#endif // BUILD_NUM_H\n")

모든 정의를 정수로 만들었지만, 단순한 정수이기 때문에 원하는 경우 표준 문자열 지정 기술을 사용하여 문자열을 만들 수 있습니다.또한 사전 정의된 문자열을 추가로 구축하기 위해 확장될 수도 있습니다.

이 프로그램은 Python 3.x 버전을 포함하여 Python 2.6 이상에서 정상적으로 실행됩니다.할 수 있습니다.예를 들어 Python은 사용하지 예를 들어 사용하지 않는 경우 등.partition()를 참조해 주세요.

추가 '(스페이스)'를 교체하려는 사용자에게는 일수가 10 미만인 경우 다음을 사용하십시오.

#define BUILD_DATE (char const[]) { __DATE__[0], __DATE__[1], __DATE__[2], __DATE__[3], (__DATE__[4] == ' ' ?  '0' : __DATE__[4]), __DATE__[5], __DATE__[6], __DATE__[7], __DATE__[8], __DATE__[9], __DATE__[10], __DATE__[11] }

출력 : 2019년 9월 6일

부분적인 답변이 있습니다.이것은, GCC로부터 얻은 정보에 근거하고 있습니다.

__DATE__"Jul 27 2012"

__TIME__21:06:19

파일에 .build_defs.h:

#ifndef BUILD_DEFS_H

#define BUILD_DEFS_H


#define BUILD_YEAR ((__DATE__[7] - '0') * 1000 +  (__DATE__[8] - '0') * 100 + (__DATE__[9] - '0') * 10 + __DATE__[10] - '0')

#define BUILD_DATE ((__DATE__[4] - '0') * 10 + __DATE__[5] - '0')


#if 0
#if (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n')
    #define BUILD_MONTH  1
#elif (__DATE__[0] == 'F' && __DATE__[1] == 'e' && __DATE__[2] == 'b')
    #define BUILD_MONTH  2
#elif (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r')
    #define BUILD_MONTH  3
#elif (__DATE__[0] == 'A' && __DATE__[1] == 'p' && __DATE__[2] == 'r')
    #define BUILD_MONTH  4
#elif (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y')
    #define BUILD_MONTH  5
#elif (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n')
    #define BUILD_MONTH  6
#elif (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l')
    #define BUILD_MONTH  7
#elif (__DATE__[0] == 'A' && __DATE__[1] == 'u' && __DATE__[2] == 'g')
    #define BUILD_MONTH  8
#elif (__DATE__[0] == 'S' && __DATE__[1] == 'e' && __DATE__[2] == 'p')
    #define BUILD_MONTH  9
#elif (__DATE__[0] == 'O' && __DATE__[1] == 'c' && __DATE__[2] == 't')
    #define BUILD_MONTH 10
#elif (__DATE__[0] == 'N' && __DATE__[1] == 'o' && __DATE__[2] == 'v')
    #define BUILD_MONTH 11
#elif (__DATE__[0] == 'D' && __DATE__[1] == 'e' && __DATE__[2] == 'c')
    #define BUILD_MONTH 12
#else
    #error "Could not figure out month"
#endif
#endif

#define BUILD_HOUR ((__TIME__[0] - '0') * 10 + __TIME__[1] - '0')
#define BUILD_MIN ((__TIME__[3] - '0') * 10 + __TIME__[4] - '0')
#define BUILD_SEC ((__TIME__[6] - '0') * 10 + __TIME__[7] - '0')

#endif // BUILD_DEFS_H

Linux GCC의 GCC입니다.모든 게 잘 풀리는데, 그 달의 번호를 어떻게 구해야 할지 모르겠다는 문제만 빼면요.[ ] #if 0 메시지와 을 제기합니다.GCC를 사용하다

error: token ""Jul 27 2012"" is not valid in preprocessor expressions

세 글자의 월 약자를 일종의 고유한 숫자로 변환하는 것은 간단한 일입니다. 첫 번째 글자에서 A를 빼고 두 번째와 세 번째 글자에서 A를 뺀 다음 26진수로 변환하는 것입니다.하지만 1월이나 그 이후로는 1로 평가하려고 하는데 어떻게 해야 할지 모르겠어요.

EDIT: 방금 깨달았습니다만, 정수로 계산하는 식이 아니라 문자열을 요구하고 있습니다.

스태틱 스트링을 작성하기 위해 다음과 같은 트릭을 사용하려고 합니다.

#define BUILD_MAJOR 1
#define BUILD_MINOR 4
#define VERSION STRINGIZE(BUILD_MAJOR) "." STRINGIZE(BUILD_MINOR)

char build_str[] = {
    BUILD_MAJOR + '0', '.' BUILD_MINOR + '0', '.',
    __DATE__[7], __DATE__[8], __DATE__[9], __DATE__[10],
    '\0'
};

가 " is constant"라고GCC가 "Initializer Element is not constant"는 "Initializer Element is not constant"로 표시됩니다.__DATE__.

죄송해요, 어떻게 도와드려야 할지 모르겠어요.컴파일러로 시험해 볼 수 있을까요?아니면 그게 너에게 아이디어를 줄지도 몰라.

행운을 빌어요.

P.S. 숫자가 아니라 고유한 빌드 문자열만 원하는 경우 다음과 같이 간단합니다.

const char *build_str = "Version: " VERSION " " __DATE__ " " __TIME__;

GCC를 사용하면 다음과 같은 결과가 됩니다.

Version: 1.4 Jul 27 2012 21:53:59

그것은 매우 간단하다…

[파일 만들기]

==== 1 ===================

OBJS = ....\

version.o <<== add to your obj lists

==== 2 ===================

날짜 = $(쉘 날짜 +'char szVersionStr[20] = "%Y-%m-%d %H:%M:%S";' <== 추가

모두: 버전 $(프로그램)ID) <<== 버전 처음에 추가

버전: <<== 추가

echo '$(DATE)' > version.c  <== add ( create version.c file)

[프로그램 중]

=====3 =============

외부 char szVersionStr[20];

[사용]

=== 4 ====

printf( "Version: %s\n", szVersionStr );

언급URL : https://stackoverflow.com/questions/11697820/how-to-use-date-and-time-predefined-macros-in-as-two-integers-then-stri

반응형