Class: Rake::ExtensionTask

Inherits:
TaskLib
  • Object
show all
Defined in:
lib/rake/extensiontask.rb

Overview

Create a build task that will generate a Ruby extension (e.g. .so) from one or more C (.c) or C++ (.cc, .cpp, .cxx) files, and is intended as a replcaement for mkmf. It determines platform-specific settings (e.g. file extensions, compiler flags, etc.) from rbconfig (note: examples assume *nix file extensions).

Note: Strings vs Symbols In places where filenames are expected (e.g. lib_name and objs), Strings are used as verbatim filenames, while, Symbols have the platform-dependant extension appended (e.g. ‘.so’ for libraries and ‘.o’ for objects). Also, only Symbols have #dir prepended to them.

Example:

desc "build sample extension"
# build sample.so (from foo.{c,cc,cxx,cpp}, through foo.o)
Rake::ExtensionTask.new :sample => :foo do |t|
  # all extension files under this directory
  t.dir = 'ext'
  # link libraries (libbar.so)
  t.link_libs << 'bar'
end
Author

Steve Sloan ([email protected])

Copyright

Copyright © 2006-2009 Steve Sloan

License

MIT

Direct Known Subclasses

SWIGExtensionTask

Constant Summary collapse

@@DefaultEnv =

The default environment for all extensions.

{
  :cxx => 'c++',
  :cxxflags => '',
  :c_exts => ['c'],
  :cpp_exts => ['cc', 'cxx', 'cpp'],
  :includedirs => [],
  :libdirs => [],
}.update(@@DefaultEnv)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) {|_self| ... } ⇒ ExtensionTask

Same arguments as Rake::define_task

Yields:

  • (_self)

Yield Parameters:



56
57
58
59
60
61
62
# File 'lib/rake/extensiontask.rb', line 56

def initialize( args, &blk )
  @env = @@DefaultEnv.dup
  @name, @objs = resolve_args(args)
  set_defaults
  yield self  if block_given?
  define_tasks
end

Instance Attribute Details

#dirObject

The directory where the extension files (source, output, and intermediate) are stored.



46
47
48
# File 'lib/rake/extensiontask.rb', line 46

def dir
  @dir
end

#envObject

Environment configuration – i.e. CONFIG from rbconfig, with a few other settings, and converted to lowercase-symbols.



50
51
52
# File 'lib/rake/extensiontask.rb', line 50

def env
  @env
end

#lib_nameObject

The filename of the extension library file (e.g. ‘extension.so’)



39
40
41
# File 'lib/rake/extensiontask.rb', line 39

def lib_name
  @lib_name
end

Additional link libraries



53
54
55
# File 'lib/rake/extensiontask.rb', line 53

def link_libs
  @link_libs
end

#nameObject

The name of the extension



36
37
38
# File 'lib/rake/extensiontask.rb', line 36

def name
  @name
end

#objsObject

Object files to build and link into the extension.



42
43
44
# File 'lib/rake/extensiontask.rb', line 42

def objs
  @objs
end

Class Method Details

.envObject



116
117
118
# File 'lib/rake/extensiontask.rb', line 116

def env
  @@DefaultEnv
end

.env=(e) ⇒ Object



119
120
121
# File 'lib/rake/extensiontask.rb', line 119

def env=(e)
  @@DefaultEnv = e
end

Instance Method Details

#define_rulesObject

Defines C and C++ source-to-object rules, using the source extensions from env.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/rake/extensiontask.rb', line 97

def define_rules
  for ext in env[:c_exts]
    Rake::Task.create_rule '.'+env[:objext] => '.'+ext do |r|
      sh_cmd :cc, :cflags, :cppflags, {'-D' => :defines}, {'-I' => :includedirs}, {'-I' => :topdir},
            '-c', '-o', r.name, r.sources
    end
  end

  for ext in env[:cpp_exts]
    Rake::Task.create_rule '.'+env[:objext] => '.'+ext do |r|
      sh_cmd :cxx, :cxxflags, :cppflags, {'-D' => :defines}, {'-I' => :includedirs}, {'-I' => :topdir},
            '-o', r.name, '-c', r.sources
    end
  end
end

#define_tasksObject

Defines the library task.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rake/extensiontask.rb', line 80

def define_tasks
  output_objs = @objs.collect { |obj| filepath obj, :objext }
  output_lib = filepath lib_name, :dlext

  task name => output_lib

  file output_lib => output_objs do |t|
    sh_cmd :ldshared, :dldflags, :ldflags, {'-L' => :libdirs}, '-o', output_lib, output_objs.join(' '),
           link_libs.collect { |l| "-l#{l}" }.join(' '), :libs, :dldlibs, :librubyarg_shared
  end

  CLEAN.include output_objs
  CLOBBER.include output_lib
  define_rules
end

#set_defaultsObject

Generate default values. This is called from initialize before the yield block.

Defaults:

  • lib_name: name.so

  • objs: name.o (<- name.c,cxx,cpp,cc)

  • dir: .

  • link_libs: <none>



72
73
74
75
76
77
# File 'lib/rake/extensiontask.rb', line 72

def set_defaults
  @lib_name ||= name.to_sym
  @objs = [name.to_sym]  unless @objs and @objs.any?
  @dir ||= '.'
  @link_libs ||= []
end