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:
The rule for the hgstamp target specifies the prerequisite update_hgstamp.
The update_hgstamp target is marked as a phony target (see make manual) which forces the recipe for hgstamp to be executed every time.
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.