From 2901bb9dba855ae65a70cf9345b3f81c1c8f9d1b Mon Sep 17 00:00:00 2001 From: Nikhil Dabas Date: Sat, 3 Oct 2026 12:30:33 +0100 Subject: [PATCH 1/3] Add test for make install on Windows --- .github/scripts/cmake-consumer/CMakeLists.txt | 15 ++++ .github/scripts/cmake-consumer/main.c | 8 ++ .../scripts/cmake-consumer/test-consumer.ps1 | 34 ++++++++ .github/workflows/windows_make_install.yml | 82 +++++++++++++++++++ 4 files changed, 139 insertions(+) create mode 100644 .github/scripts/cmake-consumer/CMakeLists.txt create mode 100644 .github/scripts/cmake-consumer/main.c create mode 100644 .github/scripts/cmake-consumer/test-consumer.ps1 create mode 100644 .github/workflows/windows_make_install.yml diff --git a/.github/scripts/cmake-consumer/CMakeLists.txt b/.github/scripts/cmake-consumer/CMakeLists.txt new file mode 100644 index 0000000000..89d48f8d94 --- /dev/null +++ b/.github/scripts/cmake-consumer/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.19) +project(openblas_cmake_consumer C) + +find_package(OpenBLAS REQUIRED CONFIG) +# a repeated lookup must not try to redefine the imported target +find_package(OpenBLAS REQUIRED CONFIG) + +get_target_property(implib OpenBLAS::OpenBLAS IMPORTED_IMPLIB) +get_filename_component(implib_name "${implib}" NAME) +if (NOT implib_name STREQUAL EXPECTED_IMPLIB) + message(FATAL_ERROR "IMPORTED_IMPLIB is ${implib}, expected ${EXPECTED_IMPLIB}") +endif () + +add_executable(consumer main.c) +target_link_libraries(consumer PRIVATE OpenBLAS::OpenBLAS) diff --git a/.github/scripts/cmake-consumer/main.c b/.github/scripts/cmake-consumer/main.c new file mode 100644 index 0000000000..b768c95bba --- /dev/null +++ b/.github/scripts/cmake-consumer/main.c @@ -0,0 +1,8 @@ +#include + +int main(void) +{ + double a[4] = {1, 2, 3, 4}, b[4] = {5, 6, 7, 8}, c[4] = {0}; + cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 2, 2, 2, 1.0, a, 2, b, 2, 0.0, c, 2); + return !(c[0] == 19 && c[1] == 22 && c[2] == 43 && c[3] == 50); +} diff --git a/.github/scripts/cmake-consumer/test-consumer.ps1 b/.github/scripts/cmake-consumer/test-consumer.ps1 new file mode 100644 index 0000000000..80f9ae195f --- /dev/null +++ b/.github/scripts/cmake-consumer/test-consumer.ps1 @@ -0,0 +1,34 @@ +#Requires -Version 7.4 +# Builds and runs a CMake project against a Windows `make install` tree, with MinGW and MSVC. +param( + [Parameter(Mandatory)][string]$Prefix, + [Parameter(Mandatory)][ValidateSet('x64', 'arm64')][string]$Arch, + [Parameter(Mandatory)][string]$MinGWCompiler, + [Parameter(Mandatory)][string]$DefFile, + [Parameter(Mandatory)][string]$BuildDir +) +$ErrorActionPreference = 'Stop' +$PSNativeCommandUseErrorActionPreference = $true + +$Prefix = $Prefix -replace '\\', '/' +$env:PATH = "$($Prefix -replace '/', '\')\bin;$env:PATH" + +function Test-Consumer([string]$name, [string]$implib, [string[]]$cmakeArgs) { + $build = Join-Path $BuildDir $name + cmake -S $PSScriptRoot -B $build "-DCMAKE_PREFIX_PATH=$Prefix" "-DEXPECTED_IMPLIB=$implib" @cmakeArgs + cmake --build $build + & "$build/consumer.exe" +} + +Test-Consumer mingw libopenblas.dll.a @('-G', 'MinGW Makefiles', "-DCMAKE_C_COMPILER=$MinGWCompiler", '-DCMAKE_SH=CMAKE_SH-NOTFOUND') + +$vcTools = @{ x64 = 'x86.x64'; arm64 = 'ARM64' }[$Arch] +$vs = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * ` + -requires "Microsoft.VisualStudio.Component.VC.Tools.$vcTools" -property installationPath +$hostArch = if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') { 'arm64' } else { 'amd64' } +& "$vs\Common7\Tools\Launch-VsDevShell.ps1" -Arch ($Arch -eq 'x64' ? 'amd64' : 'arm64') -HostArch $hostArch -SkipAutomaticLocation +Test-Consumer msvc-dlla libopenblas.dll.a @('-G', 'NMake Makefiles', '-DCMAKE_C_COMPILER=cl') + +# release packages add an MSVC import library, which the config should prefer +lib /nologo "/machine:$Arch" "/def:$DefFile" /name:libopenblas.dll "/out:$Prefix/lib/libopenblas.lib" +Test-Consumer msvc-lib libopenblas.lib @('-G', 'NMake Makefiles', '-DCMAKE_C_COMPILER=cl') diff --git a/.github/workflows/windows_make_install.yml b/.github/workflows/windows_make_install.yml new file mode 100644 index 0000000000..9e9298eea1 --- /dev/null +++ b/.github/workflows/windows_make_install.yml @@ -0,0 +1,82 @@ +name: Windows make install + +on: + push: + branches: + - develop + paths-ignore: + - 'docs/**' + - '**/*.md' + pull_request: + branches: + - develop + paths-ignore: + - 'docs/**' + - '**/*.md' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + build: + if: "github.repository == 'OpenMathLib/OpenBLAS'" + name: ${{ matrix.msystem }} + runs-on: ${{ matrix.runner }} + + strategy: + fail-fast: false + matrix: + include: + - arch: x64 + runner: windows-latest + msystem: UCRT64 + cc: gcc + target: HASWELL + - arch: arm64 + runner: windows-11-arm + msystem: CLANGARM64 + cc: clang + target: ARMV8 + + env: + OPENBLAS_MAKE_ARGS: CC=${{ matrix.cc }} TARGET=${{ matrix.target }} NOFORTRAN=1 NO_LAPACK=1 NO_LAPACKE=1 + + defaults: + run: + shell: msys2 {0} + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Install build dependencies + id: msys2 + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.msystem }} + update: true + install: make + pacboy: >- + cc:p + cmake:p + make:p + + - name: Build OpenBLAS + run: make -j$(nproc) $OPENBLAS_MAKE_ARGS + + - name: Install OpenBLAS + run: | + prefix="$(cygpath -m "$RUNNER_TEMP")/openblas" + make install PREFIX="$prefix" $OPENBLAS_MAKE_ARGS + cat "$prefix/lib/cmake/openblas/OpenBLASConfig.cmake" + + - name: Test OpenBLASConfig.cmake with MinGW and MSVC consumers + shell: pwsh + run: | + $env:PATH = "${{ steps.msys2.outputs.msys2-location }}\$('${{ matrix.msystem }}'.ToLower())\bin;$env:PATH" + ./.github/scripts/cmake-consumer/test-consumer.ps1 -Arch ${{ matrix.arch }} -MinGWCompiler ${{ matrix.cc }} ` + -Prefix "$env:RUNNER_TEMP/openblas" -DefFile exports/libopenblas.def -BuildDir "$env:RUNNER_TEMP/consumer" From e2e8d9b014640e4cf334ab559df30518144469b2 Mon Sep 17 00:00:00 2001 From: Nikhil Dabas Date: Sat, 3 Oct 2026 12:45:34 +0100 Subject: [PATCH 2/3] Add CLANGARM64 to msys2 tests --- .github/workflows/dynamic_arch.yml | 45 +++++++++++++++++------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/.github/workflows/dynamic_arch.yml b/.github/workflows/dynamic_arch.yml index 718c21de10..e1422a1e20 100644 --- a/.github/workflows/dynamic_arch.yml +++ b/.github/workflows/dynamic_arch.yml @@ -193,41 +193,46 @@ jobs: msys2: if: "github.repository == 'OpenMathLib/OpenBLAS'" - runs-on: windows-latest + runs-on: ${{ matrix.runner || 'windows-latest' }} strategy: fail-fast: false matrix: - msystem: [UCRT64, MINGW32, CLANG64] + msystem: [UCRT64, MINGW32, CLANG64, CLANGARM64] idx: [int32, int64] build-type: [Release] include: - msystem: UCRT64 idx: int32 - target-prefix: mingw-w64-ucrt-x86_64 - fc-pkg: mingw-w64-ucrt-x86_64-fc + fc-pkg: fc:p - msystem: MINGW32 idx: int32 - target-prefix: mingw-w64-i686 fc-pkg: - msystem: CLANG64 idx: int32 - target-prefix: mingw-w64-clang-x86_64 - fc-pkg: mingw-w64-clang-x86_64-fc + fc-pkg: fc:p + - msystem: CLANGARM64 + idx: int32 + runner: windows-11-arm + target: ARMV8 + fc-pkg: fc:p - msystem: UCRT64 idx: int64 idx64-flags: -DBINARY=64 -DINTERFACE64=1 - target-prefix: mingw-w64-ucrt-x86_64 - fc-pkg: mingw-w64-ucrt-x86_64-fc + fc-pkg: fc:p - msystem: CLANG64 idx: int64 idx64-flags: -DBINARY=64 -DINTERFACE64=1 - target-prefix: mingw-w64-clang-x86_64 - fc-pkg: mingw-w64-clang-x86_64-fc + fc-pkg: fc:p + - msystem: CLANGARM64 + idx: int64 + idx64-flags: -DBINARY=64 -DINTERFACE64=1 + runner: windows-11-arm + target: ARMV8 + fc-pkg: fc:p - msystem: UCRT64 idx: int32 - target-prefix: mingw-w64-ucrt-x86_64 - fc-pkg: mingw-w64-ucrt-x86_64-fc + fc-pkg: fc:p build-type: None exclude: - msystem: MINGW32 @@ -253,13 +258,13 @@ jobs: msystem: ${{ matrix.msystem }} update: true release: false # Use pre-installed version - install: >- - base-devel - ${{ matrix.target-prefix }}-cc + install: base-devel + pacboy: >- + cc:p ${{ matrix.fc-pkg }} - ${{ matrix.target-prefix }}-cmake - ${{ matrix.target-prefix }}-ninja - ${{ matrix.target-prefix }}-ccache + cmake:p + ninja:p + ccache:p - name: Checkout repository uses: actions/checkout@v6 @@ -305,7 +310,7 @@ jobs: -DDYNAMIC_ARCH=ON \ -DUSE_THREAD=ON \ -DNUM_THREADS=64 \ - -DTARGET=CORE2 \ + -DTARGET=${{ matrix.target || 'CORE2' }} \ ${{ matrix.idx64-flags }} \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_Fortran_COMPILER_LAUNCHER=ccache \ From 878d49a0c1727843efd8212e16cb96eacbb2d8a1 Mon Sep 17 00:00:00 2001 From: Nikhil Dabas Date: Sat, 3 Oct 2026 15:40:04 +0100 Subject: [PATCH 3/3] Fix Windows jobs on Azure pipelines --- azure-pipelines.yml | 101 ++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 45 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 53199ec67c..4cc7e3a4ce 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -21,7 +21,7 @@ resources: - container: oneapi-basekit image: intel/oneapi-basekit:latest options: '-v /usr/bin/sudo:/usr/bin/sudo -v /usr/lib/sudo/libsudo_util.so.0:/usr/lib/sudo/libsudo_util.so.0 -v /usr/lib/sudo/sudoers.so:/usr/lib/sudo/sudoers.so' - + jobs: # manylinux1 is useful to test because the # standard Docker container uses an old version @@ -84,7 +84,7 @@ jobs: - job: Windows_cl pool: vmImage: 'windows-latest' - steps: + steps: - task: CMake@1 inputs: workingDirectory: 'build' # Optional @@ -103,7 +103,7 @@ jobs: timeoutInMinutes: 100 pool: vmImage: 'windows-latest' - steps: + steps: - script: | mingw32-make CC=gcc NOLAPACK=1 DYNAMIC_ARCH=1 DYNAMIC_LIST="SANDYBRIDGE" @@ -111,80 +111,91 @@ jobs: pool: vmImage: 'windows-latest' steps: - - script: | - set "PATH=C:\Miniconda\Scripts;C:\Miniconda\Library\bin;C:\Miniconda\Library\usr\bin;C:\Miniconda\condabin;%PATH%" - set "LIB=C:\Miniconda\Library\lib;%LIB%" - set "CPATH=C:\Miniconda\Library\include;%CPATH% + - pwsh: | + #Requires -Version 7.4 + $ErrorActionPreference = 'Stop' + $PSNativeCommandUseErrorActionPreference = $true + $env:PATH = "C:\Miniconda\Scripts;C:\Miniconda\Library\bin;C:\Miniconda\Library\usr\bin;C:\Miniconda\condabin;$env:PATH" + $env:LIB = "C:\Miniconda\Library\lib;$env:LIB" + $env:CPATH = "C:\Miniconda\Library\include;$env:CPATH" conda config --add channels conda-forge --force conda config --set auto_update_conda false conda install --yes ninja - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - mkdir build + $vs = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath + & "$vs\Common7\Tools\Launch-VsDevShell.ps1" -Arch amd64 -HostArch amd64 -SkipAutomaticLocation + mkdir build cd build cmake -G "Ninja" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_MT=mt -DCMAKE_BUILD_TYPE=Release -DNOFORTRAN=1 -DMSVC_STATIC_CRT=ON .. cmake --build . --config Release - ctest + ctest --no-tests=error --output-on-failure - job: Windows_flang_clang pool: vmImage: 'windows-2022' steps: - - script: | - set "PATH=C:\Miniconda\Scripts;C:\Miniconda\Library\bin;C:\Miniconda\Library\usr\bin;C:\Miniconda\condabin;%PATH%" - set "LIB=C:\Miniconda\Library\lib;%LIB%" - set "CPATH=C:\Miniconda\Library\include;%CPATH%" + - pwsh: | + #Requires -Version 7.4 + $ErrorActionPreference = 'Stop' + $PSNativeCommandUseErrorActionPreference = $true + $env:PATH = "C:\Miniconda\Scripts;C:\Miniconda\Library\bin;C:\Miniconda\Library\usr\bin;C:\Miniconda\condabin;$env:PATH" + $env:LIB = "C:\Miniconda\Library\lib;$env:LIB" + $env:CPATH = "C:\Miniconda\Library\include;$env:CPATH" conda config --add channels conda-forge --force conda config --set auto_update_conda false - conda install --yes --quiet ninja flang - mkdir build + conda install --yes --quiet ninja flang flang-rt_win-64 + $vs = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath + & "$vs\Common7\Tools\Launch-VsDevShell.ps1" -Arch amd64 -HostArch amd64 -SkipAutomaticLocation + mkdir build cd build - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - cmake -G "Ninja" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_Fortran_COMPILER="flang -I C:\Miniconda\Library\include\flang" -DBUILD_TESTING=OFF -DCMAKE_MT=mt -DCMAKE_BUILD_TYPE=Release -DMSVC_STATIC_CRT=ON .. + cmake -G "Ninja" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_Fortran_COMPILER=flang -DBUILD_TESTING=OFF -DCMAKE_MT=mt -DCMAKE_BUILD_TYPE=Release -DMSVC_STATIC_CRT=ON .. cmake --build . --config Release - ctest + ctest --no-tests=error --output-on-failure - job: Windows_cl_flang pool: vmImage: 'windows-2022' steps: - - script: | - set "PATH=C:\Miniconda\Scripts;C:\Miniconda\Library\bin;C:\Miniconda\Library\usr\bin;C:\Miniconda\condabin;%PATH%" - set "LIB=C:\Miniconda\Library\lib;%LIB%" - set "CPATH=C:\Miniconda\Library\include;%CPATH%" + - pwsh: | + #Requires -Version 7.4 + $ErrorActionPreference = 'Stop' + $PSNativeCommandUseErrorActionPreference = $true + $env:PATH = "C:\Miniconda\Scripts;C:\Miniconda\Library\bin;C:\Miniconda\Library\usr\bin;C:\Miniconda\condabin;$env:PATH" + $env:LIB = "C:\Miniconda\Library\lib;$env:LIB" + $env:CPATH = "C:\Miniconda\Library\include;$env:CPATH" conda config --add channels conda-forge --force conda config --set auto_update_conda false - conda install --yes --quiet ninja flang - mkdir build + conda install --yes --quiet ninja flang flang-rt_win-64 + $vs = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath + & "$vs\Common7\Tools\Launch-VsDevShell.ps1" -Arch amd64 -HostArch amd64 -SkipAutomaticLocation + mkdir build cd build - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" cmake -G "Ninja" -DCMAKE_C_COMPILER=cl -DCMAKE_Fortran_COMPILER=flang-new -DC_LAPACK=1 -DCMAKE_MT=mt -DCMAKE_BUILD_TYPE=Release -DMSVC_STATIC_CRT=ON .. cmake --build . --config Release - ctest - ctest --rerun-failed --output-on-failure + ctest --no-tests=error --output-on-failure - job: OSX_OpenMP pool: vmImage: 'macOS-15' - steps: + steps: - script: | brew update make TARGET=CORE2 DYNAMIC_ARCH=1 USE_OPENMP=1 INTERFACE64=1 CC=gcc-13 FC=gfortran-13 make TARGET=CORE2 DYNAMIC_ARCH=1 USE_OPENMP=1 INTERFACE64=1 CC=gcc-13 FC=gfortran-13 PREFIX=../blasinst install ls -lR ../blasinst - + - job: OSX_GCC_Nothreads pool: vmImage: 'macOS-15' - steps: + steps: - script: | brew update make USE_THREADS=0 CC=gcc-13 FC=gfortran-13 - + - job: OSX_GCC15 pool: vmImage: 'macOS-latest' - steps: + steps: - script: | brew update make CC=gcc-15 FC=gfortran-15 @@ -195,7 +206,7 @@ jobs: vmImage: 'macOS-latest' variables: RANLIB: touch - steps: + steps: - script: | wget https://github.com/macports/macports-base/releases/download/v2.12.6/MacPorts-2.12.6-15-Sequoia.pkg sudo installer -pkg MacPorts-2.12.6-15-Sequoia.pkg -target / @@ -211,7 +222,7 @@ jobs: vmImage: 'macOS-latest' variables: RANLIB: touch - steps: + steps: - script: | wget https://github.com/macports/macports-base/releases/download/v2.12.6/MacPorts-2.12.6-15-Sequoia.pkg sudo installer -pkg MacPorts-2.12.6-15-Sequoia.pkg -target / @@ -224,7 +235,7 @@ jobs: timeoutInMinutes: 100 pool: vmImage: 'macOS-latest' - steps: + steps: - script: | set -euo pipefail wget https://github.com/macports/macports-base/releases/download/v2.12.6/MacPorts-2.12.6-15-Sequoia.pkg @@ -237,7 +248,7 @@ jobs: cmake -DTARGET=CORE2 -DUSE_OPENMP=1 -DINTERFACE64=1 -DDYNAMIC_ARCH=1 -DDYNAMIC_LIST='NEHALEM;HASWELL;SKYLAKEX' -DCMAKE_C_COMPILER=clang-mp-23 -DNOFORTRAN=1 -DNO_AVX512=1 .. cmake --build . --parallel "$(sysctl -n hw.logicalcpu)" ctest - + - job: OSX_dynarch_cmake timeoutInMinutes: 100 pool: @@ -245,7 +256,7 @@ jobs: variables: LD_LIBRARY_PATH: /usr/local/opt/llvm/lib LIBRARY_PATH: /usr/local/opt/llvm/lib - steps: + steps: - script: | set -euo pipefail mkdir build @@ -263,7 +274,7 @@ jobs: LIBRARY_PATH: /usr/local/opt/llvm/lib RANLIB: touch MACOS_FORTRAN_COMPONENTS: intel.oneapi.mac.ifort-compiler - steps: + steps: - script: | wget https://github.com/macports/macports-base/releases/download/v2.12.6/MacPorts-2.12.6-15-Sequoia.pkg sudo installer -pkg MacPorts-2.12.6-15-Sequoia.pkg -target / @@ -278,7 +289,7 @@ jobs: path: /opt/intel/oneapi key: '"install" | "$(MACOS_HPCKIT_URL)" | "$(MACOS_FORTRAN_COMPONENTS)"' cacheHitVar: CACHE_RESTORED - - script: | + - script: | curl --output webimage.dmg --url $(MACOS_HPCKIT_URL) --retry 5 --retry-delay 5 hdiutil attach webimage.dmg sudo /Volumes/"$(basename "$(MACOS_HPCKIT_URL)" .dmg)"/bootstrapper.app/Contents/MacOS/bootstrapper -s --action install --components="$(MACOS_FORTRAN_COMPONENTS)" --eula=accept --continue-with-optional-error=yes --log-dir=. @@ -287,15 +298,15 @@ jobs: exit $installer_exit_code displayName: install condition: ne(variables.CACHE_RESTORED, 'true') - - script: | + - script: | source /opt/intel/oneapi/setvars.sh make CC=/opt/local/bin/clang-mp-23 FC=ifort - + - job: OSX_NDK_ARMV7 pool: vmImage: 'macOS-15' - steps: - - script: | + steps: + - script: | brew update brew install --cask android-ndk export ANDROID_NDK_HOME=/usr/local/share/android-ndk @@ -354,4 +365,4 @@ jobs: alpine echo "int main(){" >> test_install.c alpine echo "cpu_set_t* cpu_set = NULL;}" >>test_install.c alpine gcc -Imytestdir/include test_install.c -Lmytestdir/lib -lopenblas -lpthread -lgfortran -o test_install - +