Skip to content

Commit

Permalink
Bugfix: windows fortran builds (#506)
Browse files Browse the repository at this point in the history
Fixes various issues related to building Fortran interfaces and examples on Windows
  • Loading branch information
balos1 authored and gardner48 committed Jun 20, 2024
1 parent 1451b5e commit e4717fe
Show file tree
Hide file tree
Showing 109 changed files with 534 additions and 421 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/windows-latest-intel.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Build and Test - Windows/intel/ninja (short)

on:
pull_request:
merge_group:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
build_and_test:
runs-on: windows-latest

steps:
- uses: fortran-lang/setup-fortran@v1
id: setup-fortran
with:
compiler: intel
version: '2023.2'

- name: Install Ninja
run: choco install ninja

- uses: actions/checkout@v3

- name: Configure CMake (Static)
run: cmake -G "Ninja" -B ${{github.workspace}}/build_static -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_FLAGS=-Wno-deprecated-declarations -DCMAKE_C_COMPILER=icx-cl -DCMAKE_CXX_COMPILER=icx-cl -DCMAKE_Fortran_COMPILER=ifx -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_FORTRAN_MODULE_INTERFACE=ON -DSUNDIALS_BUILD_WITH_PROFILING=ON -DSUNDIALS_TEST_UNITTESTS=OFF -DEXAMPLES_ENABLE_CXX=ON

- name: Build (Static)
run: cmake --build ${{github.workspace}}/build_static --verbose

- name: Test (Static)
working-directory: ${{github.workspace}}/build_static
run: ctest -C ${{env.BUILD_TYPE}} --output-on-failure

- name: Configure CMake (Shared)
run: cmake -G "Ninja" -B ${{github.workspace}}/build_shared -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_FLAGS=-Wno-deprecated-declarations -DCMAKE_C_COMPILER=icx-cl -DCMAKE_CXX_COMPILER=icx-cl -DCMAKE_Fortran_COMPILER=ifx -DBUILD_STATIC_LIBS=OFF -DBUILD_SHARED_LIBS=ON -DBUILD_FORTRAN_MODULE_INTERFACE=ON -DSUNDIALS_BUILD_WITH_PROFILING=ON -DSUNDIALS_TEST_UNITTESTS=OFF -DEXAMPLES_ENABLE_CXX=ON

- name: Build (Shared)
run: cmake --build ${{github.workspace}}/build_shared --verbose

- name: Test (Shared)
working-directory: ${{github.workspace}}/build_shared
run: ctest -C ${{env.BUILD_TYPE}} --output-on-failure
49 changes: 40 additions & 9 deletions .github/workflows/windows-latest-mingw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ concurrency:
cancel-in-progress: true

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
Expand Down Expand Up @@ -42,27 +41,59 @@ jobs:
install: >-
base-devel
${{ matrix.target-prefix }}-cmake
${{ matrix.target-prefix }}-cc
${{ matrix.target-prefix }}-gcc
${{ matrix.target-prefix }}-gcc-fortran
${{ matrix.target-prefix }}-openblas
${{ matrix.target-prefix }}-suitesparse
- name: Configure CMake
- name: Configure CMake (Static)
# Configure CMake in a 'build' subdirectory
run: |
cmake \
-B ${GITHUB_WORKSPACE}/build \
-G "MSYS Makefiles" \
-B ${GITHUB_WORKSPACE}/build_static \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_C_FLAGS=-Wno-deprecated-declarations \
-DBUILD_FORTRAN_MODULE_INTERFACE=ON \
-DBUILD_SHARED_LIBS=OFF \
-DSUNDIALS_BUILD_WITH_PROFILING=ON \
-DSUNDIALS_LOGGING_LEVEL=2 \
-DSUNDIALS_TEST_UNITTESTS=OFF \
-DEXAMPLES_ENABLE_CXX=ON \
-DENABLE_KLU=ON
- name: Build
- name: Build (Static)
# Build program
run: cmake --build ${GITHUB_WORKSPACE}/build
run: cmake --build ${GITHUB_WORKSPACE}/build_static --verbose

- name: Test
working-directory: ${{github.workspace}}/build
- name: Test (Static)
working-directory: ${{github.workspace}}/build_static
# Execute tests
run: ctest
run: ctest --output-on-failure

# TODO(CJB): shared libraries with the fortran interfaces turned on
# fail to link correctly with this toolchain see https://github.com/LLNL/sundials/issues/507.
- name: Configure CMake (Shared)
# Configure CMake in a 'build' subdirectory
run: |
cmake \
-G "MSYS Makefiles" \
-B ${GITHUB_WORKSPACE}/build_shared \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_C_FLAGS=-Wno-deprecated-declarations \
-DBUILD_FORTRAN_MODULE_INTERFACE=OFF \
-DBUILD_STATIC_LIBS=OFF \
-DSUNDIALS_BUILD_WITH_PROFILING=ON \
-DSUNDIALS_LOGGING_LEVEL=2 \
-DSUNDIALS_TEST_UNITTESTS=OFF \
-DEXAMPLES_ENABLE_CXX=ON \
-DENABLE_KLU=ON
- name: Build (Shared)
# Build program
run: cmake --build ${GITHUB_WORKSPACE}/build_shared --verbose

- name: Test (Shared)
working-directory: ${{github.workspace}}/build_shared
# Execute tests
run: ctest --output-on-failure
12 changes: 3 additions & 9 deletions .github/workflows/windows-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ concurrency:
cancel-in-progress: true

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
Expand All @@ -21,16 +20,11 @@ jobs:
- uses: actions/checkout@v3

- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_STATIC_LIBS=OFF -DSUNDIALS_BUILD_WITH_PROFILING=ON -DSUNDIALS_LOGGING_LEVEL=2 -DSUNDIALS_TEST_UNITTESTS=ON -DEXAMPLES_ENABLE_CXX=ON
run: cmake -G "Visual Studio 17 2022" -B ${{github.workspace}}/build -DSUNDIALS_BUILD_WITH_PROFILING=ON -DSUNDIALS_TEST_UNITTESTS=ON -DEXAMPLES_ENABLE_CXX=ON

- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --verbose

- name: Test
working-directory: ${{github.workspace}}/build
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest -C ${{env.BUILD_TYPE}}
run: ctest -C ${{env.BUILD_TYPE}} --output-on-failure
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ Fix bug on LLP64 platforms (like Windows 64-bit) where `KLU_INDEXTYPE` could be
Check if size of `SuiteSparse_long` is 8 if the size of `sunindextype` is 8
when using KLU.

Fixed several build errors with the Fortran interfaces on Windows systems.

### Deprecation Notices

Numerous ARKODE stepper-specific functions are now deprecated in favor of
Expand Down
2 changes: 1 addition & 1 deletion cmake/SundialsBuildOptionsPre.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ sundials_option(BUILD_SHARED_LIBS BOOL "Build shared libraries" ON)

# Make sure we build at least one type of libraries
if(NOT BUILD_STATIC_LIBS AND NOT BUILD_SHARED_LIBS)
print_error("Both static and shared library generation were disabled.")
message(FATAL_ERROR "Both static and shared library generation were disabled.")
endif()

# ---------------------------------------------------------------
Expand Down
19 changes: 0 additions & 19 deletions cmake/SundialsSetupFortran.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,6 @@
# Fortran 2003 standard
# ---------------------------------------------------------------

# If the Fortran compiler flags are set using environemnt variables (i.e.,
# CMAKE_Fortran_FLAGS is not set), then check if both FFLAGS and FCFLAGS are
# set. If both are set and not the same then a fatal error occurs.
#
# NOTE: This check must occur before 'enable_language(Fortran)' as it will use
# the value of FFLAGS to set CMAKE_Fortran_FLAGS
set(ENV_FFLAGS "$ENV{FFLAGS}")
set(ENV_FCFLAGS "$ENV{FCFLAGS}")

# check if environment variables are used and CMAKE_Fortran_FLAGS is not
if ((NOT "${ENV_FFLAGS}" STREQUAL "") AND (NOT "${ENV_FCFLAGS}" STREQUAL "")
AND ("${CMAKE_Fortran_FLAGS}" STREQUAL ""))

# check if environment variables are equal
if (NOT "${ENV_FFLAGS}" STREQUAL "${ENV_FCFLAGS}")
print_error("FFLAGS='${ENV_FFLAGS}' and FCFLAGS='${ENV_FCFLAGS}' are both set but are not equal.")
endif()
endif()

# -----------------------------------------------------------------------------
# Enable Fortran
# -----------------------------------------------------------------------------
Expand Down
48 changes: 32 additions & 16 deletions cmake/macros/SundialsAddLibrary.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ macro(sundials_add_library target)
# --------------------------------------------------------------------------

# create the target for the object library
add_library(${obj_target} OBJECT ${sources})
add_library(${obj_target} OBJECT ${sources} ${sundials_add_library_UNPARSED_ARGUMENTS})

set_target_properties(${obj_target} PROPERTIES FOLDER "obj")

Expand All @@ -173,6 +173,19 @@ macro(sundials_add_library target)
else()
set(_all_libs ${sundials_add_library_LINK_LIBRARIES})
endif()
# Due to various issues in CMake, particularly https://gitlab.kitware.com/cmake/cmake/-/issues/25365,
# we create a fake custom target to enforce a build order. Without this, parallel builds
# might fail with an error about a missing '.mod' file when Fortran is enabled (see GitHub #410).
set(_stripped_all_libs ${_all_libs})
list(FILTER _stripped_all_libs EXCLUDE REGEX "PUBLIC|INTERFACE|PRIVATE")
foreach(_item ${_stripped_all_libs})
if(NOT TARGET ${_item})
list(REMOVE_ITEM _stripped_all_libs ${_item})
endif()
endforeach()
add_custom_target(fake_to_force_build_order_${obj_target})
add_dependencies(fake_to_force_build_order_${obj_target} ${_stripped_all_libs})
add_dependencies(${obj_target} fake_to_force_build_order_${obj_target})
target_link_libraries(${obj_target} ${_all_libs})
endif()

Expand Down Expand Up @@ -239,25 +252,22 @@ macro(sundials_add_library target)
# set target name
set(_actual_target_name ${target}${_lib_suffix})

add_library(${_actual_target_name} ${_libtype} $<TARGET_OBJECTS:${obj_target}>)

set_target_properties(${_actual_target_name} PROPERTIES FOLDER "src")

# add any object library dependencies
set(_object_sources $<TARGET_OBJECTS:${obj_target}>)
if(sundials_add_library_OBJECT_LIBRARIES)
if(${_libtype} MATCHES "STATIC")
append_static_suffix(sundials_add_library_OBJECT_LIBRARIES _all_objs)
else()
set(_all_objs ${sundials_add_library_OBJECT_LIBRARIES})
endif()
foreach(_tmp ${_all_objs})
# We use target_sources since target_link_libraries does not work
# as expected with CMake 3.12 (see CMake issues 18090 and 18692).
# TODO(DJG): Update whenever we require CMake 3.14 or newer
target_sources(${_actual_target_name} PRIVATE $<TARGET_OBJECTS:${_tmp}>)
list(APPEND _object_sources $<TARGET_OBJECTS:${_tmp}>)
endforeach()
endif()

add_library(${_actual_target_name} ${_libtype} ${_object_sources} ${sundials_add_library_UNPARSED_ARGUMENTS})

set_target_properties(${_actual_target_name} PROPERTIES FOLDER "src")

# add all link libraries
if(SUNDIALS_MATH_LIBRARY)
target_link_libraries(${_actual_target_name} PRIVATE "${SUNDIALS_MATH_LIBRARY}")
Expand Down Expand Up @@ -426,34 +436,41 @@ macro(sundials_add_f2003_library target)
cmake_parse_arguments(sundials_add_f2003_library
"${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

# set target properties and target dependencies so that includes
# and links get passed on when this target is used
if(CMAKE_Fortran_MODULE_DIRECTORY)
set(_includes
PUBLIC
$<BUILD_INTERFACE:${CMAKE_Fortran_MODULE_DIRECTORY}_{{libtype}}>
$<INSTALL_INTERFACE:${Fortran_INSTALL_MODDIR}>
)
set(_properties PROPERTIES Fortran_MODULE_DIRECTORY "${CMAKE_Fortran_MODULE_DIRECTORY}_{{libtype}}")
set(_properties PROPERTIES
Fortran_MODULE_DIRECTORY "${CMAKE_Fortran_MODULE_DIRECTORY}_{{libtype}}"
WINDOWS_EXPORT_ALL_SYMBOLS ON)
else()
set(_includes
PUBLIC
$<BUILD_INTERFACE:${CMAKE_Fortran_MODULE_DIRECTORY}_{{libtype}}>
$<INSTALL_INTERFACE:${Fortran_INSTALL_MODDIR}>
)
set(_properties PROPERTIES Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir")
set(_properties PROPERTIES
Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir"
WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()

# get the name of the C library which the fortran library interfaces to
string(REPLACE "sundials_f" "sundials_" _clib_name "${target}")
string(REPLACE "_mod" "" _clib_name "${_clib_name}")
if(TARGET ${_clib_name})
set(_clib_target ${_clib_name})
else()
set(_clib_target )
endif()

sundials_add_library(${target}
SOURCES ${sundials_add_f2003_library_SOURCES}
OBJECT_LIBRARIES ${sundials_add_f2003_library_OBJECT_LIBRARIES}
LINK_LIBRARIES
PUBLIC ${_clib_target} # depend on the c library
${sundials_add_f2003_library_LINK_LIBRARIES}
PUBLIC ${_clib_name} # depend on the c library
INCLUDE_DIRECTORIES
${sundials_add_f2003_library_INCLUDE_DIRECTORIES}
${_includes}
Expand All @@ -466,7 +483,6 @@ macro(sundials_add_f2003_library target)
SOVERSION ${sundials_add_f2003_library_SOVERSION}
${sundials_add_f2003_library_UNPARSED_ARGUMENTS}
)

endmacro()


Expand Down
2 changes: 2 additions & 0 deletions doc/shared/RecentChanges.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ Fix bug on LLP64 platforms (like Windows 64-bit) where ``KLU_INDEXTYPE`` could b
Check if size of ``SuiteSparse_long`` is 8 if the size of ``sunindextype`` is 8
when using KLU.

Fixed several build errors with the Fortran interfaces on Windows systems.

**Deprecation Notices**

Numerous ARKODE stepper-specific functions are now deprecated in favor of
Expand Down
3 changes: 1 addition & 2 deletions doc/shared/sundials/Fortran.rst
Original file line number Diff line number Diff line change
Expand Up @@ -557,8 +557,7 @@ Important notes on portability
------------------------------
The SUNDIALS Fortran 2003 interface *should* be compatible with any compiler
supporting the Fortran 2003 ISO standard. However, it has only been tested and
confirmed to be working with GNU Fortran 4.9+ and Intel Fortran 18.0.1+.
supporting the Fortran 2003 ISO standard.
Upon compilation of SUNDIALS, Fortran module (``.mod``) files are generated for
each Fortran 2003 interface. These files are highly compiler specific, and thus
Expand Down
13 changes: 9 additions & 4 deletions doc/shared/sundials/Install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,8 @@ default configuration:
.. _Installation.CMake.Options:


Configuration options (Unix/Linux)
-----------------------------------
Configuration options
---------------------

A complete list of all available options for a CMake-based SUNDIALS
configuration is provide below. Note that the default values shown
Expand Down Expand Up @@ -590,6 +590,11 @@ illustration only.

Default: ``OFF``

.. warning:: There is a known issue with MSYS/gfortran and SUNDIALS shared libraries
that causes linking the Fortran interfaces to fail when buidling SUNDIALS. For
now the work around is to only build with static libraries when using MSYS with
gfortran on Windows.

.. cmakeoption:: SUNDIALS_LOGGING_LEVEL

Set the maximum logging level for the SUNLogger runtime API. The higher this is set,
Expand Down Expand Up @@ -669,7 +674,7 @@ illustration only.

Default: "REF;OMP"

.. versionchanged: x.y.z
.. versionchanged: x.y.z
The ``DPCPP`` option was changed to ``SYCL`` to align with Ginkgo's naming convention.
Expand Down Expand Up @@ -1704,7 +1709,7 @@ header files.
without any notice and relying on them may break your code.


Using SUNDIALS in your prpject
Using SUNDIALS in your project
------------------------------

After building and installing SUNDIALS, using SUNDIALS in your application involves
Expand Down
Loading

0 comments on commit e4717fe

Please sign in to comment.