Should the target and cpu be passed to clang when a target isn't provided?

I’m not sure if this is unexpected behavior or not, but what I’m noticing when trying to compile C++ with zig, the -target and -mcpu flags are not being set and passed to clang when the target is “native”. Here is the output - I’m forcing a compiler error to see the clang command, not sure if there’s a way to print it otherwise

Running with zig version: 0.12.0-dev.146+020105d0d

# ran: zig build

zig build-exe test-tgt Debug native: error: the following command failed with 1 compilation errors:
/home/shail/GitHub/zig/build/stage3/bin/zig build-exe -cflags -std=c++17 -- /home/shail/Testing/tgt_zig/src/main.cpp -lc++ --cache-dir /home/shail/Testing/tgt_zig/zig-cache --global-cache-dir /home/shail/.cache/zig --name test-tgt --listen=- 

Now running zig build -Dtarget=x86_64-linux-gnu, the target is my native linux triple

zig build-exe test-tgt Debug x86_64-linux-gnu: error: the following command failed with 1 compilation errors:
/home/shail/GitHub/zig/build/stage3/bin/zig build-exe -cflags -std=c++17 -- /home/shail/Testing/tgt_zig/src/main.cpp -lc++ --cache-dir /home/shail/Testing/tgt_zig/zig-cache --global-cache-dir /home/shail/.cache/zig --name test-tgt -target x86_64-linux-gnu -mcpu x86_64 --listen=- 

In the second run, -target and -mcpu are being set. Is there a reason why its not for native builds? The reason I’d prefer it being set is that clang is defining __SSE4_2__ and __PCLMUL__ when those intrinsics don’t exist on my architecture and setting the target and cpu appears to correct that.

From zig build-exe --help:

  --verbose-cc                 Display C compiler invocations

So far you have not shown the flags that are actually passed to clang; in your post we only see the flags that are passed to zig build-exe.

1 Like

Thanks for the reply!

I ran the command with --verbose-cc, at first I thought it wasn’t working because it said “error” but it looks like it is producing the binary. So now looking at it, the target and cpu are being passed in to both, but whats strange is that I’m seeing specific flags being enabled for native when they are being disabled for x86_64-linux-gnu.

For example, I see the flags --target-feature -Xclang -sse4.2 when the target is x86_64-linux-gnu but when the target is native I see -target-feature -Xclang +sse4.2 . (I’m assuming the difference in +/- is enabling the feature vs not for clang?)

I guess that would explain why __SSE4_2__ is being defined when it shouldn’t on native builds but I would assume that the flags between the targets should be the same because my native target is x86_64-linux-gnu

Attached are the outputs of the native build, x86_64-linux-gnu build, and their wdiff if incase there’s anything else that I’m missing in them.

diff.txt (9.4 KB)
native.txt (8.1 KB)
x86_64-linux-gnu.txt (8.4 KB)

Zig will automatically enable CPU features that are present when no specific target is passed. This sounds like it could be a bug in the feature detection code, though I’m not sure. I believe you can pass -march=generic to stop that behavior.

1 Like

Yeah maybe I’ll try and poke around with how features are detected, is the -march=generic an option to pass into zig build? It doesn’t seem to be a valid option, unless I’m using it wrong