@@ -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,84 @@ 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+ #include <cstddef>
3037+ std::nullptr_t const *const conftest_nullptr = nullptr;
3038+ CXX
3039+ [ RbConfig ::MAKEFILE_CONFIG , RbConfig ::CONFIG ] . each do |conf |
3040+ conf [ 'CXXFLAGS' ] << " -DHAVE_NULLPTR"
3041+ end
3042+ end
30263043 end
30273044 @have_devel
30283045 end
30293046
3047+ def check_prog_for_cc ( stem , repl , cc )
3048+ cxx = cc . sub ( /#{ stem } (?=[^\/ ]*\z )/ , repl )
3049+ cxx if find_executable0 ( cxx )
3050+ end
3051+
3052+ # Find C++ programs at runtime, according to CONFIG['CC'].
3053+ def find_cxx_progs
3054+ cc , = config_string ( 'CC' ) . shellsplit
3055+ case File . basename ( cc )
3056+ when 'cc' # /(?:\A|[ \/])cc(?: |\z)/
3057+ # Don't try g++/clang++ when CC=cc
3058+ {
3059+ 'CXX' => %w[ cl.exe CC c++ ] . find { |cc | find_executable0 ( cc ) } ,
3060+ }
3061+ when /icc/
3062+ # Intel C++ has interprocedural optimizations. It tends to come with its
3063+ # own linker etc.
3064+ {
3065+ 'AR' => check_prog_for_cc ( "icc" , "xiar" , cc ) ,
3066+ 'CXX' => check_prog_for_cc ( "icc" , "icpc" , cc ) ,
3067+ 'LD' => check_prog_for_cc ( "icc" , "xild" , cc ) ,
3068+ }
3069+ when /gcc/
3070+ # Ditto for GCC.
3071+ {
3072+ 'LD' => check_prog_for_cc ( "gcc" , "ld" , cc ) ,
3073+ 'AR' => check_prog_for_cc ( "gcc" , "gcc-ar" , cc ) ,
3074+ 'CXX' => check_prog_for_cc ( "gcc" , "g++" , cc ) ,
3075+ 'NM' => check_prog_for_cc ( "gcc" , "gcc-nm" , cc ) ,
3076+ 'RANLIB' => check_prog_for_cc ( "gcc" , "gcc-ranlib" , cc ) ,
3077+ }
3078+ when /clang/
3079+ # Ditto for LLVM. Note however that llvm-as is a LLVM-IR to LLVM bitcode
3080+ # assembler that does not target your machine native binary.
3081+
3082+ # Xcode has its own version tools that may be incompatible with
3083+ # genuine LLVM tools, use the tools in the same directory.
3084+
3085+ llvm_prefix = IO . popen ( [ cc , *%w" -E -dM -xc - " ] , in : :close , &:read )
3086+ llvm_prefix = llvm_prefix . include? ( "__apple_build_version__" ) ? "" : "llvm-"
3087+ {
3088+ 'LD' => check_prog_for_cc ( "clang" , "ld" , cc ) , # ... maybe try lld ?
3089+ 'AR' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } ar" , cc ) ,
3090+ # 'AS' => check_prog_for_cc("clang", "#{llvm_prefix}as", cc),
3091+ 'CXX' => check_prog_for_cc ( "clang" , "clang++" , cc ) ,
3092+ 'NM' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } nm" , cc ) ,
3093+ 'OBJCOPY' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } objcopy" , cc ) ,
3094+ 'OBJDUMP' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } objdump" , cc ) ,
3095+ 'RANLIB' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } ranlib" , cc ) ,
3096+ 'STRIP' => check_prog_for_cc ( "clang" , "#{ llvm_prefix } strip" , cc ) ,
3097+ }
3098+ else
3099+ return
3100+ end . compact
3101+ end
3102+
30303103 def conftest_source
30313104 CONFTEST_CXX
30323105 end
0 commit comments