Search code examples
rustcompilationintegerarmgolem

Usize breaking zksync when compiling for ARM


This is a complex and hard issue, but I will break it down to the best of my abilities. It comes down to when I am compiling a rust project for ARM64 (goal is to run on rasp pi 4).

A large majority of the libraries compile (704 / 740) but it breaks during compilation when it goes to compile a zksync directory. The the yagna client for golem is what I am compiling, I am using

target - target.arm-unknown-linux-musleabi linker - arm-linux-gnueabihf-ld

I'd love to hear ideas solutions, or what I am doing wrong so I can get this project running on ARM. The error code I am getting is

 Ok(stat.blocks_available() as u64 * stat.fragment_size())
^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `u32`

among other errors, all revolving around bit differences when converting integers. This had led to me suspecting usize to be the culprit as it bases size off CPU architecture, which would explain the ARM compilation messing it up, and not showing up until you have to handle the int (at conversion).

let me know if there is any more information you need, tried to my best to encapsulate the problem


Solution

  • stat is a Statvfs structure, the return type of Statvfs::blocks_available() is fsblkcnt_t, and the return type of Statvfs::fragment_size() is c_ulong. These two types are defined in the libc package, which is a paper-thin wrapper around the low-level C OS-calls. The types are equivalent to the C types in the OS-specific *.h files. The sizes of the types vary from platform to platform.

    The library you're compiling appears to have some assumptions baked in about these sizes and their arithmetic compatibility.

    Some bug reports to the library authors would be in order.

    If you're willing to patch the library yourself, then you should first investigate your platform's libc package and check the definitions of all types involved in the errors you're seeing. Then fix the arithmetic expressions so the types are compatible and they don't overflow.

    I don't think Rust's type system is smart enough to support one body of code that handles all potential combinations of type sizes both safely (without overflow or truncation) and efficiently (without needlessly casting everything up to u128) . It might be that platform-specific patches are necessary.