rcee_precompiled 0.4.0-x64-mingw-ucrt → 0.5.1-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc8ffc92ab84b0ab6702b2660813147d510133e695112725d12b811474159cd9
4
- data.tar.gz: 0fc96bed69ced30aa3be061b9c9901f4eb3c479134edbd3e3a04b6211e9ba33c
3
+ metadata.gz: 7c687549676ed304691c57100f0b9790648d31ae083c140d8901c86ae46facbb
4
+ data.tar.gz: e4622f58b30e2bbfcf7144760af06ebd2227324e20fc865aa8a07ab32dbccf0e
5
5
  SHA512:
6
- metadata.gz: 8c9592a70ef1486f27604c600023d580276f47c98f22a4607a97aa9fd37d332096e306e6a20d7b569303615f0ec8fc58cdd4466cad979c3c03a4252edbc4c4c1
7
- data.tar.gz: 2a10c77e1e60b39c1c641b7434bafa46663a1148cd267131cad0851937ef77532967c29fa7801594493e01ba0de63780a7b6a6fa8c2b1ee0589e305d2c286fae
6
+ metadata.gz: ed42d3298f97bfb1df350ef671e755a699ac5bd25883e9706449f3a0603874714ce10ddcf2619f213e2c5ffacad2d61c70e90483a2b60832978890c16e6e2cb4
7
+ data.tar.gz: 6affd1e1aa30e429ba9bd0b69cbcc71c3b52ed143894e8d65cc3b44083fc0154918f8179714221de9cfb6cc522f50ee22a6a6d34ccdf4a8e3b63bebdc6de7c9e
data/Gemfile CHANGED
@@ -8,6 +8,6 @@ gemspec
8
8
  gem "rake", "~> 13.0"
9
9
 
10
10
  gem "rake-compiler"
11
- gem "rake-compiler-dock", "~> 1.2.1"
11
+ gem "rake-compiler-dock", "1.5.0.rc1"
12
12
 
13
13
  gem "minitest", "~> 5.0"
data/README.md CHANGED
@@ -26,15 +26,20 @@ This is really powerful stuff, and once we assume that we can cross-compile reli
26
26
  First, we need to add some features to our `Rake::ExtensionTask` in `Rakefile`:
27
27
 
28
28
  ``` ruby
29
- cross_rubies = ["3.1.0", "3.0.0", "2.7.0", "2.6.0"]
29
+ cross_rubies = ["3.3.0", "3.2.0", "3.1.0", "3.0.0"]
30
30
  cross_platforms = [
31
- "x64-mingw32",
31
+ "aarch64-linux-gnu",
32
+ "aarch64-linux-musl",
33
+ "arm-linux-gnu",
34
+ "arm-linux-musl",
35
+ "arm64-darwin",
32
36
  "x64-mingw-ucrt",
33
- "x86-linux",
34
- "x86_64-linux",
35
- "aarch64-linux",
37
+ "x64-mingw32",
38
+ "x86-linux-gnu",
39
+ "x86-linux-musl",
36
40
  "x86_64-darwin",
37
- "arm64-darwin",
41
+ "x86_64-linux-gnu",
42
+ "x86_64-linux-musl",
38
43
  ]
39
44
  ENV["RUBY_CC_VERSION"] = cross_rubies.join(":")
40
45
 
@@ -92,30 +97,33 @@ The top task (or, really, _set_ of tasks) runs on the host system, and invokes t
92
97
  Changes to the `extconf.rb`:
93
98
 
94
99
  ``` ruby
95
- ENV["CC"] = RbConfig::CONFIG["CC"]
100
+ def configure_cross_compilers
101
+ RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
102
+ ENV["CC"] = RbConfig::CONFIG["CC"]
103
+ end
96
104
  ```
97
105
 
98
106
  This makes sure that the cross-compiler is the compiler used within the guest container (and not the native linux compiler).
99
107
 
100
108
  ``` ruby
101
- cross_build_p = enable_config("cross-build")
109
+ def cross_build?
110
+ enable_config("cross-build")
111
+ end
102
112
  ```
103
113
 
104
114
  The cross-compile rake task signals to `extconf.rb` that it's cross-compiling by using a commandline flag that we can inspect. We'll need this for `libyaml` to make sure that set the appropriate flags during precompilation (flags which shouldn't be set when compiling natively).
105
115
 
106
116
  ``` ruby
107
- MiniPortile.new("yaml", "0.2.5").tap do |recipe|
108
- # ...
109
- # configure the environment that MiniPortile will use for subshells
110
- ENV.to_h.dup.tap do |env|
111
- # -fPIC is necessary for linking into a shared library
112
- env["CFLAGS"] = [env["CFLAGS"], "-fPIC"].join(" ")
113
- env["SUBDIRS"] = "include src" # libyaml: skip tests
114
-
115
- recipe.configure_options += env.map { |key, value| "#{key}=#{value.strip}" }
117
+ # pass some environment variables to the libyaml configuration for cross-compilation
118
+ if cross_build?
119
+ ENV.to_h.tap do |env|
120
+ # -fPIC is necessary for linking into a shared library
121
+ env["CFLAGS"] = [env["CFLAGS"], "-fPIC"].join(" ")
122
+ env["SUBDIRS"] = "include src" # libyaml: skip tests
123
+
124
+ recipe.configure_options += env.map { |key, value| "#{key}=#{value.strip}" }
125
+ end
116
126
  end
117
- # ...
118
- end
119
127
  ```
120
128
 
121
129
  The rest of the extconf changes are related to configuring libyaml at build time. We need to set the -fPIC option so we can mix static and shared libraries together. (This should probably always be set.)
@@ -128,14 +136,14 @@ We have one more small change we'll need to make to how the extension is require
128
136
  lib
129
137
  └── rcee
130
138
  ├── precompiled
131
- │   ├── 2.6
132
- │   │   └── precompiled.so
133
- │   ├── 2.7
134
- │   │   └── precompiled.so
135
139
  │   ├── 3.0
136
140
  │   │   └── precompiled.so
137
141
  │   ├── 3.1
138
142
  │   │   └── precompiled.so
143
+ │   ├── 3.2
144
+ │   │   └── precompiled.so
145
+ │   ├── 3.3
146
+ │   │   └── precompiled.so
139
147
  │   └── version.rb
140
148
  └── precompiled.rb
141
149
  ```
@@ -158,6 +166,22 @@ end
158
166
  Go ahead and try it! `gem install rcee_precompiled`. If you're on windows, linux, or macos you should get a precompiled version that installs in under a second. Everyone else (hello FreeBSD people!) it'll take a few more seconds to build the vanilla gem's packaged tarball.
159
167
 
160
168
 
169
+ ### Windows notes
170
+
171
+ You may have noticed that the gem for `x64-mingw32` only contains `.../3.0/precompiled.so` and not a shared library for 3.1, 3.2, or 3.3. Conversely, the gem for `x64-mingw-ucrt` does *not* contain 3.0 (but contains 3.1..3.3 inclusive).
172
+
173
+ This is because the Windows installer for Ruby switched from `msvcrt` to `ucrt` for the C standard library. Rubies 3.0 and earlier use `msvcrt` but later Rubies use `ucrt`. So if you're on Ruby 3.0 on Windows, bundler will resolve your platform as `x64-mingw32`; but if you're on Ruby 3.1 or later, bundler will resolve your platform as `x64-mingw-ucrt`. See [the rubyinstaller release notes](https://rubyinstaller.org/2021/12/31/rubyinstaller-3.1.0-1-released.html) for more information.
174
+
175
+ This is all taken care of for you by `rake-compiler-dock` and there's no additional work necessary to create those specialized native gems. However, you'll see this libc transition in the CI testing matrix in `.github/workflows/precompiled.yml`.
176
+
177
+
178
+ ### Linux notes
179
+
180
+ On Linux, the default C library for a long time was GNU libc, and so when you see native gem platforms like `x86_64-linux` the _implied_ libc is `gnu`. However, in recent years the `musl` libc project has gotten off the ground in distributions like Alpine. Often, `musl` systems are able to run code compiled on (and for) `gnu` systems; but not always. And in those incompatible cases, users had to work around it or avoid Alpine.
181
+
182
+ As of Rubygems 3.3.22, the `gem` and `bundle` tools are able to distinguish platforms by their libc type (e.g., `x86_64-linux-gnu` versus `x86_64-linux-musl`); and `rake-compiler-dock` started to be able to build `musl` native gems as of v1.5.0.
183
+
184
+
161
185
  ## Testing
162
186
 
163
187
  See [.github/workflows/precompiled.yml](../.github/workflows/precompiled.yml)
data/Rakefile CHANGED
@@ -6,22 +6,26 @@ require "rake/testtask"
6
6
  require "rake/extensiontask"
7
7
  require "rake_compiler_dock"
8
8
 
9
- cross_rubies = ["3.1.0", "3.0.0", "2.7.0", "2.6.0"]
9
+ cross_rubies = ["3.3.0", "3.2.0", "3.1.0", "3.0.0"]
10
10
  cross_platforms = [
11
- "aarch64-linux",
12
- "arm-linux",
11
+ "aarch64-linux-gnu",
12
+ "aarch64-linux-musl",
13
+ "arm-linux-gnu",
14
+ "arm-linux-musl",
13
15
  "arm64-darwin",
14
16
  "x64-mingw-ucrt",
15
17
  "x64-mingw32",
16
- "x86-linux",
18
+ "x86-linux-gnu",
19
+ "x86-linux-musl",
17
20
  "x86_64-darwin",
18
- "x86_64-linux",
21
+ "x86_64-linux-gnu",
22
+ "x86_64-linux-musl",
19
23
  ]
20
24
  ENV["RUBY_CC_VERSION"] = cross_rubies.join(":")
21
25
 
22
26
  rcee_precompiled_spec = Bundler.load_gemspec("rcee_precompiled.gemspec")
23
27
  Gem::PackageTask.new(rcee_precompiled_spec).define #packaged_tarball version of the gem for platform=ruby
24
- task "package" => cross_platforms.map { |p| "gem:#{p}" } # "package" task for all the native platforms
28
+ task "package" => "gem:all"
25
29
 
26
30
  Rake::TestTask.new(:test) do |t|
27
31
  t.libs << "test"
@@ -38,6 +42,11 @@ Rake::ExtensionTask.new("precompiled", rcee_precompiled_spec) do |ext|
38
42
  # remove things not needed for precompiled gems
39
43
  spec.dependencies.reject! { |dep| dep.name == "mini_portile2" }
40
44
  spec.files.reject! { |file| File.fnmatch?("*.tar.gz", file) }
45
+
46
+ if spec.platform.os == "linux"
47
+ # the `-gnu` suffix is not recognized in earlier versions of rubygems
48
+ spec.required_rubygems_version.concat([">= 3.3.22"])
49
+ end
41
50
  end
42
51
  end
43
52
 
@@ -1,41 +1,78 @@
1
1
  require "mkmf"
2
2
  require "mini_portile2"
3
3
 
4
- package_root_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
4
+ module RCEE
5
+ module Precompiled
6
+ module ExtConf
7
+ PACKAGE_ROOT_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
5
8
 
6
- RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
7
- ENV["CC"] = RbConfig::CONFIG["CC"]
9
+ class << self
10
+ def configure
11
+ configure_cross_compilers
12
+ configure_packaged_libraries
13
+ create_makefile("rcee/precompiled/precompiled")
14
+ end
8
15
 
9
- cross_build_p = enable_config("cross-build")
16
+ def configure_cross_compilers
17
+ RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
18
+ ENV["CC"] = RbConfig::CONFIG["CC"]
19
+ end
10
20
 
11
- MiniPortile.new("yaml", "0.2.5").tap do |recipe|
12
- recipe.files = [{
13
- url: "https://github.com/yaml/libyaml/releases/download/0.2.5/yaml-0.2.5.tar.gz",
14
- sha256: "c642ae9b75fee120b2d96c712538bd2cf283228d2337df2cf2988e3c02678ef4",
15
- }]
16
- recipe.target = File.join(package_root_dir, "ports")
21
+ def configure_packaged_libraries
22
+ recipe = libyaml_recipe
17
23
 
18
- # configure the environment that MiniPortile will use for subshells
19
- if cross_build_p
20
- ENV.to_h.tap do |env|
21
- # -fPIC is necessary for linking into a shared library
22
- env["CFLAGS"] = [env["CFLAGS"], "-fPIC"].join(" ")
23
- env["SUBDIRS"] = "include src" # libyaml: skip tests
24
+ # pass some environment variables to the libyaml configuration for cross-compilation
25
+ if cross_build?
26
+ ENV.to_h.tap do |env|
27
+ # -fPIC is necessary for linking into a shared library
28
+ env["CFLAGS"] = [env["CFLAGS"], "-fPIC"].join(" ")
29
+ env["SUBDIRS"] = "include src" # libyaml: skip tests
24
30
 
25
- recipe.configure_options += env.map { |key, value| "#{key}=#{value.strip}" }
26
- end
27
- end
31
+ recipe.configure_options += env.map { |key, value| "#{key}=#{value.strip}" }
32
+ end
33
+ end
28
34
 
29
- unless File.exist?(File.join(recipe.target, recipe.host, recipe.name, recipe.version))
30
- recipe.cook
31
- end
35
+ # ensure libyaml has already been unpacked, configured, and compiled
36
+ unless File.exist?(File.join(recipe.target, recipe.host, recipe.name, recipe.version))
37
+ recipe.cook
38
+ end
39
+
40
+ # use the packaged libyaml
41
+ recipe.activate
42
+ pkg_config(File.join(recipe.path, "lib", "pkgconfig", "yaml-0.1.pc"))
43
+
44
+ # assert that we can build against the packaged libyaml
45
+ unless have_library("yaml", "yaml_get_version", "yaml.h")
46
+ abort("\nERROR: *** could not find libyaml development environment ***\n\n")
47
+ end
48
+ end
32
49
 
33
- recipe.activate
34
- pkg_config(File.join(recipe.path, "lib", "pkgconfig", "yaml-0.1.pc"))
50
+ def cross_build?
51
+ enable_config("cross-build")
52
+ end
53
+
54
+ def download
55
+ libyaml_recipe.download
56
+ end
57
+
58
+ def libyaml_recipe
59
+ MiniPortile.new("yaml", "0.2.5").tap do |recipe|
60
+ recipe.files = [{
61
+ url: "https://github.com/yaml/libyaml/releases/download/0.2.5/yaml-0.2.5.tar.gz",
62
+ sha256: "c642ae9b75fee120b2d96c712538bd2cf283228d2337df2cf2988e3c02678ef4"
63
+ }]
64
+ recipe.target = File.join(PACKAGE_ROOT_DIR, "ports")
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
35
70
  end
36
71
 
37
- unless have_library("yaml", "yaml_get_version", "yaml.h")
38
- abort("\nERROR: *** could not find libyaml development environment ***\n\n")
72
+ # run "ruby ./ext/precompiled/extconf.rb -- --download-dependencies" to download the tarball
73
+ if arg_config("--download-dependencies")
74
+ RCEE::Precompiled::ExtConf.download
75
+ exit!(0)
39
76
  end
40
77
 
41
- create_makefile("rcee/precompiled/precompiled")
78
+ RCEE::Precompiled::ExtConf.configure
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RCEE
4
4
  module Precompiled
5
- VERSION = "0.4.0"
5
+ VERSION = "0.5.1"
6
6
  end
7
7
  end
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.summary = "Example gem demonstrating a basic C extension."
16
16
  spec.description = "Part of a project to explain how Ruby C extensions work."
17
17
  spec.homepage = "https://github.com/flavorjones/ruby-c-extensions-explained"
18
- spec.required_ruby_version = ">= 2.6.0"
18
+ spec.required_ruby_version = ">= 3.0.0"
19
19
  spec.license = "MIT"
20
20
 
21
21
  # Specify which files should be added to the gem when it is released.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rcee_precompiled
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.1
5
5
  platform: x64-mingw-ucrt
6
6
  authors:
7
7
  - Mike Dalessio
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-19 00:00:00.000000000 Z
11
+ date: 2024-01-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Part of a project to explain how Ruby C extensions work.
14
14
  email:
@@ -26,13 +26,15 @@ files:
26
26
  - ext/precompiled/precompiled.h
27
27
  - lib/rcee/precompiled.rb
28
28
  - lib/rcee/precompiled/3.1/precompiled.so
29
+ - lib/rcee/precompiled/3.2/precompiled.so
30
+ - lib/rcee/precompiled/3.3/precompiled.so
29
31
  - lib/rcee/precompiled/version.rb
30
32
  - rcee_precompiled.gemspec
31
33
  homepage: https://github.com/flavorjones/ruby-c-extensions-explained
32
34
  licenses:
33
35
  - MIT
34
36
  metadata: {}
35
- post_install_message:
37
+ post_install_message:
36
38
  rdoc_options: []
37
39
  require_paths:
38
40
  - lib
@@ -43,15 +45,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
43
45
  version: '3.1'
44
46
  - - "<"
45
47
  - !ruby/object:Gem::Version
46
- version: 3.2.dev
48
+ version: 3.4.dev
47
49
  required_rubygems_version: !ruby/object:Gem::Requirement
48
50
  requirements:
49
51
  - - ">="
50
52
  - !ruby/object:Gem::Version
51
53
  version: '0'
52
54
  requirements: []
53
- rubygems_version: 3.3.4
54
- signing_key:
55
+ rubygems_version: 3.3.26
56
+ signing_key:
55
57
  specification_version: 4
56
58
  summary: Example gem demonstrating a basic C extension.
57
59
  test_files: []