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]