lib/rbplusplus/extension.rb in rbplusplus-1.3.0 vs lib/rbplusplus/extension.rb in rbplusplus-1.4.0
- old
+ new
@@ -1,11 +1,11 @@
require 'optparse'
module RbPlusPlus
# This is the starting class for Rb++ wrapping. All Rb++ projects start as such:
- #
+ #
# Extension.new "extension_name" do |e|
# ...
# end
#
# where "extension_name" is what the resulting Ruby library will be named.
@@ -16,12 +16,12 @@
# e = Extension.new "extension_name"
# ...
#
# The following calls are required in both formats:
#
- # e.sources - The directory / array / name of C++ header files to parse.
- #
+ # e.sources - The directory / array / name of C++ header files to parse.
+ #
# In the non-block format, the following calls are required:
#
# e.working_dir - Specify the directory where the code will be generated. This needs
# to be a full path.
#
@@ -30,12 +30,12 @@
#
# e.build - Fires the code generation process
#
# e.write - Writes out the generated code into files
#
- # e.compile - Compiles the generated code into a Ruby extension.
- #
+ # e.compile - Compiles the generated code into a Ruby extension.
+ #
class Extension
# Where will the generated code be put
attr_accessor :working_dir
@@ -43,18 +43,18 @@
attr_accessor :modules
# Various options given by the user to help with
# parsing, linking, compiling, etc.
#
- # See #sources for a list of the possible options
+ # See #sources for a list of the possible options
attr_accessor :options
# Create a new Ruby extension with a given name. This name will be
# the actual name of the extension, e.g. you'll have name.so and you will
# call require 'name' when using your new extension.
#
- # This constructor can be standalone or take a block.
+ # This constructor can be standalone or take a block.
def initialize(name, &block)
@name = name
@modules = []
@writer_mode = :multiple
@requesting_console = false
@@ -97,18 +97,26 @@
# * <tt>:libraries</tt> - Path(s) to be added as -l flags
# * <tt>:cxxflags</tt> - Flag(s) to be added to command line for parsing / compiling
# * <tt>:ldflags</tt> - Flag(s) to be added to command line for linking
# * <tt>:includes</tt> - Header file(s) to include at the beginning of each .rb.cpp file generated.
# * <tt>:include_source_files</tt> - C++ source files that need to be compiled into the extension but not wrapped.
- # * <tt>:include_source_dir</tt> - A combination option for reducing duplication, this option will
- # query the given directory for source files, adding all to <tt>:include_source_files</tt> and
- # adding all h/hpp files to <tt>:includes</tt>
+ # * <tt>:include_source_dir</tt> - A combination option for reducing duplication, this option will
+ # query the given directory for source files, adding all to <tt>:include_source_files</tt> and
+ # adding all h/hpp files to <tt>:includes</tt>
#
def sources(dirs, options = {})
- parser_options = {}
+ parser_options = {
+ :includes => [],
+ :cxxflags => [
+ # Force castxml into C++ mode
+ "-x c++",
+ # Allow things like `<::`
+ "-fpermissive"
+ ]
+ }
- if (code_dir = options.delete(:include_source_dir))
+ if (code_dir = options.delete(:include_source_dir))
options[:include_source_files] ||= []
options[:includes] ||= []
Dir["#{code_dir}/*"].each do |f|
next if File.directory?(f)
@@ -116,24 +124,24 @@
end
end
if (paths = options.delete(:include_paths))
@options[:include_paths] << paths
- parser_options[:includes] = paths
+ parser_options[:includes] << paths
end
if (lib_paths = options.delete(:library_paths))
- @options[:library_paths] << lib_paths
+ @options[:library_paths] << lib_paths
end
if (libs = options.delete(:libraries))
@options[:libraries] << libs
end
if (flags = options.delete(:cxxflags))
@options[:cxxflags] << flags
- parser_options[:cxxflags] = flags
+ parser_options[:cxxflags] << flags
end
if (flags = options.delete(:ldflags))
@options[:ldflags] << flags
end
@@ -144,11 +152,11 @@
[files].flatten.each do |f|
options[:includes] << f if File.extname(f) =~ /hpp/i || File.extname(f) =~ /h/i
end
end
-
+
if (flags = options.delete(:includes))
includes = Dir.glob(flags)
if(includes.length == 0)
puts "Warning: There were no matches for includes #{flags.inspect}"
else
@@ -193,12 +201,12 @@
#
def writer_mode(mode)
raise "Unknown writer mode #{mode}" unless [:multiple, :single].include?(mode)
@writer_mode = mode
end
-
- # Start the code generation process.
+
+ # Start the code generation process.
def build
raise ConfigurationError.new("Must specify working directory") unless @working_dir
raise ConfigurationError.new("Must specify which sources to wrap") unless @parser
Logger.info "Beginning code generation"
@@ -215,11 +223,11 @@
# #build must be called before this step or nothing will be written out
def write
Logger.info "Writing code to files"
prepare_working_dir
process_other_source_files
-
+
# Create the code
writer_class = @writer_mode == :multiple ? Writers::MultipleFilesWriter : Writers::SingleFileWriter
writer_class.new(@builder, @working_dir).write
# Create the extconf.rb
@@ -255,11 +263,11 @@
opts.on_head("-h", "--help", "Show this help message") do
puts opts
exit
end
- opts.on("-v", "--verbose", "Show all progress messages (INFO, DEBUG, WARNING, ERROR)") do
+ opts.on("-v", "--verbose", "Show all progress messages (INFO, DEBUG, WARNING, ERROR)") do
Logger.verbose = true
end
opts.on("-q", "--quiet", "Only show WARNING and ERROR messages") do
Logger.quiet = true
@@ -305,11 +313,11 @@
end
end
# Cool little eval / binding hack, from need.rb
def build_working_dir(&block)
- file_name =
+ file_name =
if block.respond_to?(:source_location)
block.source_location[0]
else
eval("__FILE__", block.binding)
end
@@ -329,10 +337,10 @@
ARGV.replace(ARGV.dup)
IRB.setup(nil)
ARGV.replace(args)
@__initialized = true
end
-
+
workspace = WorkSpace.new(binding)
irb = Irb.new(workspace)
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]