Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross-compilation for DragonFly fails #409

Open
mneumann opened this issue Oct 12, 2022 · 10 comments
Open

Cross-compilation for DragonFly fails #409

mneumann opened this issue Oct 12, 2022 · 10 comments

Comments

@mneumann
Copy link
Contributor

$ ldd ./hello 
./hello:
        libc.so.7 => not found (0)
        libdl.so.1 => not found (0)
        libthr.so.3 => not found (0)
        libm.so.5 => not found (0)
        libexecinfo.so.1 => /usr/lib/libexecinfo.so.1 (0x80046d000)
        libc.so.8 => /lib/libc.so.8 (0x80067c000)

I assume that when the libsavi_runtime is cross-compiled on a FreeBSD machine, it's using the libc etc from the FreeBSD host and not the one found on DragonFly. For instance, libc has version 8 on DragonFly (not version .7).

@jemc
Copy link
Contributor

jemc commented Oct 12, 2022

@mneumann - can you share the Savi invocation you are using?

Note that you'll need to have a viable DragonFly sys root somewhere on your system, and to use the SAVI_SYS_ROOT environment variable to let the Savi compiler know where to look for that sysroot.

You may also need to first fix linker scripts within the sys root that are relying on an absolute path.

To see this in action, take a look at the code I wrote for cross-compiling Savi programs to FreeBSD, which downloads the sys root package, checks its hash, and then uses sed -i to patch the linker scripts. Then see that we are setting the SAVI_SYS_ROOT env var to point to this extracted sys root directory before running the build command.

I'd expect that if you do something similar with a DragonFly sys root, you will find success in cross-compiling.

If you do manage to do so successfully, then please also share the steps you did, or do a pull request to that repo so that the build-release action for Savi programs can support DragonFly as well.

@mneumann
Copy link
Contributor Author

@jemc, I was just using -X option. Will try with SAVI_SYS_ROOT. You might get away with the path patching by installing savi into the sysroot and using chroot.

@jemc
Copy link
Contributor

jemc commented Oct 12, 2022

Yeah, so you need to supply both the -X TARGET_TRIPLE option as well as the SAVI_SYS_ROOT=PATH_TO_SYS_ROOT env var.

Unless you're in a situation like on MacOS where the same SDK root is used for multiple MacOS architecture, or on Windows where you're running in the WSL subsytem, but cross-compiling to a native windows binary. In both of these situations, no explicit SAVI_SYS_ROOT env var is needed.

@jemc
Copy link
Contributor

jemc commented Oct 12, 2022

You might get away with the path patching by installing savi into the sysroot and using chroot.

I'm unsure about this... I haven't dealt with chroot much before, but wouldn't this require the savi binary itself to be compiled for that target system (and depending on the versions of libc.so etc that are in the sys root)? If so, then that would kind of defeat the purpose, because the goal with the cross-compilation capability is to be able to build a Savi program for any supported target platform with one single savi compiler binary running on a single host platform.

This goal is important to the eventual self-hosting of the language (i.e. a Savi compiler written in Savi) - as in such a situation you need the ability to cross-compile from one host platform/binary to many target platforms, such that you only need one working Savi compiler to create Savi compilers for all platforms.

@mneumann
Copy link
Contributor Author

It seems I missed linking in libatomic. The __atomic_compare_exchange is undefined for DragonFly's version of libsavi_runtime, where for FreeBSD's version, that symbol does not appear:

> llvm-nm libsavi_runtime-x86_64-unknown-dragonfly.bc | grep atomic_compare
                 U __atomic_compare_exchange
>
> llvm-nm libsavi_runtime-x86_64-unknown-freebsd.bc | grep atomic_compare
>

@jemc Is there a simple way how I can take the libsavi_runtime.bc for dragonfly and link it with libatomic.a that I have from a DragonFly symbol and get a resulting .bc again?

@mneumann
Copy link
Contributor Author

@jemc I got some more success by linking against libatomic on DragonFly. It has one symbol undefined:

00000000002467e0 D __progname

This is required by DragonFly's libc. Any hints on that?

@mneumann
Copy link
Contributor Author

this seems to be a BSDism and is a non-portable alternative to argv[0]. I assume, the DragonFly compiler will add a __progname definition, and this is somehow missing when cross-compiling.

@jemc
Copy link
Contributor

jemc commented Oct 13, 2022

@mneumann - maybe this could be resolved by adding -lcsu on DragonFly, to link libcsu along with libatomic?

This comment implies that the __progname symbol comes from that library?

freebsd/pkg#1733 (comment)

@mneumann
Copy link
Contributor Author

there is no libcsu on DragonFly. But __progname is defined in crt1.o:

> llvm-nm -U /dfly-sysroot/usr/lib/crt1.o
0000000000000000 D __progname
000000000000008c T _start
0000000000000000 r abitag
000000000000001c r crt_noinit_tag
0000000000000000 B environ
0000000000000048 t finalizer
0000000000000000 t fix_iplta

The built hello binary exports __progname:

> llvm-nm -g hello | grep __progname
00000000002467e0 D __progname

But when I run it on DragonFly, I get:

% ./hello 
/lib/libc.so.8: Undefined symbol "__progname"

I am a bit lost here.

@mneumann
Copy link
Contributor Author

binary

I'm unsure about this... I haven't dealt with chroot much before, but wouldn't this require the savi binary itself to be compiled for that target system (and depending on the versions of libc.so etc that are in the sys root)? If so, then that would kind of defeat the purpose, because the goal with the cross-compilation capability is to be able to build a Savi program for any supported target platform with one single savi compiler binary running on a single host platform.

concerning chroot: the only effect this has is that the sysroot would become the real "root" (that is "/"). That would avoid changing absolute paths to point to the sysroot. Dunno if Linux supports chroot though. So before starting to link, you'd chroot into the sysroot, of course every object that you link would have to reside within the new chroot (or in memory or you'd have an open file descriptor for). Any external program that is called by the linking process would also have to reside within the chroot. But I think you use the compiled-in LLVM linker. There are some package build systems that actually use that technology (or jails) to make package building reproduceable and independent of potentially installed packages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants