superenv: handle formulae with runtime CPU detection

Some formulae are able to detect the features of the runtime CPU, and
execute code accordingly. This typically entails 1) the detection of
features of the build-time CPU in order to determine the targets that
the compiler can generate code for, and 2) generating code for the
targets that the compiler can support.

Our filtering of optimization flags can cause misdetection of compiler
features, leading to failed builds [1], and miscompilation even when the
build does not fail [2].

Let's try to fix this by allowing formulae to declare
`ENV.runtime_cpu_detection` which skips the filtering of `-march` and
related flags.

I've also skipped the filtering of the optimisation
level, since it seems to me that if upstream maintainers have gone to
the lengths of writing code that detects runtime hardware, they probably
also know better about appropriate `-O` flags to use.

This is a partial list of formulae that should make use of this feature:
1. apache-arrow
2. fftw
3. gromacs
4. open-mpi
5. openblas

Partially resolves Homebrew/homebrew-core#76537.

[1] open-mpi/ompi#8306 and linked issues/PRs
[2] Homebrew/homebrew-core#76537
This commit is contained in:
Carlo Cabrera 2021-06-27 17:46:50 +01:00
parent eec2d609bd
commit 0404da7ba7
No known key found for this signature in database
GPG Key ID: C74D447FC549A1D0
2 changed files with 17 additions and 5 deletions

View File

@ -91,10 +91,11 @@ module Superenv
# g - Enable "-stdlib=libc++" for clang. # g - Enable "-stdlib=libc++" for clang.
# h - Enable "-stdlib=libstdc++" for clang. # h - Enable "-stdlib=libstdc++" for clang.
# K - Don't strip -arch <arch>, -m32, or -m64 # K - Don't strip -arch <arch>, -m32, or -m64
# d - Don't strip -march=<target>. Use only in formulae that
# have runtime detection of CPU features.
# w - Pass -no_weak_imports to the linker # w - Pass -no_weak_imports to the linker
# #
# These flags will also be present: # These flags will also be present:
# s - apply fix for sed's Unicode support
# a - apply fix for apr-1-config path # a - apply fix for apr-1-config path
end end
alias generic_setup_build_environment setup_build_environment alias generic_setup_build_environment setup_build_environment
@ -314,6 +315,11 @@ module Superenv
append_to_cccfg "K" append_to_cccfg "K"
end end
sig { void }
def runtime_cpu_detection
append_to_cccfg "d"
end
sig { void } sig { void }
def cxx11 def cxx11
append_to_cccfg "x" append_to_cccfg "x"

View File

@ -173,10 +173,12 @@ class Cmd
case arg case arg
when /^-g\d?$/, /^-gstabs\d+/, "-gstabs+", /^-ggdb\d?/, when /^-g\d?$/, /^-gstabs\d+/, "-gstabs+", /^-ggdb\d?/,
/^-march=.+/, /^-mtune=.+/, /^-mcpu=.+/, /^-mtune=.+/, /^-mcpu=.+/, /^-O[0-9zs]?$/,
/^-O[0-9zs]?$/, "-fast", "-no-cpp-precomp", "-fast", "-no-cpp-precomp", "-pedantic",
"-pedantic", "-pedantic-errors", "-Wno-long-double", "-pedantic-errors", "-Wno-long-double",
"-Wno-unused-but-set-variable" "-Wno-unused-but-set-variable"
when /^-march=.+/
args << arg if runtime_cpu_detection?
when "-fopenmp", "-lgomp", "-mno-fused-madd", "-fforce-addr", "-fno-defer-pop", when "-fopenmp", "-lgomp", "-mno-fused-madd", "-fforce-addr", "-fno-defer-pop",
"-mno-dynamic-no-pic", "-fearly-inlining", /^-f(?:no-)?inline-functions-called-once/, "-mno-dynamic-no-pic", "-fearly-inlining", /^-f(?:no-)?inline-functions-called-once/,
/^-finline-limit/, /^-f(?:no-)?check-new/, "-fno-delete-null-pointer-checks", /^-finline-limit/, /^-f(?:no-)?check-new/, "-fno-delete-null-pointer-checks",
@ -283,7 +285,7 @@ class Cmd
args << "-pipe" args << "-pipe"
args << "-w" unless configure? args << "-w" unless configure?
args << "-#{ENV["HOMEBREW_OPTIMIZATION_LEVEL"]}" args << "-#{ENV["HOMEBREW_OPTIMIZATION_LEVEL"]}"
args.concat(optflags) args.concat(optflags) unless runtime_cpu_detection?
args.concat(archflags) args.concat(archflags)
args << "-std=#{@arg0}" if /c[89]9/.match?(@arg0) args << "-std=#{@arg0}" if /c[89]9/.match?(@arg0)
args args
@ -385,6 +387,10 @@ class Cmd
config.include?("K") config.include?("K")
end end
def runtime_cpu_detection?
config.include?("d")
end
def no_weak_imports? def no_weak_imports?
config.include?("w") config.include?("w")
end end