Differences between revisions 12 and 18 (spanning 6 versions)
Revision 12 as of 2010-01-28 13:01:59
Size: 2268
Comment:
Revision 18 as of 2015-08-10 06:26:49
Size: 3283
Editor: follower
Comment: Correct misuse of .PHONY with wrong target introduced in Revision 14. Fix wrong target name in LaTeX example.
Deletions are marked like this. Additions are marked like this.
Line 15: Line 15:
Make rebuilds targets only if one of the dependencies is newer. That means even if the version has changed, due to a change somewhere, files using HGVERSION will not be rebuild automatically. To overcome this add new dependency in the Makefile to updated these files: Make rebuilds targets only if one of the dependencies is newer. That means even if the version has changed, due to a change somewhere, files using HGVERSION will not be rebuilt automatically. To overcome this, add a new dependency in the Makefile to update these files:
Line 19: Line 19:
.PHONY: update_hgstamp
Line 20: Line 21:
update_hgstamp:
[ -f hgstamp ] || touch hgstamp
        echo $(HGVERSION) | cmp -s hgstamp - || echo $(HGVERSION) > hgstamp
        [ -f $@ ] || touch $@
        echo $(HGVERSION) | cmp -s $@ - || echo $(HGVERSION) > $@
Line 24: Line 24:
In this example version.c depend has the extra dependency hgstamp, which is generated by the rule 'update_hgstamp'. This rule updates hgstamp if and only if the version has ''really'' changed. You will see in this example `version.o` has the extra dependency on the file `hgstamp`.

How this works:
 1. The rule for the `hgstamp` target specifies the prerequisite `update_hgstamp`.
 1. The `update_hgstamp` target is marked as a ''phony target'' (see [[http://www.gnu.org/software/make/manual/html_node/Phony-Targets.html|make manual]]) which forces the recipe for `hgstamp` to be executed every time.
 1. '''''However''''' `make` only forces `version.o` to be remade when the modification time of the `hgstamp` ''file'' changes and ''this'' only happens when the `hgstamp` recipe ''actually'' updates the content of the `hgstamp` file--which only happens if and only if the version has ''really'' changed.

See https://bitbucket.org/follower/hgversion-handling for an example of a correctly functioning Makefile.

{{{#!wiki caution
It is ''essential'' that the `hgstamp` target is '''''not''''' marked as phony.

If `hgstamp` is marked as phony then the `hgstamp` file will be considered out of date every time `make` is run--which will cause `version.o` and everything that depends on `version.o` to be rebuilt ''every time''. (Revisions 14-17 of this page used `.PHONY` for the wrong target causing rebuilds every time.)
}}}
Line 27: Line 40:
If you are using automake add the following lines to your Makefile.am If you are using automake add the following lines to your Makefile.am:
Line 34: Line 47:
.PHONY: update_hgstamp
Line 35: Line 49:
update_hgstamp:
[ -f hgstamp ] || touch hgstamp
        echo $(HGVERSION) | cmp -s hgstamp - || echo $(HGVERSION) > hgstamp
        [ -f $@ ] || touch $@
        echo $(HGVERSION) | cmp -s $@ - || echo $(HGVERSION) > $@
Line 41: Line 54:
 * hg parents, the -R option is added to prevent hg to search in lower directories in the case we don't have a repository  * hg parents, the -R option is added to prevent hg from searching in lower directories in case we don't have a repository
Line 46: Line 59:
Just a add the following lines to your Makefile Just add the following lines to your Makefile
Line 50: Line 63:
.PHONY: update_hgid
Line 51: Line 65:
update_hgid:
[ -f hgid.tex ] || touch hgid.tex
        echo '$(HGID)' | cmp -s hgid.tex - || echo '$(HGID)' > hgid.tex
        [ -f $@ ] || touch $@
        echo '$(HGID)' | cmp -s $@ - || echo '$(HGID)' > $@
Line 55: Line 68:
and this lines to your main tex file and this lines to your main tex file:
Line 61: Line 74:
now one can use the command \hgid to get the version everywhere. Now one can use the command \hgid to get the version everywhere.

Simple

Add the following line to your Makefile

HGVERSION:= $(shell hg parents --template 'hgid: {node|short}')

and

-DHGVERSION="\"${HGVERSION}\""

to your CPPFLAGS. Now one can use the define HGVERSION inside the code.

Rebuild files using HGVERSION

Make rebuilds targets only if one of the dependencies is newer. That means even if the version has changed, due to a change somewhere, files using HGVERSION will not be rebuilt automatically. To overcome this, add a new dependency in the Makefile to update these files:

version.o: hgstamp
.PHONY: update_hgstamp
hgstamp: update_hgstamp
        [ -f $@ ] || touch $@
        echo $(HGVERSION) | cmp -s $@ - || echo $(HGVERSION) > $@

You will see in this example version.o has the extra dependency on the file hgstamp.

How this works:

  1. The rule for the hgstamp target specifies the prerequisite update_hgstamp.

  2. The update_hgstamp target is marked as a phony target (see make manual) which forces the recipe for hgstamp to be executed every time.

  3. However make only forces version.o to be remade when the modification time of the hgstamp file changes and this only happens when the hgstamp recipe actually updates the content of the hgstamp file--which only happens if and only if the version has really changed.

See https://bitbucket.org/follower/hgversion-handling for an example of a correctly functioning Makefile.

It is essential that the hgstamp target is not marked as phony.

If hgstamp is marked as phony then the hgstamp file will be considered out of date every time make is run--which will cause version.o and everything that depends on version.o to be rebuilt every time. (Revisions 14-17 of this page used .PHONY for the wrong target causing rebuilds every time.)

Autotools

If you are using automake add the following lines to your Makefile.am:

HGVERSION:= $(shell hg -R $(top_srcdir) parents --template 'hgid: {node|short}' 2> /dev/null || grep node $(top_srcdir)/.hg_archival.txt 2> /dev/null || true )
AM_CPPFLAGS = -DHGVERSION="\"${HGVERSION}\""

version.o: hgstamp
.PHONY: update_hgstamp
hgstamp: update_hgstamp
        [ -f $@ ] || touch $@
        echo $(HGVERSION) | cmp -s $@ - || echo $(HGVERSION) > $@

The definition of HGVERSION is more robust here. It tries to get the version in the following order

  • hg parents, the -R option is added to prevent hg from searching in lower directories in case we don't have a repository
  • grabbing it from .hg_archival.txt, in case we are using a tarball made by hg archive
  • undefined

LaTeX

Just add the following lines to your Makefile

HGID:=$(shell hg parents -R . --template "{node|short}" | sed 's/.*/\\renewcommand{\\hgid}{&}/')
.PHONY: update_hgid
hgid.tex: update_hgid
        [ -f $@ ] || touch $@
        echo '$(HGID)' | cmp -s $@ - || echo '$(HGID)' > $@

and this lines to your main tex file:

\newcommand{\hgid}{null}
\input{hgid}

Now one can use the command \hgid to get the version everywhere.


CategoryHowTo

VersioningWithMake (last edited 2015-08-10 06:26:49 by follower)