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.

Andrew T
  • 5,549
  • 7
  • 43
  • 55

4 Answers4

4

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ý
  • 40,587
  • 6
  • 104
  • 126
  • 2
    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. – Andrew T Oct 08 '09 at 18:30
4

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
  • 10,157
  • 6
  • 43
  • 82
  • I'm unable to make it work after conversion to Visual Studio project (with qmake). It seems to disappear. If the very same command is added to `QMAKE_POST_LINK` then it properly shows up in post build step. (Yet for this use case it is far to late.) – Adam Badura Feb 06 '13 at 11:50
1

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 Brase
  • 78,112
  • 7
  • 148
  • 169
1

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
  • 1,573
  • 2
  • 14
  • 18
  • This does not work if the shell command contains spaces as qmake inserts `-D` into the command. You have to surround this with `'`: `'\\\"\`./setlocalversion.sh --some --parameters\`\\\"'` (What an escape hell: SO markup, qmake, make, shell ...) – iliis Jun 03 '14 at 08:30
  • And as another complication: If the output of your command contains spaces as well you need another layer of double quotes. But then you cannot execute code with backticks anymore and you must use `$(shell)`: see http://stackoverflow.com/a/24010395/211520 for details. – iliis Jun 03 '14 at 08:51