Open stefson opened 5 years ago
The build.log itself isn't very usefull, as it hides the actuall compile commands from the user. Therefore, the first thing to do in an attempt to debug this is, to reenable cargo build -v in the cargo.eclass in the local portage tree:
cargo: reenable cargo build -v for debugging
diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass
index 051d5c499a6..8e92cb86277 100644
--- a/eclass/cargo.eclass
+++ b/eclass/cargo.eclass
@@ -122,7 +122,7 @@ cargo_src_compile() {
export CARGO_HOME="${ECARGO_HOME}"
- cargo build -j $(makeopts_jobs) $(usex debug "" --release) "$@" \
+ cargo build -v -j $(makeopts_jobs) $(usex debug "" --release) "$@" \
|| die "cargo build failed"
}
which gives a more verbose build.log to read through: cbindgen-0.6.7-cross.log.zip
next step would be to find out, wether a build outside of portage would work: I copied the folder src
and Cargo.toml
from /var/tmp/portage/dev-util/cbindgen-0.6.7/work/cbindgen-0.6.7/
to temporary folder, entered it via the cmd line and made it compile via cargo build --target=armv7-unknown-linux-gnueabihf
here is the build log of that approach: cbindgen-0.6.7-cross-non-portage.log.zip
which gives a valid arm binary: file cbindgen
cbindgen: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, with debug_info, not stripped
which can be striped with cross-strip: file cbindgen
cbindgen: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, stripped
one smoking gun I found is, that upon linking during cross-compile cargo has to be told about where the cross-gcc is to be found via ~/.cargo/config
[target.armv7-unknown-linux-gnueabihf] linker = "armv7a-unknown-linux-gnueabihf-gcc"
otherwise the non-portage build would flake out with error: linking with `cc` failed: exit code: 1
and it seems to me that portage sets its own cargo home config during each install, which makes sense as emerge is run via the the user/group portage:portage, and it doesn't have a folder in /home/
but, to be honest, I think the first problem here is that portage doesn't invoke rustc with the correct --target option at all, but simply issues the native rustc command.
How may I change this behavior, for to emerge the package with cross-portage?
ok, we're getting closer as I switched on --target option via the cargo.eclass
diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass
index 8e92cb86277..b4b5d86ffcb 100644
--- a/eclass/cargo.eclass
+++ b/eclass/cargo.eclass
@@ -122,7 +122,7 @@ cargo_src_compile() {
export CARGO_HOME="${ECARGO_HOME}"
- cargo build -v -j $(makeopts_jobs) $(usex debug "" --release) "$@" \
+ cargo build -v --target=armv7-unknown-linux-gnueabihf -j $(makeopts_jobs) $(usex debug "" --release) "$@" \
|| die "cargo build failed"
}
This is of course very unsophisticated, needs more general approach if ever going to the overlay or the tree even. But it makes emerge run into the linker errors, as it should when picking native gcc to link a foreign binary, which shows that cross-compile has happened at some point:
error: linking with `cc` failed: exit code: 1
full log
Ok, so let's set up the linker as well:
diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass
index b4b5d86ffcb..73f0dcad9cd 100644
--- a/eclass/cargo.eclass
+++ b/eclass/cargo.eclass
@@ -111,6 +111,10 @@ cargo_gen_config() {
[source.crates-io]
replace-with = "gentoo"
local-registry = "/nonexistant"
+
+ [target.armv7-unknown-linux-gnueabihf]
+ linker = "armv7a-unknown-linux-gnueabihf-gcc"
+
EOF
}
this solves the linking error, but still emerge installs the native binary in src_install.
>>> Completed installing cbindgen-0.6.7 into /usr/armv7a-unknown-linux-gnueabihf/tmp/portage/dev-util/cbindgen-0.6.7/image
* Final size of build directory: 237468 KiB (231.9 MiB)
* Final size of installed tree: 8072 KiB ( 7.8 MiB)
strip: armv7a-unknown-linux-gnueabihf-strip --strip-unneeded -R .comment -R .GCC.command.line -R .note.gnu.gold-version
/usr/bin/cbindgen
armv7a-unknown-linux-gnueabihf-strip:/usr/armv7a-unknown-linux-gnueabihf/tmp/portage/dev-util/cbindgen-0.6.7/image/usr/bin/cbindgen: file format not recognized
./
./usr/
./usr/bin/
./usr/bin/cbindgen
>>> Done.
portage acutally ends up with two binaries now, one native and one cross-compiled one, in seperate folders:
user@tuxbox /usr/armv7a-unknown-linux-gnueabihf/tmp/portage/dev-util/cbindgen-0.6.7/work/cbindgen-0.6.7/target/release $ file cbindgen
cbindgen: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, with debug_info, not stripped
user@tuxbox /usr/armv7a-unknown-linux-gnueabihf/tmp/portage/dev-util/cbindgen-0.6.7/work/cbindgen-0.6.7/target/armv7-unknown-linux-gnueabihf/release $ file cbindgen
cbindgen: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, with debug_info, not stripped
Ok, finally got there: https://github.com/rust-lang/cargo/pull/5614 added an option to enable cargo install --target
diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass
index 73f0dcad9cd..75e7f0cf388 100644
--- a/eclass/cargo.eclass
+++ b/eclass/cargo.eclass
@@ -136,7 +136,7 @@ cargo_src_compile() {
cargo_src_install() {
debug-print-function ${FUNCNAME} "$@"
- cargo install -j $(makeopts_jobs) --root="${D}/usr" $(usex debug --debug "") "$@" \
+ cargo install --target=armv7-unknown-linux-gnueabihf -j $(makeopts_jobs) --root="${D}/usr" $(usex debug --debug "") "$@" \
|| die "cargo install failed"
rm -f "${D}/usr/.crates.toml"
lousy ebuild I hacked for rust-std-bin:
https://github.com/stefson/gentoo-extras/blob/master/dev-lang/rust-std/rust-std-1.30.1.ebuild
Do you plan producing thumb targets for rust-std? Also why haven't you pushed it into ::rust?
how can you not see the thumb code in the ebuild? https://github.com/gentoo/gentoo-rust/blob/master/dev-lang/rust/rust-1.41.0-r666.ebuild#L102
The ebuild requires you to be on an arm arch or otherwise have arm-none-eabi-gcc
to build it.
I mean https://github.com/stefson/gentoo-extras/blob/master/dev-lang/rust-std/rust-std-1.41.0.ebuild
You're welcome to use my overlay if you want to, the thumb target is in an extra package named rust-std-neon since I couldn't find a way to make my rust-std ebuild installing both armv7 and thumbv7neon on an amd64 host. You'll need both of them for cross compiling firefox.
Actually I don't think you'll need arm-none-eabi-gcc for compiling the thumbv7neon target. Where did you get that information from?
On Thu, Feb 27, 2020 at 01:03:08PM -0800, stefson wrote:
You're welcome to use my overlay if you want to, the thumb target is in an extra package named rust-std-neon since I couldn't find a way to make my rust-std ebuild installing both armv7 and thumbv7neon on an amd64 host. You'll need both of them for cross compiling firefox.
My question was why isn't it in ::rust.
Actually I don't think you'll need arm-none-eabi-gcc for compiling the thumbv7neon target. Where did you get that information from?
From trying to build it (in fact thumbv6m-none-eabi, as i need it): couldn't find required command: "arm-none-eabi-gcc"
-- () ascii ribbon campaign - against html mail /\ http://arc.pasp.de/ - against proprietary attachments
bootstrapping additional rust-std from source requires you to have a suitable gcc cross compiler at hand for linking, and yes some of the crates are so stupid to only look for gcc name paterns matching those of debian based distros. You have no choice but to symlink your own cross compiler to the debian name scheme.
That said, please take the ebuild and modify it for your own case. You're not presenting any usefull information to me for helping you with that. Thanks.
recently I did some research into how to to use rust and cargo to cross-compile, especially for armhf.
I found out, it's rather easy to set up rust for that: if rust-bin is your rust-provider, download rust-std-${PN}-${ARCH-TRIPLE}.tar.xz and install it with:
./install.sh --disable-verify --prefix=/opt/${P}/ --mandir="/usr/share/${P}/man" --disable-ldconfig
which gives you a rust-bin with the ability to cross-compile. (since rustc is more or less a frontend to llvm, you should have it emerged with llvm_target_arm?)
also emerge a full cross toolchain with crossdev, since rustc needs the cross-gcc as a linker.
now, it is common practice to cross-compile with emerge-wrappers, so an
emerge-armv7a-unknown-linux-gnueabihf -auvND world
should bootstrap a base cross system to work with, inheriting @system, and from there on it should be possible to compile individual packages and copy the tbz2 files from the cross environement over to the memory restrained arm device and emerge with the-k
option to grab a binary if possible. Done that withsys-devel/gcc
,sys-devel/llvm
,dev-libs/boost
, etc. pp.Now, with a host where rustc has the foreign rust-std installed it should just work to emerge, for instance,
dev-util/cbindgen
this way. It does, however, with a bit of a show stopper:the binary is in fact not a cross-compiled one, but for the hosts arch, thus cross-strip can't do anything about it.