So I’ve been deep diving porting embedded arm-none-eabi-gcc
projects to Zig’s C/C++ compiler, and I can’t quite grok some subtle differences in how Zig handles the target triples passed to the -target
argument vs. Clang that I had to discover via trial and error.
For instance, an incredibly simple example:
dummy.c
:
int main() {
return 0;
}
Compiling with clang
:
clang -target thumb-none-eabi -mcpu=cortex-m7 -nostdlib dummy.c
ld.lld: warning: cannot find entry symbol _start; not setting start address
Makes total sense, this is a freestanding target, I’m not linking in the standard libraries, I wouldn’t expect _start
to be defined. All is well.
Compiling with zig cc
:
First naive attempt:
zig cc -target thumb-none-eabi -mcpu=cortex-m7 -nostdlib dummy.c
error: unable to parse target query 'thumb-none-eabi': UnknownOperatingSystem
Huh… Okay. After some fiddling and trial + error, I come up with:
zig cc -target thumb-freestanding-eabi -mcpu=cortex-m7 -nostdlib dummy.c
info: available CPUs for architecture 'thumb':
arm1020e
arm1020t
arm1022e
arm10e
arm10tdmi
arm1136j_s
arm1136jf_s
arm1156t2_s
arm1156t2f_s
arm1176jz_s
arm1176jzf_s
arm710t
arm720t
arm7tdmi
arm7tdmi_s
arm8
arm810
arm9
arm920
arm920t
arm922t
arm926ej_s
arm940t
arm946e_s
arm966e_s
arm968e_s
arm9e
arm9tdmi
baseline
cortex_a12
cortex_a15
cortex_a17
cortex_a32
cortex_a35
cortex_a5
cortex_a53
cortex_a55
cortex_a57
cortex_a7
cortex_a710
cortex_a72
cortex_a73
cortex_a75
cortex_a76
cortex_a76ae
cortex_a77
cortex_a78
cortex_a78c
cortex_a8
cortex_a9
cortex_m0
cortex_m0plus
cortex_m1
cortex_m23
cortex_m3
cortex_m33
cortex_m35p
cortex_m4
cortex_m55
cortex_m7
cortex_m85
cortex_r4
cortex_r4f
cortex_r5
cortex_r52
cortex_r7
cortex_r8
cortex_x1
cortex_x1c
cyclone
ep9312
exynos_m1
exynos_m2
exynos_m3
exynos_m4
exynos_m5
generic
iwmmxt
krait
kryo
mpcore
mpcorenovfp
neoverse_n1
neoverse_n2
neoverse_v1
sc000
sc300
strongarm
strongarm110
strongarm1100
strongarm1110
swift
xscale
error: unknown CPU: 'cortex'
Huh! Okay getting somewhere, but why is my CPU wrong? Oh
cortex_m7
with Zig instead of cortex-m7
.
So we arrive at:
zig cc -target thumb-freestanding-eabi -mcpu=cortex_m7 -nostdlib dummy.c
LLD Link... ld.lld: warning: cannot find entry symbol _start; not setting start address
Great! Now per a comment from this thread, it looks like this new “freestanding” option for OS takes away the need for -nostdlib
:
zig cc -target thumb-freestanding-eabi -mcpu=cortex_m7 dummy.c
LLD Link... ld.lld: warning: cannot find entry symbol _start; not setting start address
Perfect, it appears Zig figured out based on “freestanding” not to include the standard libraries automatically in linking.
So… are there any resources/Github issues I could look at explaining some of these small differences and the reasons for them? I’m trying to make a porting guide and want to be able to explain why you need to change certain flag values. Because based on an (albeit old) article written by Andrew here:
…the
zig cc
sub-command is available, and it supports the same options as Clang, which, in turn, supports the same options as GCC
In this particular case, that unfortunately isn’t entirely accurate given Clang supports the flags I took from arm-none-eabi-gcc
verbatim, whereas zig cc
requries a bit of massaging to get compiling. I’ll even help write the documentation for these differences! Just need some context
*Edit:
- I would also love additional instances where
zig cc
won’t behave likeclang
I may not have uncovered yet