Skip to content

Commit db0d855

Browse files
committed
chore: Add native.rake
1 parent bae53ad commit db0d855

File tree

4 files changed

+174
-15
lines changed

4 files changed

+174
-15
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ issues/
1515
pkg/
1616
ports/
1717
tmp/
18+
tmp_chdb/
1819
vendor/
1920
test/
2021
testdb/
22+
ext/chdb/include/
23+
ext/chdb/lib/

Rakefile

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
11
# frozen_string_literal: true
22

3-
require 'bundler/gem_tasks'
4-
require 'rspec/core/rake_task'
5-
require 'rake/extensiontask'
6-
require 'rubocop/rake_task'
7-
8-
# require "bundler"
3+
require 'bundler'
94
CHDB_SPEC = Bundler.load_gemspec('chdb.gemspec')
105

11-
RSpec::Core::RakeTask.new(:spec)
12-
13-
Rake::ExtensionTask.new('chdb') do |ext|
14-
ext.lib_dir = 'lib/chdb'
15-
end
16-
17-
RuboCop::RakeTask.new
18-
19-
task default: %i[spec rubocop]
6+
task default: %i[rubocop compile test]

dependencies.yml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
chdb:
2+
version: "3.1.1"

rakelib/native.rake

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# frozen_string_literal: true
2+
3+
require "bundler/gem_tasks"
4+
require "rubygems/package_task"
5+
require "rake/extensiontask"
6+
require "rake_compiler_dock"
7+
require "yaml"
8+
9+
cross_platforms = [
10+
"aarch64-linux-gnu",
11+
"x86_64-linux-gnu",
12+
"arm64-darwin",
13+
"x86_64-darwin"
14+
]
15+
16+
RakeCompilerDock.set_ruby_cc_version("~> 3.1")
17+
18+
# Gem::PackageTask.new(CHDB_SPEC).define # packaged_tarball version of the gem for platform=ruby
19+
task "package" => cross_platforms.map { |p| "gem:#{p}" } # "package" task for all the native platforms
20+
21+
module CHDBDependency
22+
class << self
23+
def setup
24+
dependencies = YAML.load_file(File.join(__dir__, "..", "dependencies.yml"), symbolize_names: true)
25+
chdb_info = dependencies[:chdb]
26+
version = chdb_info[:version]
27+
28+
cross_platforms.each do |platform|
29+
platform_key = platform.gsub(/-/, '_').to_sym
30+
next unless chdb_info[:platforms][platform_key]
31+
32+
download_and_extract(platform, version)
33+
end
34+
end
35+
36+
private
37+
38+
def download_and_extract(platform, version)
39+
file_name = case platform
40+
when 'aarch64-linux-gnu' then 'linux-aarch64-libchdb.tar.gz'
41+
when 'x86_64-linux-gnu' then 'linux-x86_64-libchdb.tar.gz'
42+
when 'arm64-darwin' then 'macos-arm64-libchdb.tar.gz'
43+
when 'x86_64-darwin' then 'macos-x86_64-libchdb.tar.gz'
44+
end
45+
46+
url = "https://github.com/chdb-io/chdb/releases/download/v#{version}/#{file_name}"
47+
48+
archive_dir = File.join("ports", "archives")
49+
FileUtils.mkdir_p(archive_dir)
50+
51+
tarball = File.join(archive_dir, name)
52+
unless File.exist?(tarball)
53+
puts "Downloading #{name}..."
54+
URI.open(url) do |remote|
55+
IO.copy_stream(remote, tarball)
56+
end
57+
end
58+
59+
tmp_dir = File.join(archive_dir, "tmp_chdb")
60+
FileUtils.rm_rf(tmp_dir)
61+
FileUtils.mkdir_p(tmp_dir)
62+
63+
system("tar xzf #{tarball} -C #{tmp_dir}")
64+
65+
ext_chdb_path = File.expand_path("ext/chdb", __dir__)
66+
[%w[include *.h], %w[lib *.so], %w[lib *.dylib]].each do |(src_dir, pattern)|
67+
src = File.join(tmp_dir, src_dir, pattern)
68+
dest = File.join(ext_chdb_path, src_dir)
69+
FileUtils.mkdir_p(dest)
70+
FileUtils.cp_r(Dir.glob(src), dest, remove_destination: true)
71+
end
72+
73+
# 清理临时目录
74+
FileUtils.rm_rf(tmp_dir)
75+
end
76+
end
77+
end
78+
79+
def gem_build_path
80+
File.join("pkg", CHDB_SPEC.full_name)
81+
end
82+
83+
def add_file_to_gem(relative_source_path)
84+
if relative_source_path.nil? || !File.exist?(relative_source_path)
85+
raise "Cannot find file '#{relative_source_path}'"
86+
end
87+
88+
dest_path = File.join(gem_build_path, relative_source_path)
89+
dest_dir = File.dirname(dest_path)
90+
91+
mkdir_p(dest_dir) unless Dir.exist?(dest_dir)
92+
rm_f(dest_path) if File.exist?(dest_path)
93+
safe_ln(relative_source_path, dest_path)
94+
95+
CHDB_SPEC.files << relative_source_path
96+
end
97+
98+
task gem_build_path do
99+
dependencies = YAML.load_file(File.join(__dir__, "..", "dependencies.yml"), symbolize_names: true)
100+
sqlite_tarball = File.basename(dependencies[:sqlite3][:files].first[:url])
101+
archive = Dir.glob(File.join("ports", "archives", sqlite_tarball)).first
102+
add_file_to_gem(archive)
103+
end
104+
105+
Rake::ExtensionTask.new("chdb_native", CHDB_SPEC) do |ext|
106+
ext.ext_dir = "ext/chdb"
107+
ext.lib_dir = "lib/chdb"
108+
ext.cross_compile = true
109+
ext.cross_platform = cross_platforms
110+
ext.cross_config_options << "--enable-cross-build" # so extconf.rb knows we're cross-compiling
111+
112+
ext.prerequisites << :download_chdb_deps
113+
end
114+
115+
namespace "gem" do
116+
cross_platforms.each do |platform|
117+
desc "build native gem for #{platform}"
118+
task platform do
119+
RakeCompilerDock.sh(<<~EOF, platform: platform, verbose: true)
120+
gem install bundler --no-document &&
121+
bundle &&
122+
bundle exec rake gem:#{platform}:buildit
123+
EOF
124+
end
125+
126+
namespace platform do
127+
# this runs in the rake-compiler-dock docker container
128+
task "buildit" do
129+
# use Task#invoke because the pkg/*gem task is defined at runtime
130+
Rake::Task["native:#{platform}"].invoke
131+
Rake::Task["pkg/#{CHDB_SPEC.full_name}-#{Gem::Platform.new(platform)}.gem"].invoke
132+
end
133+
end
134+
end
135+
136+
desc "build native gem for all platforms"
137+
task "all" => [cross_platforms, "gem"].flatten
138+
end
139+
140+
desc "Temporarily set VERSION to a unique timestamp"
141+
task "set-version-to-timestamp" do
142+
# this task is used by bin/test-gem-build
143+
# to test building, packaging, and installing a precompiled gem
144+
version_constant_re = /^\s*VERSION\s*=\s*["'](.*)["']$/
145+
146+
version_file_path = File.join(__dir__, "../lib/chdb/version.rb")
147+
version_file_contents = File.read(version_file_path)
148+
149+
current_version_string = version_constant_re.match(version_file_contents)[1]
150+
current_version = Gem::Version.new(current_version_string)
151+
152+
fake_version = Gem::Version.new(format("%s.test.%s", current_version.bump, Time.now.strftime("%Y.%m%d.%H%M")))
153+
154+
unless version_file_contents.gsub!(version_constant_re, " VERSION = \"#{fake_version}\"")
155+
raise("Could not hack the VERSION constant")
156+
end
157+
158+
File.write(version_file_path, version_file_contents)
159+
160+
puts "NOTE: wrote version as \"#{fake_version}\""
161+
end
162+
163+
CLEAN.add("{ext,lib}/**/*.{o,so}", "pkg", "ext/chdb/{include,lib}")
164+
165+
task :download_chdb_deps do
166+
CHDBDependency.setup
167+
end

0 commit comments

Comments
 (0)