gem-ext-zig_builder 0.2.1 → 0.3.0

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: 55b4bf2fe202be13789c3afbc3fc71d515d49f56b08b92720cd882ebed52d13d
4
- data.tar.gz: 7fee2a3b6f222b25ce72b95275cdb8be2b2c61ca0948a44ae12f4d5098649e77
3
+ metadata.gz: 352295a2ed859fecfef121e9b8748b10efaa83eb2cc14842307cd43779c21724
4
+ data.tar.gz: 6222bdbd160014d6cf7c0e060a49d9ce9da9e8f37b4e774937ea3f7da0b912a9
5
5
  SHA512:
6
- metadata.gz: 38802825ac0b746613ef0fba7447db7cda21879eaef100307689a083e3f05640ccea6adce95f2805b0d5ce2af2150fc1a21a06b1b769a0f2875c060a62cba970
7
- data.tar.gz: 570fd46fc68606563c097b858e763ea92564d3189e6bba9f43971ea591403bd4561033fbe073afafd5318d16b2c5d095abf672a0e45119b0d30f7f949e6aaf54
6
+ metadata.gz: f38796b73f8c45131a5b0b6281304f2b8e5b76d2aab3a50bac322843794f24af60adea60c0a4ff295a24d9ebde9d8eba90a1f4966a999c0379abb125164c915d
7
+ data.tar.gz: 727f9954335613743bbd4dceaf35e7d359c4fa0bb5759c109323a1f6ad679e11a7d68446c13d5ae3771b2e5fb9fb40278f035163010b10660423883b38af0b80
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Gem
2
4
  module Ext
3
5
  class Builder; end
6
+
4
7
  class ZigBuilder < Builder
5
- VERSION = '0.2.1'
8
+ VERSION = '0.3.0'
6
9
  end
7
10
  end
8
11
  end
@@ -1,54 +1,141 @@
1
1
  # frozen_string_literal: true
2
- require 'gem/ext/zig_builder/version'
2
+
3
+ require_relative 'zig_builder/version'
3
4
  require 'rubygems/ext/builder'
4
- require 'rubygems/command'
5
- require 'shellwords'
6
5
  require 'rbconfig'
7
6
  require 'tmpdir'
8
7
 
8
+ # This class is used by rubygems to build Zig extensions. It is a thin-wrapper
9
+ # over the zig build command. To trigger this builder, specify a build.zig
10
+ # file in the gem spec.
11
+ #
12
+ # A minimal zig.build example:
13
+ #
14
+ # const std = @import("std");
15
+ # pub fn build(b: *std.Build) void {
16
+ # const optimize = b.standardOptimizeOption(.{});
17
+ # const target = b.standardTargetOptions(.{});
18
+ # const lib = b.addSharedLibrary(.{
19
+ # .name = "zigrb_example",
20
+ # .root_source_file = .{ .path = "src/zigrb.zig" },
21
+ # .target = target,
22
+ # .optimize = optimize,
23
+ # });
24
+ # lib.linkSystemLibrary(std.os.getenv("RUBY_PC") orelse "ruby");
25
+ # lib.linkSystemLibrary("c");
26
+ # b.installArtifact(lib);
27
+ # }
28
+ #
29
+ # A minimal zigrb.zig example:
30
+ #
31
+ # const std = @import("std");
32
+ # const ruby = @cImport(@cInclude("ruby/ruby.h"));
33
+ # export fn Init_libzigrb_example() void {
34
+ # ruby.ruby_init();
35
+ # }
36
+ #
37
+ # An example of defining a ruby class and adding a zig method:
38
+ #
39
+ # var zig_rb_class: ruby.VALUE = ruby.rb_define_class("ZigExample", ruby.rb_cObject);
40
+ # _ = ruby.rb_define_method(zig_rb_class, "method_name", rb_example_method, 2);
41
+ #
42
+ # An example of a zig ruby method:
43
+ #
44
+ # fn rb_example_method(...) callconv(.C) ruby.VALUE {
45
+ # var ap = @cVaStart();
46
+ # defer @cVaEnd(&ap);
47
+ # // first argument is `self` in ruby; discard it
48
+ # var self = @cVaArg(&ap, ruby.VALUE); _ = self;
49
+ # // additional arguments
50
+ # var _ = @cVaArg(&ap, ruby.VALUE);
51
+ # var _ = @cVaArg(&ap, ruby.VALUE);
52
+ # return ruby.QNil
53
+ # }
54
+ #
55
+ # An example of ruby zig type conversions:
56
+ #
57
+ # var m = ruby.NUM2INT(@cVaArg(&ap, ruby.VALUE));
58
+ # var n = ruby.NUM2INT(@cVaArg(&ap, ruby.VALUE));
59
+ # return ruby.INT2NUM(f(m, n));
60
+ #
9
61
  class Gem::Ext::ZigBuilder < Gem::Ext::Builder
62
+ #
63
+ # This module patches the Builder builder_for method to ensure that
64
+ # this builder class is used for build.zig extensions.
65
+ #
10
66
  module PatchBuilderLookup
11
67
  def builder_for(extension)
12
68
  /build.zig/ === extension ? Gem::Ext::ZigBuilder : super
13
69
  end
14
70
  end
15
71
 
16
- def self.build(extension, dest_path, results, args=[], lib_dir=nil, extension_dir=nil)
17
- tmp_dir = Dir.mktmpdir
18
- dlext = RbConfig::CONFIG['DLEXT']
19
- target_vendor = RbConfig::CONFIG['target_vendor']
20
- pkg_config_path = "#{RbConfig::CONFIG['libdir']}/pkgconfig"
21
- ruby_pc = "#{File.basename(RbConfig::CONFIG['ruby_pc'], '.pc')}"
22
-
23
- cmd = [].tap {|c|
24
- c << 'zig' << 'build' << '-Doptimize=ReleaseSafe'
25
- c << '--prefix-lib-dir' << tmp_dir
26
- c << 'test' << 'install'
27
- }
28
-
29
- # older versions of ruby do not support the 5th `env` argument to run,
30
- # so pollute the global ENV as a cheap workaround
31
- ENV['PKG_CONFIG_PATH'] = pkg_config_path
32
- ENV['RUBY_PC' ] = ruby_pc
33
-
34
- # even older versions of ruby do not support the 4th extension_dir arg
35
- Dir.chdir(extension_dir ? extension_dir : '.') do
36
- run(cmd, results, 'zig')
72
+ class << self
73
+ def build(_extension, dest_path, results, _args = [], _lib_dir = nil, extension_dir = nil)
74
+ dlext = RbConfig::CONFIG['DLEXT']
75
+ tmp_dir = Dir.mktmpdir
76
+ command = _build_command(tmp_dir)
77
+ envvars = _build_envvars
78
+
79
+ _run(command, results, 'zig', extension_dir, envvars)
80
+ _install_artifacts(tmp_dir, dlext, dest_path)
81
+
82
+ results
83
+ ensure
84
+ FileUtils.remove_entry tmp_dir if tmp_dir
37
85
  end
38
86
 
39
- Dir.chdir tmp_dir do
40
- if target_vendor == 'apple' && dlext == 'bundle'
41
- Dir.glob('*.dylib').each do |dylib|
42
- FileUtils.mv dylib, "#{File.basename(dylib, '.dylib')}.bundle"
43
- end
87
+ private
88
+
89
+ def _build_command(tmp_dir)
90
+ [].tap { |c|
91
+ c << 'zig' << 'build' << '-Doptimize=ReleaseSafe'
92
+ c << '--prefix-lib-dir' << tmp_dir
93
+ c << 'test' << 'install'
94
+ }
95
+ end
96
+
97
+ def _build_envvars
98
+ {
99
+ 'PKG_CONFIG_PATH' => "#{RbConfig::CONFIG['libdir']}/pkgconfig",
100
+ 'RUBY_PC' => File.basename(RbConfig::CONFIG['ruby_pc'], '.pc'),
101
+ }
102
+ end
103
+
104
+ def _run(command, results, command_name, dir, env)
105
+ # old versions do not support the 4th `dir` arg
106
+ # old versions do not support the 5th `env` arg
107
+ case method(:run).parameters.count
108
+ when 3
109
+ _pollute_env(env)
110
+ run(command, results, command_name)
111
+ when 4
112
+ _pollute_env(env)
113
+ run(command, results, command_name, dir)
114
+ when 5
115
+ run(command, results, command_name, dir, env)
116
+ else
117
+ raise ArgumentError, 'wrong number of arguments'
44
118
  end
119
+ end
45
120
 
46
- FileUtils.mv Dir.glob("*.#{dlext}"), dest_path
121
+ def _pollute_env(env)
122
+ env.each do |k, v| ENV[k] = v end
47
123
  end
48
124
 
49
- results
50
- ensure
51
- FileUtils.remove_entry tmp_dir if tmp_dir
125
+ def _install_artifacts(tmp_dir, dlext, dest_path)
126
+ target_vendor = RbConfig::CONFIG['target_vendor']
127
+
128
+ Dir.chdir tmp_dir do
129
+ if target_vendor == 'apple' && dlext == 'bundle'
130
+ # zig builds a .dylib but ruby wants to load a .bundle
131
+ Dir.glob('*.dylib').each do |dylib|
132
+ FileUtils.mv dylib, "#{File.basename(dylib, '.dylib')}.bundle"
133
+ end
134
+ end
135
+
136
+ FileUtils.mv Dir.glob("*.#{dlext}"), dest_path
137
+ end
138
+ end
52
139
  end
53
140
  end
54
141
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # RubyGems will load plugins in the latest version of each installed gem
4
+ # or $LOAD_PATH. Plugins must be named ‘rubygems_plugin’ (.rb, .so,
5
+ # etc) and placed at the root of your gem’s #require_path. Plugins are
6
+ # installed at a special location and loaded on boot.
7
+ # https://guides.rubygems.org/plugins/
8
+
9
+ require_relative 'gem/ext/zig_builder'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem-ext-zig_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank J. Cameron
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-11 00:00:00.000000000 Z
11
+ date: 2023-05-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ''
14
14
  email:
@@ -19,6 +19,7 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - lib/gem/ext/zig_builder.rb
21
21
  - lib/gem/ext/zig_builder/version.rb
22
+ - lib/rubygems_plugin.rb
22
23
  homepage: https://gitlab.com/fjc/gem-ext-zig_builder
23
24
  licenses:
24
25
  - MIT
@@ -26,6 +27,7 @@ metadata:
26
27
  homepage_uri: https://gitlab.com/fjc/gem-ext-zig_builder
27
28
  source_code_uri: https://gitlab.com/fjc/gem-ext-zig_builder
28
29
  changelog_uri: https://gitlab.com/fjc/gem-ext-zig_builder
30
+ rubygems_mfa_required: 'true'
29
31
  post_install_message:
30
32
  rdoc_options: []
31
33
  require_paths:
@@ -34,7 +36,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
34
36
  requirements:
35
37
  - - ">="
36
38
  - !ruby/object:Gem::Version
37
- version: 2.3.0
39
+ version: 2.5.0
38
40
  required_rubygems_version: !ruby/object:Gem::Requirement
39
41
  requirements:
40
42
  - - ">="