views:

304

answers:

4

My current workflow:

  1. hg update (or whatever one uses to check out a revision)
  2. MyProject.proqmakeMyProject.vcproj
  3. Open Visual Studio, edit files
  4. Build project

During the build step, how can I update my config.h header file with information from version control system (e.g. hg id)?

MyProject.vcproj is generated by qmake, so I shouldn't edit it by hand.

+3  A: 

You can execute external commands from inside qmake. The easiest way to make the information available in your sources would be to use a define:

HGID = $$system(hg id)
DEFINES += HGID=\\\"$$HGID\\\"

I'm not sure if you can edit an external file from qmake. You could use an external tool, but on Windows you normally don't have things like sed, so it might be a little more problematic.

Lukáš Lalinský
This command will be executed during qmake run. I want to execute it just before compiling source code. It seems there is no easy way to do this.
goodrone
+1  A: 

One opton is to enable the Keyword Extension. Put something like this in your hgrc (or Mercurial.ini if that's your thing):

[extensions]
hgext.keyword=

[keyword]
config.h =

[keywordmaps]
HGREV = {node}

Then in config.h put:

#define HGREV "$HGREV$"

You might need to parse the hex value out of the "$HGREV: deadbeefdeadbeef $" that you'll get, but that's easily done by whatever code is accessing the HGREV define.

Ry4an
+4  A: 

You can accomplish that using a custom build target and the PRE_TARGETDEPS keyword. Assuming config.h.in has the folowing format:

#define HGID $HGID

You can define a custom build target that will process hgid.h.in and output to hgid.h prior to building your main target as follows:

hgid.target = hgid
hgid.commands = sed s/\\\$$HGID/`hg id`/ hgid.h.in > hgid.h
QMAKE_EXTRA_TARGETS += hgid
PRE_TARGETDEPS += hgid
Ton van den Heuvel
A: 

In addition to Lukáš Lalinský and goodrone's comment, I'd like to mention that qmake can link directly to the script, not only to it's output. So one can say

DEFINES += REPO_ID=\\\"`./setlocalversion.sh`\\\"

and the script will be freshly executed for every single target.

marvin2k