From af615aa30bbdc7fb0f4a26a7ff9ed236954eeaf4 Mon Sep 17 00:00:00 2001 From: Matthew Brett Date: Mon, 20 Jun 2022 17:02:27 +0100 Subject: [PATCH 1/2] Refactor main build script Allow use of some command line arguments. Make defaults for everything. Pass LDFLAGS --- tools/build_openblas.sh | 108 +++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 39 deletions(-) diff --git a/tools/build_openblas.sh b/tools/build_openblas.sh index 59f72f88..ea1a6a9c 100644 --- a/tools/build_openblas.sh +++ b/tools/build_openblas.sh @@ -1,40 +1,62 @@ #!/bin/bash # Build script for OpenBLAS on Windows -# Expects environment variables: -# OPENBLAS_ROOT -# OPENBLAS_COMMIT -# BUILD_BITS -# START_DIR -# Expects "lib.exe" and "gcc" to be on the path +# +# Usage: build_openblas.sh [openblas_root [build_bits [if_bits]]] +# +# e.g build_openblas.sh c:\\opt 64 32 +# +# Uses the optional environment variables. We always prefer command line argument +# values above to environment variable values: +# +# OPENBLAS_ROOT (default directory root for binaries, unspecified -> c:\opt). +# BUILD_BITS (default binary architecture, 32 or 64, unspec -> 64). +# INTERFACE64 (1 for 64-bit interface, anything else or undefined for 32, +# This gives the default value if if_bits not specified above). +# START_DIR (directory containing OpenBLAS source, unspec -> .. from here) +# OPENBLAS_COMMIT (unspec -> current submodule commit) +# LDFLAGS (example: "-lucrt -static -static-libgcc") +# +# Expects at leasts these binaries on the PATH: +# realpath, cygpath, zip, gcc, make, ar, dlltool +# usually as part of an msys installation. -set -ex +# Convert to Unix-style path +openblas_root="$(cygpath ${1:-${OPENBLAS_ROOT:-c:\\opt}})" +build_bits="${2:-${BUILD_BITS:-64}}" +if [ "$INTERFACE64" == "1" ]; then if_default=64; else if_default=32; fi +if_bits=${3:-${if_default}} +# Our directory for later copying +if [ -z "$START_DIR" ]; then + our_wd="$(realpath $(dirname "${BASH_SOURCE[0]}")/..)" +else + our_wd=$(cygpath "$START_DIR") +fi -# Paths in Unix format -OPENBLAS_ROOT=$(cygpath "$OPENBLAS_ROOT") +echo "Building from $our_wd, to $openblas_root" +echo "Binaries are $build_bits bit, interface is $if_bits bit" +echo "Using gcc at $(which gcc), --version:" +gcc --version -# Our directory for later copying -our_wd=$(cygpath "$START_DIR") -cd $our_wd # Make output directory for build artifacts -rm -rf builds -mkdir builds +builds_dir="$our_wd/builds" +rm -rf $builds_dir +mkdir $builds_dir -cd OpenBLAS +cd "${our_wd}/OpenBLAS" git submodule update --init --recursive -# Check which gcc we're using -which gcc -gcc --version # Get / clean code git fetch origin -git checkout $OPENBLAS_COMMIT +if [ -n "$OPENBLAS_COMMIT" ]; then + git checkout $OPENBLAS_COMMIT +fi git clean -fxd git reset --hard -rm -rf $OPENBLAS_ROOT/$BUILD_BITS +rm -rf $openblas_root/$build_bits # Set architecture flags -if [ "$BUILD_BITS" == 64 ]; then +if [ "$build_bits" == 64 ]; then march="x86-64" # https://csharp.wekeepcoding.com/article/10463345/invalid+register+for+.seh_savexmm+in+Cygwin extra="-fno-asynchronous-unwind-tables" @@ -51,9 +73,9 @@ cflags="-O2 -march=$march -mtune=generic $extra" fflags="$fextra $cflags -frecursive -ffpe-summary=invalid,zero" # Set suffixed-ILP64 flags -if [ "$INTERFACE64" == "1" ]; then - interface64_flags="INTERFACE64=1 SYMBOLSUFFIX=64_" - SYMBOLSUFFIX=64_ +if [ "$if_bits" == "64" ]; then + SYMBOLSUFFIX="64_" + interface64_flags="INTERFACE64=1 SYMBOLSUFFIX=${SYMBOLSUFFIX}" # We override FCOMMON_OPT, so we need to set default integer manually fflags="$fflags -fdefault-integer-8" else @@ -66,42 +88,50 @@ OPENBLAS_VERSION=$(git describe --tags) # Build OpenBLAS # Variable used in creating output libraries export LIBNAMESUFFIX=${OPENBLAS_VERSION}-${GCC_TAG} -make BINARY=$BUILD_BITS DYNAMIC_ARCH=1 USE_THREAD=1 USE_OPENMP=0 \ +make BINARY=$build_bits DYNAMIC_ARCH=1 USE_THREAD=1 USE_OPENMP=0 \ NUM_THREADS=24 NO_WARMUP=1 NO_AFFINITY=1 CONSISTENT_FPCSR=1 \ BUILD_LAPACK_DEPRECATED=1 TARGET=PRESCOTT BUFFERSIZE=20\ + LDFLAGS="$LDFLAGS" \ COMMON_OPT="$cflags" \ FCOMMON_OPT="$fflags" \ MAX_STACK_ALLOC=2048 \ $interface64_flags -make PREFIX=$OPENBLAS_ROOT/$BUILD_BITS $interface64_flags install +make PREFIX=$openblas_root/$build_bits $interface64_flags install DLL_BASENAME=libopenblas${SYMBOLSUFFIX}_${LIBNAMESUFFIX} -if [ "$INTERFACE64" == "1" ]; then +if [ "$if_bits" == "64" ]; then # OpenBLAS does not build a symbol-suffixed static library on Windows: # do it ourselves set -x # echo commands static_libname=$(find . -maxdepth 1 -type f -name '*.a' \! -name '*.dll.a' | tail -1) make -C exports $interface64_flags objcopy.def objcopy --redefine-syms exports/objcopy.def "${static_libname}" "${static_libname}.renamed" - cp -f "${static_libname}.renamed" "$OPENBLAS_ROOT/$BUILD_BITS/lib/${static_libname}" - cp -f "${static_libname}.renamed" "$OPENBLAS_ROOT/$BUILD_BITS/lib/${DLL_BASENAME}.a" + cp -f "${static_libname}.renamed" "$openblas_root/$build_bits/lib/${static_libname}" + cp -f "${static_libname}.renamed" "$openblas_root/$build_bits/lib/${DLL_BASENAME}.a" set +x fi -cd $OPENBLAS_ROOT +cd $openblas_root # Copy library link file for custom name -cd $BUILD_BITS/lib +cd $build_bits/lib +cp ${our_wd}/OpenBLAS/exports/${DLL_BASENAME}.def ${DLL_BASENAME}.def # At least for the mingwpy wheel, we have to use the VC tools to build the # export library. Maybe fixed in later binutils by patch referred to in # https://sourceware.org/ml/binutils/2016-02/msg00002.html -cp ${our_wd}/OpenBLAS/exports/${DLL_BASENAME}.def ${DLL_BASENAME}.def -"lib.exe" /machine:${vc_arch} /def:${DLL_BASENAME}.def +# "lib.exe" /machine:${vc_arch} /def:${DLL_BASENAME}.def +# Maybe this will now work (after 2016 patch above). +dlltool --input-def ${DLL_BASENAME}.def \ + --output-exp ${DLL_BASENAME}.exp \ + --dllname ${DLL_BASENAME}.dll \ + --output-lib ${DLL_BASENAME}.lib +# Replace the DLL name with the generated name. +sed -i "s/ -lopenblas$/ -l${DLL_BASENAME:3}/g" pkgconfig/openblas.pc cd ../.. # Build template site.cfg for using this build -cat > ${BUILD_BITS}/site.cfg.template << EOF +cat > ${build_bits}/site.cfg.template << EOF [openblas${SYMBOLSUFFIX}] libraries = $DLL_BASENAME -library_dirs = {openblas_root}\\${BUILD_BITS}\\lib -include_dirs = {openblas_root}\\${BUILD_BITS}\\include +library_dirs = {openblas_root}\\${build_bits}\\lib +include_dirs = {openblas_root}\\${build_bits}\\include EOF -ZIP_NAME="openblas${SYMBOLSUFFIX}-${OPENBLAS_VERSION}-${plat_tag}-${GCC_TAG}.zip" -zip -r $ZIP_NAME $BUILD_BITS -cp $ZIP_NAME $our_wd/builds +zip_name="openblas${SYMBOLSUFFIX}-${OPENBLAS_VERSION}-${plat_tag}-${GCC_TAG}.zip" +zip -r $zip_name $build_bits +cp $zip_name ${builds_dir} From df2b6938bfbaddb5255c81a02569ac0983e65b95 Mon Sep 17 00:00:00 2001 From: Matthew Brett Date: Mon, 20 Jun 2022 17:03:36 +0100 Subject: [PATCH 2/2] Refactor build to use Powershell Refactor build_gfortran to run builds in own directory. --- .github/workflows/build.yml | 94 ++++++++++++++----------------------- .gitignore | 2 +- OpenBLAS | 2 +- tools/build_gfortran.sh | 17 +++++-- 4 files changed, 50 insertions(+), 65 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1773b4f0..f951d784 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,11 +1,5 @@ -# This is a basic workflow to help you get started with Actions - name: Windows build -defaults: - run: - shell: bash - on: push: branches: [ master ] @@ -15,13 +9,16 @@ on: env: OPENBLAS_COMMIT: "bfd9c1b58cd3" OPENBLAS_ROOT: "c:\\opt" + # Preserve working directory for calls into bash + CHERE_INVOKING: "yes" + BASH_PATH: "c:\\rtools40\\usr\\bin\\bash" jobs: build: strategy: matrix: BUILD_BITS: [64, 32] - INTERFACE64: ['1', ''] + INTERFACE64: ['1', '0'] os: [windows-latest] exclude: - BUILD_BITS: 32 @@ -31,65 +28,46 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: ilammy/msvc-dev-cmd@v1 - - - name: Setup + - name: install-rtools run: | - BITS=${{ matrix.BUILD_BITS }} - echo "BUILD_BITS=$BITS" >> $GITHUB_ENV; - if [ "$BITS" == "32" ]; then - echo "PLAT=i686" >> $GITHUB_ENV; - else - echo "PLAT=x86_64" >> $GITHUB_ENV; - fi - echo "START_DIR=$PWD" >> $GITHUB_ENV; - choco install -y zip - - - run: | - choco install -y mingw --forcex86 --force --version=8.1.0 - choco install -y make - name: Install 32-bit mingw - shell: powershell - if: ${{ matrix.BUILD_BITS == '32' }} + choco install rtools --no-progress - - run: | - # see https://www.mail-archive.com/gcc-bugs@gcc.gnu.org/msg586184.html - if [ "${{ matrix.BUILD_BITS }}" == "64" ]; then - include=/c/ProgramData/Chocolatey/lib/mingw/tools/install/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/avx512fintrin.h - else - include=/c/ProgramData/Chocolatey/lib/mingw/tools/install/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/avx512fintrin.h - fi - sed -i -e"s/_mm512_abs_pd (__m512 __A)/_mm512_abs_pd (__m512d __A)/" $include - name: Fix gcc bug + - name: Set env variables + run: | + echo "START_DIR=$PWD" >> $env:GITHUB_ENV + $BITS = ${{ matrix.BUILD_BITS }} + echo "BUILD_BITS=$BITS" >> $env:GITHUB_ENV + # For interpretation of MSYSTEM, see: + # https://sourceforge.net/p/msys2/discussion/general/thread/b7dfdac8/#3939 + if ($BITS -eq 32) { + echo "PLAT=i686" >> $env:GITHUB_ENV + echo "MSYSTEM=MINGW32" >> $env:GITHUB_ENV + echo "LDFLAGS=-static -static-libgcc" >> $env:GITHUB_ENV + } else { + echo "PLAT=x86_64" >> $env:GITHUB_ENV + echo "MSYSTEM=UCRT64" >> $env:GITHUB_ENV + echo "LDFLAGS=-lucrt -static -static-libgcc" >> $env:GITHUB_ENV + } + if ( ${{ matrix.INTERFACE64 }} -eq 1 ) { + echo "INTERFACE64=1" >> $env:GITHUB_ENV + } - name: Build run: | - BITS=${{ matrix.BUILD_BITS }} - if [ "${{ matrix.INTERFACE64 }}" == "1" ]; then - export INTERFACE64=1 - fi - if [ "$BITS" == "32" ]; then - export PATH=/c/ProgramData/chocolatey/lib/mingw/tools/install/mingw32/bin:$PATH - fi - echo $PATH git submodule update --init --recursive - tools/build_openblas.sh + & $env:BASH_PATH -lc tools/build_openblas.sh - name: Test run: | - BITS=${{ matrix.BUILD_BITS }} - if [ "$BITS" == "32" ]; then - export PATH=/c/ProgramData/chocolatey/lib/mingw/tools/install/mingw32/bin:$PATH - fi - if [ "${{ matrix.INTERFACE64 }}" == "1" ]; then - export INTERFACE64=1 - fi - tools/build_gfortran.sh - cp test.exe builds - cp test_dyn.exe builds - ./test.exe - cp $(cygpath $OPENBLAS_ROOT)/$BITS/bin/*.dll . - ./test_dyn.exe + & $env:BASH_PATH -lc tools/build_gfortran.sh + echo "Static test" + .\for_test\test.exe + echo "Dynamic test" + .\for_test\test_dyn.exe + + - name: Copy + run: | + cp for_test\test*.exe builds - uses: actions/upload-artifact@v3 with: @@ -100,4 +78,4 @@ jobs: OPENBLAS_LIBS_STAGING_UPLOAD_TOKEN: ${{ secrets.MULTIBUILD_WHEELS_STAGING_ACCESS }} run: | pip install -q git+https://github.com/Anaconda-Platform/anaconda-client@1.8.0 - tools/upload_to_anaconda_staging.sh + & $env:BASH_PATH -lc tools/upload_to_anaconda_staging.sh diff --git a/.gitignore b/.gitignore index fc6879df..2d8e2638 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ builds/ *~ *.pyc *.swp -test.exe +for_test/ diff --git a/OpenBLAS b/OpenBLAS index 0b678b19..bfd9c1b5 160000 --- a/OpenBLAS +++ b/OpenBLAS @@ -1 +1 @@ -Subproject commit 0b678b19dc03f2a999d6e038814c4c50b9640a4e +Subproject commit bfd9c1b58cd347517d4849f06504011522cc640f diff --git a/tools/build_gfortran.sh b/tools/build_gfortran.sh index 678f7f21..5b7aba9e 100644 --- a/tools/build_gfortran.sh +++ b/tools/build_gfortran.sh @@ -2,16 +2,23 @@ set -e -cd $(cygpath "$START_DIR") +rm -rf for_test +mkdir for_test +cd for_test + +repo_path=$(cygpath "$START_DIR") OBP=$(cygpath $OPENBLAS_ROOT\\$BUILD_BITS) static_libname=$(find $OBP/lib -maxdepth 1 -type f -name '*.a' \! -name '*.dll.a' | tail -1) dynamic_libname=$(find $OBP/lib -maxdepth 1 -type f -name '*.dll.a' | tail -1) +dll_name=$(echo $dynamic_libname | sed 's#/lib/#/bin/#' | sed 's/.a$//') + +cp $dll_name . if [ "$INTERFACE64" == "1" ]; then - gfortran -I $OBP/include -fdefault-integer-8 -o test.exe test64_.f90 $static_libname - gfortran -I $OBP/include -fdefault-integer-8 -o test_dyn.exe test64_.f90 $dynamic_libname + gfortran -I $OBP/include -fdefault-integer-8 -o test.exe ${repo_path}/test64_.f90 $static_libname + gfortran -I $OBP/include -fdefault-integer-8 -o test_dyn.exe ${repo_path}/test64_.f90 $dynamic_libname else - gfortran -I $OBP/include -o test.exe test.f90 $static_libname - gfortran -I $OBP/include -o test_dyn.exe test.f90 $dynamic_libname + gfortran -I $OBP/include -o test.exe ${repo_path}/test.f90 $static_libname + gfortran -I $OBP/include -o test_dyn.exe ${repo_path}/test.f90 $dynamic_libname fi