-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcompilation_tasks.rb
More file actions
141 lines (111 loc) · 3.57 KB
/
compilation_tasks.rb
File metadata and controls
141 lines (111 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# frozen_string_literal: true
require "bundler"
require "rubygems/package_task"
require "rake/extensiontask"
module EasyCompile
class CompilationTasks
attr_reader :gemspec, :native, :create_packaging_task, :extension_task
attr_accessor :binary_name
def initialize(create_packaging_task = false, gemspec = nil)
@gemspec = Bundler.load_gemspec(gemspec || find_gemspec)
verify_gemspec!
@create_packaging_task = create_packaging_task
end
def setup
with_mkmf_monkey_patch do
gemspec.extensions.each do |path|
define_task(path)
end
end
setup_packaging if create_packaging_task
end
def ruby_cc_version
required_ruby_version = @gemspec.required_ruby_version
selected_rubies = RubySeries.versions_to_compile_against(required_ruby_version)
selected_rubies.map(&:to_s).join(":")
end
def normalized_platform
platform = RUBY_PLATFORM
if darwin?
RUBY_PLATFORM.sub(/(.*-darwin)\d+/, '\1')
else
platform
end
end
private
def setup_packaging
Gem::PackageTask.new(gemspec) do |pkg|
pkg.need_zip = true
pkg.need_tar = true
end
end
def with_mkmf_monkey_patch
require "mkmf"
instance = self
previous_create_makefile = method(:create_makefile)
Object.define_method(:create_makefile) do |name, *args|
instance.binary_name = name
previous_create_makefile.call(name, *args)
end
Object.define_method(:create_rust_makefile) do |name, *args|
instance.binary_name = name
end
yield
ensure
Object.remove_method(:create_makefile)
Object.remove_method(:create_rust_makefile)
end
def define_task(path)
require File.expand_path(path)
@extension_task = Rake::ExtensionTask.new do |ext|
ext.name = File.basename(binary_name)
ext.config_script = File.basename(path)
ext.ext_dir = File.dirname(path)
ext.lib_dir = binary_lib_dir if binary_lib_dir
ext.gem_spec = gemspec
ext.cross_platform = normalized_platform
ext.cross_compile = true
end
disable_shared unless Gem.win_platform?
ensure
self.binary_name = nil
end
def binary_lib_dir
dir = File.dirname(binary_name)
return if dir == "."
gemspec.raw_require_paths.first + "/#{dir}"
end
def darwin?
Gem::Platform.local.os == "darwin"
end
def disable_shared
makefile_tasks = Rake::Task.tasks.select { |task| task.name =~ /Makefile/ }
makefile_tasks.each do |task|
task.enhance do
makefile_content = File.read(task.name)
makefile_content.match(/LIBRUBYARG_SHARED = (.*)/) do |match|
shared_flags = match[1].split(" ")
shared_flags.reject! { |flag| flag == "-l$(RUBY_SO_NAME)" }
makefile_content.gsub!(/(LIBRUBYARG_SHARED = ).*/, "\\1#{shared_flags.join(' ')}")
File.write(task.name, makefile_content)
end
end
end
end
def find_gemspec(glob = "*.gemspec")
gemspec = Dir.glob(glob).sort.first
return gemspec if gemspec
raise GemspecError, <<~EOM
Couldn't find a gemspec in the current directory.
Make sure to run any easy_compile commands in the root of your gem folder.
EOM
end
def verify_gemspec!
return if gemspec.extensions.any?
raise GemspecError, <<~EOM
Your gem has no native extention defined in its gemspec.
This tool can't be used on pure Ruby gems.
EOM
end
end
end