ralna / spral

Sparse Parallel Robust Algorithms Library
https://ralna.github.io/spral/
Other
104 stars 27 forks source link

C++ runtime should not be hardcoded in configure #165

Open barracuda156 opened 10 months ago

barracuda156 commented 10 months ago

This will be wrong for most set-up of macOS:

# Establish -lstdc++ or equivalent
if test "x$CXXLIB" == "x"; then
   if test "x$CXX" == "xifort"; then
      CXXLIB="-cxxlib"
   else
      CXXLIB="-lstdc++"
   fi
fi

As well as some other systems, which happen to use libc++ (but not ifort fortran).

barracuda156 commented 10 months ago

UPD. Surprisingly, some runtime flag is still required for w/e reason: just trashing it breaks linking.

jfowkes commented 10 months ago

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?).

barracuda156 commented 10 months ago

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.

jfowkes commented 10 months ago

Thanks @barracuda156, we can definitely do that.

mjacobse commented 10 months ago

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.

barracuda156 commented 10 months ago

@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.

barracuda156 commented 10 months ago

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.)

jfowkes commented 10 months ago

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.

barracuda156 commented 10 months ago

@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.

jfowkes commented 10 months ago

@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++.

barracuda156 commented 10 months ago

@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).

mjacobse commented 10 months ago

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?

barracuda156 commented 10 months ago

@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).

svigerske commented 10 months ago

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.

jfowkes commented 10 months ago

@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.

amontoison commented 7 months ago

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.

barracuda156 commented 6 months ago

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
amontoison commented 6 months ago

Did you compile with the Meson build system? We only updated this build system (https://github.com/ralna/spral/pull/181).

barracuda156 commented 6 months ago

Ok, got it. No, we build it with autotools at the moment.