Build Numbers synchronicity when delivering on multiple OS platforms - build-process

My organization builds a C++ application that runs on multiple operating systems.
Should the build number, visible to customer, be the same for a given state of the source code tree on all the platforms?

Yes, I think so.
One practice you can use is to use the changelist number or however your source control system identifies the checkin that your build system pulled to build your product. That way you always know what source you should pull to rebuild it as well.

There aren't any downsides that I can see. You want to be able to reproduce the build, so each should say what the build is. If it's the same build, it should be the same build number.

If you choose to (or cannot - from a build process point of view) not use the exact same versionnumber for builds made for different platforms, you should document exactly what your versionnumbers actually imply.
If you don't, typically a user of the software will treat the whole thing (e.g. 3.1.0.333 - where 333 would be the build number) as identifying a certain version of the software (thuse the code tree). If they use your software on differnt platforms, they then might think that 3.1.0.333 and 3.1.0.334 are actually refering differnt versions (as in code changes) of the product, which they might not.
The same is true for outher "build number" styles, like using some sort of date/time derived build-id.
If you globally manage your build numbers, you might consider adding a platform ID. So that you can build 3.1.0.333-x86 and 3.1.0.333-amd64 one after the other, but still have them share the same "number". It will also be more obvious to the user what the indent/meaning is.

Related

Build system supports multiple output per target

I work in the field of bioinformatics. My daily work processes several data files (DNA sequences, alignments, etc..) and produce many result files, so I want to use something like Unix make to automate the whole process, especially to resolve dependencies between different data.
However, the Unix make only supports one output per target, as it is designed for software build, which typically generates one object file from several source files, or one executable from several object files. If you use custom virtual targets, it won't benefit from timestamp checking. Is there any build system that supports multiple output file per one target? If there aren't any, I'm going to make the wheel.
Have a look at Drake, which is a replacement of make designed for data workflow management (make for data).
Another option is makepp, which is an improved make. Among other features it supports multiple targets.

QT doesn't display previous build warnings unless the entire project is rebuilt

I'm not sure if this is standard behavior for IDEs, but I personally find it irritating. If a file produces warnings when built (unused variables, mismatched ints/longs/etc.), those warnings will cease to be displayed if another file is modified and the "Build project" button is clicked. Doesn't it make more sense for warnings pertaining to unmodified code to continue to be displayed? Is there a way to force this behavior?
The warnings are displayed when the compiler emits them -- unfortunately, that's the design decision taken by both VS team (up to 2008 at least) and by Qt Creator team.
It seems to be standard behavior, and I don't know of any options to override it. It should be easy to fix in Qt Creator, but may be hard to fix in Visual Studio unless relevant APIs are present. For VS you'd need to write an add-in and there would need to be an API available that gives you read-write access to the error list and to the build process. If such APIs exist, then it'd be a simple thing to do as well.
This is "standard behavior", and more specifically, behavior is an attribute of how build systems on Earth "are-designed-to-behave".
As #Kuba notes, the warnings are emitted by the compiler. They aren't stored (except in the "log-of-all-errors/warnings" for the build operation, which the IDE typically never reads-back-and-excerpts-from-for-future-build-operations, which would get their own log of their new warnings/errors). Thus, you won't see the warning again unless the compiler actually compiles the file again, and that's because they would be new warnings that are generated again by the new build operation.
To get what you want (a clever thought, IMHO), the build system would need to:
store warnings from each file-compile (probably on a "per-file-basis")
recall/display those warnings each time that file-output-product was "used"
Very clever. I'm not aware of any system that does that. It would require fairly significant IDE or build-tool-level management of build products, which IMHO, none of them do well (but some are better than others).
This is the year 2012, and not only are we missing our flying cars, but we're missing build systems that merely/quickly build-only-what's-required-using-all-cores while easily handling different configurations. Both were expected by now.
Then, sometime after that, you could probably get your feature. That would be a bonus, because then you could use it in your flying car.

How to query the containing partition of a file with KDE/Qt4?

I'm using KDE, and I'm toying with the idea of hacking the code for Dolphin File Manager (and potentially Konqueror if necessary) to get context-sensitive drag and drop behaviour (i.e. files are moved within the same partition, or copied if they're moved across partitions or the source is read only).
To do this, I think I'd need to find out the containing partition of the source and destination (easy enough on Windows using the drive letter, but on Linux, as mount points can be almost anywhere, it can't be reliably derived from the file path), and compare them.
Does anyone know how I can find out the partition that contains a given file?
It must be possible - I know Nautilus provides this sort of behaviour, but I'm not familiar enough with GTK to track down the appropriate section in the source code to see how its done...
Qt doesn't provide API for this. For POSIX, have a look at stat.
For KDE, you can use KIO::stat() to get mostly the same info as POSIX' stat function but asynchronously.
The device id should be in the field UDS_DEVICE_ID of the result.

How to share code with continuous integration

I've just started working in a continuous integration environment (TeamCity). I understand the basic idea of not getting so abstracted out in your code that you are never able to build it to test functionality, etc. However, when there is deep coding going on, occasionally it will take me several days to get buildable code--but in the interim other team members may need to see my code.
If I check the code in, it breaks the build. However, if I don't check it in, my team members are unable to see the most recent work. I'm wondering how this situation is best dealt with.
A tool like Code Collaborator (Google link, smartbear.com is down..) would allow your peers to see your code, without you committing it. Instead, you just submit it for review.
It's a little extra trouble for them to run it though.
Alternatively, setup a second branch/fork of your codebase for you to work in, your peers can sync to that, and it won't break the build server. When you're done working in your own branch, you can merge it back with mainline/trunk/whatever.
In a team environment, it is usually highly undesirable for anybody to be in an unbuildable state for days. I try to break large code deliveries to as many buildable check-ins as I can. At minimum, create and check in your interfaces even if you do not have the implementation ready so others can start to code against them.
One of the primary benefits of Continuous Integration is that it shows you when things break and when things are fixed. If you commit those pieces of code that break the system, other developers will be forced to get it into a working state before continuing the development. This is a good thing because it doesn't allow code changes to be made on top of broken things (which could cause issues where a co-workers code worked on the broken system, but doesn't work once the initial break is fixed).
This is also a prime example of a good time to use branches/forks, and simply merge to the trunk when all the broken things are fixed.
I am in exactly the same situation here.. As build engineer I have this working beautifully.
First of all, let me break down the branches / projects. #Dolph Mathews has already mentioned branching and tbh, that is an essential part of getting your setup to work.
Take the main code base and integrate it into several personal or "smaller" team branches. i.e. branch_team_a, branch_team_b, branch_team_c
Then set up teamcity to build against these branches under different project headings. So you will eventually have the following: Project Main, Project Team A, Project Team B, Project Team C
Thirdly, then setup developer checkins so that they run pre-commits builds for the broken down branches.. You can find the TC plugin for this under tools and settings.. They have it for IntelliJ or VS.
You now have your 3-tier setup..
- Developer kick starts a remote-run pre-commit build from their desktop against their project. If it passes, it get's checked into the repository i.e. branch_team_a
- Project Team A passes after several check-ins; at which point you integrate your changes from branch_team_A to main branch
- Project Main builds!
If all is successful then you have a candidate release.. If one part fails, projects a, b or c. it doesn't get checked into main. This has been my tried and tested method and works everytime. It also vastly improves team communication.

Product management & assembly versions

We are approaching the initial release of a new product at our company, and I am trying to determine the best method of managing the versions of all of the different components and cross referencng those components with the marketing department version of our software. For various reasons, marketing has determined that the initial release of our product will be 10.1, however all of the components will initially start out at 1.0.0. Through normal bug fixes and patching and continued development work, the different components will no longer be at the same version number, so when marketing department decides it's time for version 10.2, it might contain 1.1.54, 1.2.32, 1.8.2, etc. Obviously, I could use a simple spreadsheet, but that isn't exactly the most user friendly method, and has issues for our tech support people to cross-reference the component versions (the customer is really only aware of version 10.1, 10.2, etc).
Is there a more "professional" method for this, or is a simple spreadsheet the best option?
The main principle I'd suggest is: Use the simplest scheme you can.
Consider making things easy for yourself, your marketing department, and your users.
When you do a release, increment the major/minor version number, and then stamp that across all your components. So in the 10.1 release, all your assemblies will have version numbers 10.1.xx.yy
Then if you really want to complicate matters with different versions within a release (e.g. for minor patches/updates, different customer variants, or just for internal daily or CI builds), then use the xx.yy fields. (In many cases you can get the compiler to automatically fill these two fields in with the date/time of compilation, for example).
This means you have a meaningful "marketing version" which is actually linked to your code versions (so you and marketing can talk about a particular release without any chance of confusion), and you can add extra information (e.g. build date) if (and only if) needed on the dev side.
edit: P.S. Even if a component doesn't change, rebuild it with the new version number. Trying to track a hundred out-of-sync version numbers is an avoidable nightmare.
At places where I've worked, we'd force the software version number to match the official, public (i.e. Marketing's) release number: if they wanted to ship "10.1" then that's what we'd set the software's version resource to, as part of the release build.
Why not leave all components at their "random" version numbers and create one super tag/label with the marketing version that encompasses all components? This allows you to keep updating the components in-between marketing builds and increment their build versions (without having to go to 10.1.001, 10.1.002 that may be visible to the customer) and also keep track of the marketing build. Also, what happens if you update some components for the next marketing build, but not others? Do you need to build those components just to update the version number?
Depending on your source control system, you should be able to easily create a release with a specified name/version that contains all of these components at different versions.
You should also just need to update one properties file with the marketing build number so it shows on all about screens, splash screens, tool bars, etc. If you don't have such a configuration in place, you may want to move to such a system. This allows for easy changes to the customer visible number while maintaining all component build numbers. Besides, what happens when marketing determines that the next version isn't going to be 10.2, but "Crimson?"

Resources