mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00

When testing under the ruby/ruby setup, mkmf.rb needs to the `$extout` global variable set properly. This is because, in this particular case, the `ruby.h` header needed to compile extensions is constructed from `$(extout)/include($arch)/ruby/config.h` but `$extout` is not set by default. I tried to fix this in mkmf.rb itself but I couldn't figure it. But setting it externally to workaround the issue fixes the specs, so I'll start with that. Also setting it externally causes issues when running specs upstream against Ruby 2.3 (I guess because of some difference with Ruby 2.3 mkmf.rb implementation). So I'm avoiding doing it on Ruby 2.3 to woraround that. https://github.com/rubygems/rubygems/commit/d782984585
188 lines
5.8 KiB
Ruby
188 lines
5.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe "installing a gem with native extensions" do
|
|
it "installs" do
|
|
build_repo2 do
|
|
build_gem "c_extension" do |s|
|
|
s.extensions = ["ext/extconf.rb"]
|
|
s.write "ext/extconf.rb", <<-E
|
|
require "mkmf"
|
|
$extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"] unless RUBY_VERSION < "2.4"
|
|
name = "c_extension_bundle"
|
|
dir_config(name)
|
|
raise "OMG" unless with_config("c_extension") == "hello"
|
|
create_makefile(name)
|
|
E
|
|
|
|
s.write "ext/c_extension.c", <<-C
|
|
#include "ruby.h"
|
|
|
|
VALUE c_extension_true(VALUE self) {
|
|
return Qtrue;
|
|
}
|
|
|
|
void Init_c_extension_bundle() {
|
|
VALUE c_Extension = rb_define_class("CExtension", rb_cObject);
|
|
rb_define_method(c_Extension, "its_true", c_extension_true, 0);
|
|
}
|
|
C
|
|
|
|
s.write "lib/c_extension.rb", <<-C
|
|
require "c_extension_bundle"
|
|
C
|
|
end
|
|
end
|
|
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo2)}"
|
|
gem "c_extension"
|
|
G
|
|
|
|
bundle "config set build.c_extension --with-c_extension=hello"
|
|
bundle "install"
|
|
|
|
expect(out).to include("Installing c_extension 1.0 with native extensions")
|
|
|
|
run "Bundler.require; puts CExtension.new.its_true"
|
|
expect(out).to eq("true")
|
|
end
|
|
|
|
it "installs from git" do
|
|
build_git "c_extension" do |s|
|
|
s.extensions = ["ext/extconf.rb"]
|
|
s.write "ext/extconf.rb", <<-E
|
|
require "mkmf"
|
|
$extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"] unless RUBY_VERSION < "2.4"
|
|
name = "c_extension_bundle"
|
|
dir_config(name)
|
|
raise "OMG" unless with_config("c_extension") == "hello"
|
|
create_makefile(name)
|
|
E
|
|
|
|
s.write "ext/c_extension.c", <<-C
|
|
#include "ruby.h"
|
|
|
|
VALUE c_extension_true(VALUE self) {
|
|
return Qtrue;
|
|
}
|
|
|
|
void Init_c_extension_bundle() {
|
|
VALUE c_Extension = rb_define_class("CExtension", rb_cObject);
|
|
rb_define_method(c_Extension, "its_true", c_extension_true, 0);
|
|
}
|
|
C
|
|
|
|
s.write "lib/c_extension.rb", <<-C
|
|
require "c_extension_bundle"
|
|
C
|
|
end
|
|
|
|
bundle "config set build.c_extension --with-c_extension=hello"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "c_extension", :git => #{lib_path("c_extension-1.0").to_s.dump}
|
|
G
|
|
|
|
expect(err).to_not include("warning: conflicting chdir during another chdir block")
|
|
|
|
run "Bundler.require; puts CExtension.new.its_true"
|
|
expect(out).to eq("true")
|
|
end
|
|
|
|
it "installs correctly from git when multiple gems with extensions share one repository" do
|
|
build_repo2 do
|
|
["one", "two"].each do |n|
|
|
build_lib "c_extension_#{n}", "1.0", :path => lib_path("gems/c_extension_#{n}") do |s|
|
|
s.extensions = ["ext/extconf.rb"]
|
|
s.write "ext/extconf.rb", <<-E
|
|
require "mkmf"
|
|
$extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"] unless RUBY_VERSION < "2.4"
|
|
name = "c_extension_bundle_#{n}"
|
|
dir_config(name)
|
|
raise "OMG" unless with_config("c_extension_#{n}") == "#{n}"
|
|
create_makefile(name)
|
|
E
|
|
|
|
s.write "ext/c_extension_#{n}.c", <<-C
|
|
#include "ruby.h"
|
|
|
|
VALUE c_extension_#{n}_value(VALUE self) {
|
|
return rb_str_new_cstr("#{n}");
|
|
}
|
|
|
|
void Init_c_extension_bundle_#{n}() {
|
|
VALUE c_Extension = rb_define_class("CExtension_#{n}", rb_cObject);
|
|
rb_define_method(c_Extension, "value", c_extension_#{n}_value, 0);
|
|
}
|
|
C
|
|
|
|
s.write "lib/c_extension_#{n}.rb", <<-C
|
|
require "c_extension_bundle_#{n}"
|
|
C
|
|
end
|
|
end
|
|
build_git "gems", :path => lib_path("gems"), :gemspec => false
|
|
end
|
|
|
|
bundle "config set build.c_extension_one --with-c_extension_one=one"
|
|
bundle "config set build.c_extension_two --with-c_extension_two=two"
|
|
|
|
# 1st time, require only one gem -- only one of the extensions gets built.
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "c_extension_one", :git => #{lib_path("gems").to_s.dump}
|
|
G
|
|
|
|
# 2nd time, require both gems -- we need both extensions to be built now.
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "c_extension_one", :git => #{lib_path("gems").to_s.dump}
|
|
gem "c_extension_two", :git => #{lib_path("gems").to_s.dump}
|
|
G
|
|
|
|
run "Bundler.require; puts CExtension_one.new.value; puts CExtension_two.new.value"
|
|
expect(out).to eq("one\ntwo")
|
|
end
|
|
|
|
it "install with multiple build flags" do
|
|
build_git "c_extension" do |s|
|
|
s.extensions = ["ext/extconf.rb"]
|
|
s.write "ext/extconf.rb", <<-E
|
|
require "mkmf"
|
|
$extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"] unless RUBY_VERSION < "2.4"
|
|
name = "c_extension_bundle"
|
|
dir_config(name)
|
|
raise "OMG" unless with_config("c_extension") == "hello" && with_config("c_extension_bundle-dir") == "hola"
|
|
create_makefile(name)
|
|
E
|
|
|
|
s.write "ext/c_extension.c", <<-C
|
|
#include "ruby.h"
|
|
|
|
VALUE c_extension_true(VALUE self) {
|
|
return Qtrue;
|
|
}
|
|
|
|
void Init_c_extension_bundle() {
|
|
VALUE c_Extension = rb_define_class("CExtension", rb_cObject);
|
|
rb_define_method(c_Extension, "its_true", c_extension_true, 0);
|
|
}
|
|
C
|
|
|
|
s.write "lib/c_extension.rb", <<-C
|
|
require "c_extension_bundle"
|
|
C
|
|
end
|
|
|
|
bundle "config set build.c_extension --with-c_extension=hello --with-c_extension_bundle-dir=hola"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "c_extension", :git => #{lib_path("c_extension-1.0").to_s.dump}
|
|
G
|
|
|
|
run "Bundler.require; puts CExtension.new.its_true"
|
|
expect(out).to eq("true")
|
|
end
|
|
end
|