-
Notifications
You must be signed in to change notification settings - Fork 142
Description
I'm working on a project targeting a variety of embedded architectures, including i386. And I actually mean i386, as in my target CPU is truly equivalent to an original Intel i386 CPU in terms of the instructions it supports.
My general approach when using this crate to cross-compile is to set CC=clang and allow cmake to automagically pass my target triple down to Clang's --target argument. But this doesn't fully work when targeting an i386 CPU; the compiler emits SSE instructions which are not available on my device.
Turns out, LLVM/Clang interprets the first member of the target triple as the desired CPU architecture, not a specific CPU. The strings i386, i486, i586, and i686 are all explicitly treated as "Pentium 4", and Clang will happily emit SSE and other instructions.
Lot of background here ☝️. Lot of history (and GCC compat?) behind this behavior. So while this is extremely unintuitive and could be argued it's a bug, I think it's unlikely to ever be changed.
This isn't an issue for the Rust code in my project because I'm using a custom target JSON which explicitly contains "cpu": "i386". And as a workaround when using the cmake crate, I'm able to pass .cflag("-march=i386") which explicitly forces Clang to generate code for my desired CPU.
My reason for opening this issue is to see if there's some way to make the cmake crate smarter in this scenario. For example, by detecting whether the current Rust target specifies an explicit CPU type and, if so, passing -march along with the --target flag when cross compiling.