Open mneumann opened 1 year ago
@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.
@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
.
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.
You might get away with the path patching by installing
savi
into the sysroot and usingchroot
.
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.
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?
@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?
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.
@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?
https://github.com/freebsd/pkg/issues/1733#issuecomment-468389407
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.
binary
I'm unsure about this... I haven't dealt with
chroot
much before, but wouldn't this require thesavi
binary itself to be compiled for that target system (and depending on the versions oflibc.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 singlesavi
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.
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).