Some background to my question: We have a traditionally windows-only C++ code-base which we are in the process of porting to linux. Parts of the system have been running on linux for many years, but some parts have never been built using any compiler other than Visual Studio. Most of the code is in Subversion, and we use Jenkins for automatic building.

My question is: given the circumstances (Windows+Linux, C++, Subversion, Jenkins), are there any good solutions to prevent developers from breaking builds on other platforms? Forcing developers to manually build on each supported platform is not a particularly effective method.

(I know that there are solutions based on git (e.g. Gerrit) which can prevent commits from making it into the mainline, but switching everything over to Git isn't an option at the moment.)

  • I might be missing something here... but why not unit tests? – Liath Mar 19 '18 at 15:00
  • 2
    @Liath you are missing the multiple platforms. E.g. GCC has different warnings-as-errors to MSVC, and something that passes on one fails on the other – Caleth Mar 19 '18 at 15:55
  • Use docker to build. Create a container for each platform/compilers. Test build for each containers. Each container image file (Dockerfile) can be saved in svn. A script can orchestrate the build in all containers. – sturcotte06 Mar 19 '18 at 17:41
  • I'm not asking "how do I let developers build on multiple platforms", but rather "how do I prevent commits which do not build to enter trunk". "Gated commits" was mentioned as a solution, but I don't know of any solutions to implement that with Subversion. – JesperE Mar 20 '18 at 8:02
  • Also, making developers build on all platforms is what we attempt to do now, but developers being humans, this is not particularly effective. – JesperE Mar 20 '18 at 8:03

You need a build before you can break it. You're already using Jenkins? Great! Now add a Linux box as a build slave, and create a build for Linux that mirrors your Windows builds.

Note that your requirements – breakage must be prevented, but you don't want gated commits – are a bit contradictory. But testing doesn't have to be all-or-nothing. Instead, alerting developers about breakage is still valuable when it happens after the fact. They can then fix the breakage.

Unfortunately, this only works if

  1. you start with a build that works on Linux, and
  2. whenever the build breaks, it is fixed before other commits are made.

If developers can commit on top of a bad build, they'll learn to ignore the Linux build result, rendering it nearly worthless.

It is also in your interest to enable easy testing on Linux before committing, as that can avoid much breakage. E.g. this could be virtual machines or SSH logins that are pre-configured with a build environment, or a tool to trigger custom jobs on Jenkins. This is different from forcing the devs to build on Linux. Instead, they can weigh the risks whether a change should be tested by the Jenkins build after the commit, or whether the change is more risky and should be tested manually first. If using the Linux environment is sufficiently convenient, this is a no-brainer.

While you are still transitioning to multi-platform support, it may be best to avoid automated alerts, and instead let a separate team do the porting using their own workflow. Whenever they achieve some sub-goal, it is sensible to immediately add that as a Jenkins job to avoid future regressions. E.g. intermediate steps could be that one component can be compiled on Linux, or that the build works using MinGW (i.e., still on Windows but with a non-MSVC compiler), or that an extra warning could be enabled.

Of course, none of this is an entirely technical solution. Tools alone can't solve your problems, but they can help by notifying developers about problems as they arise. More important than the tools is that the developers use their tools (because they find them genuinely useful), and that you have someone who can build and configure the tools the devs actually need.

  • We have Linux buildslaves already, but they can only detect (but not prevent) build breakage. There are plenty of ways for developers to build before committing, but this all hinges on developers actually taking the extra steps to build on Linux. Getting developers to do that is a "people problem" which does not have a technical solution. – JesperE Mar 20 '18 at 7:59
  • I can accept gated commits, but I don't know of any good solutions to implement gated commits for Subversion. Am I missing somethings? – JesperE Mar 20 '18 at 8:00

With the arrival of Docker in the recent years, I've found that building on many different platforms isn't as painful as it used to be, even manually. With little effort, you can have a set of lightweight Docker images to do the build for you (e.g., Ubuntu x86 and x64, CentOS 6 and 7, different libc versions...) If you're just testing that those versions actually build, it's a very feasible solution. Of course, if you can't automate this before actually committing, there must be a strong will of the team to enforce this new policy of "build everywhere before committing."

Of course, we're talking about just testing the "buildability" of the software. Acceptance or integration tests are different beasts (that probably require more heavyweight and costly solutions). And even in that case, I encourage you to do those as well. It's hard to see how good it is to do it systematically in the long term, especially during the maintenance phase, but I can tell you it brings a lot of calm to your nights.

  • By "different platforms" I meant "different operating systems", not "different Linux distributions". – JesperE Mar 20 '18 at 7:53
  • Still, you can build on Windows normally and let the Linux testing run in the background using containers. I think Windows is also "dockerable", but I don't know the status of this approach though. And as a fallback you can use a Windows VM. Not perfect, but still a better solution than no automation at all in my honest opinion. – Jesus Alonso Abad Mar 20 '18 at 15:31
  • But my main point was to prevent bad commits. We have several ways for developers to build on various hosts, but none of them can really be made mandatory. – JesperE Mar 21 '18 at 5:50
  • I think Subversion indeed has hooks, similar to those of Git. Maybe you can trap the commit before actually happening and test the constructability of the code to cancel the commit if it fails. It's harder to orchestrate the builds if you can't rely just on upon Docker or VMs, but if I had to go one way, I'd try this. It's actually the next step in the automation of a multiplatform project I'm working on at this moment. – Jesus Alonso Abad Mar 21 '18 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.