Skip to content

feature: zig-cc like cross compilation #1585

@NobodyXu

Description

@NobodyXu

Zulip discussion

motivation

cc would want zig-cc like smooth, out-of-the-box cross compilation.

experiments using zig-cc tarball

With the official zig-cc tarball, we can build a sysroot for compiling and creating archive, but not linked executable:

cp -r lib/libc/musl/ /tmp/musl-sysroot/
cp -r lib/libc/include/aarch64-linux-musl/* /tmp/musl-sysroot/include/
cp -r lib/libc/include/generic-musl/* /tmp/musl-sysroot/include/
cp -r lib/libc/include/aarch64-linux-any/* /tmp/musl-sysroot/include/
cp -r lib/libc/include/any-linux-any/* /tmp/musl-sysroot/include/

the idea/plan

My idea is that we have a new feature flag headers-for-cross-compilation, which pulls in our new dependency zig-cc-sysroot that contains the sysroot copied from zig-cc, it would be compressed nicely (would be even better if we have zstd compression for crate).

It would provide some function to create a sysroot given a target (since you'd need to copy a bunch of directories for headers).

cc don't need crt since cc usually just build archive, not executable.

Would be good if we have some way to cache things across build scripts, apart from for zig-cc style sysroot building, the is flag supported logic also could be cached.

the issues we need to resolve/workaround

By @bjorn3

Looks like we don't do filtering of actually used symbols for raw-dylibs, so it would cover move than the libc api's called from rust, but the libc crate still doesn't define all symbols that C may want to use. For example the FILE * pointers for stdin/stdout/stderr are missing as well as implementation details of various macros in the libc header files.

For example __libc_start_main is not meant to ever be called by the user, yet is called by the crt and thus necessary to link. Also in glibc there are many symbols with different versions. libc should only expose a single version to the user, but C code may be compiled against a different version (by the way the header files and the shared library against which you link need to be from the exact same glibc version to avoid mismatches. the header files don't explicitly bind against a particular symbol version, but they do expect the symbol version matching the glibc version they are for to be picked by the linker. this also means that if the cc ships with the headers, then cc would also need to be responsible for shipping the shared library or import library and you can't have multiple cc versions in the same compilation as those may bind against different glibc versions).

@madsmtm mentioned that we could have libc exporting raw-dynlib symbols dor bridging symbol version issue.

I think we should start at musl, as it is simpler than glibc with its symbol version, and then actually turn it on to see if the crt turns out to be an issue for actual cross compilation of cc-rs project, like zstd

cc don't need to support every cross compilation cases from day 1, it should focus on common, widely used crate that makes cross compilation harder, they might not need all symbols from crt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions