Saturday, October 26, 2024

Setting up pkgsrc on Solaris or Illumos

NetBSD pkgsrc framework is a collection of make files, scripts and patches, used for downloading, configuring and building mostly open source software packages. See https://pkgsrc.org for more details.

Every quarter a new pkgsrc release is made. To keep up to date with the recent releases, download them from https://cdn.netbsd.org/pub/pkgsrc/.

Pkgsrc can also be used on Solaris or Illumos, however there are a few extra steps required to bootstrap it before it can be used. There are many different ways in how pkgsrc can be configured, depending on personal preferences. The notes below are mainly for myself and describe how I tend to use it on Solaris.

1. Decide which toolchain to use

On Solaris there may be multiple toolchains installed: Sun/Oracle studio compilers, GNU compilers, or LLVM compilers. Pkgsrc can support different toolchains, however a lot of open source software builds with the least problems using GNU compilers. For that reason I would recommend using GCC C and C++ compilers.

GCC compilers can be configured to use either Sun original binutils or GNU binutils. It is recommended to use GCC compilers configured with Sun binutils, as this seems to result in the least problems when building software from source. I have another article which describes how to build GCC compilers on Solaris from scratch. At the time of writing this article, gcc-14.X causes build failure with some packages as it has more pedantic error checking, hence using gcc-13.X provides a less painful experience.

Pkgsrc includes several GCC compilers, which can be built from source using pkgsrc framework and installed as pkgsrc packages, however in order to build a compiler from pkgsrc, you need to bootsrap pkgsrc with a native compiler. Bootstrapping pkgsrc builds various support binaries and if the native compiler is GCC, it links the binaries to GCC native compiler's shared libraries. Later when you build a new compiler from pkgsrc and tell it to use this compiler, then it will link later binaries to pkgsrc GCC compiler's share libraries. In the end, you end up with some binaries linked to one compiler and another set to another compiler. There are ways to hack around it, but on Solaris I always build GCC compilers from source and use them as the native compilers. This way I can have multiple compilers and have the freedom to install whichever GCC version that works best for me, instead of relying on pkgsrc for this task.

I normally install GCC compilers under /opt and then setup /opt/gcc symlink to point to a working compiler version.

2. Decide on pkgsrc install location and directory name

I normally install pkgsrc packages under /opt/pkg-<release_ver> and then setup /opt/pkg symlink to point the current stable packages directory. This way, I can use the same Solaris zone for building multiple pkgsrc releases concurrently. For example, I can use current /opt/pkg-2024Q2 packages while building and installing /opt/pkg-2024Q3 packages. If the new packages build and run correctly, I can later simply update the symlink and may be a few rc.d start scripts, as they hardcode the absolute paths to binaries.

3. Download pkgsrc stable release

Here "stable" is a relative term and probably applies mostly to NetBSD. Some packages may or may not build and work on Solaris/Illumos.

cd /opt &&
wget https://cdn.netbsd.org/pub/pkgsrc/pkgsrc-2024Q3/pkgsrc.tar.gz &&
gtar -xf pkgsrc.tar.gz &&
mv pkgsrc pkgsrc-2024Q3 &&
chown -RP root:root pkgsrc-2024Q3

4. Define environment variables for bootstrapping pkgsrc

Adjust these based on your own preferences.

MAKE_JOBS=128 &&
GCC_BASE="/opt/gcc" &&
PKGSRC_VER="2024Q3" &&
PKGSRC_BASE="/opt/pkgsrc-${PKGSRC_VER:?}" &&
PKG_BASE="/opt/pkg-${PKGSRC_VER:?}" &&
LD_OPTIONS="\
-L${PKG_BASE:?}/lib-gcc -R${PKG_BASE:?}/lib-gcc \
-L${PKG_BASE:?}/lib-gcc/sparcv9 -R${PKG_BASE:?}/lib-gcc/sparcv9" &&
PATH="${GCC_BASE:?}/bin:${PKG_BASE:?}/bin:${PKG_BASE:?}/sbin:/bin:/usr/bin:/sbin:/usr/sbin" &&
export LD_OPTIONS PATH

GCC_BASE is the base directory where native GCC compilers are installed. This consists of various sub-directories like bin/, lib/, etc.

PKGSRC_BASE is the base directory where the pkgsrc tree is located.

PKG_BASE is the base directory where binary pkgsrc packages get installed.

LD_OPTIONS is set for Solaris linker to hardcode the path for GCC shared libraries. See pkg/57685 why the usual LDFLAGS variable does not work here.

PATH should contain directories with: GCC compiler binaries, pkgsrc installed binaries and all other system binaries.

4. Copy GCC libraries to pkgsrc install directory

When building packages from source, some of them get linked to GCC shared libraries. We need to make sure that:

  1. We tell pkgsrc where to find GCC libraries. For that we export Solaris linker LD_OPTIONS environment variable.
  2. Packages continue to work correctly if the GCC compiler used to build them is later removed from the system. For that we physically copy required libraries to pkgsrc install directory.
test -d "${PKG_BASE:?}/lib-gcc/sparcv9" || \
	mkdir -p "${PKG_BASE:?}/lib-gcc/sparcv9" &&
gtar -C "${GCC_BASE:?}/lib" -cf - $(ls "${GCC_BASE:?}/lib/"lib*.so* | \
	while read i; do basename "$i"; done) | \
	gtar -C "${PKG_BASE:?}/lib-gcc" -xpf - &&
gtar -C "${GCC_BASE:?}/lib/sparcv9" -cf - $(ls "${GCC_BASE:?}/lib/sparcv9/"lib*.so* | \
	while read i; do basename "$i"; done) | \
	gtar -C "${PKG_BASE:?}/lib-gcc/sparcv9" -xpf -

5. Bootstrap pkgsrc

Here we build pkgsrc support binaries, using /opt/pkg-<release_ver>.objects as the base directory for object files and /opt/pkg-<release_ver>.distfiles as the base directory for downloaded source archives.

rm -rf "/opt/pkg-${PKGSRC_VER:?}.objects/bootstrap" &&
env \
MAKECONF="" \
PKGMAKECONF="" \
DISTDIR="/opt/pkg-${PKGSRC_VER:?}.distfiles" \
PKGSRC_COMPILER=gcc \
USE_NATIVE_GCC=yes \
CC="${GCC_BASE:?}/bin/gcc" \
CXX="${GCC_BASE:?}/bin/g++" \
CFLAGS="-O2 -mcpu=v9" \
CXXFLAGS="-O2 -mcpu=v9" \
"${PKGSRC_BASE:?}/bootstrap/bootstrap" \
	--prefer-pkgsrc yes \
	--make-jobs     "${MAKE_JOBS:?}" \
	--workdir       "/opt/pkg-${PKGSRC_VER:?}.objects/bootstrap" \
	--prefix        "${PKG_BASE:?}" \
	--pkgdbdir      "${PKG_BASE:?}/db/pkg"

6. Generate pkgsrc mk.conf

The mk.conf file is used by pkgsrc when building software packages from source. It contains various preference settings that specifies file locations, build options and compiler flags.

mv "${PKG_BASE:?}/etc/mk.conf" "${PKG_BASE:?}/etc/mk.conf.orig" &&
cat > "${PKG_BASE:?}/etc/mk.conf" << EOF
.ifdef BSD_PKG_MK       # begin pkgsrc settings

# Build packages concurrently. On Solaris this requires installing pkgtools/shlock package
#PKGSRC_LOCKTYPE=          sleep
#PKGSRC_SLEEPSECS=         60

OBJHOSTNAME=              yes

ABI=                      64
UNPRIVILEGED=             no
X11_TYPE=                 modular
MAKE_JOBS=                16

# WARNING: Changing PREFER_* after bootstrap will require rebuilding all
# packages with a dependency that switched between native/pkgsrc.
PREFER_PKGSRC=            yes
SKIP_LICENSE_CHECK=       yes
DEPENDS_TARGET=           package-install

LOCALBASE=                /opt/pkg-${PKGSRC_VER:?}
PKG_DBDIR=                \${LOCALBASE}/db/pkg
SYSCONFBASE=              \${LOCALBASE}/etc
VARBASE=                  \${LOCALBASE}/var
PKG_TOOLS_BIN=            \${LOCALBASE}/sbin
PKGINFODIR=               info
PKGMANDIR=                man

# Use Solaris /usr/bin/bash as the shell
TOOLS_PLATFORM.sh?=       /usr/bin/bash

# Use pkgsrc install
TOOLS_PLATFORM.install?=  \${LOCALBASE}/bin/bsdinstall

# Use pkgsrc sed. May need to be uncommented on older versions of Solaris.
# Check pkgsrc etc/mk.conf.orig to see if this line was enabled.
#TOOLS_PLATFORM.sed?=      \${LOCALBASE}/bin/nbsed

# Enable when using native GCC
PKGSRC_COMPILER=          gcc
USE_NATIVE_GCC=           yes
CC=                       /opt/gcc/bin/gcc
CXX=                      /opt/gcc/bin/g++

# Enable when using pkgsrc GCC
#USE_PKGSRC_GCC=           yes
#USE_PKGSRC_GCC_RUNTIME=   yes
#GCC_REQD=                 13

CFLAGS+=                  -O2 -mcpu=v9
CXXFLAGS+=                -O2 -mcpu=v9

DBG=                      # prevent DBG from adding default optimizer flags

PACKAGES=                 /opt/pkg-${PKGSRC_VER:?}.packages
WRKOBJDIR=                /opt/pkg-${PKGSRC_VER:?}.objects
DISTDIR=                  /opt/pkg-${PKGSRC_VER:?}.distfiles

MASTER_SORT=              .uk .be .fr .de .dk .ch .it .fi .pl .no .nl .se
.endif                  # end pkgsrc settings
EOF

7. Build some packages

🖙 Before building more packages, it may be prudent to save current pkgsrc bootstrap state into tar archive, so that later it could be extracted on a different machine without bootstrapping it from scratch

gtar -zcf "/opt/pkg-${PKGSRC_VER:?}_bootstrap.tgz" "${PKG_BASE:?}"

It is best to create a script for this

PKGSRC_VER="2024Q3" &&
PKGSRC_BASE="/opt/pkgsrc-${PKGSRC_VER:?}" &&
PKG_BASE="/opt/pkg-${PKGSRC_VER:?}" &&
PKG_DBDIR="${PKG_BASE:?}/db/pkg" &&
LD_OPTIONS="\
-L${PKG_BASE:?}/lib-gcc -R${PKG_BASE:?}/lib-gcc \
-L${PKG_BASE:?}/lib-gcc/sparcv9 -R${PKG_BASE:?}/lib-gcc/sparcv9" &&
PATH="${GCC_BASE:?}/bin:${PKG_BASE:?}/bin:${PKG_BASE:?}/sbin:${PKG_BASE:?}/libexec:/bin:/usr/bin:/sbin:/usr/sbin" &&
export PKG_DBDIR LD_OPTIONS PATH

PKG_LIST='
meta-pkgs/modular-xorg-protos
meta-pkgs/modular-xorg-libs
meta-pkgs/modular-xorg-fonts
meta-pkgs/modular-xorg-utils
meta-pkgs/modular-xorg-apps
'

for i in ${PKG_LIST:?}
do
	cd "${PKGSRC_BASE:?}/${i}" && bmake package-install || break
done

# For pkgsrc support commands to work correctly, PKG_DBDIR must be set correctly
pkg_info -a

Thursday, October 24, 2024

Installing Developer Studio 12.6 on SPARC Solaris

Oracle seem to offer Developer Studio compilers free of charge. You just need to sign in with your free Oracle account, request access to software packages and accept license terms.

I encountered a number of snags with this process:

First, I could not figure out where to download the key and certificate files, which would allow me to set up pkg publisher. The instructions read:

Download your personal key and certificate files, called pkg.oracle.com.key.pem and pkg.oracle.com.certificate.pem from the certificate page.

The last two words: "certificate page" are linked to the certificate page, however the link is nearly impossible to see, since the text highlight colour blends in with the normal text colour on the page.

Second, the instructions for setting up the publisher seem to be incorrect. They tell you to download the key and certificate files to your home directory and then run 'pkg set-publisher'. However this results in errors:

# pkg set-publisher \
-k ./pkg.oracle.com.key.pem \
-c ./pkg.oracle.com.certificate.pem \
-G'*' -g https://pkg.oracle.com/solarisstudio/release solarisstudio

Unable to locate certificate '//pkg.oracle.com.certificate.pem' for publisher 'solarisstudio' needed to access 'https://pkg.oracle.com/solarisstudio/release/'.

It looks like the key and certificate files need to be copied to /var/pkg/ssl directory in order for them to be correctly located:

# ls -1 pkg*
pkg.oracle.com.certificate.pem
pkg.oracle.com.key.pem

# cp pkg* /var/pkg/ssl
# pkg set-publisher \
-k /var/pkg/ssl/pkg.oracle.com.key.pem \
-c /var/pkg/ssl/pkg.oracle.com.certificate.pem \
-G '*' -g https://pkg.oracle.com/solarisstudio/release solarisstudio

# pkg publisher
PUBLISHER                   TYPE     STATUS P LOCATION
solaris        (syspub)     origin   online T <system-repository>
solarisstudio               origin   online F https://pkg.oracle.com/solarisstudio/release/

# pkg install --accept developerstudio-126
...

# /opt/developerstudio12.6/bin/cc -V
cc: Studio 12.6 Sun C 5.15 SunOS_sparc 2017/05/30

All done.

Wednesday, October 16, 2024

Building GCC compilers for SPARC Solaris

In this article I would like to share some ideas on how to build C, C++ and Ada compilers for SPARC Solaris.

To build GCC compilers we need a bootstrap compiler with which to build. It may be possible to use for example, x86 Linux GCC host and then cross compile for SPARC Solaris target. However, this article assumes there is a native SPARC Solaris GCC compiler, which is then used to build a new version of a native GCC compiler. If the bootstrap GCC compiler does not support Ada programming language, then exclude it from GCC configure --enable-languages list.

GCC needs binutils (assembler, linker, loader, etc) programs in order to work correctly. There are two types of binutils for Solaris: Sun original binutils and GNU binutils. GCC can use either of them, however it is not able to switch between them dynamically, hence GCC needs to be configured and built separately for each type of binutils. This article describes both versions, just in case.


1. Create build directories

First we create build directories for downloaded packages, source files and object files.

BUILD_ROOT="/opt/gcc_build" &&
TAR_DIR="${BUILD_ROOT:?}/tar" &&
SRC_DIR="${BUILD_ROOT:?}/src" &&
OBJ_DIR="${BUILD_ROOT:?}/obj"
mkdir -p ${TAR_DIR:?} ${SRC_DIR:?} ${OBJ_DIR:?}

BUILD_ROOT is set to /opt/gcc_build.
TAR_DIR
is set to /opt/gcc_build/tar, downloaded packages are stored here.
SRC_DIR is set to /opt/gcc_build/src, source files are unpacked here.
OBJ_DIR is set to /opt/gcc_build/obj, object files are stored here.


2. Download and unpack packages

These versions of packages are known to build on Solaris. Later versions may introduce various Linuxisms, thus causing breakage.

DEVUTILS_PREFIX=/opt/gcc_build_tools &&
PATH="${DEVUTILS_PREFIX:?}/bin:/usr/bin:/usr/sbin" &&
export PATH &&
\
GCC_VER="13.3.0" &&
MAKE_VER="4.4" &&
TAR_VER="1.35" &&
PATCH_VER="2.7.6" &&
COREUTILS_VER="9.4" &&
BINUTILS_VER="2.43" &&
OPENSSL_VER="3.3.1" &&
WGET_VER="1.24.5" &&
cd ${TAR_DIR:?} && WGET_OPT="--no-check-certificate" &&
\
# These packages are needed for building GCC. Stock binaries may be too old on some versions of Solaris \
wget ${WGET_OPT:?} https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VER:?}/gcc-${GCC_VER:?}.tar.gz &&
wget ${WGET_OPT:?} https://ftp.gnu.org/gnu/make/make-${MAKE_VER:?}.tar.gz &&
wget ${WGET_OPT:?} https://ftp.gnu.org/gnu/tar/tar-${TAR_VER:?}.tar.gz &&
wget ${WGET_OPT:?} https://ftp.gnu.org/gnu/patch/patch-${PATCH_VER}.tar.gz &&
wget ${WGET_OPT:?} https://ftp.gnu.org/gnu/coreutils/coreutils-${COREUTILS_VER}.tar.gz &&
wget ${WGET_OPT:?} https://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VER:?}.tar.gz &&
wget ${WGET_OPT:?} https://www.openssl.org/source/openssl-${OPENSSL_VER:?}.tar.gz &&
wget ${WGET_OPT:?} https://ftp.gnu.org/gnu/wget/wget-${WGET_VER:?}.tar.gz &&
\
# These packages are optional and only needed for testing GCC \
DEJAGNU_VER="1.6.3" &&
TCL_VER="8.6.14" &&
EXPECT_VER="5.45.4" &&
WGET_OPT="--no-check-certificate" &&
wget ${WGET_OPT:?} https://ftp.gnu.org/gnu/dejagnu/dejagnu-${DEJAGNU_VER:?}.tar.gz &&
wget ${WGET_OPT:?} https://prdownloads.sourceforge.net/tcl/tcl${TCL_VER:?}-src.tar.gz &&
wget ${WGET_OPT:?} https://sourceforge.net/projects/expect/files/Expect/${EXPECT_VER:?}/expect${EXPECT_VER:?}.tar.gz
\
# Unpack all packages \
cd ${SRC_DIR:?} &&
for i in $(ls ${TAR_DIR:?}); do gtar -xf ${TAR_DIR:?}/$i & done; wait


3. Download GCC prerequisites

GCC needs several prerequisites packages in order to build correctly. These include: GMP, MPFR, MPC, etc. We patch the download_prerequisites script to avoid errors on systems which cannot verify SSL certificates.

cd ${SRC_DIR:?}/gcc-${GCC_VER:?} &&
cp contrib/download_prerequisites contrib/download_prerequisites.orig &&
sed "s/fetch='wget'/fetch='wget --no-check-certificate'/g" contrib/download_prerequisites.orig > contrib/download_prerequisites &&
/bin/sh contrib/download_prerequisites


4.A Build GCC with Sun binutils

The script below configures and builds GCC with Sun binutils and installs new compilers under /opt/gcc-<version>_sun_binutils.

PREFIX specifies GCC installation prefix.
DEVUTILS_PREFIX contains various build tools needed for downloading, patching, configuring and building GCC.
BUILD_CC contains the bootstrap build compiler.

MAKE_JOBS=64 &&
MARCH="sparc64-sun-solaris2.11" &&
PREFIX="/opt/gcc-${GCC_VER:?}_sun_binutils" &&
DEVUTILS_PREFIX=/opt/gcc_build_tools &&
BUILD_CC="/opt/gcc" &&
PATH="${DEVUTILS_PREFIX:?}/bin:${BUILD_CC:?}/bin:/usr/bin:/usr/sbin" &&
CC="gcc" &&
CXX="g++" &&
unset LDFLAGS &&
export PATH CC CXX \
\
# Build and install GCC \
pkg="gcc-${GCC_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
${SRC_DIR:?}/${pkg:?}/configure --prefix="${PREFIX:?}" \
--build="${MARCH:?}" --host="${MARCH:?}" --target="${MARCH:?}" --with-cpu=v9 \
--enable-languages=c,c++,ada --enable-shared --enable-threads=posix \
--enable-bootstrap --enable-multilib --enable-obsolete --disable-nls \
--with-as="/usr/bin/as" --with-ld="/usr/bin/ld" &&
gmake --output-sync=target -j "${MAKE_JOBS:?}" && gmake install &&
\
# Perform final cleanup: \
rm -rf ${PREFIX:?}/share/info

# Run GCC tests (requires tcl, expect and dejagnu) \
# See https://gcc.gnu.org/install/test.html \
MAKE_JOBS=64 &&
PREFIX="/opt/gcc-${GCC_VER:?}_sun_binutils" &&
DEVUTILS_PREFIX=/opt/gcc_build_tools &&
PATH="${DEVUTILS_PREFIX:?}/bin:${PREFIX:?}/bin:/usr/bin:/usr/sbin" &&
CC="gcc" &&
CXX="g++" &&
LDFLAGS="" &&
export PATH CC CXX LDFLAGS &&
pkg="gcc-${GCC_VER:?}"; cd ${OBJ_DIR:?}/${pkg:?} &&
ulimit -s 32768 && gmake -j ${MAKE_JOBS:?} -k check

# Test results are in the following files
$ find . -name "*.sum"


4.B Build GCC with GNU binutils

The script below configures and builds GCC with GNU binutils and installs new compilers under /opt/gcc-<version>_gnu_binutils.

PREFIX specifies GCC installation prefix.
DEVUTILS_PREFIX contains various build tools needed for downloading, patching, configuring and building GCC.
BUILD_CC contains the bootstrap build compiler.

First, we build GNU binutils with bootstrap compiler. We use option --with-static-standard-libraries so that binutils do not depend on any bootstrap compiler's shared libraries.

Second, we build new version of GCC compilers. It is important that the directory with GNU binutils is located first in our PATH so that GCC configure script can correctly locate GNU as (assembler) and ld (linker) tools.

Third, we rebuild GNU binutils with shared standard libraries. We set LDFLAGS to hardcode the paths to new GCC compilers shared libraries.

🖙 Don't try to use binutils --enable-gold=default linker config option, this linker doesn't seem to work properly on SPARC Solaris when building GCC.

MAKE_JOBS=64 &&
MARCH="sparc64-sun-solaris2.11" &&
PREFIX="/opt/gcc-${GCC_VER:?}_gnu_binutils" &&
DEVUTILS_PREFIX=/opt/gcc_build_tools &&
BUILD_CC="/opt/gcc" &&
PATH="${PREFIX:?}/bin:${DEVUTILS_PREFIX:?}/bin:${BUILD_CC:?}/bin:/usr/bin:/usr/sbin" &&
CC="gcc" &&
CXX="g++" &&
unset LDFLAGS &&
export PATH CC CXX \
\
# Build and install temporary binutils with static standard libs \
pkg="binutils-${BINUTILS_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
${SRC_DIR:?}/${pkg:?}/configure --prefix=${PREFIX:?} \
--build="${MARCH:?}" --host="${MARCH:?}" --target="${MARCH:?}" \
--with-static-standard-libraries \
--enable-shared --enable-ld=default --enable-64-bit-bfd --disable-nls &&
gmake MAKEINFO=true -j "${MAKE_JOBS:?}" &&
gmake MAKEINFO=true -j "${MAKE_JOBS:?}" install &&
cd ../ && rm -rf ${pkg:?} &&
\
# Build and install GCC \
pkg="gcc-${GCC_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
${SRC_DIR:?}/${pkg:?}/configure --prefix="${PREFIX:?}" \
--build="${MARCH:?}" --host="${MARCH:?}" --target="${MARCH:?}" --with-cpu=v9 \
--enable-languages=c,c++,ada --enable-shared --enable-threads=posix \
--enable-bootstrap --enable-multilib --enable-obsolete --disable-nls \
--with-gnu-as --with-gnu-ld &&
gmake --output-sync=target -j "${MAKE_JOBS:?}" && gmake install &&
\
# Build and install final binutils with dynamic standard libs \
PATH="${DEVUTILS_PREFIX:?}/bin:${PREFIX:?}/bin:/usr/bin:/usr/sbin" &&
CC="gcc" &&
CXX="g++" &&
LDFLAGS="-Wl,--library-path=${PREFIX:?}/lib -Wl,-rpath=${PREFIX:?}/lib" &&
export PATH CC CXX LDFLAGS &&
\
pkg="binutils-${BINUTILS_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
${SRC_DIR:?}/${pkg:?}/configure --prefix=${PREFIX:?} --disable-nls \
--build="${MARCH:?}" --host="${MARCH:?}" --target="${MARCH:?}" \
--enable-shared --enable-ld=default --enable-64-bit-bfd --disable-nls &&
gmake MAKEINFO=true -j "${MAKE_JOBS:?}" &&
gmake MAKEINFO=true -j "${MAKE_JOBS:?}" install &&
\
# Perform final cleanup \
unset LDFLAGS &&
rm -rf ${PREFIX:?}/share/info

# Run GCC tests (requires tcl, expect and dejagnu) \
# See https://gcc.gnu.org/install/test.html \
MAKE_JOBS=64 &&
PREFIX="/opt/gcc-${GCC_VER:?}_gnu_binutils" &&
DEVUTILS_PREFIX=/opt/gcc_build_tools &&
PATH="${DEVUTILS_PREFIX:?}/bin:${PREFIX:?}/bin:/usr/bin:/usr/sbin" &&
CC="gcc" &&
CXX="g++" &&
LDFLAGS="" &&
export PATH CC CXX LDFLAGS &&
pkg="gcc-${GCC_VER:?}"; cd ${OBJ_DIR:?}/${pkg:?} &&
ulimit -s 32768 && gmake -j ${MAKE_JOBS:?} -k check

# Test results are in the following files
$ find . -name "*.sum"


5. Build GCC tools

It is useful to have a small set of self-contained build tools, with which new versions of GCC can be built. Many of these tools can be installed with Solaris native package management commands. This may not be an option with older and unsupported versions of Solaris, hence a process for building these tools manually is described below.

DEVUTILS_PREFIX is set to where build tools will be installed.
BUILD_CC is set to the base directory where current build compiler is located. There could be multiple compilers, hence set up /opt/gcc to be a symlink to the working compiler.

Note that CFLAGS and CXXFLAGS contain -static-libgcc -static-libstdc++ flags. This builds standalone tools which do not depend on GCC shared libraries. The build compiler can later be removed from the system and the tools should continue to work.

MAKE_JOBS=64 &&
MARCH="sparc64-sun-solaris2.11" &&
DEVUTILS_PREFIX=/opt/gcc_build_tools &&
BUILD_CC="/opt/gcc" &&
PATH="${DEVUTILS_PREFIX:?}/bin:${BUILD_CC:?}/bin:/usr/bin:/usr/sbin" &&
CC="gcc" &&
CXX="g++" &&
CFLAGS="-O2 -mcpu=v9 -static-libgcc -static-libstdc++" &&
CXXFLAGS="-O2 -mcpu=v9 -static-libgcc -static-libstdc++" &&
LDFLAGS="-Wl,-L${DEVUTILS_PREFIX:?}/lib -Wl,-R${DEVUTILS_PREFIX:?}/lib" &&
export PATH CC CXX CFLAGS CXXFLAGS LDFLAGS &&
\
# Build and install GNU make \
pkg="make-${MAKE_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
${SRC_DIR:?}/${pkg:?}/configure --prefix=${DEVUTILS_PREFIX:?} --disable-nls &&
./build.sh && ./make install && ln -sf make ${DEVUTILS_PREFIX:?}/bin/gmake &&
hash -r &&
\
# Build and install GNU tar \
pkg="tar-${TAR_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
FORCE_UNSAFE_CONFIGURE=1 ${SRC_DIR:?}/${pkg:?}/configure --prefix=${DEVUTILS_PREFIX:?} --disable-nls &&
gmake -j ${MAKE_JOBS:?} && gmake install &&
ln -s tar ${DEVUTILS_PREFIX:?}/bin/gtar &&
\
# Build and install GNU patch \
pkg="patch-${PATCH_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
${SRC_DIR:?}/${pkg:?}/configure --prefix=${DEVUTILS_PREFIX:?} --disable-nls &&
gmake -j ${MAKE_JOBS:?} && gmake install &&
\
# Build and Install subset of GNU coreutils (needed by GCC contrib/download_prerequisites script) \
pkg="coreutils-${COREUTILS_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
FORCE_UNSAFE_CONFIGURE=1 ${SRC_DIR:?}/${pkg:?}/configure --prefix=${DEVUTILS_PREFIX:?} --disable-nls &&
gmake -j ${MAKE_JOBS:?} && mkdir -p ${DEVUTILS_PREFIX:?}/bin &&
src/ginstall -c src/md5sum src/sha1sum src/sha512sum ${DEVUTILS_PREFIX:?}/bin &&
\
# Build and install OpenSSL (needed by wget) \
pkg="openssl-${OPENSSL_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
${SRC_DIR:?}/${pkg:?}/Configure --prefix=${DEVUTILS_PREFIX:?} --libdir=lib \
shared solaris64-sparcv9-gcc &&
gmake -j ${MAKE_JOBS:?} && gmake install_sw &&
\
# Build and install GNU wget (needed by GCC contrib/download_prerequisites script) \
pkg="wget-${WGET_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
OPENSSL_CFLAGS="-I${DEVUTILS_PREFIX:?}/include" \
OPENSSL_LIBS="-L${DEVUTILS_PREFIX:?}/lib -lssl -lcrypto" \
${SRC_DIR:?}/${pkg:?}/configure --prefix=${DEVUTILS_PREFIX:?} --with-ssl=openssl --disable-nls &&
gmake -j ${MAKE_JOBS:?} && gmake install &&
\
# These are only needed for testing GCC \
\
# Build and install tcl \
pkg="tcl${TCL_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
${SRC_DIR:?}/${pkg:?}/unix/configure --prefix=${DEVUTILS_PREFIX:?} &&
gmake -j ${MAKE_JOBS:?} && gmake install && gmake install-private-headers &&
ln -s tclsh* ${DEVUTILS_PREFIX:?}/bin/tclsh &&
\
# Build and install expect \
pkg="expect${EXPECT_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
${SRC_DIR:?}/${pkg:?}/configure --prefix=${DEVUTILS_PREFIX:?} \
--with-tcl=${DEVUTILS_PREFIX:?}/lib --with-tclinclude=${DEVUTILS_PREFIX:?}/include &&
gmake -j ${MAKE_JOBS:?} && gmake install &&
\
# Build and install dejagnu \
pkg="dejagnu-${DEJAGNU_VER:?}"; cd ${OBJ_DIR:?} &&
test ! -d ${pkg:?} && mkdir ${pkg:?}; cd ${pkg:?} &&
${SRC_DIR:?}/${pkg:?}/configure --prefix=${DEVUTILS_PREFIX:?} &&
gmake -j ${MAKE_JOBS:?} && gmake install

Tuesday, October 15, 2024

SPARC T4-2: SMI link failed memory link test

During the first boot up sequence, one of my SPARC T4-2 machines started logging hardware errors. This was a brand new machine, never used before, which I unpacked myself from a sealed box.

[CPU 0:0:0] NOTICE: Initializing MCU 0 [CPU 1:0:0] NOTICE: Initializing MCU 0 [CPU 0:0:0] NOTICE: Initializing MCU 1 [CPU 1:0:0] NOTICE: Initializing MCU 1 [CPU 0:0:0] NOTICE: SMI Channel 0, SB Mapping 0 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 1:0:0] NOTICE: SMI Channel 0, SB Mapping 0 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 0:0:0] NOTICE: SMI Channel 0, SB Mapping 1 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 1:0:0] NOTICE: SMI Channel 0, SB Mapping 1 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 0:0:0] NOTICE: SMI Channel 1, SB Mapping 0 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 1:0:0] NOTICE: SMI Channel 1, SB Mapping 0 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 0:0:0] NOTICE: SMI Channel 1, SB Mapping 1 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 1:0:0] NOTICE: SMI Channel 1, SB Mapping 1 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 1:0:0] NOTICE: SMI Channel 0, SB Mapping 0 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 1:0:0] NOTICE: SMI Channel 0, SB Mapping 1 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 1:0:0] NOTICE: SMI Channel 1, SB Mapping 0 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 1:0:0] NOTICE: SMI Channel 1, SB Mapping 1 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 0:0:0] NOTICE: SMI Channel 0, SB Mapping 0 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 0:0:0] NOTICE: SMI Channel 0, SB Mapping 1 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 0:0:0] NOTICE: SMI Channel 1, SB Mapping 0 -- ERRCNT: 0x0 LNERR: 0x0 [CPU 0:0:0] NOTICE: SMI Channel 1, SB Mapping 1 -- ERRCNT: 0xf LNERR: 0x188 [CPU 0:0:0] ERROR: N0.MCU1: SMI link failed memory link test. [CPU 0:0:0] ERROR: /SYS/MB/CMP0/MCU1 failed to initialize [CPU 0:0:0] NOTICE: Updating Config Information for Guest Manager [CPU 0:0:0] NOTICE: Issuing Host warm Reset [CPU 1:0:0] NOTICE: Reconfiguring System [CPU 0:0:0] NOTICE: Reconfiguring System [CPU 1:0:0] NOTICE: MCU0: Memory Capacity is 64GB [CPU 0:0:0] NOTICE: /SYS/MB/CMP0/MCU1 is disabled [CPU 0:0:0] NOTICE: MCU0: Memory Capacity is 64GB [CPU 1:0:0] NOTICE: MCU1: Memory Capacity is 64GB [CPU 0:0:0] ERROR: /SYS/MB/CMP0/L3T1: unusable (MCU disabled). Not configured [CPU 0:0:0] ERROR: /SYS/MB/CMP0/L3T3: unusable (MCU disabled). Not configured [CPU 0:0:0] ERROR: /SYS/MB/CMP0/L3T5: unusable (MCU disabled). Not configured [CPU 0:0:0] ERROR: /SYS/MB/CMP0/L3T7: unusable (MCU disabled). Not configured [CPU 0:0:0] ERROR: /SYS/MB/CMP1/L3T0: unusable (Global symmetry rules). Not configured [CPU 0:0:0] ERROR: /SYS/MB/CMP1/L3T2: unusable (Global symmetry rules). Not configured [CPU 0:0:0] ERROR: /SYS/MB/CMP1/L3T4: unusable (Global symmetry rules). Not configured [CPU 0:0:0] ERROR: /SYS/MB/CMP1/L3T6: unusable (Global symmetry rules). Not configured [CPU 1:0:0] ERROR: /SYS/MB/CMP1/MCU0: Not configured due to partial cache mode [CPU 0:0:0] ERROR: /SYS/MB/CMP0/CORE1: Not configured (Required L3T not available) [CPU 1:0:0] ERROR: /SYS/MB/CMP1/CORE1: Not configured (Required L3T not available) [CPU 0:0:0] ERROR: /SYS/MB/CMP0/CORE3: Not configured (Required L3T not available) [CPU 1:0:0] ERROR: /SYS/MB/CMP1/CORE3: Not configured (Required L3T not available) [CPU 0:0:0] ERROR: /SYS/MB/CMP0/CORE5: Not configured (Required L3T not available) [CPU 1:0:0] ERROR: /SYS/MB/CMP1/CORE5: Not configured (Required L3T not available) [CPU 0:0:0] ERROR: /SYS/MB/CMP0/CORE7: Not configured (Required L3T not available) [CPU 1:0:0] ERROR: /SYS/MB/CMP1/CORE7: Not configured (Required L3T not available) [CPU 0:0:0] NOTICE: Usable strands: 00ff00ff00ff00ff [CPU 1:0:0] NOTICE: Usable strands: 00ff00ff00ff00ff [CPU 0:0:0] NOTICE: System memory capacity is 128GB [CPU 0:0:0] NOTICE: Enabling caches [CPU 1:0:0] NOTICE: Enabling caches [CPU 0:0:0] NOTICE: L3 Banks Enabled: 55 [CPU 1:0:0] NOTICE: L3 Banks Enabled: aa

Similar issue was previously logged with Sun/Oracle, however access to the root cause and its resolution is blocked for anyone who does not have a valid support contract. How nice of them.

I assumed the issue was related to one of the memory riser boards, so I carried out the following steps:

  1. Cleared the fault in the system ILOM.
  2. Powered off the system and unplugged power cables. Unplugging is required since there is normally a standby power of 3.3V.
  3. Unplugged each memory riser, one by one, and then reseated individual memory modules.
Next time when I powered on the system, the fault was resolved and did not appear again.


Not sure of the actual root cause, possibly a bad connection with one of the memory modules. If anyone knows the details, let me know in the comments.