I am trying to build a little web app running on my NAS (Synology DS 118, ARMv8 architecture) using Actix, but when rustc tries to compile crates cc and collect2 I get the following errors:
For collect2:
build_script_build-2658c761abe611dc.build_script_build.fv45wib7-cgu.0.rcgu.o: file not recognized: File format not recognized
For cc:
build_script_build-c7aceb023bce76f7.build_script_build.3k2aoytq-cgu.0.rcgu.o: file not recognized: File format not recognized
So I guess that object file have been pre-built for another architecture. Is that a bug or that means that they are not available for my ARM architecure?
Are you trying to build on or for ARMv8? If you are trying to build for, you will need to install a cross-compilation toolchain and point rustc at the correct linker.
Do you have file installed? If so can you run file target/**/build_script_build-2658c761abe611dc.build_script_build.fv45wib7-cgu.0.rcgu.o and post the output?
The "file format not recognized" error is typically encountered when the compiler is accidentally invoked with an object file as its input. Can you somehow get the complete compiler invocation out of the build script? I suspect the compiler is being called incorrectly.
You could try checking the permissions on the object file as well as trying to execute it directly – maybe it's an already-linked executable. (If so, I have no idea why.)
You could also try seeing what the specific toolchain is. Maybe rustup found and installed the wrong one? Having checked the official documentation, I see that there are a ton of different aarch64-supporting toolchains. Perhaps it's a question of linux-gnu vs linux-musl vs none (bare metal) – does the NAS run an OS? (I suppose so, but I've never used one.) Can you SSH into it and check if it's using GNU libc or MUSL?
And output of rustup toolchain list is: stable-aarch64-unknown-linux-gnu
ldd strangely is not installed or maybe is not in the path, so I am honestly know how to check if I am using GNU libc or MUSL, but since Synology uses a Linux derived OS, I guess is GNU libc.
Hmm, that does seem it's the linking phase, so that's correct, then.
To check for GNU vs other libc, you could do an nm /usr/lib/libc.so or otool /usr/lib/libc.so and then pipe the output into grep -i gnu. But unfortunately, at this point I don't think that's the key difference.
libc.so doesn't exist in /usr/lib/, but I have only libc.so.6 (with no symbolic link)
libc.so exists in /usr/local/aarch64-unknown-linux-gnueabi/aarch64-unknown-linux-gnueabi/sysroot/usr/lib/
In both case the output of nm is: File format not recognized
So I tried to open it to investigate and I found this :
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-littleaarch64)
GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) )
So I think something is wrong with Synology setup.
I have already found a post on StackOverflow that is talking about this issue. I will investigate further to understand how to fix it!
So I think that it is not an issue of rustup/cargo or cc, collect2 crates, but a Synology issue.
Nice find! To me, the strangest thing is actually that in the linked SO post, the solution was to feed the linker the 32-bit version of the library instead of the 64-bit one. But weren't we on a 64-bit architecture all along? Why would then GCC look for a 32-bit library? Odd.
Thinking about this a bit more, I remember needing to install "gcc-multilib" and similar packages on a 32-bit Linux distro that I installed on a system with a 64-bit CPU. Maybe the OS running on your NAS is also 32-bit, and you need the 32-bit version of the system libraries for the C toolchain to work? I'm honestly quite lost at this point, but it could be worth a try.
Yeah, you're right the solution suggested in the SO post seems odd also to me and as I was expecting it is not working. With the current setup I am able to compile C++ stuff with no errors (just tried some little projects), switching to 32-bit library ld fails (with both c++ and rustc) since I don't even have the lib32 libraries installed (folder /lib32 is completely empty).