-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathRakefile
More file actions
164 lines (136 loc) · 4.92 KB
/
Rakefile
File metadata and controls
164 lines (136 loc) · 4.92 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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# frozen_string_literal: true
require "bundler/gem_tasks"
require "minitest/test_task"
Minitest::TestTask.create
begin
require "rubocop/rake_task"
RuboCop::RakeTask.new
rescue LoadError
# rubocop not available in cross-compilation environment
end
begin
require "rake/extensiontask"
PLATFORMS = [
"aarch64-linux-gnu",
"aarch64-linux-musl",
"arm-linux-gnu",
"arm-linux-musl",
"arm64-darwin",
"x86-linux-gnu",
"x86-linux-musl",
"x86_64-darwin",
"x86_64-linux-gnu",
"x86_64-linux-musl",
].freeze
GO_PLATFORMS = {
"aarch64-linux-gnu" => { goos: "linux", goarch: "arm64", cc: "aarch64-linux-gnu-gcc" },
"aarch64-linux-musl" => { goos: "linux", goarch: "arm64", cc: "aarch64-linux-musl-gcc" },
"arm-linux-gnu" => { goos: "linux", goarch: "arm", cc: "arm-linux-gnueabihf-gcc" },
"arm-linux-musl" => { goos: "linux", goarch: "arm", cc: "arm-linux-musleabihf-gcc" },
"arm64-darwin" => { goos: "darwin", goarch: "arm64", cc: "o64-clang" },
"x86-linux-gnu" => { goos: "linux", goarch: "386", cc: "i686-linux-gnu-gcc" },
"x86-linux-musl" => { goos: "linux", goarch: "386", cc: "i686-unknown-linux-musl-gcc" },
"x86_64-darwin" => { goos: "darwin", goarch: "amd64", cc: "o64-clang" },
"x86_64-linux-gnu" => { goos: "linux", goarch: "amd64", cc: "x86_64-linux-gnu-gcc" },
"x86_64-linux-musl" => { goos: "linux", goarch: "amd64", cc: "gcc" },
}.freeze
def go_version
go_mod = File.read("go/go.mod")
go_mod[/^go (\d+\.\d+\.\d+)/, 1] || go_mod[/^go (\d+\.\d+)/, 1]
end
def detect_go_platform
cpu = RbConfig::CONFIG["host_cpu"]
os = RbConfig::CONFIG["host_os"]
arch = case cpu
when /aarch64|arm64/ then "arm64"
when /x86_64|amd64/ then "amd64"
else cpu
end
goos = case os
when /darwin/ then "darwin"
else "linux"
end
"#{goos}_#{arch}"
end
namespace :go do
desc "Build Go archive for current platform"
task :build do
platform = detect_go_platform
output_dir = "go/build/#{platform}"
FileUtils.mkdir_p(output_dir)
sh "cd go && CGO_ENABLED=1 go build -buildmode=c-archive -o build/#{platform}/libbubblezone.a ."
end
desc "Build Go archives for all platforms"
task :build_all do
GO_PLATFORMS.each_value do |env|
output_dir = "go/build/#{env[:goos]}_#{env[:goarch]}"
FileUtils.mkdir_p(output_dir)
sh "cd go && CGO_ENABLED=1 GOOS=#{env[:goos]} GOARCH=#{env[:goarch]} go build -buildmode=c-archive -o build/#{env[:goos]}_#{env[:goarch]}/libbubblezone.a ."
end
end
desc "Clean Go build artifacts"
task :clean do
FileUtils.rm_rf("go/build")
end
desc "Format Go source files"
task :fmt do
sh "gofmt -s -w go/"
end
end
Rake::ExtensionTask.new do |ext|
ext.name = "bubblezone"
ext.ext_dir = "ext/bubblezone"
ext.lib_dir = "lib/bubblezone"
ext.source_pattern = "*.c"
ext.gem_spec = Gem::Specification.load("bubblezone.gemspec")
ext.cross_compile = true
ext.cross_platform = PLATFORMS
end
namespace "gem" do
task "prepare" do
require "rake_compiler_dock"
sh "bundle config set cache_all true"
gemspec_path = File.expand_path("./bubblezone.gemspec", __dir__)
spec = eval(File.read(gemspec_path), binding, gemspec_path)
RakeCompilerDock.set_ruby_cc_version(spec.required_ruby_version.as_list)
rescue LoadError
abort "rake_compiler_dock is required for this task"
end
PLATFORMS.each do |platform|
desc "Build the native gem for #{platform}"
task platform => "prepare" do
require "rake_compiler_dock"
env = GO_PLATFORMS[platform]
build_script = <<~BASH
curl -sSL https://go.dev/dl/go#{go_version}.linux-amd64.tar.gz -o /tmp/go.tar.gz && \
sudo tar -C /usr/local -xzf /tmp/go.tar.gz && \
rm /tmp/go.tar.gz && \
export PATH=$PATH:/usr/local/go/bin && \
cd go && \
mkdir -p build/#{env[:goos]}_#{env[:goarch]} && \
CGO_ENABLED=1 CC=#{env[:cc]} GOOS=#{env[:goos]} GOARCH=#{env[:goarch]} go build -buildmode=c-archive -o build/#{env[:goos]}_#{env[:goarch]}/libbubblezone.a . && \
cd .. && \
rm -f .ruby-version && \
rm -rf vendor/bundle && \
bundle install && \
rake native:#{platform} gem RUBY_CC_VERSION='#{ENV.fetch("RUBY_CC_VERSION", nil)}'
BASH
RakeCompilerDock.sh(build_script, platform: platform)
end
end
end
rescue LoadError => e
desc "Compile task not available (rake-compiler not installed)"
task :compile do
puts e
abort <<~MESSAGE
rake-compiler is required for this task.
Are you running `rake` using `bundle exec rake`?
Otherwise:
* try to run bundle install
* add it to your Gemfile
* or install it with: gem install rake-compiler
MESSAGE
end
end
task default: [:test, :compile]