Skip to content

BUG: Missing npymath.lib on Arm64 Windows #29577

Description

@da-woods

Describe the issue:

I was trying to test Cython on Arm64 on Windows.

We have it set up so that our Numpy tests try to link to npymath and found that this didn't work. From unzipping the Numpy wheels, it looks like the AMD64 one has the file _core/lib/npymath.lib while the ARM64 one has _core/lib/libnpymath.a (which doesn't seem right for a Windows build).

This looks to be the case for at least the Python 3.12 and 3.13 wheels.

With that said, I fixed the issue in the Cython tests by just removing the link to npymath, so this may be a non-issue where no-one really needs to link to it any more at all.

Reproduce the code example:

N/A

Error message:

Python and NumPy Versions:

Python 3.12, Numpy 2.3.2

Runtime Environment:

No response

Context for the issue:

This should probably not be prioritized.

Activity

  1. added this to the 2.3.3 release milestone on Aug 17, 2025
  2. theAeon commented on Aug 18, 2025

    @theAeon

    Is it being built with clang-mingw? that's the only way this output makes any sense to me.

  3. rgommers commented on Aug 19, 2025

    @rgommers
    Member

    Is it being built with clang-mingw? that's the only way this output makes any sense to me.

    It's built with clang-cl, unlike the x86-64 wheels which are built with MSVC. Compiler selected here:

    - name: Setup LLVM for Windows ARM64
    if: ${{ matrix.buildplat[1] == 'win_arm64' }}
    uses: ./.github/windows_arm64_steps

    And build log output from a recent log:

      Build type: native build
      Activating VS 17.14.9 (July 2025)
      Project name: NumPy
      Project version: 2.4.0.dev0+git20250816.4e00e4d
      C compiler for the host machine: clang-cl (clang-cl 19.1.5)
      C linker for the host machine: lld-link lld-link 19.1.5
      C++ compiler for the host machine: clang-cl (clang-cl 19.1.5)
      C++ linker for the host machine: lld-link lld-link 19.1.5
    

    With that said, I fixed the issue in the Cython tests by just removing the link to npymath, so this may be a non-issue where no-one really needs to link to it any more at all.

    SciPy still uses it. I'm not aware of other projects using it. So you might want to keep the test on x86-64.

    It's unclear to me if this requires a change or not. SciPy win-arm64 builds seem fine with it. And I suspect it's a case of needing to use the same compiler for consuming this static library as was used to produce it.

  4. carlkl commented on Aug 20, 2025

    @carlkl
    Member

    Time to get rid of this library in scipy?

  5. theAeon commented on Aug 20, 2025

    @theAeon

    statsmodels needs it, for one.

  6. rgommers commented on Aug 20, 2025

    @rgommers
    Member

    statsmodels needs it, for one.

    Ah thank you, I wasn't aware.

    Time to get rid of this library in scipy?

    Yes, but the effort to get that done stalled a bit. xref gh-20880 and scipy/scipy#17498

  7. rgommers commented on Aug 28, 2025

    @rgommers
    Member

    With that said, I fixed the issue in the Cython tests by just removing the link to npymath, so this may be a non-issue where no-one really needs to link to it any more at all.

    I think I'd like to go with this. The couple of projects that need this static library should really use the same compiler (clang-cl in this case) that was used to produce it, at which point there is no problem.

  8. removed this from the 2.3.3 release milestone on Aug 28, 2025
  9. da-woods commented on Aug 28, 2025

    @da-woods
    ContributorAuthor

    Fine by me - I was flagging it as an inconsistency that might cause problems rather than because it was an issue for me

  10. bashtage commented on Sep 12, 2025

    @bashtage
    Contributor

    This is OK for library writers, but it is unfortunate to not be able to use the default toolchain on win-arm64, in case someone wanted to develop locally on win-arm64.

  11. bashtage commented on Sep 12, 2025

    @bashtage
    Contributor

    No easy fix following the path trying to use CIBW to build on win-arm64. I suspect that @rgommers suggestion effectively requires a meson-based build rather than setup.py-based build.

    The action runs but then still end up with the standard platform compiler and linker

    "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\bin\HostARM64\ARM64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -DCYTHON_TRACE_NOGIL=0 -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION -IC:\Users\runneradmin\AppData\Local\Temp\build-env-f_892_j4\Lib\site-packages\numpy\_core\include -IC:\Users\runneradmin\AppData\Local\Temp\build-env-f_892_j4\include -IC:\Users\runneradmin\AppData\Local\pypa\cibuildwheel\Cache\nuget-cpython\pythonarm64.3.11.9\tools\include -IC:\Users\runneradmin\AppData\Local\pypa\cibuildwheel\Cache\nuget-cpython\pythonarm64.3.11.9\tools\Include "-IC:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\ATLMFC\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\VS\include" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\um" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\shared" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\cppwinrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" /Tcstatsmodels/tsa/stl/_stl.c /Fobuild\temp.win-arm64-cpython-311\Release\statsmodels\tsa\stl\_stl.obj
    
    "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\bin\HostARM64\ARM64\link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\Users\runneradmin\AppData\Local\Temp\build-env-f_892_j4\Lib\site-packages\numpy\_core\include\..\lib /LIBPATH:C:\Users\runneradmin\AppData\Local\Temp\build-env-f_892_j4\libs /LIBPATH:C:\Users\runneradmin\AppData\Local\pypa\cibuildwheel\Cache\nuget-cpython\pythonarm64.3.11.9\tools\libs /LIBPATH:C:\Users\runneradmin\AppData\Local\pypa\cibuildwheel\Cache\nuget-cpython\pythonarm64.3.11.9\tools /LIBPATH:C:\Users\runneradmin\AppData\Local\Temp\build-env-f_892_j4\PCbuild\arm64 "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\ATLMFC\lib\ARM64" "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\lib\ARM64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.26100.0\ucrt\arm64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\\lib\10.0.26100.0\\um\arm64" npymath.lib /EXPORT:PyInit__stl build\temp.win-arm64-cpython-311\Release\statsmodels\tsa\stl\_stl.obj /OUT:build\lib.win-arm64-cpython-311\statsmodels\tsa\stl\_stl.cp311-win_arm64.pyd /IMPLIB:build\temp.win-arm64-cpython-311\Release\statsmodels\tsa\stl\_stl.cp311-win_arm64.lib
    
  12. rgommers commented on Sep 12, 2025

    @rgommers
    Member

    @bashtage I honestly don't mind it becoming a little harder to use libnpymath. We want it to go away after all (see gh-20880). That is really hard to communicate in a reasonable way, so this minor barrier hopefully causes more people to get that message. And I don't even know if it would work to use a different set of compilers - we certainly cannot guarantee that. We have jumped through strange hoops in the past to make mixed compilers used because we had to (MSVC + Mingw-w64, for SciPy), but it's a lot of obscure work and it's best effort (although you're using so little of npymath that it's very likely to work).

    In statsmodels it's only used in Cython code - WDYT about moving to letting Cython generate C++ code? You only need a few complex number functions like npy_clog/np.cexp and with C++ you shouldn't need libnpymath at all. AFAIK the only reason we need those functions today is because MSVC's support for C is so poor.

    The action runs but then still end up with the standard platform compiler and linker

    The output you pasted shows cl.exe being used rather than clang-cl.exe. I quickly refreshed my memory, and it looks like pypa/distutils and setuptools never bothered to merge PRs with support forclang-cl (xref pypa/setuptools#2065). I think that says enough about whether one should still be using those packages .....

    I suspect that @rgommers suggestion effectively requires a meson-based build rather than setup.py-based build.

    scikit-build-core will work too, as will pretty much any other build system with sane support for common compilers.

    Note that the reason we decided to use clang-cl is because MSVC was both missing features and crashing when building numpy (see #29174 (comment)), it wasn't arbitrary or us not wanting to support MSVC.

    I did a bit of digging and it looks like we'd be able to switch to outputting a .lib instead of .a by tweaking this:

    numpy/numpy/meson.build

    Lines 31 to 41 in f346e58

    # We install libnpymath and libnpyrandom; ensure they're using a `.lib` rather
    # than a `.a` file extension in order not to break including them in a
    # distutils-based build (see gh-23981 and
    # https://mesonbuild.com/FAQ.html#why-does-building-my-project-with-msvc-output-static-libraries-called-libfooa)
    if is_windows and cc.get_id() == 'msvc'
    name_prefix_staticlib = ''
    name_suffix_staticlib = 'lib'
    else
    name_prefix_staticlib = []
    name_suffix_staticlib = []
    endif

    It'd be a one-line patch; it should be verified first that it doesn't affect building SciPy on win_arm64 with clang-cl.

    I'd be interested in helping statsmodels remove the dependency on libnpymath and/or move to meson-python.

    I'm also willing to help change to .lib in numpy 2.4.0 if statsmodels cares enough - but I'm not really interested in spending time beyond that to support setuptools+MSVC-on-arm+libnpymath - those are three things that are each pretty bad, and best moved away from.

  13. bashtage commented on Sep 12, 2025

    @bashtage
    Contributor

    And I don't even know if it would work to use a different set of compilers

    Isn't ABI compatibility a promise of clang-cl? When I got NumPy building with clang-cl using the old build system, I recall it working for building downstream projects.

    In statsmodels it's only used in Cython code - WDYT about moving to letting Cython generate C++ code? You only need a few complex number functions like npy_clog/np.cexp and with C++ you shouldn't need libnpymath at all. AFAIK the only reason we need those functions today is because MSVC's support for C is so poor.

    I think the deeper issue is that MSVC's support for complex is poor. Specifically, here we use the NumPy version of the complex functions, which lets us avoid all of the pain of worrying about cross-platform compatibility.

    The alternative is to copy the relevant parts from NumPy and build our own library to link to.

    It'd be a one-line patch; it should be verified first that it doesn't affect building SciPy on win_arm64 with clang-cl.

    If this worked, it would be appreciated for now, since it would allow the latest existing point release to be built for win-arm64.

  14. rgommers commented on Sep 12, 2025

    @rgommers
    Member

    Isn't ABI compatibility a promise of clang-cl?

    Building a static library with one toolchain and then folding it into a shared library with another toolchain is not just about ABI (it's just a no no with no hard guarantees). Last time we had a problem it was because of some compiler-specific content in the .lib file that was not part of the ABI, just some internal directives that shouldn't matter to anyone unless they do something that's not supported like mix two toolchains to produce a single .pyd.

    I think the deeper issue is that MSVC's support for complex is poor.

    Yes, but only in C, not in C++.

    If this worked, it would be appreciated for now

    Okay, I'll give it a try. We'll just release some nightlies with the change, and if those work for you and no one else notices a problem, we can call it good for this issue.

  15. removed
    57 - Close?Issues which may be closable unless discussion continued
    on Sep 12, 2025
  16. bashtage commented on Sep 12, 2025

    @bashtage
    Contributor

    A little rethink and the statsmodels dependency appears to be easy to work around

    PR in progress statsmodels/statsmodels#9631

  17. added a commit that references this issue on Sep 13, 2025
    df9770a
  18. rgommers commented on Sep 13, 2025

    @rgommers
    Member

    Awesome, thanks! PR for the .a -> .lib change up anyway at gh-29750.

  19. added this to the 2.4.0 release milestone on Sep 14, 2025
  20. rgommers commented on Sep 14, 2025

    @rgommers
    Member

    Implemented the change, nightly wheels should be available in about an hour.

  21. added a commit that references this issue on Sep 30, 2025
    228f180
  22. added a commit that references this issue on Dec 7, 2025
    1baf467
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions