paper_house 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/Rakefile +3 -10
  4. data/examples/executable/Rakefile +5 -0
  5. data/examples/executable/Rakefile.llvm +5 -0
  6. data/examples/executable/hello.c +7 -0
  7. data/examples/executable_subdirs/Rakefile +11 -0
  8. data/examples/executable_subdirs/includes/hello.h +1 -0
  9. data/examples/executable_subdirs/sources/hello.c +6 -0
  10. data/examples/executable_subdirs/sources/main.c +8 -0
  11. data/examples/fail/Rakefile +5 -0
  12. data/examples/fail/hello +0 -0
  13. data/examples/fail/hello.c +1 -0
  14. data/examples/ruby_extension/Rakefile +5 -0
  15. data/examples/ruby_extension/Rakefile.llvm +5 -0
  16. data/examples/ruby_extension/hello.c +6 -0
  17. data/examples/shared_library/Rakefile +23 -0
  18. data/examples/shared_library/Rakefile.llvm +25 -0
  19. data/examples/shared_library/hello.c +6 -0
  20. data/examples/shared_library/hello.h +1 -0
  21. data/examples/shared_library/main.c +7 -0
  22. data/examples/shared_library_subdirs/Rakefile +28 -0
  23. data/examples/shared_library_subdirs/includes/hello.h +1 -0
  24. data/examples/shared_library_subdirs/sources/hello.c +6 -0
  25. data/examples/shared_library_subdirs/sources/main.c +8 -0
  26. data/examples/static_library/Rakefile +14 -0
  27. data/examples/static_library/Rakefile.llvm +14 -0
  28. data/examples/static_library/hello.c +6 -0
  29. data/examples/static_library/hello.h +1 -0
  30. data/examples/static_library/main.c +7 -0
  31. data/examples/static_library_subdirs/Rakefile +19 -0
  32. data/examples/static_library_subdirs/includes/hello.h +1 -0
  33. data/examples/static_library_subdirs/sources/hello.c +6 -0
  34. data/examples/static_library_subdirs/sources/main.c +8 -0
  35. data/features/step_definitions/paper_house_steps.rb +1 -1
  36. data/features/support/hooks.rb +2 -2
  37. data/lib/paper_house/auto_depends.rb +3 -8
  38. data/lib/paper_house/build_failed.rb +3 -1
  39. data/lib/paper_house/build_task.rb +7 -4
  40. data/lib/paper_house/dependency.rb +9 -7
  41. data/lib/paper_house/executable_task.rb +13 -1
  42. data/lib/paper_house/library_task.rb +7 -6
  43. data/lib/paper_house/linker_options.rb +1 -1
  44. data/lib/paper_house/platform.rb +7 -8
  45. data/lib/paper_house/ruby_extension_task.rb +0 -4
  46. data/lib/paper_house/shared_library_task.rb +11 -0
  47. data/lib/paper_house/version.rb +1 -1
  48. data/paper_house.gemspec +2 -1
  49. data/spec/paper_house/executable_task_spec.rb +35 -42
  50. data/spec/paper_house/ruby_extension_task_spec.rb +38 -76
  51. data/spec/paper_house/shared_library_task_spec.rb +71 -105
  52. data/spec/paper_house/static_library_task_spec.rb +63 -54
  53. data/spec/paper_house/version_spec.rb +2 -4
  54. data/spec/spec_helper.rb +2 -1
  55. metadata +54 -24
  56. data/lib/paper_house/safe_popen.rb +0 -26
@@ -12,9 +12,11 @@ module PaperHouse
12
12
  class BuildTask < Rake::TaskLib
13
13
  # Helper class for defining CLEAN and CLOBBER.
14
14
  class CleanTask
15
- def initialize(targets, file_list)
15
+ # Add +targets+ to +target_type+ (+:CLEAN+ or +:CLOBBER+).
16
+ # @example CleanTask.new %w(file1 file2), :CLEAN
17
+ def initialize(targets, target_type)
16
18
  @targets = targets
17
- @file_list = Object.const_get(file_list.to_s.upcase)
19
+ @file_list = Object.const_get(target_type)
18
20
  define_task
19
21
  end
20
22
 
@@ -50,6 +52,7 @@ module PaperHouse
50
52
  ENV['CC'] || @cc || 'gcc'
51
53
  end
52
54
 
55
+ # @private
53
56
  def initialize(name, &block)
54
57
  @name = name.to_s
55
58
  block.call self if block
@@ -109,8 +112,8 @@ module PaperHouse
109
112
  end
110
113
 
111
114
  def define_clean_tasks
112
- CleanTask.new objects, :clean
113
- CleanTask.new clobber_targets, :clobber
115
+ CleanTask.new objects, :CLEAN
116
+ CleanTask.new clobber_targets, :CLOBBER
114
117
  end
115
118
 
116
119
  def clobber_targets
@@ -4,30 +4,32 @@ require 'pstore'
4
4
  require 'rake'
5
5
 
6
6
  module PaperHouse
7
- #
8
7
  # Keeps compilation dependencies
9
- #
10
8
  class Dependency
11
9
  attr_reader :path
12
10
 
11
+ # Creates an object that tracks depencency information about a
12
+ # rake task specified with the +name+ argument.
13
+ #
14
+ # @example
15
+ # Dependency.new('hello')
13
16
  def initialize(name)
14
17
  @name = name
15
18
  @path = File.join(Rake.original_dir, ".#{name}.depends")
16
19
  @cache = {}
17
20
  end
18
21
 
19
- #
20
22
  # Reads the dependency information of +object_file+.
21
- #
23
+ # @return [Array<String>]
22
24
  def read(object_file)
23
25
  db.transaction(true) do |store|
24
26
  store[object_file]
25
27
  end || []
26
28
  end
27
29
 
28
- #
29
- # Saves the dependency information (+object_file+ => +dependent_files+).
30
- #
30
+ # Saves the dependency information
31
+ # (+object_file+ => +dependent_files+).
32
+ # @return [void]
31
33
  def write(object_file, dependent_files)
32
34
  db.transaction(false) do |store|
33
35
  store[object_file] = dependent_files
@@ -12,6 +12,18 @@ module PaperHouse
12
12
  class ExecutableTask < BuildTask
13
13
  include LinkerOptions
14
14
 
15
+ # Defines a rake task called +name+ that builds an executable.
16
+ # Several task attributes can be set in the +block+.
17
+ #
18
+ # @yield [task]
19
+ # @example
20
+ # PaperHouse::ExecutableTask.new :hello do |task|
21
+ # task.executable_name = 'hello'
22
+ # task.target_directory = 'objects'
23
+ # task.sources = 'sources/*.c'
24
+ # task.includes = 'includes'
25
+ # task.cflags = %w(-Wall -Wextra)
26
+ # end
15
27
  def initialize(name, &block)
16
28
  super name, &block
17
29
  Rake::Task[name].prerequisites.each do |each|
@@ -24,7 +36,7 @@ module PaperHouse
24
36
  attr_writer :executable_name
25
37
 
26
38
  def executable_name
27
- @executable_name ||= @name
39
+ (@executable_name ||= @name).to_s
28
40
  end
29
41
  alias_method :target_file_name, :executable_name
30
42
 
@@ -5,17 +5,18 @@ require 'paper_house/build_task'
5
5
  module PaperHouse
6
6
  # Common base class for static, shared, and ruby library tasks.
7
7
  class LibraryTask < BuildTask
8
- # Find a LibraryTask by name
9
- def self.find_named(name)
8
+ # Find a LibraryTask by +name+.
9
+ # @return [LibraryTask]
10
+ def self.find_by_name(name)
10
11
  ObjectSpace.each_object(self) do |each|
11
12
  obj_name = each.name
12
- if Rake::Task.task_defined?(obj_name) && obj_name == name.to_s
13
- return each
14
- end
13
+ next if !Rake::Task.task_defined?(obj_name) || obj_name != name.to_s
14
+ return each
15
15
  end
16
16
  nil
17
17
  end
18
18
 
19
+ # @private
19
20
  def initialize(name, &block)
20
21
  @library_dependencies = []
21
22
  super name, &block
@@ -23,7 +24,7 @@ module PaperHouse
23
24
 
24
25
  # Name of library.
25
26
  def library_name
26
- @library_name ||= @name
27
+ (@library_name ||= @name).to_s
27
28
  end
28
29
 
29
30
  # Name of library.
@@ -38,7 +38,7 @@ module PaperHouse
38
38
  end
39
39
 
40
40
  def maybe_enhance(name, klass)
41
- task = klass.find_named(name)
41
+ task = klass.find_by_name(name)
42
42
  enhance task if task
43
43
  end
44
44
 
@@ -3,9 +3,7 @@
3
3
  require 'rbconfig'
4
4
 
5
5
  module PaperHouse
6
- #
7
6
  # Platform-dependent stuff.
8
- #
9
7
  module Platform
10
8
  include RbConfig
11
9
 
@@ -13,13 +11,13 @@ module PaperHouse
13
11
  MAC = (/darwin|mac os/ =~ CONFIG['host_os'])
14
12
 
15
13
  # File extension of C extensions.
16
- SHARED_EXT = MAC ? '.bundle' : '.so'
14
+ SHARED_EXT = (MAC ? '.bundle' : '.so').freeze
17
15
 
18
16
  # CC options for compiling shared libraries.
19
- LDSHARED = MAC ? '-dynamic -bundle' : '-shared'
17
+ LDSHARED = (MAC ? '-dynamic -bundle' : '-shared').freeze
20
18
 
21
19
  # CC option for setting soname.
22
- SONAME_OPTION = MAC ? '-install_name' : '-soname'
20
+ SONAME_OPTION = (MAC ? '-install_name' : '-soname').freeze
23
21
 
24
22
  # Include directories for compiling C extensions.
25
23
  RUBY_INCLUDES =
@@ -27,13 +25,14 @@ module PaperHouse
27
25
  File.join(CONFIG['rubyhdrdir'], CONFIG['arch']),
28
26
  File.join(CONFIG['rubyhdrdir'], 'ruby/backward'),
29
27
  CONFIG['rubyhdrdir']
30
- ]
28
+ ].freeze
31
29
 
32
30
  # Library directories for compiling C extensions.
33
- RUBY_LIBDIR = CONFIG['libdir']
31
+ RUBY_LIBDIR = CONFIG['libdir'].freeze
34
32
 
33
+ # Platform name.
35
34
  def self.name
36
- MAC ? 'mac' : 'linux'
35
+ (MAC ? 'mac' : 'linux').freeze
37
36
  end
38
37
  end
39
38
  end
@@ -4,13 +4,9 @@ require 'paper_house/library_task'
4
4
  require 'paper_house/linker_options'
5
5
  require 'paper_house/platform'
6
6
 
7
- #
8
7
  # Rake for C projects.
9
- #
10
8
  module PaperHouse
11
- #
12
9
  # Compiles *.c files into a Ruby extension library.
13
- #
14
10
  class RubyExtensionTask < LibraryTask
15
11
  include LinkerOptions
16
12
  include Platform
@@ -13,6 +13,17 @@ module PaperHouse
13
13
  # Library version string.
14
14
  attr_accessor :version
15
15
 
16
+ # Defines a rake task called +name+ that builds a shared library.
17
+ # Note that version number must be set as the +version+ argument
18
+ # or in the +block+ to build the library.
19
+ #
20
+ # @yield [task]
21
+ # @example
22
+ # PaperHouse::SharedLibraryTask.new :libhello do |task|
23
+ # task.version = '0.1.0'
24
+ # task.sources = 'hello.c'
25
+ # task.library_dependencies = 'm'
26
+ # end
16
27
  def initialize(name, version = nil, &block)
17
28
  @version = version
18
29
  super name, &block
@@ -3,5 +3,5 @@
3
3
  # Base module.
4
4
  module PaperHouse
5
5
  # gem version.
6
- VERSION = '0.6.0'
6
+ VERSION = '0.6.1'.freeze
7
7
  end
data/paper_house.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.files = %w(CONTRIBUTING.md LICENSE Rakefile paper_house.gemspec)
20
20
  gem.files += Dir.glob('lib/**/*.rb')
21
21
  gem.files += Dir.glob('bin/**/*')
22
+ gem.files += Dir.glob('examples/**/*')
22
23
  gem.files += Dir.glob('spec/**/*')
23
24
  gem.files += Dir.glob('features/**/*')
24
25
 
@@ -30,5 +31,5 @@ Gem::Specification.new do |gem|
30
31
 
31
32
  gem.required_ruby_version = '>= 1.9.3'
32
33
  gem.add_dependency 'POpen4', '~> 0.1.4'
33
- gem.add_dependency 'rake', '~> 10.2.1'
34
+ gem.add_dependency 'rake'
34
35
  end
@@ -3,65 +3,58 @@
3
3
  require 'paper_house/executable_task'
4
4
 
5
5
  describe Rake::Task do
6
- before { Rake::Task.clear }
6
+ context 'when ExecutableTask (name = :test) is defined' do
7
+ Given { Rake::Task.clear }
8
+ Given { PaperHouse::ExecutableTask.new :test }
7
9
 
8
- describe '.[]' do
9
- subject { Rake::Task[task] }
10
+ describe '.[]' do
11
+ context 'with :test' do
12
+ Given(:name) { :test }
10
13
 
11
- context 'with :test' do
12
- let(:task) { :test }
13
-
14
- context 'when ExecutableTask named :test is defined' do
15
- before { PaperHouse::ExecutableTask.new :test }
14
+ When(:task) { Rake::Task[name] }
15
+ Then { task.is_a? Rake::Task }
16
16
 
17
17
  describe '#invoke' do
18
- it do
19
- expect do
20
- subject.invoke
21
- end.to raise_error('Cannot find sources (*.c).')
18
+ When(:result) { task.invoke }
19
+ Then do
20
+ result ==
21
+ Failure(RuntimeError, 'Cannot find sources (*.c).')
22
22
  end
23
23
  end
24
24
  end
25
-
26
- context 'when ExecutableTask named :test is not defined' do
27
- it { expect { subject }.to raise_error }
28
- end
29
25
  end
30
26
  end
31
27
  end
32
28
 
33
29
  describe PaperHouse::ExecutableTask, '.new' do
34
- context 'with name :test' do
35
- subject { PaperHouse::ExecutableTask.new :test }
36
-
37
- its(:cc) { should eq 'gcc' }
38
- its(:cflags) { should be_empty }
39
- its(:executable_name) { should eq 'test' }
40
- its(:includes) { should be_empty }
41
- its(:ldflags) { should be_empty }
42
- its(:library_dependencies) { should be_empty }
43
- its(:name) { should eq 'test' }
44
- its(:sources) { should eq '*.c' }
45
- its(:target_directory) { should eq '.' }
30
+ context 'with :test' do
31
+ When(:task) { PaperHouse::ExecutableTask.new(:test) }
32
+ Then { task.name == 'test' }
33
+ Then { task.executable_name == 'test' }
34
+ Then { task.sources == '*.c' }
35
+ Then { task.target_directory == '.' }
36
+ Then { task.cc == 'gcc' }
37
+ Then { task.cflags.empty? }
38
+ Then { task.includes.empty? }
39
+ Then { task.ldflags.empty? }
40
+ Then { task.library_dependencies.empty? }
46
41
  end
47
42
 
48
- context 'with :test and block' do
49
- subject do
50
- PaperHouse::ExecutableTask.new(:test) do | task |
51
- task.executable_name = executable_name
43
+ context "with :test and a block setting :executable_name = 'executable'" do
44
+ When(:task) do
45
+ PaperHouse::ExecutableTask.new(:test) do |task|
46
+ task.executable_name = 'executable'
52
47
  end
53
48
  end
49
+ Then { task.executable_name == 'executable' }
50
+ end
54
51
 
55
- context %(with #executable_name = 'new_name') do
56
- let(:executable_name) { 'new_name' }
57
-
58
- its(:executable_name) { should eq 'new_name' }
59
- end
60
-
61
- context 'with #executable_name = :new_name' do
62
- let(:executable_name) { :new_name }
63
-
64
- its(:executable_name) { should eq :new_name }
52
+ context 'with :test and a block setting :executable_name = :executable' do
53
+ When(:task) do
54
+ PaperHouse::ExecutableTask.new(:test) do |task|
55
+ task.executable_name = :executable
56
+ end
65
57
  end
58
+ Then { task.executable_name == 'executable' }
66
59
  end
67
60
  end
@@ -3,100 +3,62 @@
3
3
  require 'paper_house/ruby_extension_task'
4
4
 
5
5
  describe Rake::Task do
6
- before { Rake::Task.clear }
6
+ context 'when RubyExtensionTask (name = :test) is defined' do
7
+ Given { Rake::Task.clear }
8
+ Given { PaperHouse::RubyExtensionTask.new :test }
7
9
 
8
- describe '.[]' do
9
- subject { Rake::Task[task] }
10
+ describe '.[]' do
11
+ context 'with :test' do
12
+ Given(:name) { :test }
10
13
 
11
- context 'with :test' do
12
- let(:task) { :test }
13
-
14
- context 'when RubyExtensionTask named :test is defined' do
15
- before { PaperHouse::RubyExtensionTask.new :test }
14
+ When(:task) { Rake::Task[name] }
15
+ Then { task.is_a? Rake::Task }
16
16
 
17
17
  describe '#invoke' do
18
- it do
19
- expect do
20
- subject.invoke
21
- end.to raise_error('Cannot find sources (*.c).')
18
+ When(:result) { task.invoke }
19
+ Then do
20
+ result ==
21
+ Failure(RuntimeError, 'Cannot find sources (*.c).')
22
22
  end
23
23
  end
24
24
  end
25
-
26
- context 'when RubyExtensionTask named :test is not defined' do
27
- it { expect { subject }.to raise_error }
28
- end
29
25
  end
30
26
  end
31
27
  end
32
28
 
33
- describe PaperHouse::RubyExtensionTask do
34
- before { Rake::Task.clear }
35
-
36
- describe '.find_named' do
37
- subject { PaperHouse::RubyExtensionTask.find_named name }
38
-
39
- context 'with :test' do
40
- let(:name) { :test }
41
-
42
- context 'when RubyExtensionTask named :test is defined' do
43
- before { PaperHouse::RubyExtensionTask.new :test }
44
-
45
- it { expect(subject).to be_a PaperHouse::RubyExtensionTask }
46
- end
47
-
48
- context 'when RubyExtensionTask named :test is not defined' do
49
- it { expect(subject).to be_nil }
50
- end
29
+ describe PaperHouse::RubyExtensionTask, '.new' do
30
+ context 'with :test' do
31
+ When(:task) { PaperHouse::RubyExtensionTask.new(:test) }
32
+ Then { task.name == 'test' }
33
+ Then { task.library_name == 'test' }
34
+ Then { task.sources == '*.c' }
35
+ Then { task.target_directory == '.' }
36
+ Then { task.cc == 'gcc' }
37
+ if PaperHouse::Platform.name == 'mac'
38
+ Then { task.library_dependencies == ['ruby'] }
39
+ else
40
+ Then { task.library_dependencies.empty? }
51
41
  end
42
+ Then { task.cflags.empty? }
43
+ Then { task.includes.empty? }
44
+ Then { task.ldflags.empty? }
45
+ end
52
46
 
53
- context %(with 'test') do
54
- let(:name) { 'test' }
55
-
56
- context %(when RubyExtensionTask named 'test' is defined) do
57
- before { PaperHouse::RubyExtensionTask.new :test }
58
-
59
- it { expect(subject).to be_a PaperHouse::RubyExtensionTask }
47
+ context "with :test and a block setting :library_name = 'libtest'" do
48
+ When(:task) do
49
+ PaperHouse::RubyExtensionTask.new(:test) do |task|
50
+ task.library_name = 'libtest'
60
51
  end
61
52
  end
62
-
63
- context 'with :no_such_task' do
64
- let(:name) { :no_such_task }
65
-
66
- it { expect(subject).to be_nil }
67
- end
53
+ Then { task.library_name == 'libtest' }
68
54
  end
69
55
 
70
- describe '.new' do
71
- context 'with :test' do
72
- subject { PaperHouse::RubyExtensionTask.new :test }
73
-
74
- its(:cc) { should eq 'gcc' }
75
- its(:cflags) { should be_empty }
76
- its(:includes) { should be_empty }
77
- its(:name) { should eq 'test' }
78
- its(:sources) { should eq '*.c' }
79
- its(:target_directory) { should eq '.' }
80
- end
81
-
82
- context 'with :test and block' do
83
- subject do
84
- PaperHouse::RubyExtensionTask.new(:test) do | task |
85
- task.library_name = library_name
86
- end
87
- end
88
-
89
- context %(with #library_name = 'new_name') do
90
- let(:library_name) { 'new_name' }
91
-
92
- its(:library_name) { should eq 'new_name' }
93
- end
94
-
95
- context 'with #library_name = :new_name' do
96
- let(:library_name) { :new_name }
97
-
98
- its(:library_name) { should eq :new_name }
56
+ context 'with :test and a block setting :library_name = :libtest' do
57
+ When(:task) do
58
+ PaperHouse::RubyExtensionTask.new(:test) do |task|
59
+ task.library_name = :libtest
99
60
  end
100
61
  end
62
+ Then { task.library_name == 'libtest' }
101
63
  end
102
64
  end