rcee_precompiled 0.3.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/README.md +31 -20
- data/Rakefile +16 -3
- data/ext/precompiled/extconf.rb +64 -27
- data/lib/rcee/precompiled/version.rb +1 -1
- data/rcee_precompiled.gemspec +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80a6876c836d53fcde0cdcc9b6b948419be41fcc942f8add855984fdcabe99aa
|
4
|
+
data.tar.gz: 52b74c8bb35c6dfd33fa1f7fbb30aa1f7e43b7b8fda8ebcd4c885837413ba5bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8864cdae0e60f649af23b3cd5b31ca7675ee8b3ab5c73edb783351d2ba09bc33d61145c86fae21b98da8ebdaad0b4e4327d717ef6665b6c87952cab4ec77d31
|
7
|
+
data.tar.gz: 47f13c358c3b04d3b47d86424e5f21b945feedbce55c9063f5521b1b10c8fc166b2763d071156391a5eae56657e5519d92b320e53d3d5cb29d9add1d15989806
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -26,8 +26,16 @@ 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.
|
30
|
-
cross_platforms = [
|
29
|
+
cross_rubies = ["3.3.0", "3.2.0", "3.1.0", "3.0.0"]
|
30
|
+
cross_platforms = [
|
31
|
+
"x64-mingw32",
|
32
|
+
"x64-mingw-ucrt",
|
33
|
+
"x86-linux",
|
34
|
+
"x86_64-linux",
|
35
|
+
"aarch64-linux",
|
36
|
+
"x86_64-darwin",
|
37
|
+
"arm64-darwin",
|
38
|
+
]
|
31
39
|
ENV["RUBY_CC_VERSION"] = cross_rubies.join(":")
|
32
40
|
|
33
41
|
Rake::ExtensionTask.new("precompiled", rcee_precompiled_spec) do |ext|
|
@@ -84,30 +92,33 @@ The top task (or, really, _set_ of tasks) runs on the host system, and invokes t
|
|
84
92
|
Changes to the `extconf.rb`:
|
85
93
|
|
86
94
|
``` ruby
|
87
|
-
|
95
|
+
def configure_cross_compilers
|
96
|
+
RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
|
97
|
+
ENV["CC"] = RbConfig::CONFIG["CC"]
|
98
|
+
end
|
88
99
|
```
|
89
100
|
|
90
101
|
This makes sure that the cross-compiler is the compiler used within the guest container (and not the native linux compiler).
|
91
102
|
|
92
103
|
``` ruby
|
93
|
-
|
104
|
+
def cross_build?
|
105
|
+
enable_config("cross-build")
|
106
|
+
end
|
94
107
|
```
|
95
108
|
|
96
109
|
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).
|
97
110
|
|
98
111
|
``` ruby
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
112
|
+
# pass some environment variables to the libyaml configuration for cross-compilation
|
113
|
+
if cross_build?
|
114
|
+
ENV.to_h.tap do |env|
|
115
|
+
# -fPIC is necessary for linking into a shared library
|
116
|
+
env["CFLAGS"] = [env["CFLAGS"], "-fPIC"].join(" ")
|
117
|
+
env["SUBDIRS"] = "include src" # libyaml: skip tests
|
118
|
+
|
119
|
+
recipe.configure_options += env.map { |key, value| "#{key}=#{value.strip}" }
|
120
|
+
end
|
108
121
|
end
|
109
|
-
# ...
|
110
|
-
end
|
111
122
|
```
|
112
123
|
|
113
124
|
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.)
|
@@ -120,13 +131,13 @@ We have one more small change we'll need to make to how the extension is require
|
|
120
131
|
lib
|
121
132
|
└── rcee
|
122
133
|
├── precompiled
|
123
|
-
│ ├──
|
134
|
+
│ ├── 3.0
|
124
135
|
│ │ └── precompiled.so
|
125
|
-
│ ├──
|
136
|
+
│ ├── 3.1
|
126
137
|
│ │ └── precompiled.so
|
127
|
-
│ ├── 2
|
138
|
+
│ ├── 3.2
|
128
139
|
│ │ └── precompiled.so
|
129
|
-
│ ├── 3.
|
140
|
+
│ ├── 3.3
|
130
141
|
│ │ └── precompiled.so
|
131
142
|
│ └── version.rb
|
132
143
|
└── precompiled.rb
|
@@ -176,7 +187,7 @@ This strategy isn't perfect. Remember what I said earlier, that a compiled C ext
|
|
176
187
|
- the machine architecture (e.g., x86_64)
|
177
188
|
- the system libraries
|
178
189
|
|
179
|
-
The precompiled strategy mostly takes care of the first two, but there are still edge cases for system libraries. The big gotcha is that linux libc is not the same as linux musl, and we've had to work around this a few times in Nokogiri.
|
190
|
+
The precompiled strategy mostly takes care of the first two, but there are still edge cases for system libraries. The big gotcha is that linux libc is not the same as linux musl, and we've had to work around this a few times in Nokogiri.
|
180
191
|
|
181
192
|
I'm positive that there are more edge cases that will be found as users add more platforms and as more gems start precompiling. I'm willing to bet money that you can break this by setting some Ruby compile-time flags on your system. I'm honestly surprised it works as well as it has. (Worth noting: the `sassc` gem stopped shipping native gems for linux because of the musl incompatibilities.)
|
182
193
|
|
data/Rakefile
CHANGED
@@ -6,13 +6,26 @@ require "rake/testtask"
|
|
6
6
|
require "rake/extensiontask"
|
7
7
|
require "rake_compiler_dock"
|
8
8
|
|
9
|
-
cross_rubies = ["3.
|
10
|
-
cross_platforms = [
|
9
|
+
cross_rubies = ["3.3.0", "3.2.0", "3.1.0", "3.0.0"]
|
10
|
+
cross_platforms = [
|
11
|
+
"aarch64-linux",
|
12
|
+
"aarch64-linux-musl",
|
13
|
+
"arm-linux",
|
14
|
+
"arm-linux-musl",
|
15
|
+
"arm64-darwin",
|
16
|
+
"x64-mingw-ucrt",
|
17
|
+
"x64-mingw32",
|
18
|
+
"x86-linux",
|
19
|
+
"x86-linux-musl",
|
20
|
+
"x86_64-darwin",
|
21
|
+
"x86_64-linux",
|
22
|
+
"x86_64-linux-musl",
|
23
|
+
]
|
11
24
|
ENV["RUBY_CC_VERSION"] = cross_rubies.join(":")
|
12
25
|
|
13
26
|
rcee_precompiled_spec = Bundler.load_gemspec("rcee_precompiled.gemspec")
|
14
27
|
Gem::PackageTask.new(rcee_precompiled_spec).define #packaged_tarball version of the gem for platform=ruby
|
15
|
-
task "package" =>
|
28
|
+
task "package" => "gem:all"
|
16
29
|
|
17
30
|
Rake::TestTask.new(:test) do |t|
|
18
31
|
t.libs << "test"
|
data/ext/precompiled/extconf.rb
CHANGED
@@ -1,41 +1,78 @@
|
|
1
1
|
require "mkmf"
|
2
2
|
require "mini_portile2"
|
3
3
|
|
4
|
-
|
4
|
+
module RCEE
|
5
|
+
module Precompiled
|
6
|
+
module ExtConf
|
7
|
+
PACKAGE_ROOT_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
|
5
8
|
|
6
|
-
|
7
|
-
|
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
|
-
|
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
|
-
|
12
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
31
|
+
recipe.configure_options += env.map { |key, value| "#{key}=#{value.strip}" }
|
32
|
+
end
|
33
|
+
end
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
34
|
-
|
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
|
-
|
38
|
-
|
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
|
-
|
78
|
+
RCEE::Precompiled::ExtConf.configure
|
data/rcee_precompiled.gemspec
CHANGED
@@ -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 = ">=
|
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
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Dalessio
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mini_portile2
|
@@ -24,6 +24,7 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
force_ruby_platform: false
|
27
28
|
description: Part of a project to explain how Ruby C extensions work.
|
28
29
|
email:
|
29
30
|
- mike.dalessio@gmail.com
|
@@ -55,14 +56,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
56
|
requirements:
|
56
57
|
- - ">="
|
57
58
|
- !ruby/object:Gem::Version
|
58
|
-
version:
|
59
|
+
version: 3.0.0
|
59
60
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
61
|
requirements:
|
61
62
|
- - ">="
|
62
63
|
- !ruby/object:Gem::Version
|
63
64
|
version: '0'
|
64
65
|
requirements: []
|
65
|
-
rubygems_version: 3.
|
66
|
+
rubygems_version: 3.4.19
|
66
67
|
signing_key:
|
67
68
|
specification_version: 4
|
68
69
|
summary: Example gem demonstrating a basic C extension.
|