Andreas Haferburg
Andreas Haferburg

Reputation: 5520

Jenkins + Windows + CMake + multiple build types (Debug, Release)

How can I make Jenkins do the following?

Checkout trunk/ from SVN, then build configurations Debug and Release using CMake, without having duplicate jobs for the configurations.

Upvotes: 10

Views: 9138

Answers (4)

Lars Bilke
Lars Bilke

Reputation: 5229

When using the Visual Studio generator you can pass the configuration to build to the cmake --build-command:

cmake --build . --config Release
cmake --build . --config Debug

See also the CMake docs.

Upvotes: 3

Andreas Haferburg
Andreas Haferburg

Reputation: 5520

After using Jenkins for a while now, I found that you should use as few jobs as possible if you want to reuse the source directory.

The default setup in Jenkins is that each build uses a different directory as its workspace. Which implies that you do a complete SVN checkout every build. Which takes forever.

If you want to use the same source directory for every build, you have to worry about synchronization: Only one build at a time. As far as I know, Jenkins has no built-in means of synchronization. The only way is to only use one executor. Even then you can't control the way the executor chooses its next job.

Let's say job "SVN update" triggers job "Build". Someone starts "SVN update #33", which is supposed to trigger "Build #33". If, however, Jenkins' "Poll SCM" feature schedules "SVN update" #34 in the meantime, I haven't found a way to tell it that "Build #33" must run before "SVN update #34". So you might end up with "SVN update #34" running before "Build #33", and everything fails. Unless you manually disable the polling job. And remind yourself to re-enable it afterwards, of course.

Anyways. After using Jenkins for two years, I change my answer to: Never use multiple jobs that share resources (like the source dir), and bake all the logic into shell scripts (for loop over configurations).

Upvotes: 2

Andreas Haferburg
Andreas Haferburg

Reputation: 5520

Took me a while to figure this out. Here's how I managed to do it.

  1. Create a free-style job "Checkout". This job is going to do all the stuff that doesn't depend on the configuration type (Debug/Release).
  2. Under "Source Code Management" select Subversion
  3. Fill in the Repository URL. Probably a good idea to make it point to /trunk.
  4. Set Local module dir to "." (no quotes)
  5. As Check-out Strategy "Emulate clean" is nice
  6. Build trigger Poll SCM, set Schedule to "5 * * * *" to check every 5 minutes.
  7. Now under Advanced Project Options check 'Use custom workspace' and set the dir to e.g. "c:/src". We don't want Jenkins to use its internal workspace, because we want other jobs to be able to access the source.
  8. Under Build add the following Windows batch command, which is used to clean the build dir. For some reason, CMake doesn't provide a way to do this.

    cd c:\
    rmdir /S /Q build
    mkdir build
    cd build
    
    cmake --version
    rem optionally: svn info c:\src
    cmake -G "Visual Studio 10" c:\src
    
  9. Create another job "Build", this time make it a "multi-configuration" job. This job is going to run for each configuration (Debug/Release).

  10. First, set the Build Triggers to build after job "Checkout"
  11. Now under Configuration Matrix add an axis "configuration" with values "Debug Release" (whitespace = separator). Unfortunately, the CMake builder plugin for Jenkins doesn't work with multi-configuration jobs. We can't even use cmake --build, because it always builds the Debug configuration. To build, we have to use another batch script:

    cd c:\build
    call "%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
    msbuild ALL_BUILD.vcxproj /verbosity:minimal /maxcpucount:1 /property:Configuration=%configuration%
    

If you want to build the entire solution, specify the .sln file instead of ALL_BUILD.vcxproj. If you only want to build a specific project, use

    msbuild <solution>.sln /target:<project>

Upvotes: 10

malenkiy_scot
malenkiy_scot

Reputation: 16615

Use Jenkins Matrix job. Define one of the axes as build_mode with values Debug and Release. You then run CMake that will create both configurations for the compilation tool you'll be using (XCode, gcc, VisualStudio, etc.). You can then use build_mode as if it were an environment variable and pass it to build steps that do actual compilation.

Upvotes: 9

Related Questions