Exe files not interchangeable among identical Linux systems

Hi. I have installed current zig master (0.12.etc) on 3 computers. The 3 computers run Void Linux, all of them recently updated. Let’s call those computers A, B and C.

I compile the same hello world program in each computer. Results are these:

On computer A, I can run the exes compiled on computers A, B and C.

On computer B, I can run the exes compiled on computers B and C, but the exe compiled on computer A dies early with an “illegal instruction” error.

On computer C, I can run the exes compiled on the same computer C, but the exes compiled on computer A and B die early with an “illegal instruction” error.

File size is marginally different for the 3 exes. I am not using special compiling instructions, just zig build-exe hello.zig. If I strip strings or use the no-threads option, exe file sizes go dramatically down, but still differ slightly according to the system they were compiled on, and run or don’t run according to the same frustrating scheme described above.

I compile and run the 3 exes inside a folder under Dropbox (in case that information is useful).

Can you help me understand or solve the situation here?

1 Like

Doesn’t zig compile for the given computer’s CPU model? That would enable different feature flags, right?

3 Likes

The difference comes from the different processors you have on those machines. Zig without additional flags uses the full capabilities of the native CPU. If the CPU on machine A has features that B and C don’t have and LLVM-backend uses such a feature while compiling Zig on this machine the emitted binary will contain instructions that don’t exist on CPUs in B and C

5 Likes

Good to learn that, thank you! So, if the aim is interoperatibility of exes, I should compile on the oldest machine and use that exe everywhere (performance matters very little for now)?

Can you point me to some docs where I can find the compiler flags to use to compile for an older machine (older Core i7, I mean, not a Pentium to be sure)?

You can pass -mcpu=baseline to zig build-exe to use the lowest common instruction set for the given architecture iirc

5 Likes

Before reaching for the -mcpu flag, I suggest passing a -target parameter. When you don’t specify the target, it defaults to the host machine, including the OS version. When you specify the target, it not only picks a baseline CPU by default but also picks a baseline OS version to target.

-target x86_64-linux

17 Likes

Kind answer, Andrew, and wonderful build system! Thank you!

1 Like