diff --git a/Jenkinsfile b/Jenkinsfile index 7ee510e82a..8618b672d0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -17,9 +17,18 @@ def runOnNativeBuildAgent(String platform, Closure body) { def final nativeBuildStageName = 'Build SWT-native binaries' - if (platform == 'gtk.linux.x86_64') { + def dockerImage = null + switch (platform) { + case 'gtk.linux.x86_64': + dockerImage = 'eclipse/platformreleng-debian-swtgtk3nativebuild:10' + break + case 'gtk4.linux.x86_64': + dockerImage = 'eclipse/platformreleng-debian-swtnativebuild:12' + break + } + if (dockerImage != null) { podTemplate(inheritFrom: 'basic' /* inherit general configuration */, containers: [ - containerTemplate(name: 'swtbuild', image: 'eclipse/platformreleng-debian-swtnativebuild:12', + containerTemplate(name: 'swtbuild', image: dockerImage, resourceRequestCpu:'1000m', resourceRequestMemory:'512Mi', resourceLimitCpu:'2000m', resourceLimitMemory:'4096Mi', alwaysPullImage: true, command: 'cat', ttyEnabled: true) @@ -199,6 +208,7 @@ pipeline { 'gtk.linux.ppc64le',\ 'gtk.linux.riscv64',\ 'gtk.linux.x86_64',\ + 'gtk4.linux.x86_64',\ 'win32.win32.aarch64',\ 'win32.win32.x86_64' } @@ -220,22 +230,29 @@ pipeline { runOnNativeBuildAgent("${PLATFORM}") { cleanWs() // Workspace is not cleaned up by default, so we do it explicitly echo "OS: ${os}, ARCH: ${arch}" - unstash "swt.binaries.sources.${ws}" + unstash "swt.binaries.sources.${ws == 'gtk4' ? 'gtk' : ws }" dir('jdk.resources') { unstash "jdk.resources.${os}.${arch}" } withEnv(['MODEL=' + arch, "OUTPUT_DIR=${WORKSPACE}/libs", "SWT_JAVA_HOME=${WORKSPACE}/jdk.resources"]) { if (isUnix()){ - sh ''' + sh '''#!/bin/bash -x mkdir libs - if [ "${PLATFORM}" = "gtk.linux.aarch64" ]; then - sh build.sh -gtk3 install - elif [ "${PLATFORM}" = "gtk.linux.ppc64le" ]; then - sh build.sh -gtk3 install - elif [ "${PLATFORM}" = "gtk.linux.riscv64" ]; then - sh build.sh -gtk3 install - else + if [[ ${PLATFORM} == gtk.linux.* ]]; then + sh build.sh -gtk3 checklibs install + elif [[ ${PLATFORM} == gtk4.linux.* ]]; then + # We build both 3 + 4, but we only keep libswt-pi4-gtk + # We build both to help catch build errors as this + # build runs against more modern gcc/libs and helps + # with verification + sh build.sh -gtk3 checklibs + sh build.sh clean + sh build.sh -gtk4 checklibs install-pi-only + elif [[ ${PLATFORM} == cocoa.macosx.* ]]; then sh build.sh install + else + echo "Unexpected build platform ${PLATFORM}" + exit 1 fi ls -1R libs ''' @@ -258,11 +275,11 @@ pipeline { steps { dir("libs/${PLATFORM}") { unstash "swt.binaries.${PLATFORM}" - sh ''' + sh '''#!/bin/bash -x if [[ ${PLATFORM} == cocoa.macosx.* ]]; then binariesExtension='jnilib' signerUrl='https://cbi.eclipse.org/macos/codesign/sign' - elif [[ ${PLATFORM} == gtk.linux.* ]]; then + elif [[ ${PLATFORM} == gtk.linux.* || ${PLATFORM} == gtk4.linux.* ]]; then binariesExtension='so' elif [[ ${PLATFORM} == win32.win32.* ]]; then binariesExtension='dll' @@ -278,7 +295,7 @@ pipeline { done fi fi - cp *.$binariesExtension "${WORKSPACE}/eclipse.platform.swt/binaries/org.eclipse.swt.${PLATFORM}/" + cp *.$binariesExtension "${WORKSPACE}/eclipse.platform.swt/binaries/org.eclipse.swt.${PLATFORM/gtk4/gtk}/" ''' } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/build.sh b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/build.sh index 7911e9fc24..cff9c5cbef 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/build.sh +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/build.sh @@ -97,6 +97,7 @@ if [ "${MODEL}" = "" ]; then else MODEL=`uname -m` fi + export MODEL fi case $MODEL in "x86_64") diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/check_dependencies.sh b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/check_dependencies.sh new file mode 100755 index 0000000000..88edb34cf3 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/check_dependencies.sh @@ -0,0 +1,55 @@ +#!/bin/bash +############################################################################### +# Copyright (c) 2020, 2025 Kichwa Coders Canada Inc and others. +# +# This program and the accompanying materials +# are made available under the terms of the Eclipse Public License 2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +############################################################################### + +set -eu +set -o pipefail + +SCRIPT=$( basename "${BASH_SOURCE[0]}" ) + +### +# Check that executable/so ${FILE} +# use glibc symbols no greater than ${ALLOWED_GLIBC_VERSION} and depend on +# no libs other than ${ALLOWED_LIBS} +FILE=$1; shift +ALLOWED_GLIBC_VERSION=$1; shift +ALLOWED_LIBS="$@"; shift + +# grep that doesn't exit 1 on 0 matches +mygrep() { grep "$@" || test $? = 1; } + +# Check for permitted libraries using `readelf -d` looking for shared +# libraries that are listed as needed. e.g. lines like: +# 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0] +readelf -d ${FILE} | mygrep -E '\(NEEDED\)' | while read needed; do + needed=${needed//*Shared library: [/} + needed=${needed//]*/} + if [[ ! " ${ALLOWED_LIBS} " =~ " ${needed} " ]]; then + echo "ERROR: $FILE has illegal dependency of ${needed}" + exit 1 + fi +done + +# The way the version check is done is that all symbol version info is extracted +# from relocations match @GLIBC_*, the versions are sorted with the max +# allowed version added to the list too. And then we check the last entry in +# the list to make sure it is == to max allowed version. +objdump -R ${FILE} | mygrep @GLIBC_ | while read version; do + echo ${version//*@GLIBC_} +done > /tmp/version_check +echo ${ALLOWED_GLIBC_VERSION} >> /tmp/version_check +max_version_in_use=$(cat /tmp/version_check | sort --unique --version-sort | tail -n1) +if [ "$max_version_in_use" != "$ALLOWED_GLIBC_VERSION" ]; then + echo "ERROR: $FILE has dependency on glibc greater than allowed version of ${ALLOWED_GLIBC_VERSION} for at least the following symbols" + # This only lists greatest version number symbols + objdump -R ${FILE} | grep @GLIBC_${max_version_in_use} + exit 1 +fi diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak index af6e75d5db..83e76f5937 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak @@ -240,6 +240,44 @@ glx_structs.o: glx_structs.c glx_stats.o: glx_stats.c glx_stats.h $(CC) $(CFLAGS) $(GLXCFLAGS) -c glx_stats.c +# +# Permitted dependencies and glibc versions +# +# This does not include libraries that are dynamically loaded with dlopen, +# The purpose of this list, and the version limit on glibc is to ensure +# eclipse swt will be able to start on the widest range on Linuxes. +# All other error handling regarding missing/problematic libraries +# can be done at runtime. +ifeq ($(MODEL),x86_64) +PERMITTED_LIBRARIES=libc.so.6 libpthread.so.0 libdl.so.2 libm.so.6 +ifeq ($(GTK_VERSION), 4.0) +PERMITTED_GLIBC_VERSION=2.34 +PERMITTED_GTK_LIBRARIES = libgtk-4.so.1 +else +PERMITTED_GLIBC_VERSION=2.14 +PERMITTED_GTK_LIBRARIES = libgtk-3.so.0 libgdk-3.so.0 libcairo.so.2 libgthread-2.0.so.0 +endif +checklibs: all + $(info Verifying $(ALL_SWT_LIBS) have permitted dependencies) + ./check_dependencies.sh $(SWT_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) + ./check_dependencies.sh $(AWT_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) libjawt.so + ./check_dependencies.sh $(SWTPI_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) $(PERMITTED_GTK_LIBRARIES) + ./check_dependencies.sh $(CAIRO_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) libcairo.so.2 + ./check_dependencies.sh $(ATK_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) libatk-1.0.so.0 + ./check_dependencies.sh $(GLX_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) libGL.so.1 libGLU.so.1 + ./check_dependencies.sh $(WEBKIT_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) libgio-2.0.so.0 libgobject-2.0.so.0 libglib-2.0.so.0 +else +# We don't enforce max version and library sets on non-x86-64 because +# 1. We build on native hardware for those platforms so we don't have +# ability to use docker to adjust dependency versions as easily +# 2. The other platforms that are newer are generally faster moving +# and it is less likely to break users to have harder version +# requirements. +# As we get bigger user base on non-x86-64 we should start enforcing +# upper bounds for them too. +checklibs: all +endif + # # Install # @@ -253,6 +291,9 @@ glx_stats.o: glx_stats.c glx_stats.h install: all cp $(ALL_SWT_LIBS) $(OUTPUT_DIR) +install-pi-only: all + cp $(SWTPI_LIB) $(OUTPUT_DIR) + # # Clean #