Skip to content

Commit c16e05d

Browse files
committed
Parallelize cross compilation
1 parent a9f1e1f commit c16e05d

File tree

5 files changed

+52
-43
lines changed

5 files changed

+52
-43
lines changed

.circleci/config.yml

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -197,35 +197,26 @@ jobs:
197197
path: test/reports
198198

199199
cross_compile_gem:
200-
machine:
201-
image: ubuntu-2004:current
200+
parameters:
201+
platform:
202+
description: "Platform to compile the gem resources"
203+
type: string
204+
205+
docker:
206+
- image: "ghcr.io/rake-compiler/rake-compiler-dock-image:1.3.0-mri-<< parameters.platform >>"
202207

203208
steps:
204-
- ruby/install:
205-
version: '2.7'
206209
- checkout
207-
- restore_cache:
208-
name: restore gem cache
209-
keys:
210-
- v1-bundle-{{ .Branch }}-{{ checksum "tiny_tds.gemspec" }}
211-
- v1-bundle-{{ .Branch }}-
212-
- v1-bundle-
213210

214211
- run:
215212
name: bundle install gems
216213
command: |
217-
bundle install --path vendor/bundle
218-
219-
- save_cache:
220-
name: save gem cache
221-
paths:
222-
- ./vendor/bundle
223-
key: v1-bundle-{{ .Branch }}-{{ checksum "tiny_tds.gemspec" }}
214+
bundle install
224215
225216
- run:
226217
name: Write used versions for ports into file
227218
command: |
228-
bundle exec rake ports:version_file
219+
rake ports:version_file[<< parameters.platform >>]
229220
230221
- restore_cache:
231222
name: restore ports cache
@@ -234,16 +225,15 @@ jobs:
234225
- ports-
235226

236227
- run:
237-
name: Build gems
228+
name: Build gem
238229
command: |
239-
bundle exec rake gem
240-
bundle exec rake gem:native
230+
rake gem:for_platform[<< parameters.platform >>]
241231
242232
- run:
243233
name: Move gems into separate directory before caching
244234
command: |
245-
mkdir -p artifacts/gems
246-
mv pkg/*.gem artifacts/gems
235+
mkdir -p artifacts-<< parameters.platform >>/gems
236+
mv pkg/*.gem artifacts-<< parameters.platform >>/gems
247237
248238
- store_artifacts:
249239
path: artifacts/gems
@@ -256,14 +246,20 @@ jobs:
256246

257247
- persist_to_workspace:
258248
name: save gems into workspace
259-
root: artifacts
249+
root: artifacts-<< parameters.platform >>
260250
paths:
261251
- gems
262252

263253
workflows:
264254
test_supported_ruby_versions:
265255
jobs:
266-
- cross_compile_gem
256+
- cross_compile_gem:
257+
matrix:
258+
parameters:
259+
platform:
260+
- "x86-mingw32"
261+
- "x64-mingw32"
262+
- "x64-mingw-ucrt"
267263
- test_windows:
268264
requires:
269265
- cross_compile_gem

Rakefile

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,28 @@ ruby_cc_ucrt_versions = "3.2.0:3.1.0".freeze
1111
ruby_cc_mingw32_versions = "3.0.0:2.7.0:2.6.0:2.5.0:2.4.0".freeze
1212

1313
GEM_PLATFORM_HOSTS = {
14+
'x86-mingw32' => {
15+
host: 'i686-w64-mingw32',
16+
ruby_versions: ruby_cc_mingw32_versions
17+
},
1418
'x64-mingw32' => {
1519
host: 'x86_64-w64-mingw32',
1620
ruby_versions: ruby_cc_mingw32_versions
1721
},
1822
'x64-mingw-ucrt' => {
19-
host: 'mingw-w64-ucrt-x86_64',
23+
host: 'x86_64-w64-mingw32',
2024
ruby_versions: ruby_cc_ucrt_versions
2125
},
22-
'x86-mingw32' => {
23-
host: 'i686-w64-mingw32',
24-
ruby_versions: ruby_cc_mingw32_versions
25-
},
2626
}
2727

2828
# Add our project specific files to clean for a rebuild
2929
CLEAN.include FileList["{ext,lib}/**/*.{so,#{RbConfig::CONFIG['DLEXT']},o}"],
30-
FileList["exe/*"]
30+
FileList["exe/*"]
3131

3232
# Clobber all our temp files and ports files including .install files
3333
# and archives
3434
CLOBBER.include FileList["tmp/**/*"],
35-
FileList["ports/**/*"].exclude(%r{^ports/archives})
35+
FileList["ports/**/*"].exclude(%r{^ports/archives})
3636

3737
Dir['tasks/*.rake'].sort.each { |f| load f }
3838

tasks/native_gem.rake

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,19 @@ task 'gem:native' => ['ports:cross'] do
55
require 'rake_compiler_dock'
66

77
# make sure to install our bundle
8-
sh "bundle package --all" # Avoid repeated downloads of gems by using gem files from the host.
8+
sh "bundle package --all" # Avoid repeated downloads of gems by using gem files from the host.
99

1010
GEM_PLATFORM_HOSTS.each do |plat, meta|
1111
RakeCompilerDock.sh "bundle --local && RUBY_CC_VERSION=#{meta[:ruby_versions]} rake native:#{plat} gem", platform: plat
1212
end
1313
end
14+
15+
# assumes you are in a container provided by Rake compiler
16+
# if not, use the task above
17+
task 'gem:for_platform', [:gem_platform] do |_task, args|
18+
args.with_defaults(gem_platform: RbConfig::CONFIG["arch"])
19+
20+
sh "bundle install"
21+
Rake::Task["ports:compile"].invoke(GEM_PLATFORM_HOSTS[args.gem_platform][:host], args.gem_platform)
22+
sh "RUBY_CC_VERSION=#{GEM_PLATFORM_HOSTS[args.gem_platform][:ruby_versions]} rake native:#{args.gem_platform} gem"
23+
end

tasks/ports.rake

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace :ports do
1818
CLEAN.include "ports/*.installed"
1919

2020
task :openssl, [:host, :gem_platform] do |_task, args|
21-
args.with_defaults(host: RbConfig::CONFIG['host'], gem_platform: RUBY_PLATFORM)
21+
args.with_defaults(host: RbConfig::CONFIG['host'], gem_platform: RbConfig::CONFIG["arch"])
2222

2323
libraries_to_compile[:openssl].files = [OPENSSL_SOURCE_URI]
2424
libraries_to_compile[:openssl].host = args.host
@@ -29,18 +29,17 @@ namespace :ports do
2929
end
3030

3131
task :libiconv, [:host, :gem_platform] do |_task, args|
32-
args.with_defaults(host: RbConfig::CONFIG['host'], gem_platform: RUBY_PLATFORM)
32+
args.with_defaults(host: RbConfig::CONFIG['host'], gem_platform: RbConfig::CONFIG["arch"])
3333

3434
libraries_to_compile[:libiconv].files = [ICONV_SOURCE_URI]
3535
libraries_to_compile[:libiconv].host = args.host
3636
libraries_to_compile[:libiconv].gem_platform = args.gem_platform
37-
3837
libraries_to_compile[:libiconv].cook
3938
libraries_to_compile[:libiconv].activate
4039
end
4140

4241
task :freetds, [:host, :gem_platform] do |_task, args|
43-
args.with_defaults(host: RbConfig::CONFIG['host'], gem_platform: RUBY_PLATFORM)
42+
args.with_defaults(host: RbConfig::CONFIG['host'], gem_platform: RbConfig::CONFIG["arch"])
4443

4544
libraries_to_compile[:freetds].files = [FREETDS_SOURCE_URI]
4645
libraries_to_compile[:freetds].host = args.host
@@ -65,7 +64,7 @@ namespace :ports do
6564
end
6665

6766
task :compile, [:host, :gem_platform] do |_task, args|
68-
args.with_defaults(host: RbConfig::CONFIG['host'], gem_platform: RUBY_PLATFORM)
67+
args.with_defaults(host: RbConfig::CONFIG['host'], gem_platform: RbConfig::CONFIG["arch"])
6968

7069
puts "Compiling ports for #{args.host} (Ruby platform #{args.gem_platform}) ..."
7170

@@ -82,20 +81,22 @@ namespace :ports do
8281
GEM_PLATFORM_HOSTS.each do |gem_platform, meta|
8382
# make sure to install our bundle
8483
build = ['bundle']
85-
build << "rake ports:compile[#{meta[:host]},#{gem_platform}] MAKE='make -j`nproc`'"
84+
build << "RUBY_CC_VERSION=#{meta[:ruby_versions]} rake ports:compile[#{meta[:host]},#{gem_platform}] MAKE='make -j`nproc`'"
8685
RakeCompilerDock.sh build.join(' && '), platform: gem_platform
8786
end
8887
end
8988

9089
desc "Notes the actual versions for the compiled ports into a file"
91-
task "version_file" do
90+
task "version_file", [:gem_platform] do |_task, args|
91+
args.with_defaults(gem_platform: RbConfig::CONFIG["arch"])
92+
9293
ports_version = {}
9394

9495
libraries_to_compile.each do |library, library_recipe|
9596
ports_version[library] = library_recipe.version
9697
end
9798

98-
ports_version[:platforms] = GEM_PLATFORM_HOSTS.keys
99+
ports_version[:platform] = args.gem_platform
99100

100101
File.open(".ports_versions", "w") do |f|
101102
f.write ports_version

tasks/ports/recipe.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,22 @@
55

66
module Ports
77
class Recipe < MiniPortile
8-
attr_accessor :gem_platform
8+
attr_writer :gem_platform
99

1010
def cook
1111
checkpoint = "ports/checkpoints/#{name}-#{version}-#{gem_platform}.installed"
1212

1313
unless File.exist? checkpoint
1414
super
15+
FileUtils.mkdir_p("ports/checkpoints")
1516
FileUtils.touch checkpoint
1617
end
1718
end
1819

1920
private
2021

22+
attr_reader :gem_platform
23+
2124
def port_path
2225
"#{@target}/#{gem_platform}/#{@name}/#{@version}"
2326
end
@@ -59,4 +62,3 @@ def get_patches(libname, version)
5962
end
6063
end
6164
end
62-

0 commit comments

Comments
 (0)