lang/rust vs. command line corrections to default clang -mcpu=NAME+FEATURE+noFEATURE flags (e.g.)

From: Mark Millard <marklmi_at_yahoo.com>
Date: Thu, 27 Apr 2023 23:55:48 UTC
This note is because clang (even in LLVM main) has somewhat
incorrect default feature flags for -mcpu=cortex-a78c and
-mcpu=cortex-x1c (the cores in the Windows Dev Kit 2023).

Unfortunately it includes indicating a feature that does
not exist on either type of core but is indicated for at
least one type. (The details vary after clang15 but no
version is fully right yet.)

So, for now, use of -mcpu= (or related) for clang should
also involve feature specifications, such as:

-mcpu=cortex-a78c+flagm+nofp16fml

(Note: ARM documentation has "FEAT_FHM" for what clang and
gcc call "fp16fml" . rust uses "fhm" instead of "fp16fml".)

A rust equivalent is:

-C target-cpu=cortex-a78c -C target-feature=+a78c,+flagm,-fhm

(I expect the "+a78c," is redundant, given the target-cpu
assignment.)

/usr/ports/Mk/Uses/cargo.mk is designed to translate the
likes of -mcpu=cortex-a78c into rust conventions via the
likes of:

.  else
RUSTFLAGS+=     ${CFLAGS:M-mcpu=*:S/-mcpu=/-C target-cpu=/}

But this only works for translating the likes of:

-mcpu=cortex-a78c

Otherwise rust does not recognize the likes of:

-C target-cpu=cortex-a78c+flagm+nofp16fml

But rust reports ignoring such instead of stopping.
The result can end up incoherent overall.

Not wishing to deal with general translation of feature
naming and notation, I locally made the following
change adding RUSTFLAGS_CPU_FEATURES allowing an
independent way to supply the rust notation when
the simpler handling does not work (whitespace details
likely not fully preserved, so just suggestive):

# git -C /usr/ports/ diff Mk/Uses/cargo.mk
diff --git a/Mk/Uses/cargo.mk b/Mk/Uses/cargo.mk
index 76c27540f5d7..6c84f442ab34 100644
--- a/Mk/Uses/cargo.mk
+++ b/Mk/Uses/cargo.mk
@@ -145,7 +145,9 @@ WITH_LTO=   yes
 .  endif
   # Adjust -C target-cpu if -march/-mcpu is set by bsd.cpu.mk
-.  if ${ARCH} == amd64 || ${ARCH} == i386
+.  if defined(RUSTFLAGS_CPU_FEATURES)
+RUSTFLAGS+=    ${RUSTFLAGS_CPU_FEATURES}
+.  elif ${ARCH} == amd64 || ${ARCH} == i386
 RUSTFLAGS+=    ${CFLAGS:M-march=*:S/-march=/-C target-cpu=/}
 .  elif ${ARCH:Mpowerpc*}
 RUSTFLAGS+=    ${CFLAGS:M-mcpu=*:S/-mcpu=/-C target-cpu=/:S/power/pwr/}

I'm using it in my experiments with port building via
the likes of:

# more /usr/local/etc/poudriere.d/main-CA78C-make.conf
CFLAGS+= -mcpu=cortex-a78c+flagm+nofp16fml
CXXFLAGS+= -mcpu=cortex-a78c+flagm+nofp16fml
CPPFLAGS+= -mcpu=cortex-a78c+flagm+nofp16fml
RUSTFLAGS_CPU_FEATURES= -C target-cpu=cortex-a78c -C target-feature=+a78c,+flagm,-fhm


===
Mark Millard
marklmi at yahoo.com