fncnt / librna-sys

Unsafe low-level Rust bindings for the ViennaRNA package.
https://crates.io/crates/librna-sys
Other
2 stars 0 forks source link

Building a crate with `librna-sys` as a dependency might fail linking against `openmp` #3

Open fncnt opened 11 months ago

fncnt commented 11 months ago

If you use librna-sys as a dependency you might encounter an error similar to this:

error: linking with `cc` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:~/.cargo/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:~/.dotnet/tools:/var/lib/flatpak/exports/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/usr/lib/rustup/bin:~/bin" VSLANG="1033" "cc" "-m64" "/tmp/rustcVe6E8r/symbols.o" "~/crate-name/target/release/deps/executable-77097ed7f3783d37.executable.acdf1c1d4c87c16c-cgu.0.rcgu.o" "-Wl,--as-needed" "-L" "~/crate-name/target/release/deps" "-L" "/usr/lib" "-L" "/usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../lib/" "-L" "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/tmp/rustcVe6E8r/liblibrna_sys-9e8497eadd24f151.rlib" "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-b114db70ea0690b1.rlib" "-Wl,-Bdynamic" "-lc" "-lm" "-lrt" "-lpthread" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "~/Dev/crate-name/target/release/deps/executable-77097ed7f3783d37" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-Wl,-O1" "-nodefaultlibs"
  = note: /usr/bin/ld: /tmp/rustcVe6E8r/liblibrna_sys-9e8497eadd24f151.rlib(svm.o): in function `svm_predict_values._omp_fn.0':
          ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:2610:(.text+0x1544): undefined reference to `GOMP_loop_nonmonotonic_guided_start'
          /usr/bin/ld: ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:2610:(.text+0x1555): undefined reference to `GOMP_loop_end_nowait'
          /usr/bin/ld: ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:2610:(.text+0x15a9): undefined reference to `GOMP_loop_nonmonotonic_guided_next'
          /usr/bin/ld: /tmp/rustcVe6E8r/liblibrna_sys-9e8497eadd24f151.rlib(svm.o): in function `svm_predict_values._omp_fn.1':
          ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:2629:(.text+0x165c): undefined reference to `GOMP_loop_nonmonotonic_guided_start'
          /usr/bin/ld: ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:2629:(.text+0x1665): undefined reference to `GOMP_loop_end_nowait'
          /usr/bin/ld: ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:2629:(.text+0x1699): undefined reference to `GOMP_loop_nonmonotonic_guided_next'
          /usr/bin/ld: /tmp/rustcVe6E8r/liblibrna_sys-9e8497eadd24f151.rlib(svm.o): in function `svm_predict_values':
          ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:2610:(.text+0x3ec8): undefined reference to `GOMP_parallel'
          /usr/bin/ld: ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:2629:(.text+0x3f6a): undefined reference to `GOMP_parallel'
          /usr/bin/ld: /tmp/rustcVe6E8r/liblibrna_sys-9e8497eadd24f151.rlib(svm.o): in function `SVR_Q::get_Q(int, int) const [clone ._omp_fn.0]':
          ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:1408:(.text._ZNK5SVR_Q5get_QEii._omp_fn.0[_ZNK5SVR_Q5get_QEii]+0x4f): undefined reference to `GOMP_loop_nonmonotonic_guided_start'
          /usr/bin/ld: ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:1408:(.text._ZNK5SVR_Q5get_QEii._omp_fn.0[_ZNK5SVR_Q5get_QEii]+0x58): undefined reference to `GOMP_loop_end_nowait'
          /usr/bin/ld: ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:1408:(.text._ZNK5SVR_Q5get_QEii._omp_fn.0[_ZNK5SVR_Q5get_QEii]+0x8a): undefined reference to `GOMP_loop_nonmonotonic_guided_next'
          /usr/bin/ld: /tmp/rustcVe6E8r/liblibrna_sys-9e8497eadd24f151.rlib(svm.o): in function `SVC_Q::get_Q(int, int) const [clone ._omp_fn.0]':
          ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:1290:(.text._ZNK5SVC_Q5get_QEii._omp_fn.0[_ZNK5SVC_Q5get_QEii]+0x57): undefined reference to `GOMP_loop_nonmonotonic_guided_start'
          /usr/bin/ld: ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:1293:(.text._ZNK5SVC_Q5get_QEii._omp_fn.0[_ZNK5SVC_Q5get_QEii]+0xee): undefined reference to `GOMP_loop_nonmonotonic_guided_next'
          /usr/bin/ld: ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:1293:(.text._ZNK5SVC_Q5get_QEii._omp_fn.0[_ZNK5SVC_Q5get_QEii]+0xfb): undefined reference to `GOMP_loop_end_nowait'
          /usr/bin/ld: /tmp/rustcVe6E8r/liblibrna_sys-9e8497eadd24f151.rlib(svm.o): in function `SVR_Q::get_Q(int, int) const':
          ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:1408:(.text._ZNK5SVR_Q5get_QEii[_ZNK5SVR_Q5get_QEii]+0x128): undefined reference to `GOMP_parallel'
          /usr/bin/ld: /tmp/rustcVe6E8r/liblibrna_sys-9e8497eadd24f151.rlib(svm.o): in function `SVC_Q::get_Q(int, int) const':
          ~/builddir/ViennaRNA-2.6.4/src/ViennaRNA/../libsvm-3.31/svm.cpp:1290:(.text._ZNK5SVC_Q5get_QEii[_ZNK5SVC_Q5get_QEii]+0x87): undefined reference to `GOMP_parallel'
          collect2: error: ld returned 1 exit status

  = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

error: could not compile `crate-name` (bin "executable") due to previous error

The current solution to this is to add openmp-sys as a dependency to your crate as well. I'm currently hesitating to do this internally in librna-sys but that might change in the future.

fncnt commented 9 months ago

related upstream issue: https://github.com/ViennaRNA/ViennaRNA/issues/215

croots commented 2 months ago

Still getting this issue even with librna-sys as a dependency and libsvm downgraded to 3.31. Not sure what further troubleshooting approaches to take

fncnt commented 2 months ago

Hi @croots! Could you provide further information? Which version of ViennaRNA are you using? 2.6.4 is already statically linking against a bundled libsvm-3.31. There shouldn't be any need to downgrade. You said you added librna-sys as a dependency, did you mean openmp-sys? You should follow the instructions of openmp-sys (i.e. adding extern crate openmp_sys; to your code).

If that still doesn't help, could you share logs containing the specific error messages or a minimal example project reproducing the error?

croots commented 2 months ago

Hi! Thanks for your help. That was my issue - adding extern crate openmp_sys to my main fixed the build. Thanks for maintaining this useful wrapper and keeping an eye on the repo with your fast responce!

fncnt commented 2 months ago

You're welcome!

RaumZeit commented 1 month ago

Hey there, I'm not familiar at all with rust, but wouldn't it make sense to include something like:

cargo:rustc-link-lib=gomp

here? I'm just wondering, since it appears to be similar to https://github.com/rust-lang/cc-rs/issues/266, and the issue doesn't show up if you use any C/C++ compiler. The RNAlib2.pc file adds the -fopenmp flag to Libs and the C/C++ compilers then automatically link against the correct OpenMP libraries... Maybe this is not happening with the rust compiler?

Let me know if this is an issue that I could resolve at our (ViennaRNA Package) end!

Cheers!

EDIT: It seems you are already using the correct way by adding openmp-sys (https://crates.io/crates/openmp-sys) So, maybe requiring that internally in librna-sys would make sense, if the C library has been build with OpenMP support...

fncnt commented 1 month ago

@Raumzeit thanks for chiming in! Basically, the remaining issue for me is the decision whether to require openmp-sys internally or not. If I remember correctly, I didn't do this because it seemed to me that ViennaRNA can be configured without OpenMP support in which case I didn't want to break compilation of librna-sys on systems without OpenMP.

I might have to check the whole linking setup again though. It didn't appear to be a problem with an earlier version of libsvm bundled in ViennaRNA (which the SHAPEwarp people seemed to notice too).

However, I'm not familiar enough with the configuration in ViennaRNA. E.g. would disabling OpenMP support for ViennaRNA also disable OpenMP support for the bundled libsvm?

Additionally, I'm not sure whether OpenMP is linked statically in ViennaRNA. That could be the reason why the problem didn't occur in librna-sys up to a certain version of ViennaRNA when libsvm was updated? I.e. is -fopenmp in RNAlib2.pc only necessary for libsvm or does ViennaRNA itself also link dynamically against OpenMP?

If I could determine unambiguously whether libRNA.a dynamically links OpenMP somewhere (be it in ViennaRNA code or libsvm code), ~I could probably include openmp-sys conditionally in my lib.rs using some build.rs shenanigans~.

(Edit) tl;dr: if ViennaRNA unconditionally relies on OpenMP I can simply include openmp-sys as well. Otherwise I should document the solution/workaround in a more prominent location (i.e. README file) and optionally expose a cargo feature for conveniently toggling the desired behavior.