Running unix command in Makefile for parsing text and passing it to link line as define -D

StackOverflow https://stackoverflow.com/questions/23666960

  •  22-07-2023
  •  | 
  •  

Question

$ cat $HOME/version.txt

version=1.2.3.4


$ cat hello.c

#include <stdio.h>

int main()
{
   printf("Software Version = [%s]\n",VERSION);
   return 0;
}

$ cat hello.mk

FILE=$(HOME)/version.txt

VERSION:=`cat $(FILE) | cut -d = -f2 | sed -e 's-^-\\\"-g' -e 's-$-\\\"-g'`

compile :
        gcc -o hello hello.c -DVERSION=$(VERSION)

$ cat test.sh
FILE=$HOME/version.txt
# Append with \" at the beginning and end of the string for the compiler
cat $FILE | cut -d = -f2 | sed -e 's-^-\\\"-g' -e 's-$-\\\"-g'

OUTPUT of test.sh :
\"1.2.3.4\"

Problem :

I am trying to write a makefile (hello.mk) which reads a static file ($HOME/version.txt) which stores version of the software being developed in the form version=x.x.x.x. Makefile reads the file and extracts the version value and passes to the compile line through -D flag. In the 'C' code (hello.c), printing the VERSION detail. The idea is to just maintain the version file for various builds and the build will have the appropriate version number in various logs etc.,

I wrote a simple script test.sh to test the cut | sed option and it works fine from the command line. When I have them in the makefile as a MACRO, I get syntax error for the last $ sed option. Also, when I use some other hacks to get the values from the file, the compile line -DVERSION=$(VERSION) seem to expand to the macro VERSION commands rather than the actual VERSION value.

To test, in the makefile, if I replace VERSION to hardcode value like \"1.2.3.4\, then the compile goes through with desired effect.

The current format of the version file cannot be changed (legacy code and is used by many other tools).

Appreciate if you could help me to resolve this issue or any better way to parse the file.

Was it helpful?

Solution 2

You need to quote $ as $$ in make shell scripts. I've also trimmed down your pipeline to just use awk.

hello.mk

...
VERSION := $(shell awk '/^version=/ { split($$0, a, /=/); print a[2];}' $(FILE))
compile :
        gcc -o hello hello.c -DVERSION='"$(VERSION)"'

OTHER TIPS

You need to escape the $ in sed via $$; Additionally, i've used $(shell ...)

mnunberg@csure:/tmp$ make -f hello.mk 
cc -o hello hello.c -DVERSION=\"1.2.3.4\"
mnunberg@csure:/tmp$ ./hello 
Hello. Version is 1.2.3.4
mnunberg@csure:/tmp$ cat hello.mk 
FILE=version.txt

VERSION:=$(shell cat $(FILE) | cut -d = -f2 | sed -e 's-^-\\\"-g' -e 's-$$-\\\"-g')

compile :
    cc -o hello hello.c -DVERSION=$(VERSION)

Learnt a lot from both your replies. Was not aware of the '"$(VERSION)"' in the compile line. That eliminated the need to append " while parsing. Also, the shell command was cool. Not sure why it is different from when I did a backquotes (‘`’).

Thanks much again.

Did the following for now.

hello.mk ::

VERSION:=$(shell sed -e 's-^version=--g' $(FILE))
....
compile :
        gcc -o hello hello.c -DVERSION='"$(VERSION)"'
.....
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top