What are some tips to make my project compile on a fresh checkout every time?
More times than I'd like to admit I've had people new to a project do a checkout only to find they are missing various resources, dll's, settings. I'd like to get in the proper habit of having my projects compilation be smooth as can be from a fresh checkout.
What are some tips or suggestions on how to structure my projects so they don't have compilation issues on a fresh check out from version control?
I've started keeping a "Resources" folder in my projects that contain all needed dll references in source control. Can anyone else make some suggestions?
Assuming you're in a Visual Studio environment, here are some things that you might find useful, YMMV of course and note that we use Subversion, but any VCS tool should do...
- Place all (or as many as possible) dependencies under version control and reference these in your projects. We use Subversion externals to manage this.
- Don't version control standard output directories (bin, obj), i.e. use svn:ignore
- Likewise, ignore version control user items (*.user, *.suo)
- Also don't version control configuration files (App|Web.config), instead, create an App.default.config and in your projects BeforeBuild task copy this file to App.config. This allows you to get fancy by using RegEx and tokens to setup compilations per developer or build server, it also allows you to delete any existing App.config files on CI builds to ensure a pristine build every time. This also allows developers to muck around with configurations without having to disturb everyone else until they are ready, i.e. update App.default.config.
- Version control everything else :)
- If you need to version control binaries (MSI, DLL output, etc) as a result of your compilation, in your AfterBuild target project (wixproj, etc) copy the output to another directory which is under version control. One tip using Subversion is that you can add/commit to an svn:externals directory, which allows you to push libraries, etc out to project which reference them.
Final tip - After you have done a clean checkout and have a successful compilation, check to see if there are any modifications in your working copy, e.g. TortoiseSVN -> Check for modifications. If you have changes detected, then these files probably need to be ignored.
Find an older computer that isn't being used and set it up for automatic "rolling builds":
- Wait until someone checks in a change
- Update to the latest version of all files.
- Clean out all non-source control files (
make cleanisn't enough - scan for debris and remove it)
- Run unit tests.
- Once a day, save binaries from a successful run. Call it the "official build" for the day.
If the build or tests fail, send email with the error. Include the list of changes that were picked up in #2.
If you really, really can't find a machine, do it in a virtual machine.
Continuous-integration tools like cruisecontrol repeatedly check-out and build your application after each checkin, which can alert you to checkins which break the build... Also, they can run your unit-tests, and thus alert you to any regressions caused by your checkin, too...
Can anyone else make some suggestions?
- Keep the files, which you need to build, in one place (one directory and its subdirectories) ... most version control systems call this your "working directory"
- Your version control software has a command to list the differences between what's in your working directory and what's under version control ... this "difference" includes files which exist in the working directory and which aren't under version control
- Tune your version control software to exclude (from the list displayed by step 2.) files whose type you don't want to store ... for example, you might want to store only source code, and exclude
*.objand so on ... excluding these file types means that when you run step 2 the list of differences isn't crowded with files which you aren't intending to store
- Consider having a build machine, which automatically does check-out-and-builds (and which emails you if ever the 'build is broken')
Debian Linux has a really awesome tool called
pbuilder, which creates an image of a freshly installed system and then attempts to build your code. It works only with the Debian package system, but you could steal the ideas, which are really good.
Automate your build from a chrooted environment or a virtual machine that looks like a fresh install. Your build script will then install the DLLs and so on. Or your configure script will enumerate the missing dependencies (all of them, not just the first one).
It's 1am and I'm sounding incoherent, but two ideas are central:
Have a virtual machine or chroot directory that can mimic a blank system. These days a virtual machine is probably easiest.
Tweak your build system until it automatically checks and builds on your virtual machine---or else complains about what is missing.
At that point you can make the process part of an automated nightly build, and you'll be a happy camper :-)
Any resources/DLLs/settings should be checked into version control along with the source code.
They should be labeled and treated equally with the source code, which will allow you to correlate these resources against the source and treat the source code/resources/settings as a single entity.
In my company, we use Rational ClearCase. Everything is checked into source control, with the exception of generated source code files (e.g. .cpp and .h files generated from the MIDL compiler). Because of this, most builds go fairly smoothly.
You also need to ensure that your dependencies are set up properly, so when a source file is changed, all of the dependent libraries will be re-built.
You could build up a comprehensive checklist that you consult prior to every check-in - but that would be timeconsuming and error prone (especially across multiple developers, not everyone has the personality traits to follow a checklist closely everytime).
This way, you know for sure - rather than inferring things work because the checklist was followed.
SCons is another tool that works cross-platform and helps manage your dependencies. Similar to gnu make in the you have a "scons file/script" - and the fact that it uses python gives you a lot of flexibility.
(I do not have anything to do w/SCons; we just use it)