diff options
-rw-r--r-- | .SRCINFO | 81 | ||||
-rw-r--r-- | PKGBUILD | 97 | ||||
-rw-r--r-- | omr-fam.patch | 70 | ||||
-rw-r--r-- | openj9-openjdk-override-version.patch | 11 |
4 files changed, 125 insertions, 134 deletions
@@ -1,10 +1,10 @@ pkgbase = java-openj9 - pkgver = 15.0.1.b9_openj9_0.23.0 + pkgver = 20.0.1.u9_openj9_0.39.0_pre20230517 pkgrel = 1 url = http://www.eclipse.org/openj9/ arch = x86_64 license = custom - makedepends = java-environment>=11 + makedepends = java-environment>=19 makedepends = cpio makedepends = unzip makedepends = zip @@ -17,7 +17,6 @@ pkgbase = java-openj9 makedepends = libxext makedepends = libxrandr makedepends = alsa-lib - makedepends = pandoc makedepends = graphviz makedepends = freetype2 makedepends = libjpeg-turbo @@ -26,40 +25,51 @@ pkgbase = java-openj9 makedepends = lcms2 makedepends = libnet makedepends = bash - makedepends = freemarker + makedepends = harfbuzz + makedepends = gcc-libs + makedepends = glibc makedepends = numactl makedepends = nasm - source = openj9-openjdk-jdk-0.23.0.tar.gz::https://github.com/ibmruntimes/openj9-openjdk-jdk15/archive/openj9-0.23.0.tar.gz - source = https://github.com/eclipse/openj9/archive/openj9-0.23.0.tar.gz - source = openj9-omr-0.23.0.tar.gz::https://github.com/eclipse/openj9-omr/archive/openj9-0.23.0.tar.gz + makedepends = cmake + options = !lto + source = openj9-openjdk-jdk20-c6bbaba.tar.gz::https://github.com/ibmruntimes/openj9-openjdk-jdk20/archive/c6bbabab95ea24e30cf8c1225db464cff3e12594.tar.gz + source = openj9-8b5fd99.tar.gz::https://github.com/eclipse/openj9/archive/8b5fd99a8d71561e94dcbdf84af681ef7d1bb701.tar.gz + source = openj9-omr-e4f52d2.tar.gz::https://github.com/eclipse/openj9-omr/archive/e4f52d2e479f7e64e092dcec573f1fae864395cb.tar.gz source = freedesktop-java.desktop source = freedesktop-jconsole.desktop source = freedesktop-jshell.desktop source = omr-omrstr-iconv-failure-overflow.patch - source = omr-fam.patch - sha256sums = ed6b29fb098f7325298f70e6b07b283ee8aee95308c535a9979a55e1e0760a3a - sha256sums = e1962d17a45caef4b76f3c8120610d9192b43bd128a8b24dae5d5d6ccd298f1c - sha256sums = c58186d193c41e3c740ccbc29c320e18d7084b63d878bb7cc7ba90d3ebc4be5e + source = openj9-openjdk-override-version.patch + sha256sums = dd590d1a30d5e8ebabc8dde557997bd6af898fa9cbe256afcb028d518311a2b9 + sha256sums = d0c1d158569e68858b977087e9010942e98755cead82d1ad08a05541df54b44c + sha256sums = 4f962ec233a814f0f8ffb46834e9a12d18233a508502bc876526cb845073b1bd sha256sums = 7cb89746dbbcf498dd43b53fee59b124f42e3ea0d8b7134ab803cc2bd6b50230 sha256sums = bf76024528d050fd912f72d73e18a814a930df3478b132a99a887fbbdc0c9dfd sha256sums = bd2d4da78a65eec20dc32e21fd4fe134a2483b0bbe2dfb940d66755acc237975 sha256sums = f37290530dcb8eb5acb4f70609c55b7e2be134f1052ebf20f117c2996a749858 - sha256sums = c288b0a1a2424967d9c00e4d07d16f5d703f6b9b1195839753480fcd9810faf5 + sha256sums = 2a97f38ee08ed6a80be38879b47b78fc710adb9dfb69c44d2a33bee45bd06263 pkgname = jre-openj9-headless - pkgdesc = OpenJDK Java 15 headless runtime environment + pkgdesc = OpenJDK Java 20 headless runtime environment install = install_jre-openj9-headless.sh depends = java-runtime-common>=3 depends = ca-certificates-utils depends = nss depends = libjpeg-turbo + depends = libjpeg.so depends = lcms2 + depends = liblcms2.so depends = libnet depends = freetype2 + depends = libfreetype.so + depends = harfbuzz + depends = libharfbuzz.so + depends = glibc + depends = gcc-libs optdepends = java-rhino: for some JavaScript support - provides = java-runtime-headless=15 - provides = java-runtime-headless-openj9=15 - provides = jre15-openj9-headless=15.0.1.b9_openj9_0.23.0-1 + provides = java-runtime-headless=20 + provides = java-runtime-headless-openj9=20 + provides = jre20-openj9-headless=20.0.1.u9_openj9_0.39.0_pre20230517-1 backup = etc/java-openj9/logging.properties backup = etc/java-openj9/management/jmxremote.access backup = etc/java-openj9/management/jmxremote.password.template @@ -76,35 +86,40 @@ pkgname = jre-openj9-headless backup = etc/java-openj9/sound.properties pkgname = jre-openj9 - pkgdesc = OpenJDK Java 15 full runtime environment + pkgdesc = OpenJDK Java 20 full runtime environment install = install_jre-openj9.sh - depends = jre15-openj9-headless=15.0.1.b9_openj9_0.23.0-1 + depends = jre20-openj9-headless=20.0.1.u9_openj9_0.39.0_pre20230517-1 depends = giflib + depends = libgif.so + depends = glibc + depends = gcc-libs + depends = libpng optdepends = alsa-lib: for basic sound support optdepends = gtk2: for the Gtk+ 2 look and feel - desktop usage optdepends = gtk3: for the Gtk+ 3 look and feel - desktop usage - provides = java-runtime=15 - provides = java-runtime-openj9=15 - provides = jre15-openj9=15.0.1.b9_openj9_0.23.0-1 + provides = java-runtime=20 + provides = java-runtime-openj9=20 + provides = jre20-openj9=20.0.1.u9_openj9_0.39.0_pre20230517-1 pkgname = jdk-openj9 - pkgdesc = OpenJDK Java 15 development kit + pkgdesc = OpenJDK Java 20 development kit install = install_jdk-openj9.sh - depends = jre15-openj9=15.0.1.b9_openj9_0.23.0-1 + depends = jre20-openj9=20.0.1.u9_openj9_0.39.0_pre20230517-1 depends = java-environment-common=3 depends = hicolor-icon-theme depends = libelf - provides = java-environment=15 - provides = java-environment-openj9=15 - provides = jdk15-openj9=15.0.1.b9_openj9_0.23.0-1 + depends = glibc + depends = gcc-libs + provides = java-environment=20 + provides = java-environment-openj9=20 + provides = jdk20-openj9=20.0.1.u9_openj9_0.39.0_pre20230517-1 pkgname = openj9-src - pkgdesc = OpenJDK Java 15 sources - depends = jdk15-openj9=15.0.1.b9_openj9_0.23.0-1 - provides = openj915-src=15.0.1.b9_openj9_0.23.0-1 + pkgdesc = OpenJDK Java 20 sources + depends = jdk20-openj9=20.0.1.u9_openj9_0.39.0_pre20230517-1 + provides = openj9-20-src=20.0.1.u9_openj9_0.39.0_pre20230517-1 pkgname = openj9-doc - pkgdesc = OpenJDK Java 15 documentation - depends = jdk15-openj9=15.0.1.b9_openj9_0.23.0-1 - provides = openj915-doc=15.0.1.b9_openj9_0.23.0-1 - + pkgdesc = OpenJDK Java 20 documentation + depends = jdk20-openj9=20.0.1.u9_openj9_0.39.0_pre20230517-1 + provides = openj9-20-doc=20.0.1.u9_openj9_0.39.0_pre20230517-1 @@ -6,36 +6,40 @@ pkgbase=java-openj9 pkgname=('jre-openj9-headless' 'jre-openj9' 'jdk-openj9' 'openj9-src' 'openj9-doc') -_majorver=15 +_majorver=20 _minorver=0 _securityver=1 _updatever=9 -_openj9ver=0.23.0 +_openj9ver=0.39.0 pkgrel=1 -pkgver=${_majorver}.${_minorver}.${_securityver}.b${_updatever}_openj9_${_openj9ver} +pkgver=${_majorver}${_minorver:+.${_minorver}}${_securityver:+.${_securityver}}.u${_updatever}_openj9_${_openj9ver}_pre20230517 arch=('x86_64') url='http://www.eclipse.org/openj9/' license=('custom') -makedepends=('java-environment>=11' 'cpio' 'unzip' 'zip' 'libelf' 'libcups' 'libx11' - 'libxrender' 'libxtst' 'libxt' 'libxext' 'libxrandr' 'alsa-lib' 'pandoc' +makedepends=("java-environment>=$((_majorver-1))" 'cpio' 'unzip' 'zip' 'libelf' 'libcups' 'libx11' + 'libxrender' 'libxtst' 'libxt' 'libxext' 'libxrandr' 'alsa-lib' 'graphviz' 'freetype2' 'libjpeg-turbo' 'giflib' 'libpng' 'lcms2' - 'libnet' 'bash' 'freemarker' 'numactl' 'nasm') -source=(openj9-openjdk-jdk-${_openj9ver}.tar.gz::https://github.com/ibmruntimes/openj9-openjdk-jdk${_majorver}/archive/openj9-${_openj9ver}.tar.gz - https://github.com/eclipse/openj9/archive/openj9-${_openj9ver}.tar.gz - openj9-omr-${_openj9ver}.tar.gz::https://github.com/eclipse/openj9-omr/archive/openj9-${_openj9ver}.tar.gz + 'libnet' 'bash' 'harfbuzz' 'gcc-libs' 'glibc' 'numactl' 'nasm' 'cmake') +_openjdk_sha=c6bbabab95ea24e30cf8c1225db464cff3e12594 +_openj9_sha=8b5fd99a8d71561e94dcbdf84af681ef7d1bb701 +_openj9omr_sha=e4f52d2e479f7e64e092dcec573f1fae864395cb +options=(!lto) +source=(openj9-openjdk-jdk${_majorver}-${_openjdk_sha:0:7}.tar.gz::https://github.com/ibmruntimes/openj9-openjdk-jdk${_majorver}/archive/${_openjdk_sha}.tar.gz + openj9-${_openj9_sha:0:7}.tar.gz::https://github.com/eclipse/openj9/archive/${_openj9_sha}.tar.gz + openj9-omr-${_openj9omr_sha:0:7}.tar.gz::https://github.com/eclipse/openj9-omr/archive/${_openj9omr_sha}.tar.gz freedesktop-java.desktop freedesktop-jconsole.desktop freedesktop-jshell.desktop omr-omrstr-iconv-failure-overflow.patch - omr-fam.patch) -sha256sums=('ed6b29fb098f7325298f70e6b07b283ee8aee95308c535a9979a55e1e0760a3a' - 'e1962d17a45caef4b76f3c8120610d9192b43bd128a8b24dae5d5d6ccd298f1c' - 'c58186d193c41e3c740ccbc29c320e18d7084b63d878bb7cc7ba90d3ebc4be5e' + openj9-openjdk-override-version.patch) +sha256sums=('dd590d1a30d5e8ebabc8dde557997bd6af898fa9cbe256afcb028d518311a2b9' + 'd0c1d158569e68858b977087e9010942e98755cead82d1ad08a05541df54b44c' + '4f962ec233a814f0f8ffb46834e9a12d18233a508502bc876526cb845073b1bd' '7cb89746dbbcf498dd43b53fee59b124f42e3ea0d8b7134ab803cc2bd6b50230' 'bf76024528d050fd912f72d73e18a814a930df3478b132a99a887fbbdc0c9dfd' 'bd2d4da78a65eec20dc32e21fd4fe134a2483b0bbe2dfb940d66755acc237975' 'f37290530dcb8eb5acb4f70609c55b7e2be134f1052ebf20f117c2996a749858' - 'c288b0a1a2424967d9c00e4d07d16f5d703f6b9b1195839753480fcd9810faf5') + '2a97f38ee08ed6a80be38879b47b78fc710adb9dfb69c44d2a33bee45bd06263') case "${CARCH}" in x86_64) _JARCH='x86_64';; @@ -43,7 +47,7 @@ case "${CARCH}" in esac _jvmdir=/usr/lib/jvm/java-${_majorver}-openj9 -_jdkdir=openj9-openjdk-jdk${_majorver}-openj9-${_openj9ver} +_jdkdir=openj9-openjdk-jdk${_majorver}-${_openjdk_sha} _imgdir=${_jdkdir}/build/linux-${_JARCH}-server-release/images _nonheadless=(lib/libawt_xawt.{so,debuginfo} @@ -54,16 +58,13 @@ _nonheadless=(lib/libawt_xawt.{so,debuginfo} prepare() { cd ${_jdkdir} - ln -s ../openj9-openj9-${_openj9ver} openj9 - ln -s ../openj9-omr-openj9-${_openj9ver} omr + ln -s ../openj9-${_openj9_sha} openj9 + ln -s ../openj9-omr-${_openj9omr_sha} omr patch -d omr -p1 -i $srcdir/omr-omrstr-iconv-failure-overflow.patch - patch -d omr -p1 -i $srcdir/omr-fam.patch + patch -p1 -i $srcdir/openj9-openjdk-override-version.patch - sed -i -e '/^OPENJ9_SHA :=/s/:=.*/:= openj9-'${_openj9ver}/ \ - -e '/^OPENJ9_TAG :=/s/:=.*/:= openj9-'${_openj9ver}/ \ - -e '/^OPENJ9OMR_SHA :=/s/:=.*/:= openj9-'${_openj9ver}/ \ - closed/OpenJ9.gmk + find openj9/ omr/ -name CMakeLists.txt -exec sed -i -e '/set(OMR_WARNINGS_AS_ERRORS ON/s/ON/OFF/' {} + || die } build() { @@ -88,12 +89,20 @@ build() { _CXXFLAGS=${CXXFLAGS/-fno-plt/} fi + # TODO: Should be rechecked for the next releases + # compiling with -fexceptions leads to: + # /usr/bin/ld: /build/java-openjdk/src/jdk17u-jdk-17.0.3-2/build/linux-x86_64-server-release/hotspot/variant-server/libjvm/objs/zPhysicalMemory.o: in function `ZList<ZMemory>::~ZList()': + # /build/java-openjdk/src/jdk17u-jdk-17.0.3-2/src/hotspot/share/gc/z/zList.hpp:54: undefined reference to `ZListNode<ZMemory>::~ZListNode()' + # collect2: error: ld returned 1 exit status + _CFLAGS=${CFLAGS/-fexceptions/} + _CXXFLAGS=${CXXFLAGS/-fexceptions/} + # CFLAGS, CXXFLAGS and LDFLAGS are ignored as shown by a warning # in the output of ./configure unless used like such: # --with-extra-cflags="${CFLAGS}" # --with-extra-cxxflags="${CXXFLAGS}" # --with-extra-ldflags="${LDFLAGS}" - # See also paragraph "Configure Control Variables from "jdk${_majorver}-${_hg_tag}/common/doc/building.md + # See also paragraph "Configure Control Variables from "jdk${_majorver}-${_git_tag}/common/doc/building.md unset CFLAGS unset CXXFLAGS unset LDFLAGS @@ -111,23 +120,47 @@ build() { --with-libpng=system \ --with-lcms=system \ --with-zlib=system \ + --with-harfbuzz=system \ --with-jvm-features=zgc \ --enable-unlimited-crypto \ --disable-warnings-as-errors{,-omr,-openj9} \ - --with-freemarker-jar=/usr/share/java/freemarker/freemarker.jar \ --disable-ddr \ + --with-cmake \ ${NUM_PROC_OPT} #--disable-javac-server - make images legacy-jre-image docs + local mycmakeargsx=( + "-DCMAKE_C_FLAGS='${CFLAGS}'" + "-DJ9JIT_EXTRA_CFLAGS='${CFLAGS}'" + "-DCMAKE_CXX_FLAGS='${CXXFLAGS}'" + "-DJ9JIT_EXTRA_CXXFLAGS='${CXXFLAGS}'" + "-DCMAKE_EXE_LINKER_FLAGS='${LDFLAGS}'" + -DOMR_WARNINGS_AS_ERRORS=OFF + -DOMR_PORT_NUMA_SUPPORT=$(usex numa) + ) + make \ + EXTRA_CMAKE_ARGS="${mycmakeargsx[*]}" \ + OPENJDK_SHA=${_openjdk_sha} \ + OPENJ9_SHA=${_openj9_sha} \ + OPENJ9_TAG=${_openj9ver} \ + OPENJ9OMR_SHA=${_openj9omr_sha} \ + images legacy-jre-image docs # https://bugs.openjdk.java.net/browse/JDK-8173610 find "../${_imgdir}" -iname '*.so' -exec chmod +x {} \; } +check() { + cd ${_jdkdir} + # TODO package jtreg + # make -k check +} + package_jre-openj9-headless() { pkgdesc="OpenJDK Java ${_majorver} headless runtime environment" - depends=('java-runtime-common>=3' 'ca-certificates-utils' 'nss' 'libjpeg-turbo' 'lcms2' 'libnet' 'freetype2') + depends=('java-runtime-common>=3' 'ca-certificates-utils' 'nss' 'libjpeg-turbo' 'libjpeg.so' + 'lcms2' 'liblcms2.so' 'libnet' 'freetype2' 'libfreetype.so' 'harfbuzz' 'libharfbuzz.so' + 'glibc' 'gcc-libs') optdepends=('java-rhino: for some JavaScript support') provides=("java-runtime-headless=${_majorver}" "java-runtime-headless-openj9=${_majorver}" "jre${_majorver}-openj9-headless=${pkgver}-${pkgrel}") backup=(etc/${pkgbase}/logging.properties @@ -186,7 +219,8 @@ package_jre-openj9-headless() { package_jre-openj9() { pkgdesc="OpenJDK Java ${_majorver} full runtime environment" - depends=("jre${_majorver}-openj9-headless=${pkgver}-${pkgrel}" 'giflib') + depends=("jre${_majorver}-openj9-headless=${pkgver}-${pkgrel}" 'giflib' 'libgif.so' + 'glibc' 'gcc-libs' 'libpng') optdepends=('alsa-lib: for basic sound support' 'gtk2: for the Gtk+ 2 look and feel - desktop usage' 'gtk3: for the Gtk+ 3 look and feel - desktop usage') @@ -208,7 +242,8 @@ package_jre-openj9() { package_jdk-openj9() { pkgdesc="OpenJDK Java ${_majorver} development kit" - depends=("jre${_majorver}-openj9=${pkgver}-${pkgrel}" 'java-environment-common=3' 'hicolor-icon-theme' 'libelf') + depends=("jre${_majorver}-openj9=${pkgver}-${pkgrel}" 'java-environment-common=3' + 'hicolor-icon-theme' 'libelf' 'glibc' 'gcc-libs') provides=("java-environment=${_majorver}" "java-environment-openj9=${_majorver}" "jdk${_majorver}-openj9=${pkgver}-${pkgrel}") install=install_jdk-openj9.sh @@ -216,7 +251,7 @@ package_jdk-openj9() { install -dm 755 "${pkgdir}${_jvmdir}" - cp -a bin demo include jmods lib \ + cp -a bin include jmods lib \ "${pkgdir}${_jvmdir}" rm "${pkgdir}${_jvmdir}/lib/src.zip" @@ -267,7 +302,7 @@ package_openj9-src() { pkgdesc="OpenJDK Java ${_majorver} sources" # Depends on JDK to get license files depends=("jdk${_majorver}-openj9=${pkgver}-${pkgrel}") - provides=("openj9${_majorver}-src=${pkgver}-${pkgrel}") + provides=("openj9-${_majorver}-src=${pkgver}-${pkgrel}") install -Dm 644 -t "${pkgdir}${_jvmdir}/lib" ${_imgdir}/jdk/lib/src.zip @@ -279,7 +314,7 @@ package_openj9-doc() { pkgdesc="OpenJDK Java ${_majorver} documentation" # Depends on JDK to get license files depends=("jdk${_majorver}-openj9=${pkgver}-${pkgrel}") - provides=("openj9${_majorver}-doc=${pkgver}-${pkgrel}") + provides=("openj9-${_majorver}-doc=${pkgver}-${pkgrel}") install -dm 755 "${pkgdir}/usr/share/doc" cp -r ${_imgdir}/docs "${pkgdir}/usr/share/doc/${pkgbase}" diff --git a/omr-fam.patch b/omr-fam.patch deleted file mode 100644 index 9141ec17c68c..000000000000 --- a/omr-fam.patch +++ /dev/null @@ -1,70 +0,0 @@ -diff --git a/ddr/tools/blob_reader/blob_reader.cpp b/ddr/tools/blob_reader/blob_reader.cpp -index 028decd0c..a0212609f 100644 ---- a/ddr/tools/blob_reader/blob_reader.cpp -+++ b/ddr/tools/blob_reader/blob_reader.cpp -@@ -85,7 +85,7 @@ struct BlobHeaderV1 { - - struct BlobString { - uint16_t length; -- char data[1]; /* flexible array member */ -+ char data[]; - - void endian_swap() - { -diff --git a/include_core/ute_core.h b/include_core/ute_core.h -index 8b3b1c65d..330ea52c6 100644 ---- a/include_core/ute_core.h -+++ b/include_core/ute_core.h -@@ -125,7 +125,7 @@ typedef struct UtTraceRecord { - uint64_t threadSyn2; /* Thread synonym 2 */ - int32_t firstEntry; /* Offset to first trace entry */ - int32_t nextEntry; /* Offset to next entry */ -- char threadName[1]; /* Thread name */ -+ char threadName[]; /* Thread name */ - } UtTraceRecord; - - /* -diff --git a/include_core/ute_dataformat.h b/include_core/ute_dataformat.h -index 71d9e36ad..8a9dcb487 100644 ---- a/include_core/ute_dataformat.h -+++ b/include_core/ute_dataformat.h -@@ -180,7 +180,7 @@ typedef struct UtProcSection { - #define UT_TRACE_ACTIVE_SECTION_NAME "UTTA" - typedef struct UtActiveSection { - UtDataHeader header; /* Eyecatcher, version etc */ -- char active[1]; /* Trace activation commands */ -+ char active[]; /* Trace activation commands */ - } UtActiveSection; - - /* -@@ -191,7 +191,7 @@ typedef struct UtActiveSection { - #define UT_TRACE_SERVICE_SECTION_NAME "UTSS" - typedef struct UtServiceSection { - UtDataHeader header; /* Eyecatcher, version etc */ -- char level[1]; /* Service level info */ -+ char level[]; /* Service level info */ - } UtServiceSection; - - /* -@@ -202,7 +202,7 @@ typedef struct UtServiceSection { - #define UT_TRACE_STARTUP_SECTION_NAME "UTSO" - typedef struct UtStartupSection { - UtDataHeader header; /* Eyecatcher, version etc */ -- char options[1]; /* Startup options */ -+ char options[]; /* Startup options */ - } UtStartupSection; - - /* -diff --git a/omrtrace/omrtrace_internal.h b/omrtrace/omrtrace_internal.h -index e52347eac..a68a88abd 100644 ---- a/omrtrace/omrtrace_internal.h -+++ b/omrtrace/omrtrace_internal.h -@@ -157,7 +157,7 @@ typedef struct OMR_TraceGlobal OMR_TraceGlobal; - typedef struct UtTraceCfg { - UtDataHeader header; - struct UtTraceCfg *next; /* Next trace config command */ -- char command[1]; /* Start of variable length section */ -+ char command[]; /* Start of variable length section */ - } UtTraceCfg; - - typedef struct UtDeferredConfigInfo { diff --git a/openj9-openjdk-override-version.patch b/openj9-openjdk-override-version.patch new file mode 100644 index 000000000000..165262797522 --- /dev/null +++ b/openj9-openjdk-override-version.patch @@ -0,0 +1,11 @@ +--- a/closed/OpenJ9.gmk ++++ b/closed/OpenJ9.gmk +@@ -44,7 +44,7 @@ + # $4 - 'required' for a required repository, anything else for an optional one + GetVersion = $(eval $(call GetVersionHelper,$(strip $1),$(strip $2),$(strip $3),$(strip $4))) + define GetVersionHelper +- $2 := $$(if $(wildcard $3),$$(shell $(GIT) -C $3 rev-parse --short HEAD)) ++ $2 := $$(if $$($2),$$($2),$$(if $(wildcard $3),$$(shell $(GIT) -C $3 rev-parse --short HEAD))) + ifneq (,$$($2)) + VersionLabelWidth := $(shell $(ECHO) "$1" | $(AWK) "{ width = length; print (width > $(VersionLabelWidth) ? width : $(VersionLabelWidth)) }") + VersionPairs += "$1" "$$($2)" |