From 84f626d2b5a2af3818a8b43f692f0864c060702c Mon Sep 17 00:00:00 2001 From: Ralph Sennhauser Date: Sat, 15 Feb 2025 08:33:43 +0100 Subject: [PATCH] Use Debian 12 in Linux pipeline Use the single Debian 12 container image and inject CC, CXX and LDFLAGS instead. Further do the lfs checkout on the agent instead of inside the container avoiding full rebuilds due to version mismatch. Then split the debug and release builds using separate workspaces and record warnings by build preventing gcc warnings leaking into clang warnings. Based on zero warning policy and incremental builds using a reference build doesn't make sense. Removing that we can also drop an additional generic workspace. Signed-off-by: Ralph Sennhauser --- build/jenkins/pipelines/linux.Jenkinsfile | 224 +++++++++++++--------- 1 file changed, 133 insertions(+), 91 deletions(-) diff --git a/build/jenkins/pipelines/linux.Jenkinsfile b/build/jenkins/pipelines/linux.Jenkinsfile index aff93efc5d..18389f6d55 100644 --- a/build/jenkins/pipelines/linux.Jenkinsfile +++ b/build/jenkins/pipelines/linux.Jenkinsfile @@ -17,6 +17,34 @@ // This pipeline builds the game on Linux (with minimum supported versions of GCC and clang) and runs tests. +def tc_getCC(tc) { + def map = ['gcc12': 'gcc-12', 'clang14': 'clang-14'] + return map[tc] +} +def tc_getCXX(tc) { + def map = ['gcc12': 'g++-12', 'clang14': 'clang++-14'] + return map[tc] +} +def tc_getLDFLAGS(tc) { + def map = ['gcc12': '', 'clang14': '-fuse-ld=lld-14'] + return map[tc] +} + +def getParserConfig(tc, buildType) { + def config + if (tc.startsWith("gcc")) { + config = [ 'tool': 'gcc', 'name': 'GCC', 'id': 'gcc-' + buildType] + } else { + config = [ 'tool': 'clang', 'name': 'Clang', 'id': 'clang-' + buildType ] + } + if (buildType.matches("debug")) { + config['name'] += ' Debug Build' + } else { + config['name'] += ' Release Build' + } + return config +} + pipeline { // Stop previous build in pull requests, but not in branches options { disableConcurrentBuilds(abortPrevious: env.CHANGE_ID != null) } @@ -26,20 +54,8 @@ pipeline { } agent none + stages { - stage("Setup") { - agent { - node { - label 'LinuxAgent' - customWorkspace 'workspace/linux' - } - } - steps { - discoverGitReferenceBuild() - sh "cd build/jenkins/dockerfiles/ && docker build -t buster-base -f buster-base.Dockerfile ." - sh "cd build/jenkins/dockerfiles/ && docker build -t bullseye-base -f bullseye-base.Dockerfile ." - } - } stage("Linux Build") { failFast true @@ -47,98 +63,124 @@ pipeline { axes { axis { name 'JENKINS_COMPILER' - values 'gcc8', 'clang9' + values 'gcc12', 'clang14' + } + axis { + name 'BUILD_TYPE' + values 'debug', 'release' } } - agent { - dockerfile { - label 'LinuxAgent' - customWorkspace "workspace/${JENKINS_COMPILER}-pch" - dir 'build/jenkins/dockerfiles' - filename "${JENKINS_COMPILER}.Dockerfile" - // Prevent Jenkins from running commands with the UID of the host's jenkins user - // https://stackoverflow.com/a/42822143 - args '-u root' - } + environment { + CC = tc_getCC(env.JENKINS_COMPILER) + CXX = tc_getCXX(env.JENKINS_COMPILER) + LDFLAGS = tc_getLDFLAGS(env.JENKINS_COMPILER) } stages { - stage("Pre-build") { + stage("Checkout") { + agent { + node { + label "LinuxAgent" + customWorkspace "workspace/${JENKINS_COMPILER}-pch-${BUILD_TYPE}" + } + } + steps { - sh "git lfs pull -I binaries/data/tests" - sh "git lfs pull -I \"binaries/data/mods/_test.*\"" + sh "git lfs fetch -I binaries/data/tests" + sh "git lfs checkout binaries/data/tests" + sh "git lfs fetch -I \"binaries/data/mods/_test.*\"" + sh "git lfs checkout binaries/data/mods/_test.*" + } + } - sh "libraries/build-source-libs.sh ${JOBS} 2> ${JENKINS_COMPILER}-prebuild-errors.log" + stage("Container") { + agent { + dockerfile { + label 'LinuxAgent' + customWorkspace "workspace/${JENKINS_COMPILER}-pch-${BUILD_TYPE}" + dir 'build/jenkins/dockerfiles' + filename 'debian-12.Dockerfile' + // Prevent Jenkins from running commands with the UID of the host's jenkins user + // https://stackoverflow.com/a/42822143 + args '-u root' + } + } - sh "build/workspaces/update-workspaces.sh --jenkins-tests 2>> ${JENKINS_COMPILER}-prebuild-errors.log" + stages { + stage("Pre-build") { + steps { + sh "libraries/build-source-libs.sh ${JOBS} 2> ${JENKINS_COMPILER}-prebuild-errors.log" - script { - if (params.CLEANBUILD) { - sh "cd build/workspaces/gcc/ && make clean config=debug" - sh "cd build/workspaces/gcc/ && make clean config=release" + sh "build/workspaces/update-workspaces.sh --jenkins-tests 2>> ${JENKINS_COMPILER}-prebuild-errors.log" + + script { + if (params.CLEANBUILD) { + sh "make -C build/workspaces/gcc/ clean config=${BUILD_TYPE}" + } + } + } + post { + failure { + echo (message: readFile (file: "${JENKINS_COMPILER}-prebuild-errors.log")) + } + } + } + + stage("Build") { + steps { + sh ''' + rm -f thepipe + mkfifo thepipe + tee build.log < thepipe & + make -C build/workspaces/gcc/ ${JOBS} config=${BUILD_TYPE} > thepipe 2>&1 + status=$? + rm thepipe + exit ${status} + ''' + } + post { + failure { + script { if (!params.CLEANBUILD) { + build wait: false, job: "$JOB_NAME", parameters: [booleanParam(name: 'CLEANBUILD', value: true)] + }} + } + always { + script { + def config = getParserConfig(env.JENKINS_COMPILER, env.BUILD_TYPE) + recordIssues( + tool: analysisParser( + analysisModelId: config['tool'], + name: config['name'], + id : config['id'], + pattern: "build.log" + ), + skipPublishingChecks: true, + enabledForFailure: true, + qualityGates: [[threshold: 1, type: 'TOTAL', criticality: 'FAILURE']] + ) + } + } + } + } + + stage("Test") { + steps { + timeout(time: 15) { + script { + def bin = env.BUILD_TYPE == "debug" ? "test_dbg" : "test" + sh "binaries/system/${bin} > cxxtest.xml" + } + } + } + post { + always { + junit(skipPublishingChecks: true, testResults: 'cxxtest.xml') + } } } } - post { - failure { - echo (message: readFile (file: "${JENKINS_COMPILER}-prebuild-errors.log")) - } - } } - - stage("Debug Build") { - steps { - sh "cd build/workspaces/gcc/ && make ${JOBS} config=debug" - } - post { - failure { - script { if (!params.CLEANBUILD) { - build wait: false, job: "$JOB_NAME", parameters: [booleanParam(name: 'CLEANBUILD', value: true)] - }} - } - } - } - - stage("Debug Tests") { - steps { - timeout(time: 15) { - sh "cd binaries/system/ && ./test_dbg > cxxtest-debug.xml" - } - } - post { - always { - junit 'binaries/system/cxxtest-debug.xml' - } - } - } - - stage("Release Build") { - steps { - sh "cd build/workspaces/gcc/ && make ${JOBS} config=release" - } - } - - stage("Release Tests") { - steps { - timeout(time: 15) { - sh "cd binaries/system/ && ./test > cxxtest-release.xml" - } - } - post { - always { - junit 'binaries/system/cxxtest-release.xml' - } - } - } - } - } - - post { - always { - node('LinuxAgent') { ws('workspace/linux') { - recordIssues enabledForFailure: true, qualityGates: [[threshold: 1, type: 'NEW']], tools: [clang(), gcc()] - }} } } }