Skip to content

Commit 62f04fd

Browse files
committed
[Bug #21111] Find C++ programs at runtime
1 parent 9fedae9 commit 62f04fd

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

lib/mkmf.rb

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3020,13 +3020,74 @@ def self.[]=(name, mod)
30203020
"$(CXXFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
30213021

30223022
def have_devel?
3023+
if config_string('CXX') == 'false'
3024+
return @have_devel = false unless progs = find_cxx_progs
3025+
MAKEFILE_CONFIG.update(progs)
3026+
CONFIG.update(progs)
3027+
end
30233028
unless defined? @have_devel
30243029
@have_devel = true
30253030
@have_devel = try_link(MAIN_DOES_NOTHING)
30263031
end
30273032
@have_devel
30283033
end
30293034

3035+
def check_prog_for_cc(stem, repl, cc)
3036+
cxx = cc.sub(/#{stem}(?=[^\/]*\z)/, repl)
3037+
cxx if find_executable0(cxx)
3038+
end
3039+
3040+
# Find C++ programs at runtime, according to CONFIG['CC'].
3041+
def find_cxx_progs
3042+
cc, = config_string('CC').shellsplit
3043+
case File.basename(cc)
3044+
when 'cc' # /(?:\A|[ \/])cc(?: |\z)/
3045+
# Don't try g++/clang++ when CC=cc
3046+
{
3047+
'CXX' => %w[cl.exe CC c++].find {|cc| find_executable0(cc)},
3048+
}
3049+
when /icc/
3050+
# Intel C++ has interprocedural optimizations. It tends to come with its
3051+
# own linker etc.
3052+
{
3053+
'AR' => check_prog_for_cc("icc", "xiar", cc),
3054+
'CXX' => check_prog_for_cc("icc", "icpc", cc),
3055+
'LD' => check_prog_for_cc("icc", "xild", cc),
3056+
}
3057+
when /gcc/
3058+
# Ditto for GCC.
3059+
{
3060+
'LD' => check_prog_for_cc("gcc", "ld", cc),
3061+
'AR' => check_prog_for_cc("gcc", "gcc-ar", cc),
3062+
'CXX' => check_prog_for_cc("gcc", "g++", cc),
3063+
'NM' => check_prog_for_cc("gcc", "gcc-nm", cc),
3064+
'RANLIB' => check_prog_for_cc("gcc", "gcc-ranlib", cc),
3065+
}
3066+
when /clang/
3067+
# Ditto for LLVM. Note however that llvm-as is a LLVM-IR to LLVM bitcode
3068+
# assembler that does not target your machine native binary.
3069+
3070+
# Xcode has its own version tools that may be incompatible with
3071+
# genuine LLVM tools, use the tools in the same directory.
3072+
3073+
llvm_prefix = IO.popen([cc, *%w"-E -dM -xc -"], in: :close, &:read)
3074+
llvm_prefix = llvm_prefix.include?("__apple_build_version__") ? "" : "llvm-"
3075+
{
3076+
'LD' => check_prog_for_cc("clang", "ld", cc), # ... maybe try lld ?
3077+
'AR' => check_prog_for_cc("clang", "#{llvm_prefix}ar", cc),
3078+
# 'AS' => check_prog_for_cc("clang", "#{llvm_prefix}as", cc),
3079+
'CXX' => check_prog_for_cc("clang", "clang++", cc),
3080+
'NM' => check_prog_for_cc("clang", "#{llvm_prefix}nm", cc),
3081+
'OBJCOPY' => check_prog_for_cc("clang", "#{llvm_prefix}objcopy", cc),
3082+
'OBJDUMP' => check_prog_for_cc("clang", "#{llvm_prefix}objdump", cc),
3083+
'RANLIB' => check_prog_for_cc("clang", "#{llvm_prefix}ranlib", cc),
3084+
'STRIP' => check_prog_for_cc("clang", "#{llvm_prefix}strip", cc),
3085+
}
3086+
else
3087+
return
3088+
end.compact
3089+
end
3090+
30303091
def conftest_source
30313092
CONFTEST_CXX
30323093
end

0 commit comments

Comments
 (0)