Automatic build ID - c++

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?

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.

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.

It could be as simple as:
% make -DBUILD_NUMBER=`svnlook youngest /path/to/repo`

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.

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.

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!)

Related

C Compiler automatic Version increment

I'm wondering if there's a macro or a simple way to let the compiler increment either major, minor or revision of my code each time when I compile?
By the way I'm using the ARM compiler and uVision from Keil.
To set the version is not a compiler topic. This should be done in connection with a source code control / version control system like cvs/svn/git or others. Your build id should be connected to the content of your source code database to get reproducible builds from checkouts from your version control system. Or, if your code is not already committed to your database a dirty-tag should be provided and compiled in to give the user of the software a chance to see that this is not a controlled version.
Simply counting a value in a variable can be done by a Makefile or in pre- and post-build instructions which depends on the used IDE. Sorry, for keil I have no experience...
Define Post-Build Event to run small external program. The program has to modify specific .h file. In the header file define macros like VER_MAJOR, VER_MINOR, VER_BUILD. Date/time string can also be updated. I use this method and can control the version numbers as I wish.
IMO, you do not need to do this, especially increase a number every time you compile your code.
Set the major and minor revision manually in a header file; you should not have to do this often.
Build number should only be related to the source control revision number (i.e. you should be able to build and rebuild any revision under source control).
Imagine if you are a team of 5 developers, and everyone build and rebuild on their side what is the actual build number?
do they all update a header file ?
who is responsible of owning that header file ?
Some compilers do support features like "post build", which runs a program of your choice after compiling, but that would be tricky if your program is built from multiple source files. Not all compilers do though.
For that reason, I wouldn't actually do this sort of thing via the compiler. I'd do it in the build script (e.g. makefile) or by configuring the build settings in your IDE.
Assuming you're using make or similar, add a target something like setversion (you pick the name) that runs a program which modifies a header file which specifies the components of your version number. So typing make setversion will update your version numbers.
Optionally, that target can also - after updating the version numbers - do a make clean (i.e. delete all object files and executables) and make all (to recompile and link everything).
I also suggest avoiding changing version numbers after each recompile. Imagine you're busily testing and debugging code, and go through several rebuild cycles. Do you really want the version number updated every time you recompile even one source file? It can be done that way if you choose, but will make every rebuild take longer (and, in projects with multiple source files) you will need to take care if you want to preserve capability for incremental builds.

How to create dynamic defines for Visual Studio?

I have a C++ project that builds on several platforms.
On Mac OSX and Linux, I use SConstruct, which allows me to have some "smartness" regarding the different compilation steps. Namely, I could put the program version in a file named VERSION at the root of the repository, whose content is simply:
2.0
In the build SConscript, I just have to open, read and parse that file and I can create dynamic defines based on it. For instance:
env.Append(CXXFLAGS=['-DVERSION_MAJOR=%s' % open('VERSION').read().split('.')[0]])
This is, for obvious reasons, very convenient. It also allows me to put today's date in an environment variable for instance.
Now for Windows, I have a .sln file with different .vcxproj files into which I'd like to do something similar, except I have no idea how.
To summarize, my question is: how can I have "smart" defines like that (reading, parsing a file and putting its content into several environment variables) without having to change the .sln/.vcxproj files manually on every version shift ?
I know I could use SCons on Windows too, but I'd like not to (mainly because it seems less popular on the platform, and I don't want to scare potential contributors that only know Windows-specific tools).
A common way to do this is to define your constants in an include file:
e.g.
// Version.h - Autogenerated, don't edit
#define VERSION_MAJOR 1
Next you write a script or a program (in your favourite language) to obtain version from somewhere and dynamically write Version.h. Possibly parse the old Version.h and increment or get it from some external source.
In visual studio, create a custom build step for Version.h and make it dependent on something that forces it to update on every build.
You could maintain the current solution, and for Windows, integrate it with Visual Studio solution and project files generated by SCons using the MSVSProject() builder or the MSVSSolution() builder.
You can find more info about these SCons builders here.

Any way to parse preprocessed source through external tool before it compiles?

I want the compiler to run preprocessing, generate all the .i files like it normally does if I just use the "generate preprocessed file" option, and then run an external tool, wait for it to complete, and then go on with the compilation of those .i files (which by now can be modified of course).
If that is not possible, is there a way to run an external tool on every file that is being compiled before preprocessing and compilation? (Would probably be a hell to debug in environment like that, but still).
If there is no option like that, could this even be done at all? I mean, does the compiler even use those .i files, or are they just output for the user somehow?
Basically, is there any way to automatically tamper with the source before it is compiled, but without modifying the actual files?
Just for refs: I am trying to think of a smart way to obfuscate all the strings with minimum modification of the source.
Yes, you'd simply update your build system to have a preprocess step, obfuscate step, then compile-to-obj step. By default, most build systems merely merge all those to one step (and skip the obfuscate step). Should be no big deal with any "real" build system like Scons, waf, or even Make.
If you're using Visual Studio, then it is a bit more work. Microsoft wants you to write your build operations in MSBuild, and that's quite a bit of work, IMHO. It's not easy because MSVS is principally an IDE for iterative development, and NOT intended to be a build tool. It's not, and will never be, a build tool (even though it happens to do "build things", but only standard and very simple "build things"). But, you can still use the IDE with a different build tool. For example, we use Scons for our build, and it generates MSVS *.sln and *.vcproj files, and those files merely build with Scons (but all the files are edited in the MSVS IDE).
The simple answer: Your question is very simply a build-operations problem. It should be very straight-forward with any non-"toy" build system.
The distcc (distributed build tool) effectively preprocesses all files locally, then sends the *.i to remote compilers (that do not even need headers installed), and then ships back the *.obj. So, what you're talking about is pretty straight-forward.
Let x.cpp be your file you want to preprocess.
Set the compiler option to generate preprocessed output for x.cpp, let it be x.i.
Add the x.i to the project and set the "custom build tool" in the properties. Set the "output files" to x.preprocessed.cpp.
Add x.preprocessed.cpp to the project.
See msdn for details.
You should be able to perform a "Pre-Build Event" and plug in any external tools there. In VS200x it's under Configuration Properties -> Build Events -> Pre-Build Events.
Just use a decent build system. SCons, waf, or something else if you won't like those two.
You could use a make file to generate the .i files first, run your processing on them, then compile them.

Use domain-specific-language files inside C++ project

I am developping a DSL with its own graphical editor. Such files have a .own extension. I also have a small tool that compiles .own files into .h files.
X.own --> X.h and X/*.h
I have written a simple .rules file to launch the generation.
My problem is the following :
Most of my source files include X.h, but a change in X.own does not mean the generated X.h (or any other generated file) will be different. This is dealt with by the generator through the use of temporary files and file comparison. But Visual Studio does not seem to know how to deal with all this. If i set the "output file(s)" property to the right file(s), it always assumes they will be changed. If i don't, it generates its build process assuming they won't be !
How can i make things right ?
1) Launch custom build tool
2) Compute build process based on dependencies
Don't use the custom build tool options but instead set it up as a pre-build event for the solution (this can take a general command line, just like the custom build tool). This way MSVS will not examine the generated files. As long as they are #included or listed in the solution explorer they should be compiled fine as the generation of the .h files will happen before any other compilation.
I find the custom build tool is not so useful as the pre- and post- build events in general, because of the way it expects files to be generated or modified. You might find this tool useful for other things in the future (e.g. to compress the .exe after build, to generate other dependencies correctly, to ensure files are in place etc...)
There is a nice diagram showing where to find these options in the solution properties here
jheriko's answer is interesting, because it provides a way to launch custom tool, then generate build dependencies. But it's not very usable, because you then lose all possibilities to use "custom build tools" toolkit, in which you can
choose to always compile files with some precise extension
manually skip custom build for a particular file in a particular project configuration (and visualize this decision)
There is no way (or at least i have found none) to "have it all". The only way i have found is to have the custom build tool return a non-zero number when files have been updated, with a message to the user explaining that it is not an error and inviting him to launch build again. The next time, custom build tool is launched again (not optimal, but the tool i use is pretty fast) but modifies no new file, and build process goes on, using valid dependencies.
Note : the approach described above does not work with Incredibuild, which seems to ignore project build order.

Embedding SVN Revision number at compile time in a Windows app

I'd like my .exe to have access to a resource string with my svn version. I can type this in by hand, but I'd prefer an automated way to embed this at compile time. Is there any such capability in Visual Studio 2008?
I wanted a similar availability and found $Rev$ to be insufficient because it was only updated for a file if that file's revision was changed (which meant it would have to be edited and committed very time: not something I wanted to do.) Instead, I wanted something that was based on the repository's revision number.
For the project I'm working on now, I wrote a Perl script that runs svnversion -n from the top-most directory of my working copy and outputs the most recent revision information to a .h file (I actually compare it to a saved reversion in a non-versioned file in my working copy so that I'm not overwriting current revision information at every compile but whether you chose to do so is up to you.) This .h file (or a number of files if necessary, depending on your approach) is referenced both in my application code and in the resource files to get the information where I'd like it.
This script is run as a pre-build step so that everything is up-to-date before the build kicks off and the appropriate files are automatically rebuilt by your build tool.
How about using SubWCRev the command line tool that ships with TortoiseSVN. You create a template file with tokens in it like $WCREV$ $WCDATE$ etc. Then have a pre-build step that run SubWCRev on your template file to create the actual source file that is fed to the compiler.
You can get SVN to embed it for you, if that will solve the problem. See the $Rev$ keyword on that page.
Have a look at svn keyword substitution here. There is another SO question here which I found through google!
antik's solution is the one we use. Be careful of using environment variables, the .h file ensures you can have a dependency which will cause any files that need it to be recompiled when the svn rev number changes.