summaryrefslogtreecommitdiff
path: root/spec/ruby/optional/capi/spec_helper.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/optional/capi/spec_helper.rb')
-rw-r--r--spec/ruby/optional/capi/spec_helper.rb94
1 files changed, 67 insertions, 27 deletions
diff --git a/spec/ruby/optional/capi/spec_helper.rb b/spec/ruby/optional/capi/spec_helper.rb
index eda4964b69..49ce23d874 100644
--- a/spec/ruby/optional/capi/spec_helper.rb
+++ b/spec/ruby/optional/capi/spec_helper.rb
@@ -8,12 +8,17 @@ require 'rbconfig'
OBJDIR ||= File.expand_path("../../../ext/#{RUBY_ENGINE}/#{RUBY_VERSION}", __FILE__)
def object_path
- mkdir_p(OBJDIR)
- OBJDIR
+ path = OBJDIR
+ if ENV['SPEC_CAPI_CXX'] == 'true'
+ path = "#{path}/cxx"
+ end
+ mkdir_p(path)
+ path
end
def compile_extension(name)
debug = false
+ cxx = ENV['SPEC_CAPI_CXX'] == 'true'
run_mkmf_in_process = RUBY_ENGINE == 'truffleruby'
core_ext_dir = File.expand_path("../ext", __FILE__)
@@ -24,14 +29,14 @@ def compile_extension(name)
ext = "#{name}_spec"
lib = "#{object_path}/#{ext}.#{RbConfig::CONFIG['DLEXT']}"
- ruby_header = "#{RbConfig::CONFIG['rubyhdrdir']}/ruby.h"
+ rubyhdrdir = RbConfig::CONFIG['rubyhdrdir']
+ ruby_header = "#{rubyhdrdir}/ruby.h"
+ abi_header = "#{rubyhdrdir}/ruby/internal/abi.h"
if RbConfig::CONFIG["ENABLE_SHARED"] == "yes"
- if PlatformGuard.windows?
- libruby_so = "#{RbConfig::CONFIG['bindir']}/#{RbConfig::CONFIG['LIBRUBY_SO']}"
- else
- libruby_so = "#{RbConfig::CONFIG['libdir']}/#{RbConfig::CONFIG['LIBRUBY_SO']}"
- end
+ # below is defined since 2.1, except for mswin, and maybe other platforms
+ libdirname = RbConfig::CONFIG.fetch 'libdirname', 'libdir'
+ libruby = "#{RbConfig::CONFIG[libdirname]}/#{RbConfig::CONFIG['LIBRUBY']}"
end
begin
@@ -43,7 +48,8 @@ def compile_extension(name)
when mtime <= File.mtime("#{core_ext_dir}/rubyspec.h")
when mtime <= File.mtime("#{spec_ext_dir}/#{ext}.c")
when mtime <= File.mtime(ruby_header)
- when libruby_so && mtime <= File.mtime(libruby_so)
+ when (mtime <= File.mtime(abi_header) rescue nil)
+ when libruby && mtime <= File.mtime(libruby)
else
return lib # up-to-date
end
@@ -53,8 +59,16 @@ def compile_extension(name)
tmpdir = tmp("cext_#{name}")
Dir.mkdir(tmpdir)
begin
- ["#{core_ext_dir}/rubyspec.h", "#{spec_ext_dir}/#{ext}.c"].each do |file|
- cp file, "#{tmpdir}/#{File.basename(file)}"
+ files = ["#{core_ext_dir}/rubyspec.h", "#{spec_ext_dir}/#{ext}.c"]
+ if spec_ext_dir != core_ext_dir
+ files += Dir.glob("#{spec_ext_dir}/*.h")
+ end
+ files.each do |file|
+ if cxx and file.end_with?('.c')
+ cp file, "#{tmpdir}/#{File.basename(file, '.c')}.cpp"
+ else
+ cp file, "#{tmpdir}/#{File.basename(file)}"
+ end
end
Dir.chdir(tmpdir) do
@@ -64,11 +78,27 @@ def compile_extension(name)
init_mkmf unless required
create_makefile(ext, tmpdir)
else
- File.write("extconf.rb", "require 'mkmf'\n" +
- "$ruby = ENV.values_at('RUBY_EXE', 'RUBY_FLAGS').join(' ')\n" +
+ # Workaround for digest C-API specs to find the ruby/digest.h header
+ # when run in the CRuby repository via make test-spec
+ if MSpecScript.instance_variable_defined?(:@testing_ruby)
+ ruby_repository_extra_include_dir = "-I#{RbConfig::CONFIG.fetch("prefix")}/#{RbConfig::CONFIG.fetch("EXTOUT")}/include"
+ end
+
+ File.write("extconf.rb", <<-RUBY)
+ require 'mkmf'
+ $ruby = ENV.values_at('RUBY_EXE', 'RUBY_FLAGS').join(' ')
# MRI magic to consider building non-bundled extensions
- "$extout = nil\n" +
- "create_makefile(#{ext.inspect})\n")
+ $extout = nil
+ if RbConfig::CONFIG.key?("buildlibdir") # The top directory where the libruby is built.
+ # Prepend the dummy macro to bypass the conversion in `with_destdir` on DOSISH
+ # platforms, where the drive letter is replaced with `$(DESTDIR)`. `DESTDIR` is
+ # overridden by the command line argument bellow.
+ RbConfig::MAKEFILE_CONFIG["buildlibdir"] = "$(empty)" + RbConfig::CONFIG["buildlibdir"]
+ end
+ append_cflags '-Wno-declaration-after-statement'
+ #{"append_cflags #{ruby_repository_extra_include_dir.inspect}" if ruby_repository_extra_include_dir}
+ create_makefile(#{ext.inspect})
+ RUBY
output = ruby_exe("extconf.rb")
raise "extconf failed:\n#{output}" unless $?.success?
$stderr.puts output if debug
@@ -76,7 +106,7 @@ def compile_extension(name)
# Do not capture stderr as we want to show compiler warnings
make, opts = setup_make
- output = IO.popen([make, "V=1", "DESTDIR=", opts], &:read)
+ output = IO.popen([*make, "V=1", "DESTDIR=", opts], &:read)
raise "#{make} failed:\n#{output}" unless $?.success?
$stderr.puts output if debug
@@ -93,30 +123,40 @@ end
def setup_make
make = ENV['MAKE']
make ||= (RbConfig::CONFIG['host_os'].include?("mswin") ? "nmake" : "make")
- make_flags = ENV["MAKEFLAGS"] || ''
+ env = %w[MFLAGS MAKEFLAGS GNUMAKEFLAGS].to_h {|var| [var, ENV[var]]}
+ make_flags = env["MAKEFLAGS"] || ''
# suppress logo of nmake.exe to stderr
if File.basename(make, ".*").downcase == "nmake" and !make_flags.include?("l")
- ENV["MAKEFLAGS"] = "l#{make_flags}"
+ env["MAKEFLAGS"] = "l#{make_flags}"
end
opts = {}
if /(?:\A|\s)--jobserver-(?:auth|fds)=(\d+),(\d+)/ =~ make_flags
- begin
- r = IO.for_fd($1.to_i(10), "rb", autoclose: false)
- w = IO.for_fd($2.to_i(10), "wb", autoclose: false)
- rescue Errno::EBADF
- else
- opts[r] = r
- opts[w] = w
+ [$1, $2].each do |fd|
+ fd = IO.for_fd(fd.to_i(10), autoclose: false)
+ opts[fd] = fd
+ rescue
+ # Jobserver is not usable, maybe no `+` flag or on Windows.
+ job_options = /\A\s*(?:-j\d+\s*|-\S+\Kj\d+)|(?:\G|\s)\K--jobserver-(?:auth|fds)=\S+\s*/
+ env["MAKEFLAGS"] = make_flags.gsub(job_options, '')
+ %w[GNUMAKEFLAGS MFLAGS].each do |var|
+ if flags = env[var]
+ env[var] = flags.gsub(job_options, '')
+ end
+ end
+ opts.clear
+ break
end
end
- [make, opts]
+ [[env, make], opts]
end
def load_extension(name)
- require compile_extension(name)
+ ext_path = compile_extension(name)
+ require ext_path
+ ext_path
rescue LoadError => e
if %r{/usr/sbin/execerror ruby "\(ld 3 1 main ([/a-zA-Z0-9_\-.]+_spec\.so)"} =~ e.message
system('/usr/sbin/execerror', "#{RbConfig::CONFIG["bindir"]}/ruby", "(ld 3 1 main #{$1}")