LLNL / sundials

Official development repository for SUNDIALS - a SUite of Nonlinear and DIfferential/ALgebraic equation Solvers. Pull requests are welcome for bug fixes and minor changes.
https://computing.llnl.gov/projects/sundials
BSD 3-Clause "New" or "Revised" License
515 stars 125 forks source link

[BUG] SUNDIALS fails to build due to a linker error with MSYS+gfortran on Windows #507

Open balos1 opened 3 months ago

balos1 commented 3 months ago

See https://github.com/LLNL/sundials/actions/runs/9586239666/job/26433779371?pr=506 and the discussion on #506.

mmuetzel commented 3 months ago

To reduce the risk of loosing some test results over time, here is a copy of what I wrote on #506:

It looks like WINDOWS_EXPORT_ALL_SYMBOLS doesn't work with the two-step creation of shared libraries in SUNDIALS. (I wasn't aware of that.) IIUC, an object library is created from the source files. And in a second step a shared library is created from that object library. It looks like WINDOWS_EXPORT_ALL_SYMBOLS only exports symbols from the object files corresponding to a shared library (not from an object library).

Alternatively, symbols could be exported from a Fortran library using ATTRIBUTES. I tried to add dllexport attributes manually to some of the functions and subroutines in libsundials_fcore_mod like this:

diff --git "a/src/sundials/fmod_int64/fsundials_core_mod.f90" "b/src/sundials/fmod_int64/fsundials_core_mod.f90"
index 7096d0c6c..9361fa509 100644
--- "a/src/sundials/fmod_int64/fsundials_core_mod.f90"
+++ "b/src/sundials/fmod_int64/fsundials_core_mod.f90"
@@ -2311,6 +2311,8 @@ type(C_PTR), target, intent(inout) :: ctx
 integer(C_INT) :: fresult 
 type(C_PTR) :: farg1 

+!GCC$ ATTRIBUTES DLLEXPORT :: FSUNContext_Free
+
 farg1 = c_loc(ctx)
 fresult = swigc_FSUNContext_Free(farg1)
 swig_result = fresult
@@ -2838,6 +2840,8 @@ type(N_Vector), target, intent(inout) :: z
 real(C_DOUBLE) :: farg1 
 type(C_PTR) :: farg2 

+!GCC$ ATTRIBUTES DLLEXPORT :: FN_VConst
+
 farg1 = c
 farg2 = c_loc(z)
 call swigc_FN_VConst(farg1, farg2)
@@ -4656,6 +4660,8 @@ type(SUNAdaptController), target, intent(inout) :: c
 integer(C_INT) :: fresult 
 type(C_PTR) :: farg1 

+!GCC$ ATTRIBUTES DLLEXPORT :: FSUNAdaptController_Destroy
+
 farg1 = c_loc(c)
 fresult = swigc_FSUNAdaptController_Destroy(farg1)
 swig_result = fresult

With these added, I can see that they are exported from the .dll.

But iiuc, these attributes are compiler-specific. (I was using gfortran for the test.) Intel compilers would require, e.g., !DEC$ ATTRIBUTES DLLEXPORT :: FSUNAdaptController_Destroy (note: DEC instead of GCC).

What is the motivation for the two step process to create shared libraries?