Class: Mkrf::Generator
Overview
Generator
is concerned with taking configuration for an extension and writing a Rakefile
to the local filesystem which will later be used to build the extension.
You will typically only create one Generator
per extconf.rb
file, which in turn will generate a Rakefile for building one extension module.
Usage
In the most basic usage, Generator
simply takes the name of the library to compile:
require 'mkrf'
Mkrf::Generator.new('libtrivial')
Configuration of the build can be passed to the Generator
constructor as a block:
Mkrf::Generator.new('libxml') do |g|
g.include_library('socket','socket')
g.include_header('libxml/xmlversion.h',
'/opt/include/libxml2',
'/usr/local/include/libxml2',
'/usr/include/libxml2')
end
It is also possible to specify the library paths in include_library
Mkrf::Generator.new('libxml') do |g|
g.include_library('socket','socket', '/usr/local/lib/libxml')
end
Constant Summary collapse
- CONFIG =
Config::CONFIG
Instance Attribute Summary collapse
-
#additional_code ⇒ Object
Any extra code, given as a string, to be appended to the Rakefile.
-
#cflags ⇒ Object
You may append to these attributes directly in your Generator.new block, for example:
g.objects << ' ../common/foo.o ../common/bar.so -lmystuff'
org.cflags << ' -ansi -Wall'
. -
#ldshared ⇒ Object
Any additional options you’d like appended to your system-specific linker command (which is used to build the shared library).
-
#objects ⇒ Object
objects
is for adding additional object files to the link-edit command – outside of the ones that correspond to the source files.
Instance Method Summary collapse
-
#abort!(str, code = 1) ⇒ Object
Logs a fatal error and exits with a non-zero code (defaults to 1).
-
#add_define(defn) ⇒ Object
Add a define to the compile string.
-
#defines_compile_string ⇒ Object
:nodoc:.
-
#has_function?(function) ⇒ Boolean
Returns
true
if the function is able to be called based on libraries and headers currently loaded. -
#include_header(*args) ⇒ Object
Include a header in the compile.
-
#include_library(*args) ⇒ Object
Include a library in the compile.
-
#initialize(extension_name, source_patterns = ["*.c"], availability_options = {}) {|_self| ... } ⇒ Generator
constructor
Create a
Generator
object which writes a Rakefile to the current directory of the local filesystem. -
#library_path(path) ⇒ Object
:nodoc:.
-
#logger ⇒ Object
Returns mkrf’s logger instance.
-
#rakefile_contents ⇒ Object
:nodoc:.
-
#sources ⇒ Object
An array of the source patterns as single quoted strings.
-
#write_rakefile(filename = "Rakefile") ⇒ Object
:nodoc:.
Constructor Details
#initialize(extension_name, source_patterns = ["*.c"], availability_options = {}) {|_self| ... } ⇒ Generator
Create a Generator
object which writes a Rakefile to the current directory of the local filesystem.
Params:
-
extension_name
– the name of the extension -
source_patterns
– an array of patterns describing source files to be compiled. [“*.c”] is the default.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/mkrf/generator.rb', line 73 def initialize(extension_name, source_patterns = ["*.c"], = {}) @sources = source_patterns @extension_name = extension_name + ".#{CONFIG['DLEXT']}" @available = Mkrf::Availability.new() @defines = [] if @sources[0] =~ /cpp/ @cc = 'g++' # should be in CONFIG['C++'] but is not. @source_extension = 'cpp' else @cc = CONFIG['CC'] @source_extension = 'c' end @objects = '' @ldshared = '' @cflags = "#{CONFIG['CCDLFLAGS']} #{CONFIG['CFLAGS']} #{CONFIG['ARCH_FLAG']}" yield self if block_given? write_rakefile end |
Instance Attribute Details
#additional_code ⇒ Object
Any extra code, given as a string, to be appended to the Rakefile.
47 48 49 |
# File 'lib/mkrf/generator.rb', line 47 def additional_code @additional_code end |
#cflags ⇒ Object
You may append to these attributes directly in your Generator.new block, for example: g.objects << ' ../common/foo.o ../common/bar.so -lmystuff'
or g.cflags << ' -ansi -Wall'
Note the extra space at the beginning of those strings.
54 55 56 |
# File 'lib/mkrf/generator.rb', line 54 def cflags @cflags end |
#ldshared ⇒ Object
Any additional options you’d like appended to your system-specific linker command (which is used to build the shared library).
62 63 64 |
# File 'lib/mkrf/generator.rb', line 62 def ldshared @ldshared end |
#objects ⇒ Object
objects
is for adding additional object files to the link-edit command – outside of the ones that correspond to the source files.
58 59 60 |
# File 'lib/mkrf/generator.rb', line 58 def objects @objects end |
Instance Method Details
#abort!(str, code = 1) ⇒ Object
Logs a fatal error and exits with a non-zero code (defaults to 1)
147 148 149 150 |
# File 'lib/mkrf/generator.rb', line 147 def abort!(str, code = 1) logger.fatal str exit code end |
#add_define(defn) ⇒ Object
107 108 109 |
# File 'lib/mkrf/generator.rb', line 107 def add_define(defn) @available.defines << defn end |
#defines_compile_string ⇒ Object
:nodoc:
159 160 161 |
# File 'lib/mkrf/generator.rb', line 159 def defines_compile_string # :nodoc: @available.defines.collect {|define| "-D#{define}"}.join(' ') end |
#has_function?(function) ⇒ Boolean
Returns true
if the function is able to be called based on libraries and headers currently loaded. Returns false
otherwise.
Params:
-
function
– the function to check for
132 133 134 |
# File 'lib/mkrf/generator.rb', line 132 def has_function?(function) @available.has_function? function end |
#include_header(*args) ⇒ Object
Include a header in the compile. Returns false
if the header is not available, returns non-false otherwise. As a side effect, a compile time define occurs as HAVE_
appended with the name of the header in upper and scored case. Parameters are the same as Mkrf::Availability#include_header
123 124 125 |
# File 'lib/mkrf/generator.rb', line 123 def include_header(*args) @available.include_header(*args) end |
#include_library(*args) ⇒ Object
Include a library in the compile. Returns false
if the library is not available. Returns non-false otherwise. Parameters are the same as Mkrf::Availability#include_library
114 115 116 |
# File 'lib/mkrf/generator.rb', line 114 def include_library(*args) @available.include_library(*args) end |
#library_path(path) ⇒ Object
:nodoc:
163 164 165 166 167 168 169 |
# File 'lib/mkrf/generator.rb', line 163 def library_path(path) # :nodoc: if RUBY_PLATFORM =~ /mswin/ "-libpath:#{path}" else "-L#{path}" end end |
#logger ⇒ Object
142 143 144 |
# File 'lib/mkrf/generator.rb', line 142 def logger @available.logger end |
#rakefile_contents ⇒ Object
:nodoc:
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/mkrf/generator.rb', line 171 def rakefile_contents # :nodoc: objext = CONFIG['OBJEXT'] <<-END_RAKEFILE # Generated by mkrf require 'rake/clean' CLEAN.include('*.#{objext}') CLOBBER.include('#{@extension_name}', 'mkrf.log') SRC = FileList[#{sources.join(',')}] OBJ = SRC.ext('#{objext}') CC = '#{@cc}' ADDITIONAL_OBJECTS = '#{objects}' LDSHARED = "#{@available.ldshared_string} #{ldshared}" LIBPATH = "#{library_path(CONFIG['libdir'])} #{@available.library_paths_compile_string}" INCLUDES = "#{@available.includes_compile_string}" LIBS = "#{@available.library_compile_string}" CFLAGS = "#{cflags} #{defines_compile_string}" RUBYARCHDIR = "\#{ENV["RUBYARCHDIR"]}" LIBRUBYARG_SHARED = "#{CONFIG['LIBRUBYARG_SHARED']}" task :default => ['#{@extension_name}'] rule '.#{objext}' => '.#{@source_extension}' do |t| sh "\#{CC} \#{CFLAGS} \#{INCLUDES} -c \#{t.source}" end desc "Build this extension" file '#{@extension_name}' => OBJ do sh "\#{LDSHARED} \#{LIBPATH} #{@available.ld_outfile(@extension_name)} \#{OBJ} \#{ADDITIONAL_OBJECTS} \#{LIBS} \#{LIBRUBYARG_SHARED}" end desc "Install this extension" task :install => '#{@extension_name}' do makedirs "\#{RUBYARCHDIR}" install "#{@extension_name}", "\#{RUBYARCHDIR}" end #{additional_code} END_RAKEFILE end |
#sources ⇒ Object
An array of the source patterns as single quoted strings
95 96 97 |
# File 'lib/mkrf/generator.rb', line 95 def sources @sources.collect {|s| "'#{s}'"} end |
#write_rakefile(filename = "Rakefile") ⇒ Object
:nodoc:
152 153 154 155 156 157 |
# File 'lib/mkrf/generator.rb', line 152 def write_rakefile(filename = "Rakefile") # :nodoc: File.open(filename, "w+") do |f| f.puts rakefile_contents end logger.info "Rakefile written" end |