diff --git a/configure/RULES_BUILD b/configure/RULES_BUILD index 711da3434..0af9b6e55 100644 --- a/configure/RULES_BUILD +++ b/configure/RULES_BUILD @@ -359,6 +359,19 @@ tapfiles: $(TESTSCRIPTS) $(TAPFILES) @$(RM) $@ $(PERL) $(TOOLS)/makeTestfile.pl $@ $< +#--------------------------------------------------------------- +# Generate header with version number from VCS + +ifneq ($(VERHEADER),) +GENVERSIONHEADER ?= $(PERL) $(TOOLS)/genVersionHeader.pl +MODVERSION ?= undefined +MODMACRO ?= MODULEVERSION + +$(VERHEADER):: + $(GENVERSIONHEADER) -t $(TOP) -V $(MODVERSION) -N $(MODMACRO) $@ + +endif + #--------------------------------------------------------------- # Install rules for BIN_INSTALLS and LIB_INSTALLS diff --git a/src/tools/Makefile b/src/tools/Makefile index 496b0e4d1..ff5c55e39 100644 --- a/src/tools/Makefile +++ b/src/tools/Makefile @@ -49,6 +49,7 @@ PERL_SCRIPTS += dbdToMenuH.pl PERL_SCRIPTS += dbdToRecordtypeH.pl PERL_SCRIPTS += dbdExpand.pl PERL_SCRIPTS += dbdToHtml.pl +PERL_SCRIPTS += genVersionHeader.pl PERL_SCRIPTS += registerRecordDeviceDriver.pl include $(TOP)/configure/RULES diff --git a/src/tools/genVersionHeader.pl b/src/tools/genVersionHeader.pl new file mode 100644 index 000000000..0fd6db2df --- /dev/null +++ b/src/tools/genVersionHeader.pl @@ -0,0 +1,74 @@ +#!/usr/bin/env perl +# +# Generate a C header file which +# defines a macro with a string +# describing the VCS revision +# + +use EPICS::Getopts; + +use strict; + +our($opt_v,$opt_t,$opt_N,$opt_V); + +$opt_N = "MODVERSION"; +$opt_V = "undefined"; +$opt_t = "."; +my $foundvcs = 0; +my $result; + +getopts("vt:N:V:") or + die "Usage: genVersionHeader.pl [-t top] [-N NAME] [-V VERSION] output.h"; + +my ($outfile) = @ARGV; + +if(-d "$opt_t/.hg") { # Mercurial + # v1-4-abcdef-dirty + # is 4 commits after tag 'v1' with short hash abcdef + # with uncommited modifications + $result = `cd "$opt_t" && hg tip --template '{latesttag}-{latesttagdistance}-{node|short}\n'`; + chomp($result); + if(length($result)>1) { + $opt_V = $result; + $foundvcs = 1; + } + # see if working copy has modifications, additions, removals, or missing files + my $hasmod = `cd "$opt_t" && hg status -m -a -r -d`; + chomp($hasmod); + if(length($hasmod)>0) { + $opt_V = "$opt_V-dirty"; + } +} +if(!$foundvcs && -d "$opt_t/.git") { + # same format as Mercurial + $result = `git --git-dir="$opt_t/.git" describe --tags --dirty`; + chomp($result); + if(length($result)>1) { + $opt_V = $result; + $foundvcs = 1; + } +} + +my $output = "#ifndef $opt_N\n# define $opt_N \"$opt_V\"\n#endif\n"; +print "== would\n$output" if $opt_v; + +my $DST; +if(open($DST, '+<', $outfile)) { + my $actual = join("", <$DST>); + print "== have\n$actual" if $opt_v; + + if($actual eq $output) { + print "keep existing $outfile\n"; + exit(0) + } + print "updating $outfile\n"; +} else { + print "create $outfile\n"; + open($DST, '>', $outfile) or die "Unable to open or create $outfile"; +} + +seek($DST,0,0); +truncate($DST,0); +print $DST $output; + +close($DST);