diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3611056..3a496c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,14 +30,20 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: awvwgk/setup-fortran@main + - uses: fortran-lang/setup-fortran@v1 id: setup-fortran - if: runner.os != 'Windows' - # We aren't using this yet, and takes 4 mins to setup on Windows - # On macOS this causes a bug to be hit on macos-13+ and CMake, gcc14 may fix with: compiler: gcc version: 12 + # setup-fortran installs MinGW via choco, which only edits the machine PATH + # registry; GitHub Actions doesn't reload that into the running job. Put the + # bin dir on PATH so CMake can find gcc/gfortran (see pi-fortran override). + - name: Add MinGW to PATH (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + $bin = Split-Path (Get-ChildItem C:\ProgramData\chocolatey\lib\mingw -Recurse -Filter gfortran.exe | Select-Object -First 1).FullName + "$bin" | Out-File -FilePath $env:GITHUB_PATH -Append -Encoding utf8 - uses: astral-sh/setup-uv@v8.0.0 - run: uvx nox -s ${{ matrix.session }} diff --git a/noxfile.py b/noxfile.py index 422f53c..749b158 100644 --- a/noxfile.py +++ b/noxfile.py @@ -11,9 +11,8 @@ "hello-pybind11", "hello-cython", "hello-cmake-package", + "pi-fortran", ] -if not sys.platform.startswith("win"): - hello_list.append("pi-fortran") long_hello_list = [ *hello_list, "pen2-cython", diff --git a/projects/pi-fortran/CMakeLists.txt b/projects/pi-fortran/CMakeLists.txt index b04d74a..70d6b01 100644 --- a/projects/pi-fortran/CMakeLists.txt +++ b/projects/pi-fortran/CMakeLists.txt @@ -15,6 +15,8 @@ execute_process( OUTPUT_VARIABLE F2PY_INCLUDE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) +# On Windows the path comes back with backslashes, which CMake reads as escapes. +file(TO_CMAKE_PATH "${F2PY_INCLUDE_DIR}" F2PY_INCLUDE_DIR) set(f2py_module_name "pi") set(fortran_src_file "${CMAKE_SOURCE_DIR}/pi/_pi.f") @@ -41,4 +43,10 @@ target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Python::NumPy) +# With the MinGW toolchain (Windows), statically link the GNU runtime so the +# module has no external libgfortran/libgcc/libwinpthread DLL dependencies. +if(WIN32 AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + target_link_options(${CMAKE_PROJECT_NAME} PRIVATE -static) +endif() + install(TARGETS ${CMAKE_PROJECT_NAME} DESTINATION pi) diff --git a/projects/pi-fortran/pyproject.toml b/projects/pi-fortran/pyproject.toml index 7b3521d..c450f6a 100644 --- a/projects/pi-fortran/pyproject.toml +++ b/projects/pi-fortran/pyproject.toml @@ -14,3 +14,12 @@ dependencies = ["numpy>=1.21"] [tool.scikit-build] ninja.version = ">=1.10" cmake.version = ">=3.17.2" + +# Windows defaults to the Visual Studio generator, which has no Fortran support +# and ignores compiler overrides. Use Ninja with the MinGW toolchain instead +# (gcc and gfortran must be on PATH). +[[tool.scikit-build.overrides]] +if.platform-system = "win32" +cmake.args = ["-GNinja"] +cmake.define.CMAKE_C_COMPILER = "gcc" +cmake.define.CMAKE_Fortran_COMPILER = "gfortran"