From 3ce1e4a5c64bc0d71d3e6ad9ece040e4884d0378 Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Fri, 7 Apr 2023 10:39:59 +0000 Subject: [PATCH] win32_build.sh: mingw-llvm support winpthreads is a library that emulates the pthreads API using Windows primitives. It's also used by the mingw/gcc libstdc++ for std::thread. The issue is that winpthreads isn't well maintained. There have been numerous bugs that haven't been addressed in years. Specifically, we've been hitting deadlocks because of the winpthreads rw lock implementation. This change will allow building Ceph for Windows using mingw/llvm, which uses libc++ and doesn't rely on winpthreads. Signed-off-by: Lucian Petrut --- README.windows.rst | 2 + mingw_conf.sh | 130 +++++++++++++++++++++++++++++--------------- win32_build.sh | 32 ++++++++++- win32_deps_build.sh | 49 +++++++++++++++-- 4 files changed, 161 insertions(+), 52 deletions(-) diff --git a/README.windows.rst b/README.windows.rst index 2c2419c08f7..b8065b6b282 100644 --- a/README.windows.rst +++ b/README.windows.rst @@ -29,6 +29,8 @@ Flag Description Default value ================= =============================== =============================== OS Host OS distribution, for mingw ubuntu (also valid: suse) and other OS specific settings. +TOOLCHAIN Mingw toolchain: mingw-llvm or mingw-llvm + mingw-gcc. CEPH_DIR The Ceph source code directory. The same as the script. BUILD_DIR The directory where the $CEPH_DIR/build generated artifacts will be diff --git a/mingw_conf.sh b/mingw_conf.sh index aa1ac941849..7c0d527e1e2 100644 --- a/mingw_conf.sh +++ b/mingw_conf.sh @@ -1,3 +1,5 @@ +#!/usr/bin/env bash + # MINGW Settings: # Due to inconsistencies between distributions, mingw versions, binaries, # and directories must be determined (or defined) prior to building. @@ -8,6 +10,16 @@ # * MINGW_CMAKE_FILE - if set, a cmake toolchain file will be created # * MINGW_POSIX_FLAGS - if set, Mingw Posix compatibility mode will be # enabled by defining the according flags. +# * USE_MINGW_LLVM - allows using the mingw llvm toolchain +# * MINGW_LLVM_DIR - allows specifying the mingw-llvm toolchain location. +# If unset, we'll use the default path from build.deps. + +SCRIPT_DIR="$(dirname "$BASH_SOURCE")" +SCRIPT_DIR="$(realpath "$SCRIPT_DIR")" + +if [[ -n $USE_MINGW_LLVM ]]; then + MINGW_LLVM_DIR=${MINGW_LLVM_DIR:-"$SCRIPT_DIR/build.deps/mingw-llvm"} +fi # -Common mingw settings- MINGW_PREFIX="x86_64-w64-mingw32-" @@ -17,60 +29,82 @@ MINGW_DLLTOOL="${MINGW_BASE}-dlltool" MINGW_WINDRES="${MINGW_BASE}-windres" MINGW_STRIP="${MINGW_BASE}-strip" MINGW_OBJCOPY="${MINGW_BASE}-objcopy" -# -Distribution specific mingw settings- -case "$OS" in - ubuntu) - mingwPosix="-posix" - mingwLibDir="/usr/lib/gcc" - mingwVersion="$(${MINGW_CPP}${mingwPosix} -dumpversion)" - mingwTargetLibDir="${mingwLibDir}/${MINGW_BASE}/${mingwVersion}" - mingwLibpthreadDir="/usr/${MINGW_BASE}/lib" - PTW32Include=/usr/share/mingw-w64/include - PTW32Lib=/usr/x86_64-w64-mingw32/lib - ;; - rhel) - mingwPosix="" - mingwLibDir="/usr/lib64/gcc" - mingwVersion="$(${MINGW_CPP}${mingwPosix} -dumpversion)" - mingwTargetLibDir="/usr/${MINGW_BASE}/sys-root/mingw/bin" - mingwLibpthreadDir="$mingwTargetLibDir" - PTW32Include=/usr/x86_64-w64-mingw32/sys-root/mingw/include - PTW32Lib=/usr/x86_64-w64-mingw32/sys-root/mingw/lib - ;; - suse) - mingwPosix="" - mingwLibDir="/usr/lib64/gcc" - mingwVersion="$(${MINGW_CPP}${mingwPosix} -dumpversion)" - mingwTargetLibDir="/usr/${MINGW_BASE}/sys-root/mingw/bin" - mingwLibpthreadDir="$mingwTargetLibDir" - PTW32Include=/usr/x86_64-w64-mingw32/sys-root/mingw/include - PTW32Lib=/usr/x86_64-w64-mingw32/sys-root/mingw/lib - ;; - *) - echo "$ID is unknown, automatic mingw configuration is not possible." - exit 1 - ;; -esac -# -Common mingw settings, dependent upon distribution specific settings- -MINGW_FIND_ROOT_LIB_PATH="${mingwLibDir}/\${TOOLCHAIN_PREFIX}/${mingwVersion}" -MINGW_CC="${MINGW_BASE}-gcc${mingwPosix}" -MINGW_CXX="${MINGW_BASE}-g++${mingwPosix}" + +if [[ -n $USE_MINGW_LLVM ]]; then + # This package isn't currently provided by Linux distributions, we're + # fetching it from Github. + export PATH="$MINGW_LLVM_DIR/bin:$PATH" + mingwPosix="" + mingwVersion="$(${MINGW_CPP}${mingwPosix} -dumpversion)" + mingwX64IncludeDir="$MINGW_LLVM_DIR/x86_64-w64-mingw32/include" + mingwX64BinDir="$MINGW_LLVM_DIR/x86_64-w64-mingw32/bin" + mingwX64LibDir="$MINGW_LLVM_DIR/x86_64-w64-mingw32/lib" + mingwTargetLibDir="$mingwX64BinDir" + mingwLibpthreadDir="$mingwX64BinDir" + PTW32Include="$mingwX64IncludeDir" + PTW32Lib="$mingwX64LibDir" + + MINGW_CC="${MINGW_BASE}-clang${mingwPosix}" + MINGW_CXX="${MINGW_BASE}-clang++${mingwPosix}" + + MINGW_FIND_ROOT_PATH="$MINGW_LLVM_DIR/x86_64-w64-mingw32" +else + # -Distribution specific mingw settings- + case "$OS" in + ubuntu) + mingwPosix="-posix" + mingwLibDir="/usr/lib/gcc" + mingwVersion="$(${MINGW_CPP}${mingwPosix} -dumpversion)" + mingwTargetLibDir="${mingwLibDir}/${MINGW_BASE}/${mingwVersion}" + mingwLibpthreadDir="/usr/${MINGW_BASE}/lib" + PTW32Include=/usr/share/mingw-w64/include + PTW32Lib=/usr/x86_64-w64-mingw32/lib + ;; + rhel) + mingwPosix="" + mingwLibDir="/usr/lib64/gcc" + mingwVersion="$(${MINGW_CPP}${mingwPosix} -dumpversion)" + mingwTargetLibDir="/usr/${MINGW_BASE}/sys-root/mingw/bin" + mingwLibpthreadDir="$mingwTargetLibDir" + PTW32Include=/usr/x86_64-w64-mingw32/sys-root/mingw/include + PTW32Lib=/usr/x86_64-w64-mingw32/sys-root/mingw/lib + ;; + suse) + mingwPosix="" + mingwLibDir="/usr/lib64/gcc" + mingwVersion="$(${MINGW_CPP}${mingwPosix} -dumpversion)" + mingwTargetLibDir="/usr/${MINGW_BASE}/sys-root/mingw/bin" + mingwLibpthreadDir="$mingwTargetLibDir" + PTW32Include=/usr/x86_64-w64-mingw32/sys-root/mingw/include + PTW32Lib=/usr/x86_64-w64-mingw32/sys-root/mingw/lib + ;; + *) + echo "$ID is unknown, automatic mingw configuration is not possible." + exit 1 + ;; + esac + MINGW_CC="${MINGW_BASE}-gcc${mingwPosix}" + MINGW_CXX="${MINGW_BASE}-g++${mingwPosix}" + + # -Common mingw settings, dependent upon distribution specific settings- + MINGW_FIND_ROOT_LIB_PATH="${mingwLibDir}/${MINGW_BASE}/${mingwVersion}" + MINGW_FIND_ROOT_PATH="/usr/${MINGW_BASE} ${MINGW_FIND_ROOT_LIB_PATH}" +fi # End MINGW configuration if [[ -n $MINGW_CMAKE_FILE ]]; then cat > $MINGW_CMAKE_FILE <> $MINGW_CMAKE_FILE <&2 + exit 1 + fi + tar xJf mingw-llvm.tar.xz + rm mingw-llvm.tar.xz + # Remove the version from the mingw-llvm dirname, making it easier to locate + # and avoiding MAX_PATH issues with WSL. + mv `basename $mingwLlvmUrl | sed 's/\.tar\..*//g'` $mingwLlvmDir +fi + MINGW_CMAKE_FILE="$DEPS_DIR/mingw.cmake" source "$SCRIPT_DIR/mingw_conf.sh" @@ -148,17 +171,33 @@ echo "Building boost." cd $depsSrcDir if [[ ! -d $boostSrcDir ]]; then echo "Downloading boost." - wget -qO- $boostUrl | tar xz + wget -q -O boost.tar.gz $boostUrl + checksum=`sha256sum boost.tar.gz | cut -d ' ' -f 1` + if [[ "$boostSha256Sum" != "$checksum" ]]; then + echo "Invalid boost checksum: $checksum" >&2 + exit 1 + fi + tar xzf boost.tar.gz + rm boost.tar.gz fi cd $boostSrcDir -echo "using gcc : mingw32 : ${MINGW_CXX} ;" > user-config.jam + +if [[ -n $USE_MINGW_LLVM ]]; then + b2toolset="clang" + echo "using clang : : ${MINGW_CXX} ;" > user-config.jam +else + b2toolset="gcc-mingw32" + echo "using gcc : mingw32 : ${MINGW_CXX} ;" > user-config.jam +fi # Workaround for https://github.com/boostorg/thread/issues/156 # Older versions of mingw provided a different pthread lib. sed -i 's/lib$(libname)GC2.a/lib$(libname).a/g' ./libs/thread/build/Jamfile.v2 -sed -i 's/mthreads/pthreads/g' ./tools/build/src/tools/gcc.jam -sed -i 's/pthreads/mthreads/g' ./tools/build/src/tools/gcc.jam +if [[ -z $USE_MINGW_LLVM ]]; then + sed -i 's/mthreads/pthreads/g' ./tools/build/src/tools/gcc.jam + sed -i 's/pthreads/mthreads/g' ./tools/build/src/tools/gcc.jam +fi export PTW32_INCLUDE=${PTW32Include} export PTW32_LIB=${PTW32Lib} @@ -197,7 +236,7 @@ EOL ./bootstrap.sh -./b2 install --user-config=user-config.jam toolset=gcc-mingw32 \ +./b2 install --user-config=user-config.jam toolset=$b2toolset \ target-os=windows release \ link=static,shared \ threadapi=win32 --prefix=$boostDir \ -- 2.39.5