How to compile lapack with rust - rust

I am trying to use lapack with rust. Therefore I started with the example from the rust crates https://crates.io/crates/lapack
My Cargo.toml file looks like
enter [package]
name = "matmul"
version = "0.1.0"
edition = "2021"
[dependencies]
lapack = "0.19.0"
[profile.dev]
opt-level = 0
[profile.release]
opt-level = 3
When trying to compile I get the following error
error: linking with `cc` failed: exit status: 1
|
= note: "cc" "-m64"
then there is a file list
"-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs"
= note: /usr/bin/ld: ~/programs/Rust/matmul/target/debug/deps/matmul-9ca04f70dc77cf78.3ybb6pvq2ip54xxg.rcgu.o: in function `lapack::dsyev':
~/.cargo/registry/src/github.com-1ecc6299db9ec823/lapack-0.19.0/src/lapack-sys.rs:29108: undefined reference to `dsyev_'
collect2: error: ld returned 1 exit status
= help: 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 `matmul` due to previous error
Am I missing some dependencies or why does this code not compile?

Looks like your gnu linker is stuck - not uncommon. I see cc, so I’m guessing this is a Cray. You need to make sure you have the correct modules loaded and possibly figure out where lapack lives. Typically, this is cray-libsci (if I remember correctly). Then, you may need to tell cargo explicitly as suggested in the error message: cargo:rustc-link-lib.
Does that help?

Related

Could not compile `lazy_static`

I'm having a hard time cross-compiling an embedded Rust project that worked before for a raspberry pi. I have all the needed deps in Cargo.toml but on doing:
$ cargo build --target thumbv7m-none-eabi
I get the following error.
error[E0463]: can't find crate for `std`
--> /home/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-1.4.0/src/inline_lazy.rs:9:1
|
9 | extern crate std;
| ^^^^^^^^^^^^^^^^^ can't find crate
|
= note: the `thumbv7m-none-eabi` target may not support the standard library
= help: consider building the standard library from source with `cargo build -Zbuild-std`
For more information about this error, try `rustc --explain E0463`.
error: could not compile `lazy_static` due to previous error
$ rustup show
installed targets for active toolchain
--------------------------------------
thumbv7m-none-eabi
x86_64-unknown-linux-gnu
active toolchain
----------------
nightly-x86_64-unknown-linux-gnu (default)
rustc 1.64.0-nightly (38b72154d 2022-07-11)
Compilation used to work previously without lazy_static as a dependency in cargo.toml,now I don't understand why this is happening.
By default lazy_static depends on the rust standard library, which as the compiler told you
may not be supported on the thumbv7m-none-eabi target
If you do not need the standard library in your project you can enable the no-std feature of lazy_static like this:
lazy_static = { version = "1.5.0", features = ["spin_no_std"] }
as described here.

How to fix "error: could not find native static library `c`, perhaps an -L flag is missing?" or how do I compile rust binaries for openwrt?

I'm wanting to compile binaries for openwrt 19.07.7 on mips with limited space.
OpenWrt 19.07.7, r11306-c4a6851c72
-----------------------------------------------------
root#OpenWrt:~# df /
Filesystem 1K-blocks Used Available Use% Mounted on
overlayfs:/overlay 3392 1276 2116 38% /
root#OpenWrt:~# ls -s
662 crosshello 3 helloworld
root#OpenWrt:~# ldd --version
musl libc (mips-sf)
Version 1.1.24
Above you can see the size of crosshello (cross compiled using rust) and helloworld (cross compiled using gcc). There is limited space on the target as you can see.
I followed https://github.com/japaric/rust-cross and it works. However I had to reduce the size of the binary to get it to fit. Following https://github.com/johnthagen/min-sized-rust I got the binary (the "Cross compiling with cargo" hello world with clap from the first link) to fit. I haven't compiled my own program yet. I got stuck a the "Optimize libstd with build-std" section.
I'm getting the above error:
$ cargo +nightly build -Z build-std=std,panic_abort --target=mips-unknown-linux-musl --release
Compiling libc v0.2.106
...
error: could not find native static library `c`, perhaps an -L flag is missing?
error: could not compile `libc` due to previous error
warning: build failed, waiting for other jobs to finish...
error: build failed
How do I fix that? I don't want to static link against the system libc, I want it dynamically linked like other binaries on that platform. But not sure how to do that. If I use the standard libstd the binaries are dynamically linked just fine.
Alternatively I could try nostd but my code would need significant modification and I'm not sure that would fix this problem anyway. Alternatively I could just go ahead compile my actual project with libstd and it might fit. However my project is doing data logging, so the binary is competing for space with data I want to store, so I want to minimize space as much as possible.
I've also seen reference to cargo-bloat so I'll probably check that out to find what all the space is being used for in the binary.
I'm open to different strategies to achieve what I want if anyone has ideas?
On my dev system:
$ cat .cargo/config
[target.mips-unknown-linux-musl]
ar = "/home/alex/projects/openwrt-sdk-19.07.7-ath79-generic_gcc-7.5.0_musl.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-7.5.0_musl/bin/mips-openwrt-linux-ar"
linker = "/home/alex/projects/openwrt-sdk-19.07.7-ath79-generic_gcc-7.5.0_musl.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-7.5.0_musl/bin/mips-openwrt-linux-gcc"
$ cat Cargo.toml
#cargo-features = ["strip"]
[package]
name = "crosshello"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = "3.0.0-beta.5"
[profile.release]
#strip = true
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
(The binaries are stripped, currently I'm stripping them manually.)

Link to external object using the right (target-specific) compiler

I have a Rust crate that is targeting AVR. If I do a cargo build, it fails at linking, which is expected because I will need to add an extra object (compiled from C) to it. However, the error message shows that Cargo has correctly picked up from the target definition that it should use avr-gcc for linking:
"avr-gcc" "-mmcu=atmega328p" ....
= note: chirp8-avr/target/avr-unknown-gnu-atmega328/release/deps/chirp8_avr-e38dd93db57fe6d7.chirp8_avr.dlqaoark-cgu.0.rcgu.o: In function `main':
chirp8_avr.dlqaoark-cgu.0:(.text.main+0x18a): undefined reference to `font_rom_size'
chirp8_avr.dlqaoark-cgu.0:(.text.main+0x19e): undefined reference to `read_font_rom'
chirp8_avr.dlqaoark-cgu.0:(.text.main+0x1b4): undefined reference to `prog_rom_size'
chirp8_avr.dlqaoark-cgu.0:(.text.main+0x1c6): undefined reference to `read_prog_rom'
collect2: error: ld returned 1 exit status
So the next logical step is to add my external C source to the crate. From what I understand, cc is exactly the crate for that. So let's try that: I add cc to my [build-dependencies], and write the following build.rs:
fn main() {
cc::Build::new()
// .flag("-mmcu=atmega328p").pic(false)
.file("src/rom.c")
.compile("rom");
}
If I now try building again, this fails because Cargo suddenly seems to have forgotten to use avr-gcc, and is instead trying to use the system's default C compiler:
running: "cc" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-Wall" "-Wextra" "-o" "chirp8-avr/target/avr-unknown-gnu-atmega328/release/build/chirp8-avr-fd0f12cc4390c66b/out/src/rom.o" "-c" "src/rom.c"
cargo:warning=src/rom.c:1:10: fatal error: avr/pgmspace.h: No such file or directory
cargo:warning= 1 | #include <avr/pgmspace.h>
cargo:warning= | ^~~~~~~~~~~~~~~~
cargo:warning=compilation terminated.
exit code: 1
What am I doing wrong? Why is the target platform not picked up correctly by Cargo?
As documented in the cc crate's Readme:
This crate calls out to the most relevant compiler for a platform, for example using cl on MSVC.
Inspecting the source reveals that the cc crate does this with some hard-coded logic for certain statically known host/target combinations. Unfortunately, avr is not a target for which it knows to use avr-gcc.
The Readme also states:
External configuration via environment variables
To control the programs and flags used for building, the builder can
set a number of different environment variables.
[ deletia ]
CC - the actual C
compiler used. Note that this is used as an exact executable name, so
(for example) no extra flags can be passed inside this variable, and
the builder must ensure that there aren't any trailing spaces. This
compiler must understand the -c flag. For certain TARGETs, it also is
assumed to know about other flags (most common is -fPIC).
[ deletia ]
Each of these variables can also be supplied with certain prefixes and
suffixes, in the following prioritized order:
<var>_<target> - for example, CC_x86_64-unknown-linux-gnu
<var>_<target_with_underscores> - for example,
CC_x86_64_unknown_linux_gnu
<build-kind>_<var> - for example, HOST_CC
or TARGET_CFLAGS
<var> - a plain CC, AR as above.
If none of these
variables exist, cc-rs uses built-in defaults
Therefore, I suggest adding to your build.rs:
std::env::set_var("CC_avr-unknown-gnu-atmega328", "avr-gcc");

undefined reference to `__gcov_exit'?

while I am building glibc library using yocto project it is giving
error: missing attribute ((constructor)) support??
after adding the coverage flags:
TARGET_CFLAGS += "-fprofile-arcs -ftest-coverage"
TARGET_LDFLAGS += "-lgcov -fprofile-arcs -ftest-coverage"
still, I am getting an error for glibc.
Please find the link of config log file : https://drive.google.com/file/d/14tiQJ8JIFE_tDWt3H9tS8zBBQROcZDNa/view
It is not working even after adding the following line in conf/local.conf :
EXTRA_OECONF = "libc_cv_ctors_header=yes"
Even i tried this
EXTRA_OECONF_append = "libc_cv_ctors_header=yes"
please find the config log file generated during compilation : https://drive.google.com/open?id=1kxTu8pt7h_9ty55OywP9Ilmmp04T61Rr
So, How to resolve this error?
Log file error Point
poky-linux/gcc/i586-poky-linux/8.2.0/ld: /tmp/ccxetEc1.o: in function `_GLOBAL__sub_D_00100_1__start':
conftest.c:(.text.exit+0x40): undefined reference to `__gcov_exit'<br>
collect2: error: ld returned 1 exit status<br>
configure:5682: $? = 1<br>
configure:5702: error: missing __attribute__ ((constructor)) support??
You are trying to build glibc with -fprofile-arcs -ftest-coverage in CFLAGS. That will not work. The errors you see are a result of these incorrect compiler flags.
A profiling glibc requires fairly substantial changes throughout the library and needs to be created by building with --enable-profile (which is not the default).
I had this error while I tried to enable coverage on a C project using a C++ test harness (CppUTest). Build system was handled by CMake.
Compilers and gcov were aligned on the same version (gcc --version, g++ --version and gcov --version gave the same version) but it seems that my build system was generated with a gcc 5 (resulting to an additional included directory by the linker: usr/lib/gcc/x86_64-linux-gnu/5). I clean the build tree and generated it again thanks to CMake which fixed the error.

Statically linking ffmpeg-sys on Amazon Linux fails with undefined references

My project depends on the ffmpeg-sys crate which is configured to build statically, as follows:
[dependencies.ffmpeg-sys]
version = "3.4.1"
default-features = false
features = ["avcodec", "avformat", "swresample", "build", "static"]
My project consists of a single simple file:
extern crate ffmpeg_sys;
use ffmpeg_sys::av_register_all;
fn main() {
unsafe { av_register_all() };
println!("Hello, world!");
}
When compiling with cargo build I get the following error:
Compiling sample v0.1.0 (file:///home/ec2-user/sample)
error: linking with 'cc' failed: exit code: 1 | = note: "cc"
"-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L"
[... elided for clarity ...]
In function 'sample::main::hbbb19855251826d6':
/home/ec2-user/sample/src/main.rs:6: undefined reference to 'av_register_all'
collect2: error: ld returned 1 exit status
The required static libraries, libavformat.a and friends, are found in the target/build/debug folder, showing that ffmpeg-sys successfully compiled the libraries.
Here's the rustc command that is failing:
Caused by: process didn't exit successfully: 'rustc --crate-name
sample src/main.rs --crate-type bin --emit=dep-info,link -C
debuginfo=2 -C metadata=250bf40eb277d05a -C
extra-filename=-250bf40eb277d05a --out-dir
/home/ec2-user/sample/target/debug/deps -C
incremental=/home/ec2-user/sample/target/debug/incremental -L
dependency=/home/ec2-user/sample/target/debug/deps --extern
ffmpeg_sys=/home/ec2-user/sample/target/debug/deps/libffmpeg_sys-fa3ff87f80f2d27e.rlib
-L native=/home/ec2-user/sample/target/debug/build/ffmpeg-sys-0b3c813f29a9a20e/out/dist/lib'
(exit code: 1)
libffmpeg_sys-fa3ff87f80f2d27e.rlib is 207M and I assume therefore contains all the statically compiled ffmpeg code.
This only happens when I build on an Amazon Linux instance. Compiling on my regular Fedora 28 desktop results in a working binary.
How would I go about figuring out the root cause of this error?
I solved this problem by building llvm 6.0.1 and then rebuilding with LIBCLANG_PATH set to point to the newer version.
It would appear that rustc has a minimum version requirement on libclang.so, but I could not find an official source documenting that. The version installed on amazon-linux is 3.6.2 which is evidently too old.

Resources