38

Why are there two kinds of jobs for Jenkins, both the multi-configuration project and the free-style project project? I read somewhere that once you choose one of them, you can't convert to the other (easily). Why wouldn't I always pick the multi-configuration project in order to be safe for future changes?

I would like to setup a build for a project building both on Windows and Unix (and other platforms as well). I found this question), which asks the same thing, but I don't really get the answer. Why would I need three matrix projects (and not three free-style projects), one for each platform? Why can't I keep them all in one matrix, with platforms AND (for example) gcc version on one axis and (my) software versions on the other?

I also read this blog post, but that builds everything on the same machine, with just different Python versions.

So, in short: how do most people configure a multi-configuration project targeting many different platforms?

Community
  • 1
  • 1
joscarsson
  • 4,631
  • 4
  • 33
  • 41
  • "Why wouldn't I always pick the multi-configuration project in order to be safe for future changes?" I don't think this part was answered -- is there any downside to picking it over a free-style project? – Matt R Apr 02 '13 at 13:47

9 Answers9

42

The two types of jobs have separate functions:

  • Free-style jobs: these allow you to build your project on a single computer or label (group of computers, for eg "Windows-XP-32").
  • Multi-configuration jobs: these allow you to build your project on multiple computers or labels, or a mix of the two, for eg Windows-XP, Windows-Vista, Windows-7 and RedHat - useful for checking compatibility or building for multiple platforms (qt programs?)

If you have a project which you want to build on Windows & Unix, you have two options:

  • Create a separate free-style job for each configuration, in which case you have to maintain each one individually
  • You have one multi-configuration job, and you select 2 (or more) labels/computers/slaves - 1 for Windows and 1 for Unix. In this case, you only have to maintain one job for the build

You can keep the your gcc versions on one axis, and software versions on another. There is no reason you should not be able to.

The question that you link has a fair point, but one that does not relate to your question directly: in his case, he had a multi-configuration job A, which - on success - triggered another job B. Now, in a multi-configuration job, if one of the configuration fails, the entire job fails (obviously, since you want your project to build successfully on all your configurations).

IMHO, for building the same project on multiple platforms, the better way to go is to use a multi-configuration style job.

Sagar
  • 9,163
  • 5
  • 47
  • 93
  • 4
    Great answer! One question though: how do I have Jenkins launch the Windows batch file for the Windows build server only, and the shell script for the Linux build server only? With my current configuration (multi-project), it seems it is trying launch the shell script on the Windows as well. – joscarsson Sep 22 '11 at 17:11
  • 1
    That is the only issue - I debated whether to type that since it seems to be a downer for a lot of people :) If you can create an equivalent shell script and have either bash or cygwin installed, you can use that. If not, your only option would be to create separate jobs. Is there something special in the batch file that would not translate to a shell script? – Sagar Sep 22 '11 at 19:37
  • I see. I went the easy way and separated the builds into different free-style projects. I read some people are using a platform-independent build script such as Ant. – joscarsson Sep 23 '11 at 10:38
  • 1
    My problem was that I used devenv.com in Visual Studio and Windows and automake on Unix, and I couldn't see a simple way to make the same script run on both platforms. – joscarsson Sep 23 '11 at 10:39
  • No problem! Yeah, our solution was to use ant, but I don't know how you would do that with devenv. Good luck! – Sagar Sep 23 '11 at 13:54
  • 1
    The XShell plugin provides another alternative to define a single command which runs on either Windows or Unix variants (like Linux, FreeBSD, OpenBSD, MacOS). However, the practical limits of the XShell plugin mean that it is usually only good enough to launch the script of your choice (build.bat or a build shell script, for example). – Mark Waite Feb 01 '16 at 13:52
6

Another option is to use a python build step to check the current OS and then call an appropriate setup or build script. In the python script, you can save the updated environment to a file and inject the environment again using the EnvInject plugin for subsequent build steps. Depending on the size of your build environment, you could also use a multi-platform build tool like SCons.

Michael
  • 61
  • 1
  • 1
  • Python based build tools have the advantage of easier deployment on multiple platforms. We use `doit` and to ensure file manipulation works well everywhere, we use excellent `py` module (`from py.path import local`). – Jan Vlcinsky Jun 09 '15 at 12:52
4

You could create a script (e.g. build) and a batch file (e.g. build.bat) that get checked in with your source code. In Jenkins in your build step you can call $WORKSPACE/build - Windows will execute build.bat whereas Linux will run build.

decocijo
  • 748
  • 5
  • 13
4

An option is to use user-defined axis combined with slaves(windows, linux, ...), so you need to add a filter for each combination and use the Conditional BuildStep Plugin to set the build step specific for each plataform(Executar shell, Windows command, ...)

This link has a tutorial but it is in portuguese, but it's easy to work it out based on image... http://manhadalasanha.wordpress.com/2013/06/20/projeto-de-multiplas-configuracoes-matrix-no-jenkins/

2

If you go the matrix route with Windows and something else, you'll want the XShell plugin. You just create your two build scripts such as "build.bat" for cmd and "build" for bash, and tell XShell to run "build". The right one will be run in each case.

Todd Greer
  • 81
  • 1
  • 2
2

You could use the variable that jenkins create when you define a configuration matrix axis. For example: You create a slave axis with name OSTYPE and check the two slaves (Windows and Linux). Then you create two separate build steps and check for the OSTYPE environment variable.

You could use a improved script language instead, like python, which is multi-platform and can achieve the same functionality independent of the slaves' name and in just one build step.

Lucas Ces
  • 86
  • 5
  • That is actually a pretty good idea! Didn't think about using the environment variables that way, always came to the conclusion I needed one script to run on both platforms. Thanks for the tip! – joscarsson Feb 02 '12 at 15:48
  • ... or is it? :) I just tested. I still need to specify the build step as "Execute Windows batch command" or "Execute shell", and if both are specified at the same time the build fails on both platforms. – joscarsson Jul 23 '12 at 12:28
  • 1
    @joscarsson Have you tried the Conditional Build Step Plugin? This way you could run only one depending the OSTYPE. I have not tried that, please respond if that is working for you! – jan Aug 06 '14 at 08:04
1

A hack to have batch files run on Windows and shell scripts on Unix:

On Unix, make batch files exit with 0 exit status:

ln -s /bin/true /bin/cmd

On Windows, either find a true.exe, name it sh.exe and place it somewhere in the PATH.

Alternatively, if you have any sh.exe installed on Windows (From Cygwin, Git, or other source), add this to the top of the shell script in Jenkins:

[ -n "$WINDIR" ] && exit 0

larsch
  • 909
  • 7
  • 13
1

Why wouldn't you always pick the multi-configuration job type?

Some reasons come to mind:

  1. Because jobs should be easy to create and configure. If it is hard to configure any job in your environment, you are probably doing something wrong outside the scope of the jenkins job. If you are happy that you managed to create that one job and it finally runs, and you are reluctant to do this whole work again, that's where you should try to improve.
  2. Because multi configuration jobs are more complex. They usually require you to think about both the main job and the different sub job variables, and they tend to grow in complexity to a level beyond being manageable. So in a single job scenario, you'd probably waste thoughts on not using that complexity, and when extending the build variables, things might grow in the wrong direction. I'd suggest using the simple jobs as default, and the multi configuration jobs only if there is a need for multiple configurations.
  3. Because executing multi configuration jobs might need more job slots on the slaves than single jobs. There will always be a master job that is executed on a special, invisible slot (that's no problem by itself) and triggers the sub jobs, but if these sub jobs do themselves trigger sub jobs, you might easily end in a deadlock if there are more sub jobs than slots, and some sub jobs trigger again sub jobs that then cannot execute because there are no more open slots. This problem might be circumvented by using some configuration setup on the slaves, but it is present and might only occur if several multi jobs run concurrently.

So in essence: The multi configuration job is a more complex thing, and because complexity should be avoided unless necessary, the regular freestyle job is a better default.

Sven
  • 62,889
  • 9
  • 98
  • 100
0

If you want to select on which slave you run the job, you need to use multi-configuration project (otherwise you won't be able to select/limit slaves on which you run it – there are three ways to do it, however I've tried them all (Tie plugin works only for master job, Restrict in Advanced Project Options is not rock-safe trigger as well so you want to use Slave axis that is proven to work correctly today.)

igraczech
  • 2,106
  • 1
  • 22
  • 27