1

OK, so I am new to cross compilation.

I am writing some shell-scripts to compile some C++ files, on my Mac.

I want to build a "Fat universal binary", so I want this to work for Arm64 and x86_64.

After a lot of searching, I found using: --arch arm64 --arch x86_64 will solve my problem of cross compilation.

However, my old "optimisation flags" conflicted this. I used them to make my code run faster, for a computer-game I was making. Well... these are the flags:

-march=core2  -mfpmath=sse  -mmmx  -msse  -msse2  -msse4.1  -msse4.2

Unfortunately... clang can't figure out that I mean to use this, for the intel build only. I get error message of:

clang: error: the clang compiler does not support '-march=core2'

If I remove --arch arm64 --arch x86_64 the code compiles again.

I tried various things like --arch x86_64+sse4 which seem allowed by the gcc documentation, but clang does not recognise them.

As far as I know, gcc/clang do not compile sse4.2 instructions by default. Despite the CPUs being released about 17 years ago. This is quite a bad assumption I think.

boytheo
  • 133
  • 4
  • `clang -march=core2 -c foo.c` works fine on mainline clang on my x86-64 Linux desktop. I don't know about Apple Clang on MacOS; could be it doesn't support `-march=core2` at all, or that it needs some other option to make that only apply to the x86-64 half of the build for a universal binary. – Peter Cordes Jan 31 '23 at 17:02
  • Re: not defaulting to SSE4.2: the last CPUs without it (or SSSE3) were [AMD Phenom II](https://en.wikipedia.org/wiki/Phenom_II), discontinued in 2012. Some emulators and VMs might also support a lower baseline. But yeah, it's getting to be a problem that the baseline is so far behind actual CPUs, and vectorization is pretty useful on modern x86-64 CPUs. That's part of why GCC/clang support `-march=x86-64-v2` (SSE4.2, CX16, etc.: Nehalem without `-mtune=`). And also `v3` (Haswell: FMA, AVX2, BMI1/2), and `v4` (some AVX-512). https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels – Peter Cordes Jan 31 '23 at 17:09
  • How can an executable be targeted for both ARM and Intel instruction sets? There is very little in common between the two. – Thomas Matthews Jan 31 '23 at 21:24
  • @PeterCordes `-march=core2` stops working only if you enable fat-ness with `-arch arm64 -arch x86_64`. I can reproduce on Linux Clang by adding `--target=x86_64-apple-darwin17.4.0` first (to make it behave as if it was running on Mac). – HolyBlackCat Feb 01 '23 at 12:31
  • @ThomasMatthews By embedding two copies of the same code for different instruction sets, apparently. – HolyBlackCat Feb 01 '23 at 12:32
  • 1
    @ThomasMatthews: https://en.wikipedia.org/wiki/Fat_binary - Build twice, put both binaries into a file format that supports it, instead of shipping separate installers. I'd guess Apple's linker may try to reuse parts of `.rodata` and `.data` if they happen to be the same between builds (when struct layouts match, or for primitive types that are the same between ISAs, in this case AArch64 and x86-64, and that hold the same value, which might not be the case if some were derived from preprocessor macros.) – Peter Cordes Feb 01 '23 at 16:07

0 Answers0