# Read a macro from a .h into Makefile

This is a discussion on Read a macro from a .h into Makefile within the C Programming forums, part of the General Programming Boards category; How to read a macro constant from a header file into a Makefile? In my software I plan to have ...

1. ## Read a macro from a .h into Makefile

How to read a macro constant from a header file into a Makefile?
In my software I plan to have a version.h which has, say, VERSION="1.2.3" and I want the software to instal in a directory specified by the software version. For example, if I have a BASEDIR which is /home/usr, I want version 1.2.3 of my software installed in home/usr/1.2.3, 1.2.4 in home/usr/1.2.4, and so on.
I currently have a file called VERSION, and this in my Makefile:
VERSION = cat VERSION
BINDIR = $(BASEDIR)/$(VERSION)
mkdir -p $(BINDIR); \ \rm -f$(BINDIR)/$@; \ cp$@ $(BINDIR)/$@ ; \
chmod -R 755 $(BINDIR) But I would rather put the version number in a header file so that an application of my system can use something like this: #if VERSION=="1.2.3" .....use a feature available in 1.2.3 #enif 2. The canonical way to do something like this is to have the version number defined in one file, usually not in a header of a Makefile, then set up a method to do the substition everywhere before build where necessary, for example in both the Makefile and the source header. However, if you wanted to do it your way, you could expand on your cat VERSION to use a combination of grep and sed and/or cut to extract the version from the header. 3. Originally Posted by cwr The canonical way ... is to have the version number defined in one file, usually not in a header of a Makefile, then set up a method to do the substition everywhere before build where necessary, for example in both the Makefile and the source header. However, if you wanted to do it your way, you could expand on your cat VERSION to use a combination of grep and sed and/or cut to extract the version from the header. I do not quite understand. 1. Now I have this cat VERSIONthing and I do not like it. I would like to put the version info in a .h file. 2. What do you mean by "a header of a Makefile"? 3. And you also have "source header" and the header where you "extract the version from". Are all these headers the same thing? I am confused. 4. "set up a method to do the substitution" - Could you give an example of such method? 4. I meant "a header or a Makefile", it was a typo. Sorry I didn't explain clearly. The solution I proposed was to create a template, so in your header file, you'd have: Code: #define VERSION "${VERSION}"
And in your Makefile, you'd have
Code:
VERSION = ${VERSION} And that would be it in your source repository. When it came time to compile, you'd have either a script, or another Makefile go through all your files, and convert any occurence of${VERSION} (you can use another format to recognise it as a templated token if you want) to the actual version number that is stored in one place. This system can be expanded to things other than ${VERSION} should you want to perform other substitutions, such as build date and time. Once all the substitions have occured, you'd build from the resulting source+Makefile. When the build has finished, the source+Makefile is just temporary, and is deleted. The original source/Makefile is retained, with just the${VERSION} token present.

This method has the advantage that if you use a source code repository, only code changes are committed between revision changes, you don't have a bunch of revisions to a header file that is just updating the version value. Metadata like version numbers can be maintained separately, or automatically incremented on demand.

If you really want to use your method of extracting the version number from a .h, you could do something like this. Assume myheader.h contains:
Code:
#define VERSION "1.2.3"
In the Makefile, you could have:
Code:
VERSION=grep VERSION myversion.h | cut -d \" -f2
This would find the string VERSION, and get the value between the quotation marks. This is quite a dirty and ugly thing to do, IMHO.

5. Thanks. Because I am too lazy to learn how to write a script to do the substitution, I will use the dirty and ugly method. I am writing a thread migration system. As I said in my original post, I would like an application using my system to be able to determine the version of my thread migration system. That is, in an application using my system, the programmer can write something like:
#if MIG_SYS_VERSION=="1.2.3"
.....use a feature available in 1.2.3
#endif
Apparently the dirty and ugly method is not able to make the system's version number visible to an application. Any solution? How to export a system's version number, just like how GCC "exports" some predefined symbols like __VERSION__ to a C program (see http://gcc.gnu.org/onlinedocs/cpp/Co...ed-Macros.html)?

6. Well you can just use
Code:
gcc -DMYVERSION=1.2.3
Then the macro MYVERSION will be defined as 1.2.3

7. It does not work.
To clarify, the macro not only needs to be defined for my system code to use, it also needs to be defined ("exported") for the application on my system to use.
Let's call my thread migration system MIG. Assume all the system code is in mig.c. And after I boot up my thread migration system, the prompt becomes MIG> And in this prompt a user would type "mig_exec myprog" to execute an application written to run on this system. And this myprog uses MIG_VERSION in its code.
If I compile my thread migration system using
gcc -DMIG_VERSION=1.2 mig.c -o mig
and then boot up my system:
% mig
MIG>
and then execute myprog:
MIG> mig_exec myprog
the MIG_VERSION symbol is not visible by myprog. That is, if I write
#if MIG_VERSION=1.2
do something
#endif
in myprog, it is ignored.