diff --git a/build-scripts/configure b/build-scripts/configure index 931fa0319..a8ef9b9e7 100755 --- a/build-scripts/configure +++ b/build-scripts/configure @@ -72,7 +72,7 @@ case "$WITH_SYSTEMD" in esac # RHEL 8 requires an SELinux policy -if [ "x$OS" = "xrhel" ] && [ "${VER%\.*}" -gt "7" ]; then +if [ "x$OS" = "xrhel" ] && [ "${OS_VERSION%\.*}" -gt "7" ]; then var_append ARGS "--with-selinux-policy" fi diff --git a/build-scripts/detect-environment b/build-scripts/detect-environment index 6b3a14e68..c5787c66d 100644 --- a/build-scripts/detect-environment +++ b/build-scripts/detect-environment @@ -9,12 +9,15 @@ if [ "$_IS_FUNCTIONS_SOURCED" != yes ] then - echo 'FATAL: You must source "functions" script before "detect-environment"!' - exit 100 + echo 'FATAL: You must source "functions" script before "detect-environment"!' + exit 100 fi - -detect_labels() +# Detects and sets the CROSS_TARGET environment variable based on patterns +# in the label variable (see labels.txt), specifically for MinGW cross- +# compilation targets. However, if CROSS_TARGET is already set in the +# environment it will take precedence. +detect_cross_target() { case "$label" in *_x86_64_mingw*) @@ -26,197 +29,195 @@ detect_labels() export CROSS_TARGET ;; esac + + if [ -n "$CROSS_TARGET" ]; then + echo "Detected cross target $CROSS_TARGET" + else + echo "No cross target detected" + fi } +# This function exports operating system specific variables: +# - OS usually contains a specific distribution (e.g. Debian) +# - OS_VERSION operating system version (but is not always defined) +# +# Furthermore, the following variable is set, but it's not exported: +# - OS_FAMILY usually contains the kernel name (e.g. Linux) detect_os() { case "$CROSS_TARGET" in '') + # The UNAME_S, UNAME_R and UNAME_V variables are set in the "functions" + # script from the command substitution of `uname -s`, `uname -r` and + # `uname -v` which outputs the kernel name, the kernel release and the + # kernel version respectively. + case "$UNAME_S" in - Linux) + Linux) OS_FAMILY=linux - detect_distribution;; - SunOS) + detect_distribution + ;; + SunOS) OS_FAMILY=solaris OS=solaris - OS_VERSION=`echo $UNAME_R | sed -e 's/^5\.//'` + OS_VERSION=$(echo "$UNAME_R" | sed -e 's/^5\.//') ;; - AIX) + AIX) OS_FAMILY=aix - OS_VERSION=`uname -v`.$UNAME_R + OS_VERSION=$(uname -v).$UNAME_R OS=aix + # LIBPATH on AIX serves the same function as LD_LIBRARY_PATH on + # Linux. However, Java also uses this environment variable, and it + # apparently messes with the library look-ups during packaging. This + # line definitely doesn't belong here. But I'll leave it for now. unset LIBPATH ;; - Darwin) + Darwin) OS_FAMILY=darwin - OS=darwin;; - FreeBSD) + OS=darwin + ;; + FreeBSD) OS_FAMILY=freebsd - OS=freebsd;; - NetBSD) + OS=freebsd + OS_VERSION=$UNAME_R + ;; + NetBSD) OS_FAMILY=netbsd - OS=netbsd;; + OS=netbsd + ;; HP-UX) OS_FAMILY=hpux - OS=hpux;; - *) - echo "Unable to detect operating system: $UNAME_S" - exit 42;; + OS=hpux + OS_VERSION=$UNAME_R + ;; + *) + echo "Unable to detect operating system: $UNAME_S" + exit 42 + ;; esac ;; *-mingw) OS_FAMILY=mingw - OS=mingw;; + OS=mingw + ;; *) echo "Unknown cross-compilation target: $CROSS_TARGET" - exit 42;; + exit 42 + ;; esac + echo "Detected OS $OS $OS_VERSION" export OS OS_VERSION } +# The uname command does not reveal the specific distribution on Linux. Hence, +# we'll need to parse it from different files located in the /etc/ directory. +# Unfortunately, there is no standard across the existing distributions. Thus, +# this is going to be a bit messy. detect_distribution() { if [ -f /etc/redhat-release ]; then REL=$(cat /etc/redhat-release) case "$REL" in "CentOS "*) - VER="$(echo "$REL" | sed -e 's/^CentOS.* release \([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/')" - if ! echo "$VER" | egrep '^[0-9]+\.[0-9]+$' > /dev/null - then - echo "Unknown CentOS version: $VER" - exit 42 - fi - + # Example output for CentOS: + # CentOS Linux release 7.6.1810 (Core) OS=centos - OS_VERSION="$VER" ;; - "Red Hat Enterprise Linux AS release "*) - VER=${REL#Red Hat Enterprise Linux AS release } - case "$VER" in - [0-9]" "*) - MAJOR=${VER%% *};; - *) - echo "Unknown RHEL AS major version: $VER" - exit 42;; - esac - - case "$VER" in - *Update" "[0-9]")") - MINOR=${VER#*Update } - MINOR=${MINOR%\)};; - *) - echo "Unknnown RHEL AS minor version: $VER" - exit 42;; - esac - + "Red Hat Enterprise Linux "*) + # Example output for RHEL: + # Red Hat Enterprise Linux release 8.10 (Ootpa) OS=rhel - OS_VERSION="$MAJOR.$MINOR" ;; - "Red Hat Enterprise Linux Server release "*) - VER=${REL#Red Hat Enterprise Linux Server release } - VER=${VER% \(*}; - if ! echo "$VER" | egrep '^[0-9]+.[0-9]+$' > /dev/null - then - echo "Unknown RHEL Server version: $VER" - exit 42 - fi - - OS=rhel - OS_VERSION="$VER" + *) + echo "Error: Could not determine Linux distro from /etc/redhat-release: $REL" + exit 42 ;; + esac - "Red Hat Enterprise Linux release "*) - VER=${REL#Red Hat Enterprise Linux release } - VER=${VER% \(*}; - if ! echo "$VER" | egrep '^[0-9]+.[0-9]+$' > /dev/null - then - echo "Unknown RHEL Server version: $VER" - exit 42 - fi + # Common for all of these is that the version number starts just after the + # substring 'release '. Hence we reset the match (with \K) just after + # substring and extract the major and minor version. + version_string=$(echo "$REL" | grep -oP 'release \K\d+\.\d+') - OS=rhel - OS_VERSION="$VER" - ;; + # Make sure we actually found a match + if [ -z "$version_string" ]; then + echo "Error: Could not determine version number from /etc/redhat-release: $REL" + exit 42 + fi + OS_VERSION=$version_string - *) - echo "Unknown RedHat-like distribution: $REL" - exit 42;; - esac elif [ -f /etc/lsb-release ] && grep -q Ubuntu /etc/lsb-release; then + # This file was introduced by Linux Standard Base (LSB) which an attempt to + # standardize the Linux ecosystem. Unfortunately it was not adopted by many + # Linux distributions. Ubuntu dropped the support for LSB in 2015. However, + # the /etc/lsb-release file is still available as of Ubuntu 24. + # + # It might be naive to assume the file will continue to exist and that the + # existence of the file is only present in Ubuntu. Hence, if this breaks in + # the future, you'll know why. + # + # Example output of /etc/lsb-release: + # + # DISTRIB_ID=Ubuntu + # DISTRIB_RELEASE=24.04 + # DISTRIB_CODENAME=noble + # DISTRIB_DESCRIPTION="Ubuntu 24.04.2 LTS" + + # Get the line containing 'DISTRIB_RELEASE=' REL=$(grep DISTRIB_RELEASE= /etc/lsb-release) + + # Remove the 'DISTRIB_RELEASE=' part REL=${REL#DISTRIB_RELEASE=} + + # Verify that we can find a valid version number case "$REL" in - [0-9].[0-9][0-9]|[0-9][0-9].[0-9][0-9]) + [0-9][0-9].[0-9][0-9]) ;; *) echo "Unknown Ubuntu release: $REL" - exit 42;; + exit 42 + ;; esac OS=ubuntu OS_VERSION="$REL" elif [ -f /etc/debian_version ]; then + # This file contains only the version number. + # + # Example output of /etc/debian_version + # 12.11 + REL=$(cat /etc/debian_version) - if ! echo "$REL" | egrep '^[0-9]+\.[0-9]+(\.[0-9]+)?$' > /dev/null + if ! echo "$REL" | grep -E '^[0-9]+\.[0-9]+(\.[0-9]+)?$' > /dev/null then - case "$REL" in - wheezy*) - REL=7.0 - ;; - jessie*) - REL=8.0 - ;; - stretch*) - REL=9.0 - ;; - buster*) - REL=10.0 - ;; - *) - echo "Unable to detect version of Debian: $REL" - exit 42;; - esac + echo "Unable to detect version of Debian: $REL" + exit 42 fi OS=debian OS_VERSION="$REL" - elif [ -f /etc/SuSE-release ]; then - # This file is gone starting with suse 13 or something. This whole section - # can be removed when support for suse 12 and lower is dropped. I wish to - # see that day. - REL=$(head -n1 /etc/SuSE-release) - case "$REL" in - "SUSE Linux Enterprise Server "*) - MAJOR=$(grep '^VERSION' /etc/SuSE-release | awk '{print $3}') - MINOR=$(grep '^PATCHLEVEL' /etc/SuSE-release | awk '{print $3}') - - if [ -z "$MAJOR" -o -z "$MINOR" ]; then - echo "Unable to detect version of SLES: $MAJOR.$MINOR" - fi - - OS=sles - OS_VERSION="$MAJOR.$MINOR" - ;; - "openSUSE "*) - VERSION=$(grep '^VERSION' /etc/SuSE-release | awk '{print $3}') - OS=opensuse - OS_VERSION="$VERSION" - ;; - *) - echo "Unknown SUSE distribution: $REL" - exit 42;; - esac elif [ -f /etc/os-release ]; then # see https://en.opensuse.org/SDB:Find_openSUSE_version for rules of # parsing this file + + # Example output for /etc/os-release: + # + # NAME="SLES" + # VERSION="12-SP5" + # VERSION_ID="12.5" + # PRETTY_NAME="SUSE Linux Enterprise Server 12 SP5" + # ID="sles" + # ANSI_COLOR="0;32" + # CPE_NAME="cpe:/o:suse:sles:12:sp5" + os="$(sh -c ". /etc/os-release; echo \$ID")" ver="$(sh -c ". /etc/os-release; echo \$VERSION_ID")" if [ "$os" = "sles" ]; then OS=sles OS_VERSION="$ver" - fi - if expr "$os" : "opensuse" >/dev/null; then + elif expr "$os" : "opensuse" >/dev/null; then + # If the string begins with "opensuse", then strip the remaining part. It # can be "opensuse-leap" or "opensuse-tumbleweed" OS=opensuse OS_VERSION="$ver" @@ -234,6 +235,10 @@ detect_distribution() fi } +# This function determines which dependency packaging scripts shall be used +# based on the operating system and available packaging tools. E.g., if rpm is +# detected, then the "pkg-build-rpm" script will be called from the +# "install-dependencies" script. detect_packaging() { if [ -f /bin/rpm ]; then @@ -256,115 +261,150 @@ detect_packaging() case "$OS" in aix) - PACKAGING=lpp;; + PACKAGING=lpp + ;; mingw) - PACKAGING=msi;; + PACKAGING=msi + ;; *) PACKAGING=$DEP_PACKAGING;; esac + echo "Detected dependency packaging $DEP_PACKAGING" + echo "Detected packaging $PACKAGING" export DEP_PACKAGING PACKAGING } +# This function determines which architecture to build for based on the system +# we're building on. Unless we are cross compiling, then it's determined by the +# CROSS_TARGET variable. detect_arch() { case "$DEP_PACKAGING" in deb) - ARCH=`dpkg --print-architecture`;; + ARCH=$(dpkg --print-architecture) + ;; rpm) - ARCH=`rpm --eval '%{_arch}'`;; + ARCH=$(rpm --eval '%{_arch}') + ;; solaris) case $UNAME_M in sun*) - ARCH=sparc;; + ARCH=sparc + ;; i86pc) - ARCH=i86pc;; + ARCH=i86pc + ;; *) - echo "Unknown Solaris architecture: $UNAME_M";; - esac;; + echo "Unknown Solaris architecture: $UNAME_M" + ;; + esac + ;; freebsd) ARCH=$UNAME_M - OS_VERSION=$UNAME_R ;; + ;; hpux) ARCH=$UNAME_M - OS_VERSION=$UNAME_R ;; + ;; *) echo "Unknown packaging system" - exit 42;; + exit 42 + ;; esac + # Windows is build on Debian. Hence we need to determine the architecture + # based on the 'CROSS_TARGET' variable which is derived from the 'label' + # variable instead of the system that we are building on. case "$CROSS_TARGET" in '') ;; x86-*) - ARCH=x86;; + ARCH=x86 + ;; x64-*) - ARCH=x64;; + ARCH=x64 + ;; *) echo "Unknown cross-compilation target: $CROSS_TARGET" - exit 42;; + exit 42 + ;; esac + echo "Detected architecture $ARCH" export ARCH } +# This function detects the path to various tools needed by the build system. +# It's useful if the specified tool is not in PATH, or if the PATH resolution +# picks up the wrong tool, or if e.g. gmake is preferred over make. detect_tools() { # We look for GNU Make because # various dependencies have various requirements - MAKE=`func_whereis gmake make` + MAKE=$(func_whereis gmake make) if $MAKE -v | grep GNU then export MAKE + echo "Detected make path $MAKE" else - fatal "GNU Make not found" + echo "Error: GNU Make not found" + exit 42 fi - if [ "x$OS" = "xaix" ] && [ "x$OS_VERSION" = "x5.3" ]; then - RPMBUILD_CMD=rpm - else - RPMBUILD_CMD=rpmbuild - fi - export RPMBUILD_CMD + export RPMBUILD_CMD=rpmbuild - FUSER=`func_whereis fuser` + # fuser displays the PIDs of processes using specified files or file + # systems. We use it to kill processes that can mess with the build process. + FUSER=$(func_whereis fuser) export FUSER + echo "Detected fuser path $FUSER" - PATCH=`func_whereis gpatch patch` + # We use it to submit patches to the dependencies. + PATCH=$(func_whereis gpatch patch) export PATCH + echo "Detected patch path $PATCH" } +# This function appends the -j/--jobs option to the MAKEFLAGS environment +# variable based on the number of cores. However, the variable is overwritten in +# the "install-dependencies" script. I created a ticket fix this (see +# ENT-13041). detect_cores() { case "$OS_FAMILY" in aix) echo "Detected OS family is aix" - NUM_CORES="$(lscfg | grep proc | wc -l)";; + NUM_CORES="$(lscfg | grep -c proc)" + ;; solaris) echo "Detected OS family is solaris" - NUM_CORES="$(psrinfo |wc -l)";; + NUM_CORES="$(psrinfo |wc -l)" + ;; linux) echo "Detected OS family is linux" - NUM_CORES="$(cat /proc/cpuinfo | grep '^processor' | wc -l)";; + NUM_CORES="$(grep -c '^processor' /proc/cpuinfo)" + ;; hpux) echo "Detected OS family is hpux" - NUM_CORES="$(ioscan -k -C processor |grep processor | wc -l)";; + NUM_CORES="$(ioscan -k -C processor | grep -c processor)" + ;; *) echo "Detected OS family is UNKNOWN, defaulting amount of CPU cores to 1" - NUM_CORES=1;; + NUM_CORES=1 + ;; esac # Make number of jobs one higher than core count, to account for I/O, network, etc. echo "Detected amount of CPU cores is $NUM_CORES" - MAKEFLAGS="${MAKEFLAGS:--j$(($NUM_CORES + 1))}" + MAKEFLAGS="${MAKEFLAGS:--j$((NUM_CORES + 1))}" export MAKEFLAGS } detect_environment() { - detect_labels + detect_cross_target detect_os detect_packaging detect_arch @@ -386,7 +426,7 @@ detect_environment echo echo echo "==================== Current environment ========================" -env +env | grep -E "^(label|CROSS_TARGET|UNAME|OS|OS_VERSION|DEP_PACKAGING|PACKAGING|ARCH|MAKE|FUSER|PATCH|MAKEFLAGS)=" echo "=================================================================" echo echo diff --git a/build-scripts/install-dependencies b/build-scripts/install-dependencies index 053d1efd6..64dd7cb11 100755 --- a/build-scripts/install-dependencies +++ b/build-scripts/install-dependencies @@ -8,6 +8,8 @@ PATH=$PATH:$BASEDIR/buildscripts/deps-packaging # Not all dependencies support building in parallel. +# TODO: Investigate if this is still the case or disable parallel jobs for only +# the dependencies that not support it. (ENT-13041) MAKEFLAGS=-j1 set -x diff --git a/build-scripts/package b/build-scripts/package index a026cdaca..9dc875336 100755 --- a/build-scripts/package +++ b/build-scripts/package @@ -178,7 +178,7 @@ case "$PACKAGING" in # - argv[2] = a b # Also note that $RPMBUILD_OPTIONS might have spaces # which must be preserved - eval "$RPMBUILD_CMD" -bb \ + eval rpmbuild -bb \ --define "'_topdir $BASEDIR/$PKG'" \ --define "'buildprefix $BUILDPREFIX'" \ --define "'_basedir $BASEDIR'" \ diff --git a/deps-packaging/pkg-build-rpm b/deps-packaging/pkg-build-rpm index 4f71b4196..2039562aa 100755 --- a/deps-packaging/pkg-build-rpm +++ b/deps-packaging/pkg-build-rpm @@ -112,7 +112,7 @@ fi # example cmd --define 'a b': # - argv[1] = --define # - argv[2] = a b -eval $RPMBUILD_CMD -bb \ +eval rpmbuild -bb \ --define "'_topdir $BASEDIR/$PKGNAME'" \ --define "'version $VERSION'" \ --define "'buildprefix $BUILDPREFIX'" \