@@ -2809,17 +2809,19 @@ def _libdir_basename
28092809 @libdir_basename ||= config_string ( "libdir" ) { |name | name [ /\A \$ \( exec_prefix\) \/ (.*)/ , 1 ] } || "lib"
28102810 end
28112811
2812- def MAIN_DOES_NOTHING ( *refs )
2812+ def MAIN_DOES_NOTHING ( *refs ) # :yield:
28132813 src = MAIN_DOES_NOTHING
28142814 unless refs . empty?
2815- src = src . sub ( /\{ / ) do
2816- $& +
2817- "\n if (argc > 1000000) {\n " +
2815+ src = src . sub ( /\{ \K / ) do
2816+ "\n if (argc > 1000000) {\n " +
28182817 refs . map { |n |" int (* volatile #{ n } p)(void)=(int (*)(void))&#{ n } ;\n " } . join ( "" ) +
28192818 refs . map { |n |" printf(\" %d\" , (*#{ n } p)());\n " } . join ( "" ) +
28202819 " }\n "
28212820 end
28222821 end
2822+ if defined? ( yield )
2823+ src = yield src
2824+ end
28232825 src
28242826 end
28252827
@@ -3020,13 +3022,83 @@ def self.[]=(name, mod)
30203022 "$(CXXFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
30213023
30223024 def have_devel?
3025+ if config_string ( 'CXX' ) == 'false'
3026+ return @have_devel = false unless progs = find_cxx_progs
3027+ unless progs [ 'LDSHAREDXX' ] &. != ''
3028+ progs [ 'LDSHAREDXX' ] = CONFIG [ 'LDSHARED' ] . sub ( /\$ (?:\( CC\) |\{ CC\} |CC)/ , '$(CXX)' )
3029+ end
3030+ progs . each_pair { |key , val | RbConfig . fire_update! ( key , val ) }
3031+ end
30233032 unless defined? @have_devel
30243033 @have_devel = true
30253034 @have_devel = try_link ( MAIN_DOES_NOTHING )
3035+ if try_compile ( MAIN_DOES_NOTHING { |src | <<~CXX + src } )
3036+ static std::nullptr_t const *const conftest_nullptr = nullptr;
3037+ CXX
3038+ [ MAKEFILE_CONFIG , CONFIG ] . each do |conf |
3039+ conf [ 'CXXFLAGS' ] << " -DHAVE_NULLPTR"
3040+ end
3041+ end
30263042 end
30273043 @have_devel
30283044 end
30293045
3046+ def check_prog_for_cc ( stem , repl , cc )
3047+ cxx = cc . sub ( /#{ stem } (?=[^\/ ]*\z )/ , repl )
3048+ cxx if find_executable0 ( cxx )
3049+ end
3050+
3051+ # Find C++ programs at runtime, according to CONFIG['CC'].
3052+ def find_cxx_progs
3053+ cc , = config_string ( 'CC' ) . shellsplit
3054+ case File . basename ( cc )
3055+ when 'cc' # /(?:\A|[ \/])cc(?: |\z)/
3056+ # Don't try g++/clang++ when CC=cc
3057+ {
3058+ 'CXX' => %w[ cl.exe CC c++ ] . find { |cc | find_executable0 ( cc ) } ,
3059+ }
3060+ when /icc/
3061+ # Intel C++ has interprocedural optimizations. It tends to come with its
3062+ # own linker etc.
3063+ {
3064+ 'AR' => check_prog_for_cc ( "icc" , "xiar" , cc ) ,
3065+ 'CXX' => check_prog_for_cc ( "icc" , "icpc" , cc ) ,
3066+ 'LD' => check_prog_for_cc ( "icc" , "xild" , cc ) ,
3067+ }
3068+ when /gcc/
3069+ # Ditto for GCC.
3070+ {
3071+ 'LD' => check_prog_for_cc ( "gcc" , "ld" , cc ) ,
3072+ 'AR' => check_prog_for_cc ( "gcc" , "gcc-ar" , cc ) ,
3073+ 'CXX' => check_prog_for_cc ( "gcc" , "g++" , cc ) ,
3074+ 'NM' => check_prog_for_cc ( "gcc" , "gcc-nm" , cc ) ,
3075+ 'RANLIB' => check_prog_for_cc ( "gcc" , "gcc-ranlib" , cc ) ,
3076+ }
3077+ when /clang/
3078+ # Ditto for LLVM. Note however that llvm-as is a LLVM-IR to LLVM bitcode
3079+ # assembler that does not target your machine native binary.
3080+
3081+ # Xcode has its own version tools that may be incompatible with
3082+ # genuine LLVM tools, use the tools in the same directory.
3083+
3084+ llvm_prefix = IO . popen ( [ cc , *%w" -E -dM -xc - " ] , in : :close , &:read )
3085+ llvm_prefix = llvm_prefix . include? ( "__apple_build_version__" ) ? "" : "llvm-"
3086+ {
3087+ 'LD' => check_prog_for_cc ( "clang" , "ld" , cc ) , # ... maybe try lld ?
3088+ 'AR' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } ar" , cc ) ,
3089+ # 'AS' => check_prog_for_cc("clang", "#{llvm_prefix}as", cc),
3090+ 'CXX' => check_prog_for_cc ( "clang" , "clang++" , cc ) ,
3091+ 'NM' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } nm" , cc ) ,
3092+ 'OBJCOPY' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } objcopy" , cc ) ,
3093+ 'OBJDUMP' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } objdump" , cc ) ,
3094+ 'RANLIB' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } ranlib" , cc ) ,
3095+ 'STRIP' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } strip" , cc ) ,
3096+ }
3097+ else
3098+ return
3099+ end . compact
3100+ end
3101+
30303102 def conftest_source
30313103 CONFTEST_CXX
30323104 end
0 commit comments