Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting up build process for dependent projects and multiple developers

I'm fairly new to automating build processes and continuous integration, and am working on setting up a build process / server for a small team of developers. We are using SVN, CMake, and Jenkins build server. Source language is C++.

Lets say we have two projects, library (a dll) and executable. executable links to library, and so to build executable you need the .lib and .h files from library. To run executable, you then need the .dll (and possibly debug symbol files) for library.

When building the whole thing, its fairly simple, you get the latest source from the repository and build library then executable.

However, we have multiple developers, and each developer is usually working on one project at a time. Our CMake scripts allow you to choose which projects to build, so John may have a setup that only builds executable, while Bob only builds library. Giving this up is not an option.

So if Bob makes changes to library and commits the source, John will need to get the compiled .lib and .dll files (because he is not compiling library).

Right now, the binaries are in the svn. During each compilation, CMake copies src/bin to build/bin as a precompilation step, then whatever projects were selected are compiled (replacing the appropriate binary in build/bin), and finally CMake copies build/bin to src/bin.

This means that when Bob makes a change, he commits not only the source files but the compiled binary as well, and when John updated his working copy he gets the appropriate binaries, and doesn't have to do any manual file replacement.

This has been working for a while, but I really don't like it for several reasons. Is there less hack-ish way to set something like this up? (There are actually 4 developers, and about 12 projects, some are libraries that don't depend on anything, some are libraries that depend on other libraries, and some are executables that depend on other libraries.)

Edit: This is the process I'm thinking of:

Use an artifact tracking system such as Artifactory or Nexus to store binaries after build, along with the header files used to generate those binaries

In CMake, each project is marked as compiled or precompiled. Compiled projects are generated from the regular repository. Precompiled project binaries and headers are downloaded from Nexus if they are out of date, and CMake links and includes appropriately. The headers are also kept with the artifacts to prevent the race condition I described in my comment to Dave Bacher's answer.

The only thing I don't like is that I'll have to do some CMake-foo to check if the artifacts are out of date and download them, but I guess there isn't really an alternative since apparently what I'm trying to set up is so nonstandard.

like image 565
user1366088 Avatar asked Mar 07 '26 19:03

user1366088


2 Answers

I don't like that you're checking in a developer's build as the canonical reference that others will build from. It's fragile and you can end up with bad builds that work for one person in their environment, but fail for others. Or a case where someone makes changes, but forgets to check in files and suddenly, they are the only one who can build part of the project.

At the very least, you should set up Jenkins as the place to build the libraries and executables and get your developers to only check in source. Jenkins has several of plugins (e.g. SVN Publisher) that can be used to publish the libraries and executables after they've been built in your standard build environment.

In my experience, it's very straightforward to install Jenkins on a build machine and set up builds for each of your projects. That gets you started with the first step of verifying that each of your projects builds. Then work on getting Jenkins to publish its output instead of relying on developers to publish their builds.

like image 168
Dave Bacher Avatar answered Mar 09 '26 17:03

Dave Bacher


It looks like the system that is currently in place will always have a race condition between those modifying the executable and the library. Instead of trying to focus on how to solve the race condition for all developers, I suggest you use CI to catch issues that can occur from the race conditions.

Since you are just starting out, I would keep it simple and concentrate on creating a Jenkins Job that builds the whole thing whenever something is checked into the repository. Assuming that the library and executable are kept in the same SVN repository, the actions for the job should be something like this:

  1. Check out the repository
  2. Execute CMake to build the library
  3. Do any unit tests for the library (there are some, right?)
  4. Execute CMake to build the executable against the library
  5. Do any unit tests for the executable (there are some, right?)
  6. Notify the developers of the results of the build.

While it seems trivial, this will get the developers feedback as it if they are breaking things by their changes without having to force them to remember to update their copy. It will also help ease them into the paradigm shift of working with CI.

[BTW, the one gotcha the developers may run into is if they are used to checking into SVN a file at a time. Doing file-by-file changes will kick off multiple builds that only succeed when the last file is finally checked in. Check ins of multiple files need to be done as atomic actions with multiple files at a time. This is also good SCM practice as it groups the changes together into one thing that can be tracked and (if needed) rolled back.]

The paradigm shift might seem insurmountable at first, but in can happen. The project I am currently working on started with developers used to a very similar process as you described above. When we moved to running CI, there was some resistance to checking in code more often than once a week. 8 months later, if I have to do any maintenance to the Jenkins builds, I am immediately inundated with questions to why Jenkins isn't available and "how do I expect people to work if they can't get the build results back immediately?"

like image 39
jwernerny Avatar answered Mar 09 '26 17:03

jwernerny