Open barracuda156 opened 10 months ago
UPD. Surprisingly, some runtime flag is still required for w/e reason: just trashing it breaks linking.
Indeed, this is why we are transitioning to Meson. The autotools build system was originally written only for Linux. I'ts tricky to do this correctly on Mac with autotools as by default gcc is a symlink to clang on macOS (who thought that was a good idea?).
Replacing the flag with -lc++
works for Clang builds. So if a test is added for the compiler being used, then it shall work correctly: use -lc++
when clang is being used (clang is never a symlink to gcc), otherwise use -lstdc++
for gcc.
Thanks @barracuda156, we can definitely do that.
use
-lc++
when clang is being used (clang is never a symlink to gcc), otherwise use-lstdc++
for gcc.
I'm not sure this is ideal either. On Linux it is perfectly normal to use clang with libstdc++. I'd say on most distributions that is the default. Usually libc++ is even a seperate package, so you may not even have libc++ installed when using clang, which will break with that rule above.
I think ideally autotools would figure out which C++ standard library is used when linking with CXX
and link that one explicitly when linking with FC
. Or at least look for any standard library that's available and link whichever is found first, possibly configurable by the user.
@mjacobse It is also possible to use gcc
with libc++
, though it is not a typical case.
Anyway, the patch so far does not work for Clang anyway. And I agree with you, the right thing is to test for C++ runtime being used, not compiler. Going by compiler is an acceptable heuristic fixing typical scenarios, but leaving some other cases broken.
For the record, with the right library being set (as of now, we just patch it in for Clang builds), spral
build fine on every macOS version: https://ports.macports.org/port/spral/details
(PowerPC being tested locally by myself, the rest we see via buildbots here.)
Yeah I agree that ideally we should test for the C++ runtime but I have no idea if that is even possible with autotools let alone how to do it.
@jfowkes Maybe solve it another way: why at all an explicit flag is needed at the moment? It is needed indeed, but it should not be. Normally you never have to pass this flag manually, not on macOS at least.
@barracuda156 that is a good point but I believe it is mandatory when the Fortran compiler is used to link everything together at the end (cf your link failures in #170). SPRAL is very unusual in its mixing of Fortran and C++.
@jfowkes I do remember errors I got, and those surprised me. We have multiple ports which use Fortran, and quite a number of them use it together with C++. I do not recall cases where this flag was needed (this does not mean there are none, but IMO it is at least uncommon).
FWIW, LLVM documentation states it should not be required: https://releases.llvm.org/5.0.0/projects/libcxx/docs/UsingLibcxx.html (the statement is inaccurate in a sense of ignoring earlier versions of macOS and FreeBSD, but on those -lstdc++
should not be required).
As far as i know the issue is that both the C++ and the Fortran standard library are required. When linking with the Fortran compiler, only the Fortran standard library will be linked automatically, the C++ one has to be linked manually/explicitly. When linking with the C++ compiler instead, only the C++ one will be automatic but the Fortran one needs to be added manually/explicitly.
But that might actually be an idea. If we link with the C++ compiler instead, then libstdc++ or libc++ will be figured out automatically. Now we "only" need to collect the correct Fortran libraries, which is perhaps easier?
@mjacobse I believe, default Fortran will be gfortran
with its libgfortran
on any Unix-like platform. I am not sure if manual flags for supplementary libs are needed (libquadmath
etc.). Those are not universally supported, at least libquadmath
is not (i.e. it cannot be passed to the linker indiscriminately).
For the flags to link the Fortran runtime libs, there is macro AC_FC_LIBRARY_LDFLAGS
With shared libs, neither one nor the other should be necessary, but with static libs, I think so.
@mjacobse in theory linking with the C++ compiler instead would be easier but trying to figure out the correct Fortran libraries for something as complicated as Intel OneAPI would be rather tricky.
I opened a PR to update the Meson build system: https://github.com/ralna/spral/pull/181 It should better detect the correct link flag for C++. If you know additional corner cases, don't hesitate to leave a comment.
Just in case, in the latest release (2024.01.18), it is still unfixed:
/opt/local/bin/gfortran-mp-13 -fopenmp -pipe -Os -m64 -L/opt/local/lib -Wl,-headerpad_max_install_names -L/opt/local/lib/libomp -lomp -Wl,-rpath,/opt/local/lib/libgcc -Wl,-syslibroot,/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk -arch x86_64 -o spral_ssids driver/spral_ssids.o driver/cuda_helper_nogpu.o -L. -lspral -lmetis -lopenblas -L/opt/local/lib -lhwloc -lm -lxml2 -lpthread -lxml2 -lz -llzma -liconv -licui18n -licuuc -licudata -L/opt/local/lib -L/opt/local/lib/libomp -L/opt/local/lib/gcc13/gcc/x86_64-apple-darwin21/13.2.0 -L/opt/local/lib/gcc13/gcc/x86_64-apple-darwin21/13.2.0/../../.. -lomp -lgfortran -lquadmath -lstdc++
Undefined symbols for architecture x86_64:
"__ZNSt20bad_array_new_lengthC1Ev", referenced from:
__ZSt28__throw_bad_array_new_lengthB7v160006v in libspral.a(guess_topology.o)
__ZSt28__throw_bad_array_new_lengthB7v160006v in libspral.a(NumericSubtree.o)
__ZSt28__throw_bad_array_new_lengthB7v160006v in libspral.a(SymbolicSubtree.o)
__ZSt28__throw_bad_array_new_lengthB7v160006v in libspral.a(ldlt_app.o)
"__ZNSt3__119__shared_weak_count14__release_weakEv", referenced from:
__ZN5spral5ssids3cpu12assemble_preIdNS1_11AppendAllocIdEENS1_14BuddyAllocatorIdNSt3__19allocatorIdEEEEEEvbiRKNS1_12SymbolicNodeEPPvRNS1_11NumericNodeIT_T1_EERT0_RSH_RNS6_6vectorINS1_9WorkspaceENS7_ISO_EEEEPKSG_ST_ in libspral.a(NumericSubtree.o)
__ZN5spral5ssids3cpu13assemble_postIdNS1_14BuddyAllocatorIdNSt3__19allocatorIdEEEEEEviRKNS1_12SymbolicNodeEPPvRNS1_11NumericNodeIT_T0_EERSF_RNS4_6vectorINS1_9WorkspaceENS5_ISK_EEEE in libspral.a(NumericSubtree.o)
__ZN5spral5ssids3cpu23SmallLeafNumericSubtreeILb1EdNS1_11AppendAllocIdEENS1_14BuddyAllocatorIdNSt3__19allocatorIdEEEEE8assembleEiRKNS1_12SymbolicNodeEPNS1_11NumericNodeIdS9_EERS4_RS9_PiPKdSL_ in libspral.a(NumericSubtree.o)
__ZNSt3__110shared_ptrIN5spral5ssids3cpu21append_alloc_internal4PoolEED2B7v160006Ev in libspral.a(NumericSubtree.o)
__ZNSt3__110shared_ptrIN5spral5ssids3cpu20buddy_alloc_internal5TableINS_9allocatorIcEEEEED2B7v160006Ev in libspral.a(NumericSubtree.o)
__ZN5spral5ssids3cpu23SmallLeafNumericSubtreeILb0EdNS1_11AppendAllocIdEENS1_14BuddyAllocatorIdNSt3__19allocatorIdEEEEE12assemble_preERKNS1_12SymbolicNodeERNS1_11NumericNodeIdS9_EERS4_RS9_PiPKdSL_ in libspral.a(NumericSubtree.o)
__ZNSt3__110shared_ptrIiED2B7v160006Ev in libspral.a(SymbolicSubtree.o)
...
"__ZNSt3__119__shared_weak_countD2Ev", referenced from:
__ZNSt3__120__shared_ptr_pointerIPN5spral5ssids3cpu21append_alloc_internal4PoolENS_10shared_ptrIS5_E27__shared_ptr_default_deleteIS5_S5_EENS_9allocatorIS5_EEED1Ev in libspral.a(NumericSubtree.o)
__ZNSt3__120__shared_ptr_pointerIPN5spral5ssids3cpu21append_alloc_internal4PoolENS_10shared_ptrIS5_E27__shared_ptr_default_deleteIS5_S5_EENS_9allocatorIS5_EEED0Ev in libspral.a(NumericSubtree.o)
__ZNSt3__120__shared_ptr_pointerIPN5spral5ssids3cpu20buddy_alloc_internal5TableINS_9allocatorIcEEEENS_10shared_ptrIS8_E27__shared_ptr_default_deleteIS8_S8_EENS6_IS8_EEED1Ev in libspral.a(NumericSubtree.o)
__ZNSt3__120__shared_ptr_pointerIPN5spral5ssids3cpu20buddy_alloc_internal5TableINS_9allocatorIcEEEENS_10shared_ptrIS8_E27__shared_ptr_default_deleteIS8_S8_EENS6_IS8_EEED0Ev in libspral.a(NumericSubtree.o)
__ZNSt3__120__shared_ptr_pointerIPiNS_14default_deleteIA_iEENS_9allocatorIiEEED1Ev in libspral.a(SymbolicSubtree.o)
__ZNSt3__120__shared_ptr_pointerIPiNS_14default_deleteIA_iEENS_9allocatorIiEEED0Ev in libspral.a(SymbolicSubtree.o)
"__ZNSt3__15alignEmmRPvRm", referenced from:
__ZN5spral5ssids3cpu20buddy_alloc_internal4PageINSt3__19allocatorIcEEEC2EmRKS6_ in libspral.a(NumericSubtree.o)
__ZN5spral5ssids3cpu9Workspace15alloc_and_alignEm in libspral.a(NumericSubtree.o)
__ZN5spral5ssids3cpu21append_alloc_internal4Pool8allocateEm in libspral.a(NumericSubtree.o)
__ZN5spral5ssids3cpu20buddy_alloc_internal4PageINSt3__19allocatorIcEEEC2EmRKS6_ in libspral.a(ldlt_app.o)
__ZN5spral5ssids3cpu9Workspace15alloc_and_alignEm in libspral.a(ldlt_app.o)
"__ZNSt9bad_allocC1Ev", referenced from:
__ZN5spral5ssids3cpu21append_alloc_internal4PageC2EmPS3_ in libspral.a(NumericSubtree.o)
__ZN5spral5ssids3cpu9Workspace15alloc_and_alignEm in libspral.a(NumericSubtree.o)
__ZN5spral5ssids3cpu9Workspace15alloc_and_alignEm in libspral.a(ldlt_app.o)
"__ZTINSt3__119__shared_weak_countE", referenced from:
__ZTINSt3__120__shared_ptr_pointerIPN5spral5ssids3cpu21append_alloc_internal4PoolENS_10shared_ptrIS5_E27__shared_ptr_default_deleteIS5_S5_EENS_9allocatorIS5_EEEE in libspral.a(NumericSubtree.o)
__ZTINSt3__120__shared_ptr_pointerIPN5spral5ssids3cpu20buddy_alloc_internal5TableINS_9allocatorIcEEEENS_10shared_ptrIS8_E27__shared_ptr_default_deleteIS8_S8_EENS6_IS8_EEEE in libspral.a(NumericSubtree.o)
__ZTINSt3__120__shared_ptr_pointerIPiNS_14default_deleteIA_iEENS_9allocatorIiEEEE in libspral.a(SymbolicSubtree.o)
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make[1]: *** [spral_ssids] Error 1
make[1]: Leaving directory `/opt/local/var/macports/build/_Users_runner_work_macports-ports_macports-ports_ports_math_spral/spral/work/spral-2024.01.18'
make: *** [all] Error 2
make: Leaving directory `/opt/local/var/macports/build/_Users_runner_work_macports-ports_macports-ports_ports_math_spral/spral/work/spral-2024.01.18'
Error: Failed to build spral: command execution failed
DEBUG: Error code: CHILDSTATUS 9370 2
DEBUG: Backtrace: command execution failed
while executing
"system {*}$notty {*}$callback {*}$nice $fullcmdstrin
Did you compile with the Meson build system? We only updated this build system (https://github.com/ralna/spral/pull/181).
Ok, got it. No, we build it with autotools at the moment.
This will be wrong for most set-up of macOS:
As well as some other systems, which happen to use
libc++
(but notifort
fortran).