Skip to content

Commit 5e8432e

Browse files
jonahgrahamHannesWell
authored andcommitted
Build GTK3 support for linux x86-64 to maximize compatibility
Recently all SWT builds for Linux x86-64 have been done on a new Debian image. This leads to requiring such a new distro to be able to run SWT successfully. This change builds GTK3 and common code on an older debian container to increase the range of versions we support. Only GTK4's key library, libswt-pi4-gtk*.so is shipped from a build on the new debian container. We continue to build all of the natives on latest debian so we benefit from compiler warnings/errors and other such tooling. As part of the build all .so files are checked to ensure their dependencies are as expected. In particular glibc version is checked for all symbols and all libraries are checked. The version of glibc 2.14 was chosen as that is what the effective requirement has been for a while for SWT (at least since Eclipse 4.26/2022-12) Fixes #1791
1 parent 54dad6c commit 5e8432e

File tree

4 files changed

+129
-13
lines changed

4 files changed

+129
-13
lines changed

Jenkinsfile

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,18 @@
1717

1818
def runOnNativeBuildAgent(String platform, Closure body) {
1919
def final nativeBuildStageName = 'Build SWT-native binaries'
20-
if (platform == 'gtk.linux.x86_64') {
20+
def dockerImage = null
21+
switch (platform) {
22+
case 'gtk.linux.x86_64':
23+
dockerImage = 'eclipse/platformreleng-debian-swtgtk3nativebuild:10'
24+
break
25+
case 'gtk4.linux.x86_64':
26+
dockerImage = 'eclipse/platformreleng-debian-swtnativebuild:12'
27+
break
28+
}
29+
if (dockerImage != null) {
2130
podTemplate(inheritFrom: 'basic' /* inherit general configuration */, containers: [
22-
containerTemplate(name: 'swtbuild', image: 'eclipse/platformreleng-debian-swtnativebuild:12',
31+
containerTemplate(name: 'swtbuild', image: dockerImage,
2332
resourceRequestCpu:'1000m', resourceRequestMemory:'512Mi',
2433
resourceLimitCpu:'2000m', resourceLimitMemory:'4096Mi',
2534
alwaysPullImage: true, command: 'cat', ttyEnabled: true)
@@ -199,6 +208,7 @@ pipeline {
199208
'gtk.linux.ppc64le',\
200209
'gtk.linux.riscv64',\
201210
'gtk.linux.x86_64',\
211+
'gtk4.linux.x86_64',\
202212
'win32.win32.aarch64',\
203213
'win32.win32.x86_64'
204214
}
@@ -220,22 +230,29 @@ pipeline {
220230
runOnNativeBuildAgent("${PLATFORM}") {
221231
cleanWs() // Workspace is not cleaned up by default, so we do it explicitly
222232
echo "OS: ${os}, ARCH: ${arch}"
223-
unstash "swt.binaries.sources.${ws}"
233+
unstash "swt.binaries.sources.${ws == 'gtk4' ? 'gtk' : ws }"
224234
dir('jdk.resources') {
225235
unstash "jdk.resources.${os}.${arch}"
226236
}
227237
withEnv(['MODEL=' + arch, "OUTPUT_DIR=${WORKSPACE}/libs", "SWT_JAVA_HOME=${WORKSPACE}/jdk.resources"]) {
228238
if (isUnix()){
229-
sh '''
239+
sh '''#!/bin/bash -x
230240
mkdir libs
231-
if [ "${PLATFORM}" = "gtk.linux.aarch64" ]; then
232-
sh build.sh -gtk3 install
233-
elif [ "${PLATFORM}" = "gtk.linux.ppc64le" ]; then
234-
sh build.sh -gtk3 install
235-
elif [ "${PLATFORM}" = "gtk.linux.riscv64" ]; then
236-
sh build.sh -gtk3 install
237-
else
241+
if [[ ${PLATFORM} == gtk.linux.* ]]; then
242+
sh build.sh -gtk3 checklibs install
243+
elif [[ ${PLATFORM} == gtk4.linux.* ]]; then
244+
# We build both 3 + 4, but we only keep libswt-pi4-gtk
245+
# We build both to help catch build errors as this
246+
# build runs against more modern gcc/libs and helps
247+
# with verification
248+
sh build.sh -gtk3 checklibs
249+
sh build.sh clean
250+
sh build.sh -gtk4 checklibs install-pi-only
251+
elif [[ ${PLATFORM} == cocoa.macosx.* ]]; then
238252
sh build.sh install
253+
else
254+
echo "Unexpected build platform ${PLATFORM}"
255+
exit 1
239256
fi
240257
ls -1R libs
241258
'''
@@ -258,12 +275,14 @@ pipeline {
258275
steps {
259276
dir("libs/${PLATFORM}") {
260277
unstash "swt.binaries.${PLATFORM}"
261-
sh '''
278+
sh '''#!/bin/bash -x
262279
if [[ ${PLATFORM} == cocoa.macosx.* ]]; then
263280
binariesExtension='jnilib'
264281
signerUrl='https://cbi.eclipse.org/macos/codesign/sign'
265-
elif [[ ${PLATFORM} == gtk.linux.* ]]; then
282+
elif [[ ${PLATFORM} == gtk.linux.* || ${PLATFORM} == gtk4.linux.* ]]; then
266283
binariesExtension='so'
284+
# Replace 'gtk4' by 'gtk' to copy the built gtk4 library into gtk fragment
285+
PLATFORM=${PLATFORM/#gtk4/gtk}
267286
elif [[ ${PLATFORM} == win32.win32.* ]]; then
268287
binariesExtension='dll'
269288
signerUrl='https://cbi.eclipse.org/authenticode/sign'

bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ if [ "${MODEL}" = "" ]; then
9797
else
9898
MODEL=`uname -m`
9999
fi
100+
export MODEL
100101
fi
101102
case $MODEL in
102103
"x86_64")
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/bash
2+
###############################################################################
3+
# Copyright (c) 2020, 2025 Kichwa Coders Canada Inc and others.
4+
#
5+
# This program and the accompanying materials
6+
# are made available under the terms of the Eclipse Public License 2.0
7+
# which accompanies this distribution, and is available at
8+
# https://www.eclipse.org/legal/epl-2.0/
9+
#
10+
# SPDX-License-Identifier: EPL-2.0
11+
###############################################################################
12+
13+
set -eu
14+
set -o pipefail
15+
16+
SCRIPT=$( basename "${BASH_SOURCE[0]}" )
17+
18+
###
19+
# Check that executable/so ${FILE}
20+
# use glibc symbols no greater than ${ALLOWED_GLIBC_VERSION} and depend on
21+
# no libs other than ${ALLOWED_LIBS}
22+
FILE=$1; shift
23+
ALLOWED_GLIBC_VERSION=$1; shift
24+
ALLOWED_LIBS="$@"; shift
25+
26+
# grep that doesn't exit 1 on 0 matches
27+
mygrep() { grep "$@" || test $? = 1; }
28+
29+
# Check for permitted libraries using `readelf -d` looking for shared
30+
# libraries that are listed as needed. e.g. lines like:
31+
# 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
32+
readelf -d ${FILE} | mygrep -E '\(NEEDED\)' | while read needed; do
33+
needed=${needed//*Shared library: [/}
34+
needed=${needed//]*/}
35+
if [[ ! " ${ALLOWED_LIBS} " =~ " ${needed} " ]]; then
36+
echo "ERROR: $FILE has illegal dependency of ${needed}"
37+
exit 1
38+
fi
39+
done
40+
41+
# The way the version check is done is that all symbol version info is extracted
42+
# from relocations match @GLIBC_*, the versions are sorted with the max
43+
# allowed version added to the list too. And then we check the last entry in
44+
# the list to make sure it is == to max allowed version.
45+
objdump -R ${FILE} | mygrep @GLIBC_ | while read version; do
46+
echo ${version//*@GLIBC_}
47+
done > /tmp/version_check
48+
echo ${ALLOWED_GLIBC_VERSION} >> /tmp/version_check
49+
max_version_in_use=$(cat /tmp/version_check | sort --unique --version-sort | tail -n1)
50+
if [ "$max_version_in_use" != "$ALLOWED_GLIBC_VERSION" ]; then
51+
echo "ERROR: $FILE has dependency on glibc greater than allowed version of ${ALLOWED_GLIBC_VERSION} for at least the following symbols"
52+
# This only lists greatest version number symbols
53+
objdump -R ${FILE} | grep @GLIBC_${max_version_in_use}
54+
exit 1
55+
fi

bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,44 @@ glx_structs.o: glx_structs.c
240240
glx_stats.o: glx_stats.c glx_stats.h
241241
$(CC) $(CFLAGS) $(GLXCFLAGS) -c glx_stats.c
242242

243+
#
244+
# Permitted dependencies and glibc versions
245+
#
246+
# This does not include libraries that are dynamically loaded with dlopen,
247+
# The purpose of this list, and the version limit on glibc is to ensure
248+
# eclipse swt will be able to start on the widest range on Linuxes.
249+
# All other error handling regarding missing/problematic libraries
250+
# can be done at runtime.
251+
ifeq ($(MODEL),x86_64)
252+
PERMITTED_LIBRARIES=libc.so.6 libpthread.so.0 libdl.so.2 libm.so.6
253+
ifeq ($(GTK_VERSION), 4.0)
254+
PERMITTED_GLIBC_VERSION=2.34
255+
PERMITTED_GTK_LIBRARIES = libgtk-4.so.1
256+
else
257+
PERMITTED_GLIBC_VERSION=2.14
258+
PERMITTED_GTK_LIBRARIES = libgtk-3.so.0 libgdk-3.so.0 libcairo.so.2 libgthread-2.0.so.0
259+
endif
260+
checklibs: all
261+
$(info Verifying $(ALL_SWT_LIBS) have permitted dependencies)
262+
./check_dependencies.sh $(SWT_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES)
263+
./check_dependencies.sh $(AWT_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) libjawt.so
264+
./check_dependencies.sh $(SWTPI_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) $(PERMITTED_GTK_LIBRARIES)
265+
./check_dependencies.sh $(CAIRO_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) libcairo.so.2
266+
./check_dependencies.sh $(ATK_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) libatk-1.0.so.0
267+
./check_dependencies.sh $(GLX_LIB) $(PERMITTED_GLIBC_VERSION) $(PERMITTED_LIBRARIES) libGL.so.1 libGLU.so.1
268+
./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
269+
else
270+
# We don't enforce max version and library sets on non-x86-64 because
271+
# 1. We build on native hardware for those platforms so we don't have
272+
# ability to use docker to adjust dependency versions as easily
273+
# 2. The other platforms that are newer are generally faster moving
274+
# and it is less likely to break users to have harder version
275+
# requirements.
276+
# As we get bigger user base on non-x86-64 we should start enforcing
277+
# upper bounds for them too.
278+
checklibs: all
279+
endif
280+
243281
#
244282
# Install
245283
#
@@ -253,6 +291,9 @@ glx_stats.o: glx_stats.c glx_stats.h
253291
install: all
254292
cp $(ALL_SWT_LIBS) $(OUTPUT_DIR)
255293

294+
install-pi-only: all
295+
cp $(SWTPI_LIB) $(OUTPUT_DIR)
296+
256297
#
257298
# Clean
258299
#

0 commit comments

Comments
 (0)