如何在“gem 安装”期间为 ffi 创建 C 库
How to make C library for ffi during `gem install`
最近我用ffi写了一个gem。有了这个帮助,ruby 代码可以调用带有动态库的 C 扩展,我将所有 C 扩展都编译到动态库中。
我的gem结构是这样的:
.
├── ext
│ ├── common.c
│ ├── common.h
│ ├── Makefile
│ └── ...
├── Gemfile
├── lib
│ ├── ...
│ │ └── version.rb
│ └── ...
├── Rakefile
├── README.md
└── test
我打算做的是运行make
在./ext
,然后一切顺利。
但是,问题出现了。如果其他用户用gem install
安装我的gem,如何为自己制作C库?
有人愿意帮助我吗?欢迎任何想法。
- 看看ffi-compiler。 gem 的页面上有一个示例:
例子
目录布局
lib
|- example
|- example.rb
ext
|- example.c
|- Rakefile
example.gemspec
lib/example/example.rb
require 'ffi'
require 'ffi-compiler/loader'
module Example
extend FFI::Library
ffi_lib FFI::Compiler::Loader.find('example')
# example function which takes no parameters and returns long
attach_function :example, [], :long
end
ext/example.c
long
example(void)
{
return 0xdeadbeef;
}
ext/Rakefile
require 'ffi-compiler/compile_task'
FFI::Compiler::CompileTask.new('example') do |c|
c.have_header?('stdio.h', '/usr/local/include')
c.have_func?('puts')
c.have_library?('z')
end
example.gemspec
Gem::Specification.new do |s|
s.extensions << 'ext/Rakefile'
s.name = 'example'
s.version = '0.0.1'
s.email = 'ffi-example'
s.files = %w(example.gemspec) + Dir.glob("{lib,spec,ext}/**/*")
s.add_dependency 'rake'
s.add_dependency 'ffi-compiler'
end
构建 gem 并安装
gem build example.gemspec && gem install example-0.0.1.gem
Successfully built RubyGem
Name: example
Version: 0.0.1
File: example-0.0.1.gem
Building native extensions. This could take a while...
Successfully installed example-0.0.1
测试一下
$ irb
2.0.0dev :001 > require 'example/example'
=> true
2.0.0dev :002 > puts "Example.example=#{Example.example.to_s(16)}"
Example.example=deadbeef
=> nil
您可以 运行 make
在 gem 安装过程中这样命令:
- 将
spec.extensions << 'ext/mkrf_conf.rb'
添加到您的 gem 规格中。
- 创建
ext/mkrf_conf.rb
文件:
任务:默认{`制作`}
- 尽情享受吧!
最近我用ffi写了一个gem。有了这个帮助,ruby 代码可以调用带有动态库的 C 扩展,我将所有 C 扩展都编译到动态库中。
我的gem结构是这样的:
.
├── ext
│ ├── common.c
│ ├── common.h
│ ├── Makefile
│ └── ...
├── Gemfile
├── lib
│ ├── ...
│ │ └── version.rb
│ └── ...
├── Rakefile
├── README.md
└── test
我打算做的是运行make
在./ext
,然后一切顺利。
但是,问题出现了。如果其他用户用gem install
安装我的gem,如何为自己制作C库?
有人愿意帮助我吗?欢迎任何想法。
- 看看ffi-compiler。 gem 的页面上有一个示例:
例子
目录布局lib
|- example
|- example.rb
ext
|- example.c
|- Rakefile
example.gemspec
lib/example/example.rb
require 'ffi'
require 'ffi-compiler/loader'
module Example
extend FFI::Library
ffi_lib FFI::Compiler::Loader.find('example')
# example function which takes no parameters and returns long
attach_function :example, [], :long
end
ext/example.c
long
example(void)
{
return 0xdeadbeef;
}
ext/Rakefile
require 'ffi-compiler/compile_task'
FFI::Compiler::CompileTask.new('example') do |c|
c.have_header?('stdio.h', '/usr/local/include')
c.have_func?('puts')
c.have_library?('z')
end
example.gemspec
Gem::Specification.new do |s|
s.extensions << 'ext/Rakefile'
s.name = 'example'
s.version = '0.0.1'
s.email = 'ffi-example'
s.files = %w(example.gemspec) + Dir.glob("{lib,spec,ext}/**/*")
s.add_dependency 'rake'
s.add_dependency 'ffi-compiler'
end
构建 gem 并安装
gem build example.gemspec && gem install example-0.0.1.gem
Successfully built RubyGem
Name: example
Version: 0.0.1
File: example-0.0.1.gem
Building native extensions. This could take a while...
Successfully installed example-0.0.1
测试一下
$ irb
2.0.0dev :001 > require 'example/example'
=> true
2.0.0dev :002 > puts "Example.example=#{Example.example.to_s(16)}"
Example.example=deadbeef
=> nil
您可以 运行
make
在 gem 安装过程中这样命令:- 将
spec.extensions << 'ext/mkrf_conf.rb'
添加到您的 gem 规格中。 - 创建
ext/mkrf_conf.rb
文件:
任务:默认{`制作`}
- 尽情享受吧!
- 将