Building a web app on Synology (ARMv8)

Hi,

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?

Thank you

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.

Yes, I am building directly on my NAS and I have installed the toolchain using rustup.

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?

This is the output... Uhm, seems quite right to me, isn't it?

ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), not stripped

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?

So these are the arguments used to compile cc:

"cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-Wl,--eh-frame-hdr" -L"/**/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib" "-Wl,-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-ldl" "-lutil"

While these are for collect2:

"cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-Wl,--eh-frame-hdr" "-L" "**/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib" "-Wl,-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-ldl" "-lutil"

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.

Thank you.

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.

2 Likes

Uhm... Three very strange things:

  1. libc.so doesn't exist in /usr/lib/, but I have only libc.so.6 (with no symbolic link)
  2. libc.so exists in /usr/local/aarch64-unknown-linux-gnueabi/aarch64-unknown-linux-gnueabi/sysroot/usr/lib/
  3. In both case the output of nm is: File format not recognized

So I tried to open it to investigate and I found this :astonished::

/* 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.

BTW thank you very much for your support!

2 Likes

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

Mmm... I will ask support on Synology forum.

1 Like