본문 바로가기

IT/Linux

Makefile에서 프로그램의 Build 버전을 자동으로 생성하고 싶을때

    개요

가)  Application을 빌드 할 때 마다, 자동으로 빌드의 숫자가 증가하여

     이를 프로그램에서 사용 할 수 있도록 하는 내용이다.

 

나)  참조 문서

    http://www.linuxjournal.com/content/add-auto-incrementing-build-number-your-build-process

 

    Number File

가)  Application Directory 안에 빌드 넘버를 기록하는 파일을 만들고, make 가 수행 된 후에 이를 자동으로 증가 하게 한다.

나)  참조 문서 1에서는 link 옵션을 사용 하였으며, 문서 2에서는 define를 사용 하였다.

    Define 문을 사용하는 경우는  __DATE__, __TIME__을 사용 할 때와 마찬가지로, 쓰여진 해당 파일이 touch 되어야 한다. 소스 여러 곳에서 사용이 되어진다면 빌드 버전이나, 빌드 시간이 전부 다르게 나타날 것이다.

    Link 옵션을 사용하면 문서 1에서 나타나는 현상은 없어지며, link 옵션을 사용 하는 것이 맞다.

 

    Example 1

가)  Makefile

 

BUILD_NUMBER_FILE=build-number.txt

 

BUILD_NUMBER_LDFLAGS  = -Xlinker --defsym -Xlinker __BUILD_DATE=$$(date +'%Y%m%d')

BUILD_NUMBER_LDFLAGS += -Xlinker --defsym -Xlinker __BUILD_NUMBER=$$(cat $(BUILD_NUMBER_FILE))

 

# Create an auto-incrementing build number.

 

#include buildnumber.mak

 

OBJECTS=bnum.o

 

a.out: $(OBJECTS) $(BUILD_NUMBER_FILE)

        $(CC) $(LDFLAGS) $(BUILD_NUMBER_LDFLAGS) -o $@ $(OBJECTS)

 

update:

        if ! test -f $(BUILD_NUMBER_FILE); then echo 0 > $(BUILD_NUMBER_FILE); fi

        echo $$(($$(cat $(BUILD_NUMBER_FILE)) + 1)) > $(BUILD_NUMBER_FILE)

clean:

        rm bnum.o a.out

 

나)  Source

 

#include <stdio.h>

 

extern char   __BUILD_DATE;

extern char   __BUILD_NUMBER;

 

int     main(void)

{

        printf("Build date  : %u\n", (unsigned long) &__BUILD_DATE);

        printf("Build number: %u\n", (unsigned long) &__BUILD_NUMBER);

        return 0;

}

 

 

    Example 2 (QT)

가)  Makefile

# cadmus auto inc

####### Compiler, tools and options

BUILD_NUMBER_FILE=build-number.txt

BUILD_NUMBER_LDFLAGS  = -Xlinker --defsym -Xlinker __BUILD_DATE=$$(date +'%Y%m%d')

BUILD_NUMBER_LDFLAGS += -Xlinker --defsym -Xlinker __BUILD_TIME=$$(date +'%H%M%S')

BUILD_NUMBER_LDFLAGS += -Xlinker --defsym -Xlinker __BUILD_NUMBER=$$(cat $(BUILD_NUMBER_FILE))

 

#BUILD_DATE = $(shell date +'%Y%m%d')

#BUILD_TIME = $(shell date +'%H%M%S')

#BUILD_NUMBER = $(shell cat $(BUILD_NUMBER_FILE))

 

CC            = arm-linux-gcc

CXX           = arm-linux-g++

#DEFINES       = -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -DBUILD_DATE=$(BUILD_DATE) -DBUILD_NUMBER=$(BUILD_NUMBER) -DBUILD_TIME=$(BUILD_TIME)

DEFINES       = -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED

CFLAGS        = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)

CXXFLAGS      = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)

INCPATH       = -I/usr/local/qt463_arm/mkspecs/qws/linux-arm-g++ -I. -I/usr/local/qt463_arm/include/QtCore -I/usr/local/qt463_arm/include/QtNetwork -I/usr/local/qt463_arm/include/QtGui -I/usr/local/qt463_arm/include -I. -Iinclude -Ikalki -I.

LINK          = arm-linux-g++

LFLAGS        = -Wl,-O1 -Wl,-rpath,/usr/local/qt463_arm/lib $(BUILD_NUMBER_LDFLAGS)

LIBS          = $(SUBLIBS)  -L/usr/local/qt463_arm/lib -lQtGui -L/usr/local/qt463_arm/lib -lQtNetwork -lQtCore -lpthread

AR            = arm-linux-ar cqs

.

.

.

 

.

# cadmus auto inc

all: Makefile $(TARGET) version

.

.

.

 

# cadmus auto inc

version:

        if ! test -f $(BUILD_NUMBER_FILE); then echo 0 > $(BUILD_NUMBER_FILE); fi

        echo $$(($$(cat $(BUILD_NUMBER_FILE)) + 1)) > $(BUILD_NUMBER_FILE)

.

.

 

 

나)  Source

 

extern char   __BUILD_DATE;

extern char   __BUILD_TIME;

extern char   __BUILD_NUMBER;

 

printf("  Build date   : %u\n", &__BUILD_DATE);

printf("  Build time   : %u\n", &__BUILD_TIME);

printf("  Build number : %u\n", &__BUILD_NUMBER);

 

 

    참조 문서 1

 

Add an Auto-Incrementing Build-Number to Your Build Process

Jul 08, 2008  By Mitch Frazier

 

When building software it's often useful to give each iteration of your build process a unique number. Many IDEs and RAD tools do this for you automatically. If yours doesn't and you're using a make file to build your code you can add an auto-incrementing build number to your project with a few simple changes to your make file.

 

The mechanism presented here does not need to modify your source code at all, it uses linker symbols to add the build number to your program. Note however that you will probably want to modify your source code to display the build number, but that's not strictly necessary.

 

Let's start with the following simple make file for building a program:

 

# Makefile

 

OBJECTS=bnum.o

 

a.out: $(OBJECTS)

    $(CC) $(LDFLAGS) -o $@ $(OBJECTS)

 

This make file builds a.out from the file bnum.c (through a make built-in rule).

 

To add the build number to the make file we set the variable BUILD_NUMBER_FILE to the name of a file that will contain our build number value. Then we add BUILD_NUMBER_FILE to the dependencies for a.out, add BUILD_NUMBER_LDFLAGS to the flags used when linking the program, and finally include the file buildnumber.mak at the end of the make file. The converted make file looks like:

 

# Makefile

 

# Name of text file containing build number.

BUILD_NUMBER_FILE=build-number.txt

 

OBJECTS=bnum.o

 

a.out: $(OBJECTS) $(BUILD_NUMBER_FILE)

    $(CC) $(LDFLAGS) $(BUILD_NUMBER_LDFLAGS) -o $@ $(OBJECTS)

 

# Include build number rules.

include buildnumber.mak

 

The included file buildnumber.mak looks like:

 

# Create an auto-incrementing build number.

 

BUILD_NUMBER_LDFLAGS  = -Xlinker --defsym -Xlinker __BUILD_DATE=$$(date +'%Y%m%d')

BUILD_NUMBER_LDFLAGS += -Xlinker --defsym -Xlinker __BUILD_NUMBER=$$(cat $(BUILD_NUMBER_FILE))

 

# Build number file.  Increment if any object file changes.

$(BUILD_NUMBER_FILE): $(OBJECTS)

    @if ! test -f $(BUILD_NUMBER_FILE); then echo 0 > $(BUILD_NUMBER_FILE); fi

    @echo $$(($$(cat $(BUILD_NUMBER_FILE)) + 1)) > $(BUILD_NUMBER_FILE)

 

   

 

The first few lines define the linker flags and the rule defines the mechanism for incrementing the build number.

 

The linker flags cause the linker to create two symbols: __BUILD_NUMBER and __BUILD_DATE which will be equal to the build number and the build-date respectively. The build-date is set using the standard date command. The build number is simply the value contained in the build number file, which is extracted using the standard cat command.

 

The make rule for the build number file depends on all the project object files and if any of them changes the build number is incremented by executing the following commands:

 

if ! test -f build-number.txt; then echo 0 > build-number.txt; fi

echo $(($(cat build-number.txt) + 1)) > build-number.txt

 

The first command checks to see if the build number file exists. If it doesn't a single line of text, a zero is written to it. The second command uses cat to get the line of text and the shell's built-in arithmetic evaluation $((expr)) to increment it and write it back to the build number file.

 

The test program bnum.c merely writes out the build number and build-date:

 

#include <stdio.h>

 

extern char   __BUILD_DATE;

extern char   __BUILD_NUMBER;

 

main()

{

    printf("Build date  : %u\n", (unsigned long) &__BUILD_DATE);

    printf("Build number: %u\n", (unsigned long) &__BUILD_NUMBER);

}

 

Note that linker symbols are not variables, they have no memory allocated for maintaining a value, rather their address is their value.

 

A sample of iterative builds is shown below:

 

  $ rm bnum.o; make

  cc -c -o bnum.o bnum.c

  cc -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +'%Y%m%d') \

     -Xlinker --defsym -Xlinker __BUILD_NUMBER=$(cat build-number.txt) -o a.out bnum.o

  $ ./a.out

  Build date  : 20080708

  Build number: 24

  $ rm bnum.o; make

  cc -c -o bnum.o bnum.c

  cc  -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +'%Y%m%d') \

      -Xlinker --defsym -Xlinker __BUILD_NUMBER=$(cat build-number.txt) -o a.out bnum.o

  $ ./a.out

  Build date  : 20080708

  Build number: 25

 

One caveat to an auto-incrementing build number is that just because you have two versions of a program with different build numbers it does not mean they are functionally different. If you routinely run make clean; make all just for fun, you'll get a new build number but nothing will have changed.

 

 

 

    참조 문서 2

Add an auto-incrementing build number to your software

 

Written by Gian

Add an auto-incrementing build number to your software

Feb24

2011 2 Comments avatar Written by Gian

 

As part of standard build maintenance, we here at OpenHousewares incorporate auto-incrementing build numbers into our release candidates and make this build number available to the software being built to include in versioning and usage information.  For instance, instead of having a 1.1 release, we have a 1.1.38 release where that final number (38) is the build number for that release.  We find it gives us finder tuned control and allows us to not have to increment the minor version for build upgrades and simple bug fixes.  It also fits into our Agile programming paradigm by allowing us to release functionality iteratively by builds.

 

 

 

To accomplish this requires a little Makefile magic but it is very simple and straightforward to complete.  Here’s a step-by-step guide on doing this.

 

 

 

1. Create a file called “.build_number” in your source directory with the number 1 inside it.

 

$ echo "1" > .build_number

 

Note that I use a dot (“.”) in front of the name to make it invisible to normal directory listings. I do this only to keep the source directory from getting cluttered with non-source files. You are free to name this file whatever you like, you just have to make sure you change it below where the file name is mentioned.

 

 

 

2. Somewhere near the beginning / front of your makefile add in the following directives:

 

PROG_BUILD_NUM=.build_number

BUILD_DATE = $(shell date +'%Y%m%d')

BUILD_NUM = $(shell cat $(PROG_BUILD_NUM))

 

This first line sets the varialbe PROG_BUILD_NUM to point to the .build_number file we just created in the first step. The BUILD_DATE is a shell command that runs date with a particular format. Try it at your command line if you want to see how it looks:

 

$ date +%Y%m%d

20110221

 

The third line executes the shell command “cat” and takes that output from our .build_number file, currently 1, and saves it into the makefile variable BUILD_NUM

 

3. Pass the definition wherever you have your CFLAGS or CPPFLAGS. For instance:

 

CPPFLAGS += -DBUILD_DATE=$(BUILD_DATE) -DBUILD_NUM=$(BUILD_NUM)

 

 

 

Now, your BUILD_DATE and BUILD_NUM makefile variables are available as C defines to your C/C++ application.

With this much, you can now use these definitions in your programs to create uptodate, custom build numbers including build dates for use in help output or version output. Like this:

 

#define MAJ_VERSION 1

#define MIN_VERSION 23

...

void Version()

{

cout << "Version: " << MAJ_VERSION << "." << MIN_VERSION << "." << BUILD_NUM << endl;

cout << "Build Date: " << BUILD_DATE << endl;

}

 

 

 

Which would print out something like:

$ a.out -v

Version: 1.23.0

Build Date: 20101105

 

 

 

But we still have a little more work to do. We have to auto-increment the build number every time we make the project. That’s simple enough with the below code in your Makefile:

 

4. Find your “all:” or “$(TARGET):” label in the makefile and add $(BUILD_NUM) to the label like this:

 

$(TARGET): $(OBJ) $(BUILD_NUM)

$(CC) $(BUILD_LDFLAGS) --output $@ $(OBJ) $(LDFLAGS)

 

 

 

5. Create the $(BUILD_NUM) label and directives below where you just added it to the label:

$(BUILD_NUM):

@echo Incrementing build number

@if ! test -f $(PROG_BUILD_NUM); then echo 0 > $(PROG_BUILD_NUM); fi

@echo $$(($$(cat $(PROG_BUILD_NUM)) + 1)) > $(PROG_BUILD_NUM)

 

 

 

That’s it!  Now every time you ‘make’ the app, the number in .build_number will increment and be passed into the application for whatever use you see fit.

 


반응형