mkmf-lite 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +2 -0
- data/MANIFEST +7 -0
- data/README +45 -0
- data/Rakefile +28 -0
- data/lib/mkmf/lite.rb +127 -0
- data/lib/mkmf/templates/have_func.erb +10 -0
- data/lib/mkmf/templates/have_func_pointer.erb +11 -0
- data/lib/mkmf/templates/have_header.erb +5 -0
- data/lib/mkmf/templates/have_struct_member.erb +6 -0
- data/mkmf-lite.gemspec +27 -0
- data/test/test_mkmf_lite.rb +94 -0
- metadata +99 -0
data/CHANGES
ADDED
data/MANIFEST
ADDED
data/README
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
= Summary
|
2
|
+
A light version of mkmf designed for use within programs.
|
3
|
+
|
4
|
+
= Synopsis
|
5
|
+
require 'mkmf/lite'
|
6
|
+
|
7
|
+
class System
|
8
|
+
include Mkmf::Lite
|
9
|
+
|
10
|
+
HAVE_PW_NAME = have_struct_member('struct passwd', 'pw_name', 'pwd.h')
|
11
|
+
|
12
|
+
def some_method
|
13
|
+
if HAVE_PW_NAME
|
14
|
+
# Do something
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
= Description
|
20
|
+
The mkmf library that ships as part of the Ruby standard library is not
|
21
|
+
meant for use as an internal library. It's strictly designed for building
|
22
|
+
C extensions. It's huge, its methods sit in a global namespace, it contains
|
23
|
+
many methods you don't care about, and emits output to $stdout that cannot
|
24
|
+
easily be disabled. Also, the source code is monstrous.
|
25
|
+
|
26
|
+
The mkmf-lite is a module, it's small, and it's designed to be mixed into
|
27
|
+
classes. It contains a handful of methods that, most likely, will be used
|
28
|
+
in conjunction with FFI. Also, the source code is quite readable.
|
29
|
+
|
30
|
+
It does not package C extensions, nor generate a log file or a Makefile.
|
31
|
+
|
32
|
+
== License
|
33
|
+
Artistic 2.0
|
34
|
+
|
35
|
+
== Copyright
|
36
|
+
(C) 2010 Daniel J. Berger
|
37
|
+
All Rights Reserved
|
38
|
+
|
39
|
+
== Warranty
|
40
|
+
This library is provided "as is" and without any express or
|
41
|
+
implied warranties, including, without limitation, the implied
|
42
|
+
warranties of merchantability and fitness for a particular purpose.
|
43
|
+
|
44
|
+
= Author
|
45
|
+
Daniel Berger
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rbconfig'
|
4
|
+
|
5
|
+
|
6
|
+
namespace 'gem' do
|
7
|
+
desc 'Remove any existing .gem files'
|
8
|
+
task :clean do
|
9
|
+
Dir['**/*.gem'].each{ |f| File.delete(f) }
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Create the mkmf-lite gem.'
|
13
|
+
task :create => [:clean] do
|
14
|
+
spec = eval(IO.read('mkmf-lite.gemspec'))
|
15
|
+
Gem::Builder.new(spec).build
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'Install the mkmf-lite gem.'
|
19
|
+
task :install => [:create] do
|
20
|
+
file = Dir["*.gem"].first
|
21
|
+
sh "gem install #{file}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Rake::TestTask.new do |t|
|
26
|
+
t.verbose = true
|
27
|
+
t.warning = true
|
28
|
+
end
|
data/lib/mkmf/lite.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'ptools'
|
5
|
+
|
6
|
+
module Mkmf
|
7
|
+
module Lite
|
8
|
+
# The version of the mkmf-lite library
|
9
|
+
MKMF_LITE_VERSION = '0.1.0'
|
10
|
+
|
11
|
+
@@cpp_command = Config::CONFIG['CC'] || Config::CONFIG['CPP']
|
12
|
+
@@cpp_outfile = Config::CONFIG['CPPOUTFILE'] # -o conftest.i
|
13
|
+
@@cpp_libraries = Config::CONFIG['LIBS'] + Config::CONFIG['LIBRUBYARG']
|
14
|
+
@@cpp_srcfile = 'conftest.c'
|
15
|
+
|
16
|
+
# Check for the presence of the given +header+ file.
|
17
|
+
#
|
18
|
+
# Returns true if found, or false if not found.
|
19
|
+
#
|
20
|
+
def have_header(header)
|
21
|
+
erb = ERB.new(read_template('have_header.erb'))
|
22
|
+
code = erb.result(binding)
|
23
|
+
try_to_compile(code)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Check for the presence of the given +function+ in the common header
|
27
|
+
# files, or within any +headers+ that you provide.
|
28
|
+
#
|
29
|
+
# Returns true if found, or false if not found.
|
30
|
+
#
|
31
|
+
def have_func(function, headers = [])
|
32
|
+
headers = get_header_string(headers)
|
33
|
+
|
34
|
+
erb_ptr = ERB.new(read_template('have_func_pointer.erb'))
|
35
|
+
erb_std = ERB.new(read_template('have_func.erb'))
|
36
|
+
|
37
|
+
ptr_code = erb_ptr.result(binding)
|
38
|
+
std_code = erb_std.result(binding)
|
39
|
+
|
40
|
+
# Check for just the function pointer first. If that fails, then try
|
41
|
+
# to compile with the function declaration.
|
42
|
+
try_to_compile(ptr_code) || try_to_compile(std_code)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Checks whether or not the struct of type +struct_type+ contains the
|
46
|
+
# +struct_member+. If it does not, or the struct type cannot be found,
|
47
|
+
# then false is returned.
|
48
|
+
#
|
49
|
+
# An optional list of +headers+ may be specified, in addition to the
|
50
|
+
# common header files that are already searched.
|
51
|
+
#
|
52
|
+
def have_struct_member(struct_type, struct_member, headers = [])
|
53
|
+
headers = get_header_string(headers)
|
54
|
+
erb = ERB.new(read_template('have_struct_member.erb'))
|
55
|
+
code = erb.result(binding)
|
56
|
+
|
57
|
+
try_to_compile(code)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Take an array of header file names (or convert it to an array if it's a
|
63
|
+
# single argument), add the COMMON_HEADERS, flatten it out and remove any
|
64
|
+
# duplicates.
|
65
|
+
#
|
66
|
+
# Finally, convert the result into a single string of '#include'
|
67
|
+
# directives, each separated by a newline.
|
68
|
+
#
|
69
|
+
# This string is then to be used at the top of the ERB templates.
|
70
|
+
#
|
71
|
+
def get_header_string(headers)
|
72
|
+
headers = [headers] unless headers.is_a?(Array)
|
73
|
+
|
74
|
+
unless Config::CONFIG['COMMON_HEADERS'].empty?
|
75
|
+
headers += Config::CONFIG['COMMON_HEADERS'].split
|
76
|
+
end
|
77
|
+
|
78
|
+
headers = headers.flatten.uniq
|
79
|
+
headers = headers.map{ |h| "#include <#{h}>" }.join("\n")
|
80
|
+
|
81
|
+
headers
|
82
|
+
end
|
83
|
+
|
84
|
+
# Create a temporary bit of C source code in the temp directory, and
|
85
|
+
# try to compile it. If it succeeds, return true. Otherwise, return
|
86
|
+
# false.
|
87
|
+
#
|
88
|
+
# Note that $stderr is temporarily redirected to the null device because
|
89
|
+
# we don't actually care about the reason for failure.
|
90
|
+
#
|
91
|
+
def try_to_compile(code)
|
92
|
+
begin
|
93
|
+
bool = false
|
94
|
+
stderr_orig = $stderr.dup
|
95
|
+
|
96
|
+
Dir.chdir(Dir.tmpdir){
|
97
|
+
File.open(@@cpp_srcfile, 'w'){ |fh| fh.write(code) }
|
98
|
+
|
99
|
+
command = @@cpp_command + ' '
|
100
|
+
command += @@cpp_outfile + ' '
|
101
|
+
command += @@cpp_srcfile
|
102
|
+
|
103
|
+
$stderr.reopen(File.null)
|
104
|
+
bool = system(command)
|
105
|
+
}
|
106
|
+
ensure
|
107
|
+
File.delete(@@cpp_srcfile) if File.exists?(@@cpp_srcfile)
|
108
|
+
File.delete(@@cpp_outfile) if File.exists?(@@cpp_outfile)
|
109
|
+
$stderr.reopen(stderr_orig)
|
110
|
+
end
|
111
|
+
|
112
|
+
bool
|
113
|
+
end
|
114
|
+
|
115
|
+
# Slurp the contents of the template file for evaluation later.
|
116
|
+
#
|
117
|
+
def read_template(file)
|
118
|
+
IO.read(get_template_file(file))
|
119
|
+
end
|
120
|
+
|
121
|
+
# Retrieve the path to the template +file+ name.
|
122
|
+
#
|
123
|
+
def get_template_file(file)
|
124
|
+
File.join(File.dirname(__FILE__), 'templates', file)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/mkmf-lite.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'mkmf-lite'
|
5
|
+
spec.summary = 'A lighter version of mkmf designed for use as a library'
|
6
|
+
spec.version = '0.1.0'
|
7
|
+
spec.author = 'Daniel J. Berger'
|
8
|
+
spec.license = 'Artistic 2.0'
|
9
|
+
spec.email = 'djberg96@gmail.com'
|
10
|
+
spec.homepage = 'http://www.rubyforge.org/projects/shards'
|
11
|
+
spec.test_file = 'test/test_mkmf_lite.rb'
|
12
|
+
spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
|
13
|
+
|
14
|
+
spec.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST']
|
15
|
+
spec.rubyforge_project = 'shards'
|
16
|
+
|
17
|
+
spec.add_dependency('ptools')
|
18
|
+
spec.add_development_dependency('test-unit', '>= 2.0.7')
|
19
|
+
|
20
|
+
spec.description = <<-EOF
|
21
|
+
The mkmf-lite library is a light version of the the mkmf library
|
22
|
+
designed for use as a library. It does not create packages, builds,
|
23
|
+
or log files of any kind. Instead, it provides mixin methods that you
|
24
|
+
can use in FFI or tests to check for the presence of header files,
|
25
|
+
constants, and so on.
|
26
|
+
EOF
|
27
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
########################################################################
|
2
|
+
# test_mkmf_lite.rb
|
3
|
+
#
|
4
|
+
# Tests for the mkmf-lite library.
|
5
|
+
########################################################################
|
6
|
+
require 'rubygems'
|
7
|
+
gem 'test-unit'
|
8
|
+
require 'test/unit'
|
9
|
+
require 'mkmf/lite'
|
10
|
+
|
11
|
+
class TC_Mkmf_Lite < Test::Unit::TestCase
|
12
|
+
include Mkmf::Lite
|
13
|
+
|
14
|
+
def self.startup
|
15
|
+
@@windows = Config::CONFIG['host_os'] =~ /mswin|msdos|win32|mingw|cygwin/i
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup
|
19
|
+
@st_type = 'struct stat'
|
20
|
+
@st_member = 'st_uid'
|
21
|
+
@st_header = 'sys/stat.h'
|
22
|
+
end
|
23
|
+
|
24
|
+
test "version information" do
|
25
|
+
assert_equal('0.1.0', MKMF_LITE_VERSION)
|
26
|
+
end
|
27
|
+
|
28
|
+
test "have_header basic functionality" do
|
29
|
+
assert_respond_to(self, :have_header)
|
30
|
+
end
|
31
|
+
|
32
|
+
test "have_header returns expected boolean value" do
|
33
|
+
assert_true(have_header('stdio.h'))
|
34
|
+
assert_false(have_header('foobar.h'))
|
35
|
+
end
|
36
|
+
|
37
|
+
test "have_header requires one argument only" do
|
38
|
+
assert_raise(ArgumentError){ have_header }
|
39
|
+
assert_raise(ArgumentError){ have_header('stdio.h', 'stdlib.h') }
|
40
|
+
end
|
41
|
+
|
42
|
+
test "have_func basic functionality" do
|
43
|
+
assert_respond_to(self, :have_func)
|
44
|
+
end
|
45
|
+
|
46
|
+
test "have_func with no arguments returns expected boolean value" do
|
47
|
+
assert_true(have_func('abort'))
|
48
|
+
assert_false(have_header('abortxyz'))
|
49
|
+
end
|
50
|
+
|
51
|
+
test "have_func with arguments returns expected boolean value" do
|
52
|
+
assert_true(have_func('printf', 'stdio.h'))
|
53
|
+
assert_false(have_func('printfx', 'stdio.h'))
|
54
|
+
end
|
55
|
+
|
56
|
+
test "have_func requires at least one argument" do
|
57
|
+
assert_raise(ArgumentError){ have_func }
|
58
|
+
end
|
59
|
+
|
60
|
+
test "have_func accepts a maximum of two arguments" do
|
61
|
+
assert_raise(ArgumentError){ have_func('printf', 'stdio.h', 'bogus') }
|
62
|
+
end
|
63
|
+
|
64
|
+
test "have_struct_member basic functionality" do
|
65
|
+
assert_respond_to(self, :have_struct_member)
|
66
|
+
end
|
67
|
+
|
68
|
+
test "have_struct_member returns expected boolean value" do
|
69
|
+
assert_true(have_struct_member(@st_type, @st_member, @st_header))
|
70
|
+
assert_false(have_struct_member(@st_type, 'pw_bogus', @st_header))
|
71
|
+
assert_false(have_struct_member(@st_type, @st_member))
|
72
|
+
end
|
73
|
+
|
74
|
+
test "have_struct_member requires at least two arguments" do
|
75
|
+
assert_raise(ArgumentError){ have_struct_member() }
|
76
|
+
assert_raise(ArgumentError){ have_struct_member('struct passwd') }
|
77
|
+
end
|
78
|
+
|
79
|
+
test "have_struct_member accepts a maximum of three arguments" do
|
80
|
+
assert_raise(ArgumentError){
|
81
|
+
have_struct_member('struct passwd', 'pw_name', 'pwd.h', true)
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def teardown
|
86
|
+
@st_type = nil
|
87
|
+
@st_member = nil
|
88
|
+
@st_header = nil
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.shutdown
|
92
|
+
@@windows = nil
|
93
|
+
end
|
94
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mkmf-lite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Daniel J. Berger
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-24 00:00:00 -06:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: ptools
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: test-unit
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 2
|
41
|
+
- 0
|
42
|
+
- 7
|
43
|
+
version: 2.0.7
|
44
|
+
type: :development
|
45
|
+
version_requirements: *id002
|
46
|
+
description: " The mkmf-lite library is a light version of the the mkmf library\n designed for use as a library. It does not create packages, builds,\n or log files of any kind. Instead, it provides mixin methods that you\n can use in FFI or tests to check for the presence of header files,\n constants, and so on.\n"
|
47
|
+
email: djberg96@gmail.com
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
extra_rdoc_files:
|
53
|
+
- CHANGES
|
54
|
+
- README
|
55
|
+
- MANIFEST
|
56
|
+
files:
|
57
|
+
- CHANGES
|
58
|
+
- lib/mkmf/lite.rb
|
59
|
+
- lib/mkmf/templates/have_func.erb
|
60
|
+
- lib/mkmf/templates/have_func_pointer.erb
|
61
|
+
- lib/mkmf/templates/have_header.erb
|
62
|
+
- lib/mkmf/templates/have_struct_member.erb
|
63
|
+
- MANIFEST
|
64
|
+
- mkmf-lite.gemspec
|
65
|
+
- Rakefile
|
66
|
+
- README
|
67
|
+
- test/test_mkmf_lite.rb
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: http://www.rubyforge.org/projects/shards
|
70
|
+
licenses:
|
71
|
+
- Artistic 2.0
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project: shards
|
94
|
+
rubygems_version: 1.3.6
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: A lighter version of mkmf designed for use as a library
|
98
|
+
test_files:
|
99
|
+
- test/test_mkmf_lite.rb
|