views:

587

answers:

6
+7  Q: 

Automatic build ID

We're looking for a way to include some sort of build ID automatically in our builds. This needs to be portable (VC++, g++ on Linux and Mac) and automatic. VC++ is what matters most, since in the other environments we use custom Python build scripts so I can do whatever I want.

We use SVN, so we were looking at using the output of svnversion to write the revision to a header and include it. This has problems : if we put the file in SVN, it will appear as modified every time, but it would be a superfluous commit and in a sense generate an infinite loop of increasing revisions. If we don't put the file in SVN and just create it as a pre-build step, the sources wouldn't be complete, as they'd need the pre-build step or Makefile to generate that file.

We could also use __DATE__ but we can't guarantee the file that uses the __DATE__ (ie writes it to a log file) will be compiled if some other file is modified - except if we "touch" it, but then we'd cause the project to be always out of date. We could touch it as the pre-build step, so it would get touched only if the rest of the project is out of date, thus not causing a spurious compile, but if VC++ computes the dependencies before the pre-build step, this wouldn't work (the file with __DATE__ won't get compiled)

Any interesting ideas?

+8  A: 

We're using the output of svnversion, written to a header file and included. We omit the file from the repository and create it in a pre-build step; this has worked quite well for us. (I'm not sure why you object to using a pre-build step?)

We're currently using a Perl script to convert svnversion's output into a header file; I later found out that TortoiseSVN includes a subwcrev command (which has also been ported to Linux) that can do much of the same thing.

Josh Kelley
In the script that you use to generate the build id, you may want to compare the current id in the header with the new id, and do nothing is they are the same.
Arkadiy
@Arkadiy - In some cases these are not checked back in. Checking that back in would make it a 5 step process: 1. get; 2. run script; 3. check in; 4. label; 5 get and build. With just replacing a template file all you do is label, get, build - the file only serves as a template - no saving
Tim
A: 

Why not tie a GUID to it, almost every language has support for generating one, or if your's doesn't there are alot of algorithms for that around.

(Although, if you do use subversion, I personally like Josh's idea better!)

leeand00
I think you probably got a down vote because the unstated (I assume) implication of the OP was to have an ID that means something in the context of development team. A typical GUID usually looks like a random string and while it meets the criteria of the question, it is not really what he wanted.
Tim
+4  A: 

If you don't like the idea of an include file not in source control that is required for a build, consider a batch file or other build step that programmatically creates a file/include and call the svnversion within your build process.

basically GENERATE the file so you don't have an unversioned and required file.

EDIT Josh's subwcrev is probably the best idea.

Before that was implemented I wrote my own hacky tool to do the same thing - do replacement in a template file.

Tim
That's what we do with our build system, use a script in the build system to generate the version information header.
Daemin
+3  A: 

It could be as simple as:

% make -DBUILD_NUMBER=`svnlook youngest /path/to/repo`
Paul Beckingham
A: 

Automatic builds can typically be full, clean builds. In that case, you start in a clean directory and there would be no issue with __DATE__ in any case. Otherwise, see Paul Beckinham's idea.

MSalters
+2  A: 

I'd look at SvnRev. You can use it as a custom pre-build step in VS, or call it from a makefile, or whatever else you need to do, and it generates a header file that you can include in your other files that will give you what you need. There's good documentation on the site.

SubWCRev is another option, though the Linux port is newer, and I don't know that a Mac version exists. It's very useful on Windows for .NET (which I'm guessing isn't an issue for you, but I'm adding this for future reference), because it allows you to create a template file that can be used to generate, for example, the Properties file for a .NET assembly.

Harper Shelby
+1 - I add a custom target in my CMakeLists.txt that calls a small script containing the svnrev call. This is #included into a source file that logs the revision number. You can also check to see if the code has been modified since the last commit
thekidder