Thread: Read a macro from a .h into Makefile

  1. #1
    Registered User
    Join Date
    Jul 2005
    Posts
    98

    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. #2
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    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. #3
    Registered User
    Join Date
    Jul 2005
    Posts
    98
    Quote 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 VERSION`thing 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. #4
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    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. #5
    Registered User
    Join Date
    Jul 2005
    Posts
    98
    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. #6
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Well you can just use
    Code:
    gcc -DMYVERSION=1.2.3
    Then the macro MYVERSION will be defined as 1.2.3

  7. #7
    Registered User
    Join Date
    Jul 2005
    Posts
    98
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How can I know the actual bytes read in a file read
    By pliang in forum C++ Programming
    Replies: 1
    Last Post: 06-08-2005, 04:23 PM
  2. makefile blues....
    By WaterNut in forum C Programming
    Replies: 6
    Last Post: 05-30-2005, 08:22 PM
  3. What Would You Use To Read User Input?
    By djwicks in forum C Programming
    Replies: 11
    Last Post: 04-05-2005, 03:32 PM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. Help! Can't read decimal number
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 09-07-2001, 02:09 AM