6

Suppose there is a C program, which stores its version in a global char* in main.c. Can the buildsystem (gnu make) somehow extract the value of this variable on build time, so that the executable built could have the exact version name as it appears in the program?

What I'd like to achieve is that given the source:

char g_version[] = "Superprogram 1.32 build 1142";

the buildsystem would generate an executable named Superprogram 1.32 build 1142.exe

Manjabes
  • 1,884
  • 3
  • 17
  • 34

4 Answers4

5

The shell function allows you to call external applications such as sed that can be used to parse the source for the details required.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • Though his version string looks suspiciously hand-crafted, I would also have advised to check `what` tool. That plus `shell` might be what he's looking for. – Dummy00001 Jul 20 '10 at 09:19
  • Thanks for replying, this might actually work, provided that I get up to speed on my abilities on sed (and the other utils, mentioned below by mouviciel)... – Manjabes Jul 20 '10 at 09:31
5

Define your version variable from a Macro:

char g_version[] = VERSION;

then make your makefile put a -D argument on the command line when compiling

gcc hack.c -DVERSION=\"Superprogram\ 1.99\"

And of course you should in your example use sed/grep/awk etc to generate your version string.

Simson
  • 3,373
  • 2
  • 24
  • 38
  • I'm aware of the -D option, but that cannot be applied in this case. The version string has to stay where it is. – Manjabes Jul 20 '10 at 09:29
1

You can use any combination of unix text tools (grep, sed, awk, perl, tail, ...) in your Makefile in order to extract that information from source file.

mouviciel
  • 66,855
  • 13
  • 106
  • 140
0

Usually the version is defined as a composition of several #define values (like in the arv library for example).

So let's go for a simple and working example:

// myversion.h
#define  __MY_MAJOR__ 1
#define  __MY_MINOR__ 8

Then in your Makefile:

# Makefile
source_file := myversion.h
MAJOR_Identifier := __MY_MAJOR__
MINOR_Identifier := __MY_MINOR__

MAJOR := `cat $(source_file) | tr -s ' ' | grep "\#define $(MAJOR_Identifier)" | cut -d" " -f 3`
MINOR := `cat $(source_file) | tr -s ' ' | grep '\#define $(MINOR_Identifier)' | cut -d" " -f 3`

all:
  @echo "From the Makefile we extract: MAJOR=$(MAJOR) MINOR=$(MINOR)"

Explanation

Here I have used several tools so it is more robust:

  • tr -s ' ': to remove extra space between elements,
  • grep: to select the unique line matching our purpose,
  • cut -d" " -f 3: to extract the third element of the selected line which is the target value!

Note that the define values can be anything (not only numeric).

Beware to use := (not =) see: https://stackoverflow.com/a/10081105/4716013

Community
  • 1
  • 1
prodev_paris
  • 495
  • 1
  • 4
  • 17