Get scons to generate a new build number - c++

I'd like to get scons to read a previous version number from a file, update a source file with a new version number and current date and then write the number back to the original file ready for the next build.
This needs to happen only when the target is out of date. IOW the version number doesn't change if no build takes place. The original file is source controlled and isn't a source file else it could trigger another build on check-in (due to CI). CLARIFICATION From scons' point of view the code will always be out of date due to the auto-generated source file but scons will only be run from a Continuous Integration job (Jenkins) when a SCM change is detected.
I've looked into AddPostMethod, but this seems to fire for all files within the list of source files.
Command and Builder methods use the VARIANT_DIR so I can't edit these files and then check them back in as they no longer map to the repo.
I'm hoping I'm just misunderstanding some of the finer details of scons else I'm running out of ideas!
Update
Thinking this through some more, Tom's comment is correct. Although I have two files, one version controlled text file (non-source code) and one non-source controlled source file there is no way to check one file in and prevent a continuous build/check-in cycle. Jenkins will see the new text file and spin off a build, and scons will see the new generated file. So unless I delete the generated file at some point, although this seems to go against the workflow of both tools.
Does anyone have any method for achieving this? It seems pretty straightforward. Ultimately I just want to generate build numbers each time a build is started.

From SCons User Guide section 8, Order-Only Dependencies, you can use the Requires method:
import time
# put whatever text you want in your version.c; this is just regular python
version_c_text = """
char *date = "%s";
""" % time.ctime(time.time())
open('version.c', 'w').write(version_c_text)
version_obj = Object('version.c')
hello = Program('hello.c',
LINKFLAGS = str(version_obj[0]))
Requires(hello, version_obj)
Two things to note: first you have to add the explicit Requires dependency. Second, you can't make version_obj a source of the Program builder, you have to cheat (here we pass it as a linkflag), otherwise you'll get an automatic full dependency on it.
This will update the version.c always, but won't rebuild just because version.c changed.

Related

AssemblyInfo.cs needs to change in SourceControl after build completes

I'm using TFSBuildExtensions to auto version my libraries.
I've got the build template modified so that it does that nicely. Although it doesn't actually update the AssemblyInfo.cs file.
Now I would like that AssemblyFileVersion attribute in the AssemblyInfo to update in source control. How can that be done and why isn't that being done by any of the projects I've seen out there?
Is there a reason not to have this updated in source control? (essentially checkout the file and update it.)
The way I see it, if you want to update the Version number of your assemblies you have 2 choices:
Update the one(s)* in source control and then read them on build to get the version. You can update the existing version with Regex replaces, custom scripts, etc.
Get the build to set the version numbers as it goes.
If you are doing #1, you don't need #2.
If you are doing #2, it's normally because you don't want a check-in for each version - otherwise you would just do #1 :). What you are suggesting doing is automating #1 on check-in, albeit after you edit the version number in the build definition, so it isn't without user interaction.
If you really want this, you'll have to mess with the template a bit more, people who use the extension you linked normally just do #2.
* You can link many projects to a single file if you want.

project version in .exe-filename

I just tested the auto-versioning plugin and was wondering whether it is possible to put the project's version into the output exe's filename.
So e.g. the output could look like this:
myProject_0.11.8.exe
Being able to have the compile-time-date in the filename would be nice aswell:
myProject_2013_12_16.exe
Is that possible?
You can add the following to the output filename variable:
add $(TODAY) or $(NOW_) or $(NOW_L), placing it between the end of the filename and the .exe part and you will add the compile date and time (including seconds).
To add the version number you need a few steps (there may be an easier way however I don't know one and would love to hear it:)
First go to Global Compiler Settings >> #defines and add #version = RC_VERSION thusly:
Then in your project options go to:
I use today and the version number as that means you only get one exe per day and version, whereas using NOW gives an exe per minute difference and NOW_L gives an exe per second of difference.
File Link
I have uploaded a sample project at Test Project on my website http://www.dark-arts.tk (work in progress).
NB: remember to do this for each build you want formatted this way!
Hope this helps, and let me know if you need more info:)

How to store the Visual C++ debug settings?

The debug settings are stored in a .user file which should not be added to source control. However this file does contain useful information. Now I need to set each time I trying to build a fresh checkout.
Is there some workaround to make this less cumbersome?
Edit: It contains the debug launch parameters. This is often not really a per-user setting. The default is $(TargetPath), but I often set it to something like $(SolutionDir)TestApp\test.exe with a few command line arguments. So it isn't a local machine setting per se.
Well, I believe this file is human readable (xml format I think?), so you could create a template that is put into source control that everyone would check out, for instance settings.user.template. Each developer would than copy this to settings.user or whatever the name is and modify the contents to be what they need it to be.
Its been a while since I've looked at that file, but I've done similar things to this numerous times.
Set the debug launch parameters in a batch file, add the batch file to source control. Set the startup path in VS to startup.bat $(TargetPath).

Avoiding unneccessry recompilations using "branchy" development model

I'm using Mercurial for development of quite a large C++ project which takes about 30 minutes to get built from the scratch(while incremental builds are very quick).
I'm usually trying to implement each new feature in the new branch(using "hg clone") and I may have several new features developed during the day and it's quickly getting very boring to wait for the new feature branch to get built.
Are there any recipes to somehow re-use object files from other already built branches?
P.S. in git there are named branches within the same repository which make re-usage of the existing object files possible for the build system, however I prefer the simpler Mercurial separate branches model...
I suggest using ccache as a way to speed up compilation of (mostly) the same code tree. The way it works is as following:
You define a place to be used as the cache (and the maximum cache size) by using the CCACHE_DIR environment variable
Your compiler should be set to ccache ${CC} or ccache ${CXX}
ccache takes the output of ${CC} -E and the compilation flags and uses that as a base for its hash. As long as the compiler flags, source file and the headers are all unchanged, the object file will be taken from cache, saving valuable compilation time.
Note that this method speeds up compilation of any source file that eventually produces the same hash. If you share source files across projects, ccache will handle them as well.
If you already use distcc and wish to use it with ccache, set the CCACHE_PREFIX environment variable to distcc.
Using ccache sped up our source tree compilation around tenfold.
A simple way to speed up your builds could be to use a local "build directory" on your disk. This way you can checkout into this directory and start the build. The first time it will take the full time, but after that it will (hopefully) only rebuild the files where the source code changed.
My Localbranch extension was designed partly around this use case. It uses a single working directory, but I think it's simpler than git. It's essentially a mechanism for maintaining multiple repository clones under one working directory, where only one is active at a given time.
Woops, I missed your P.S. where you don't like having multiple named branches in the same repo and that you prefer separate clones.. sorry about that.
I too have somewhat large C++ projects and the clone-per-feature workflow didn't work for me very well. Firstly, I had to close down my Vim session and then reopen (many of the same) files once I've created the clone. Secondly, like you said, a lot of code must be recompiled unnecessarily. Thirdly, I have to keep track of where I've pushed to and pulled from - gets confusing when you start a new feature and then get sidetracked onto a new one. Before you know it you have many clones and not sure which ones need to be pushed back to your main.
You definitely don't want to use named branches (as I'm sure you know) to handle this as they are quite permanent.
What you need are bookmarks: https://www.mercurial-scm.org/wiki/BookmarksExtension
Bookmarks allow you to create lightweight (and otherwise anonymous) branches per feature by facilitating the naming of heads in your repo. These heads would normally be unnamed and you would have to look at the output of 'hg log' or use some graphical tool to find the revision numbers for the tip of your feature-branch. With bookmarks you can name them descriptive names like 'my-cool-feature' or 'bugfix-392'.
If you like the idea of bookmarks, I'd also recommend my own extension called 'tasks': http://bitbucket.org/alu/hgtasks. This extension works like bookmarks but adds some more functionality. It allows you created feature-branches (now called tasks) and suppress the pushing of incomplete tasks. This is handy when you have a few feature-branches at once. You may not be ready to push your 'my-cool-feature' task, but 'bugfix-392' is ready to go. Because tasks track a set of changesets (and not just one 'tip' changeset) there are some things you can do with tasks that you can't with bookmarks. See an example workflow here: http://x.zpuppet.org/2009/03/09/mercurial-tasks-extension/.
Mercurial also has local named branches, see the hg branch command.
If you insist on using hg clone to do branchy development, I guess you could try creating a folder link (shortcut under windows) in your repo to a shared obj folder. This will work with hg clone, but I'm not sure your build tool will pick it up.
Otherwise, you probably keep all your repos in one folder - just put your obj folder there (it shouldn't be under source control anyways, imo). Use relative paths to refer to it.
A word of warning: many .o symbol tables (or equivalent) contain the full path name of the source file. If that other file changes (or if the path is not visible from the new directory) you may encounter weirdness when debugging.

Symbian C++ - Persistent storage of a single variable

I wish to store a single variable in my application that will be saved between runs. This will be a version number that will be used to trigger an update option and so will change only rarely.
Does anyone have suggestions on the best way of implementing this? Considering it's such a simple requirement I am interested in the simplest solution.
Thanks!
Normally, that sort of information will be held in a constant (not a variable) in the binary, and the binary will contact an external site to find out whether there is a more recent version of the software. When it downloads the new, the newly downloaded file will have a new constant embedded in it.
Alternatively, you could keep the information in some sort of file in the file system. I'm not familiar with the Symbian environment, but something similar most likely exists.
It has already been mentioned, so I am going to elaborate on it. Create a file in your project directory that will contain the version number. Make that file a part of final SIS file by adding a line about it in the PKG file---for example, put a line in the PKG file to tell the installer to copy the file to a place like c:\System\Apps\${AppName}\${filename} on the device. Within code, read the version number from that file. The advantage you will have from doing it this way is that when you update your code and edit the file in your project directory and recreate an updated SIS file, on updating the SIS on the device, the version file will automatically get replaced with the current one.