paper_house 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +1 -0
  5. data/CONTRIBUTING.md +12 -0
  6. data/Gemfile +24 -25
  7. data/Guardfile +1 -7
  8. data/README.md +10 -10
  9. data/Rakefile +54 -65
  10. data/examples/executable/Rakefile +3 -1
  11. data/examples/executable_subdirs/Rakefile +8 -6
  12. data/examples/{c_extension → ruby_extension}/.gitignore +0 -0
  13. data/examples/ruby_extension/Rakefile +5 -0
  14. data/examples/ruby_extension/Rakefile.llvm +5 -0
  15. data/examples/{c_extension → ruby_extension}/hello.c +0 -0
  16. data/examples/shared_library/Rakefile +17 -11
  17. data/examples/shared_library/Rakefile.llvm +11 -5
  18. data/examples/shared_library_subdirs/Rakefile +16 -15
  19. data/examples/static_library/Rakefile +6 -5
  20. data/examples/static_library_subdirs/Rakefile +11 -9
  21. data/features/executable_task.feature +15 -27
  22. data/features/{c_extension_task.feature → ruby_extension_task.feature} +30 -48
  23. data/features/shared_library_task.feature +33 -60
  24. data/features/static_library_task.feature +18 -33
  25. data/features/step_definitions/paper_house_steps.rb +13 -4
  26. data/features/support/env.rb +8 -11
  27. data/features/support/hooks.rb +10 -5
  28. data/lib/paper_house/auto_depends.rb +24 -29
  29. data/lib/paper_house/build_task.rb +49 -75
  30. data/lib/paper_house/cc_options.rb +7 -17
  31. data/lib/paper_house/dependency.rb +12 -21
  32. data/lib/paper_house/executable_task.rb +12 -22
  33. data/lib/paper_house/library_task.rb +13 -15
  34. data/lib/paper_house/linker_options.rb +14 -24
  35. data/lib/paper_house/platform.rb +15 -24
  36. data/lib/paper_house/{c_extension_task.rb → ruby_extension_task.rb} +15 -35
  37. data/lib/paper_house/safe_popen.rb +4 -6
  38. data/lib/paper_house/shared_library_task.rb +14 -28
  39. data/lib/paper_house/static_library_task.rb +6 -15
  40. data/lib/paper_house/version.rb +2 -3
  41. data/lib/paper_house.rb +6 -7
  42. data/paper_house.gemspec +17 -19
  43. data/rake_simplecov_hook.rb +24 -0
  44. data/rubocop-todo.yml +6 -0
  45. data/spec/paper_house/executable_task_spec.rb +65 -20
  46. data/spec/paper_house/ruby_extension_task_spec.rb +129 -0
  47. data/spec/paper_house/shared_library_task_spec.rb +124 -49
  48. data/spec/paper_house/static_library_task_spec.rb +81 -27
  49. data/spec/paper_house/version_spec.rb +5 -5
  50. data/spec/spec_helper.rb +8 -13
  51. metadata +17 -15
  52. data/examples/c_extension/Rakefile +0 -3
  53. data/examples/c_extension/Rakefile.llvm +0 -5
  54. data/examples/shared_library/symlinks.rake +0 -7
  55. data/spec/paper_house/c_extension_task_spec.rb +0 -59
  56. data/spec/paper_house/cc_options_spec.rb +0 -59
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  #
2
3
  # Copyright (C) 2013 NEC Corporation
3
4
  #
@@ -15,59 +16,67 @@
15
16
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
17
  #
17
18
 
18
-
19
- require "paper_house/auto_depends"
20
- require "paper_house/dependency"
21
- require "paper_house/cc_options"
22
- require "rake/clean"
23
- require "rake/tasklib"
24
-
19
+ require 'paper_house/auto_depends'
20
+ require 'paper_house/dependency'
21
+ require 'paper_house/cc_options'
22
+ require 'rake/clean'
23
+ require 'rake/tasklib'
25
24
 
26
25
  module PaperHouse
27
26
  # Common base class for *.c compilation tasks.
28
27
  class BuildTask < Rake::TaskLib
29
- include CcOptions
28
+ # Helper class for defining CLEAN and CLOBBER.
29
+ class CleanTask
30
+ def initialize(targets, file_list)
31
+ @targets = targets
32
+ @file_list = Object.const_get(file_list.to_s.upcase)
33
+ define_task
34
+ end
35
+
36
+ private
30
37
 
38
+ def define_task
39
+ @targets.each do |each|
40
+ next if @file_list.include?(each)
41
+ @file_list.include each
42
+ end
43
+ @file_list.existing!
44
+ end
45
+ end
46
+
47
+ include CcOptions
31
48
 
32
49
  # Name of task.
33
50
  attr_accessor :name
34
51
 
35
-
36
52
  # @!attribute target_directory
37
53
  # Directory where *.o files are created.
38
54
  attr_writer :target_directory
39
55
 
40
56
  def target_directory
41
- @target_directory ||= "."
57
+ @target_directory ||= '.'
42
58
  end
43
59
 
44
-
45
60
  # @!attribute cc
46
61
  # C compiler name or path.
47
62
  attr_writer :cc
48
63
 
49
64
  def cc
50
- ENV[ "CC" ] || @cc || "gcc"
65
+ ENV['CC'] || @cc || 'gcc'
51
66
  end
52
67
 
53
-
54
- def initialize name, &block
68
+ def initialize(name, &block)
55
69
  @name = name.to_s
56
70
  block.call self if block
57
71
  define
58
72
  end
59
73
 
60
-
61
74
  # Relative path to target file.
62
75
  def target_path
63
- File.join target_directory, target_file_name
76
+ File.join target_directory, target_file_name.to_s
64
77
  end
65
78
 
66
-
67
- ############################################################################
68
79
  private
69
- ############################################################################
70
-
71
80
 
72
81
  def define
73
82
  define_main_task
@@ -77,112 +86,77 @@ module PaperHouse
77
86
  define_clean_tasks
78
87
  end
79
88
 
80
-
81
89
  def define_main_task
82
90
  path = target_path
83
- task name => [ target_directory, path ]
91
+ task name => [target_directory, path]
84
92
  end
85
93
 
86
-
87
94
  def define_directory_task
88
95
  directory target_directory
89
96
  end
90
97
 
91
-
92
98
  def define_all_c_compile_tasks
93
- sources_list.zip( objects ) do | source, object |
99
+ sources_list.zip(objects) do |source, object|
94
100
  define_c_compile_task source, object
95
101
  end
96
102
  end
97
103
 
98
-
99
- def define_c_compile_task source, object
100
- task object => source do | task |
101
- compile task.name, task.prerequisites[ 0 ]
104
+ def define_c_compile_task(source, object)
105
+ task object => source do |task|
106
+ compile task.name, task.prerequisites[0]
102
107
  end
103
108
  end
104
109
 
105
-
106
110
  def define_maybe_generate_target_task
107
- file target_path => objects do | task |
108
- next if uptodate?( task.name, task.prerequisites )
111
+ file target_path => objects do |task|
112
+ next if uptodate?(task.name, task.prerequisites)
109
113
  build
110
114
  end
111
115
  end
112
116
 
113
-
114
117
  def build
115
118
  check_sources_list
116
119
  generate_target
117
120
  end
118
121
 
119
-
120
122
  def check_sources_list
121
- if sources_list.empty?
122
- fail "Cannot find sources (#{ @sources })."
123
- end
123
+ fail "Cannot find sources (#{@sources})." if sources_list.empty?
124
124
  end
125
125
 
126
-
127
126
  def define_clean_tasks
128
- define_clean_task
129
- define_clobber_task
130
- end
131
-
132
-
133
- def define_clean_task
134
- objects.each do | each |
135
- next if CLEAN.include?( each )
136
- CLEAN.include each
137
- end
138
- CLEAN.existing!
127
+ CleanTask.new objects, :clean
128
+ CleanTask.new clobber_targets, :clobber
139
129
  end
140
130
 
141
-
142
- def define_clobber_task
143
- clobber_targets.each do | each |
144
- next if CLOBBER.include?( each )
145
- CLOBBER.include each
146
- end
147
- CLOBBER.existing!
148
- end
149
-
150
-
151
131
  def clobber_targets
152
- [ target_path, dependency.path ]
132
+ [target_path, dependency.path]
153
133
  end
154
134
 
155
-
156
135
  def objects
157
- sources_list.pathmap File.join( target_directory, "%n.o" )
136
+ sources_list.pathmap File.join(target_directory, '%n.o')
158
137
  end
159
138
 
160
-
161
- def compile o_file, c_file
162
- return if no_need_to_compile?( o_file, c_file )
163
- auto_depends = AutoDepends.new( c_file, o_file, cc, auto_depends_cc_options )
139
+ def compile(o_file, c_file)
140
+ return if no_need_to_compile?(o_file, c_file)
141
+ auto_depends = AutoDepends.new(c_file, o_file, cc, ad_cc_options)
164
142
  auto_depends.run
165
143
  dependency.write o_file, auto_depends.data
166
144
  end
167
145
 
168
-
169
- def no_need_to_compile?( o_file, c_file )
170
- uptodate?( o_file, dependency.read( o_file ) << c_file )
146
+ def no_need_to_compile?(o_file, c_file)
147
+ uptodate?(o_file, dependency.read(o_file) << c_file)
171
148
  end
172
149
 
173
-
174
- def auto_depends_cc_options
175
- ( cflags + [ "-fPIC" ] + i_options ).join " "
150
+ def ad_cc_options
151
+ (cflags + ['-fPIC'] + i_options).join ' '
176
152
  end
177
153
 
178
-
179
154
  def dependency
180
- @dependency ||= Dependency.new( @name )
155
+ @dependency ||= Dependency.new(@name)
181
156
  end
182
157
  end
183
158
  end
184
159
 
185
-
186
160
  ### Local variables:
187
161
  ### mode: Ruby
188
162
  ### coding: utf-8-unix
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  #
2
3
  # Copyright (C) 2013 NEC Corporation
3
4
  #
@@ -15,7 +16,6 @@
15
16
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
17
  #
17
18
 
18
-
19
19
  module PaperHouse
20
20
  # CC option utilities.
21
21
  module CcOptions
@@ -24,10 +24,9 @@ module PaperHouse
24
24
  attr_writer :sources
25
25
 
26
26
  def sources
27
- @sources ||= "*.c"
27
+ @sources ||= '*.c'
28
28
  end
29
29
 
30
-
31
30
  # @!attribute cflags
32
31
  # Compile options pass to C compiler.
33
32
  attr_writer :cflags
@@ -36,44 +35,35 @@ module PaperHouse
36
35
  @cflags ||= []
37
36
  end
38
37
 
39
-
40
38
  # @!attribute includes
41
39
  # Glob pattern to match include directories.
42
40
  attr_writer :includes
43
41
 
44
42
  def includes
45
43
  @includes ||= []
46
- FileList[ [ @includes ] ]
44
+ FileList[[@includes]]
47
45
  end
48
46
 
49
-
50
- ############################################################################
51
47
  private
52
- ############################################################################
53
-
54
48
 
55
49
  def i_options
56
- include_directories.pathmap "-I%p"
50
+ include_directories.pathmap '-I%p'
57
51
  end
58
52
 
59
-
60
53
  def include_directories
61
- ( includes + auto_includes ).uniq
54
+ (includes + auto_includes).uniq
62
55
  end
63
56
 
64
-
65
57
  def auto_includes
66
- FileList[ sources_list.pathmap( "%d" ).uniq ]
58
+ FileList[sources_list.pathmap('%d').uniq]
67
59
  end
68
60
 
69
-
70
61
  def sources_list
71
- FileList[ sources ]
62
+ FileList[sources]
72
63
  end
73
64
  end
74
65
  end
75
66
 
76
-
77
67
  ### Local variables:
78
68
  ### mode: Ruby
79
69
  ### coding: utf-8-unix
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  #
2
3
  # Copyright (C) 2013 NEC Corporation
3
4
  #
@@ -15,10 +16,8 @@
15
16
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
17
  #
17
18
 
18
-
19
- require "pstore"
20
- require "rake"
21
-
19
+ require 'pstore'
20
+ require 'rake'
22
21
 
23
22
  module PaperHouse
24
23
  #
@@ -27,46 +26,38 @@ module PaperHouse
27
26
  class Dependency
28
27
  attr_reader :path
29
28
 
30
-
31
- def initialize name
29
+ def initialize(name)
32
30
  @name = name
33
- @path = File.join( Rake.original_dir, ".#{ name }.depends" )
31
+ @path = File.join(Rake.original_dir, ".#{name}.depends")
34
32
  @cache = {}
35
33
  end
36
34
 
37
-
38
35
  #
39
36
  # Reads the dependency information of +object_file+.
40
37
  #
41
- def read object_file
42
- db.transaction( true ) do | store |
43
- store[ object_file ]
38
+ def read(object_file)
39
+ db.transaction(true) do |store|
40
+ store[object_file]
44
41
  end || []
45
42
  end
46
43
 
47
-
48
44
  #
49
45
  # Saves the dependency information (+object_file+ => +dependent_files+).
50
46
  #
51
- def write object_file, dependent_files
52
- db.transaction( false ) do | store |
53
- store[ object_file ] = dependent_files
47
+ def write(object_file, dependent_files)
48
+ db.transaction(false) do |store|
49
+ store[object_file] = dependent_files
54
50
  end
55
51
  end
56
52
 
57
-
58
- ############################################################################
59
53
  private
60
- ############################################################################
61
-
62
54
 
63
55
  def db
64
- @cache[ @name ] ||= PStore.new( @path )
56
+ @cache[@name] ||= PStore.new(@path)
65
57
  end
66
58
  end
67
59
  end
68
60
 
69
-
70
61
  ### Local variables:
71
62
  ### mode: Ruby
72
63
  ### coding: utf-8-unix
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  #
2
3
  # Copyright (C) 2013 NEC Corporation
3
4
  #
@@ -15,12 +16,10 @@
15
16
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
17
  #
17
18
 
18
-
19
- require "paper_house/build_task"
20
- require "paper_house/linker_options"
21
- require "paper_house/shared_library_task"
22
- require "paper_house/static_library_task"
23
-
19
+ require 'paper_house/build_task'
20
+ require 'paper_house/linker_options'
21
+ require 'paper_house/shared_library_task'
22
+ require 'paper_house/static_library_task'
24
23
 
25
24
  module PaperHouse
26
25
  #
@@ -29,15 +28,13 @@ module PaperHouse
29
28
  class ExecutableTask < BuildTask
30
29
  include LinkerOptions
31
30
 
32
-
33
- def initialize name, &block
31
+ def initialize(name, &block)
34
32
  super name, &block
35
- Rake::Task[ name ].prerequisites.each do | each |
36
- find_prerequisites each, [ StaticLibraryTask, SharedLibraryTask ]
33
+ Rake::Task[name].prerequisites.each do |each|
34
+ find_prerequisites each, [StaticLibraryTask, SharedLibraryTask]
37
35
  end
38
36
  end
39
37
 
40
-
41
38
  # @!attribute executable_name
42
39
  # Name of target executable file.
43
40
  attr_writer :executable_name
@@ -45,31 +42,24 @@ module PaperHouse
45
42
  def executable_name
46
43
  @executable_name ||= @name
47
44
  end
48
- alias :target_file_name :executable_name
49
-
45
+ alias_method :target_file_name, :executable_name
50
46
 
51
- ############################################################################
52
47
  private
53
- ############################################################################
54
-
55
48
 
56
49
  def generate_target
57
- sh ( [ cc ] + cc_options ).join( " " )
50
+ sh(([cc] + cc_options).join(' '))
58
51
  end
59
52
 
60
-
61
53
  def cc_options
62
- [ o_option, objects, ldflags, l_options ].flatten
54
+ [o_option, objects, ldflags, l_options].flatten
63
55
  end
64
56
 
65
-
66
57
  def o_option
67
- "-o #{ target_path }"
58
+ "-o #{target_path}"
68
59
  end
69
60
  end
70
61
  end
71
62
 
72
-
73
63
  ### Local variables:
74
64
  ### mode: Ruby
75
65
  ### coding: utf-8-unix
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  #
2
3
  # Copyright (C) 2013 NEC Corporation
3
4
  #
@@ -15,48 +16,45 @@
15
16
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
17
  #
17
18
 
18
-
19
- require "paper_house/build_task"
20
-
19
+ require 'paper_house/build_task'
21
20
 
22
21
  module PaperHouse
23
22
  # Common base class for static, shared, and ruby library tasks.
24
23
  class LibraryTask < BuildTask
25
24
  # Find a LibraryTask by name
26
- def self.find_by name
27
- ObjectSpace.each_object( self ) do | each |
28
- return each if each.name == name.to_s
25
+ def self.find_named(name)
26
+ ObjectSpace.each_object(self) do |each|
27
+ obj_name = each.name
28
+ if Rake::Task.task_defined?(obj_name) && obj_name == name.to_s
29
+ return each
30
+ end
29
31
  end
30
32
  nil
31
33
  end
32
34
 
33
-
34
- def initialize name, &block
35
+ def initialize(name, &block)
35
36
  @library_dependencies = []
36
37
  super name, &block
37
38
  end
38
39
 
39
-
40
40
  # Name of library.
41
41
  def library_name
42
42
  @library_name ||= @name
43
43
  end
44
44
 
45
-
46
45
  # Name of library.
47
- def library_name= new_name
48
- @library_name = /\Alib/=~ new_name ? new_name : "lib" + new_name
46
+ def library_name=(name)
47
+ new_name = name.to_s
48
+ @library_name = /\Alib/ =~ new_name ? new_name : 'lib' + new_name
49
49
  end
50
50
 
51
-
52
51
  # Name of library pass to -l option.
53
52
  def lname
54
- library_name.sub( /^lib/, "" )
53
+ library_name.sub(/^lib/, '')
55
54
  end
56
55
  end
57
56
  end
58
57
 
59
-
60
58
  ### Local variables:
61
59
  ### mode: Ruby
62
60
  ### coding: utf-8-unix
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  #
2
3
  # Copyright (C) 2013 NEC Corporation
3
4
  #
@@ -15,7 +16,6 @@
15
16
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
17
  #
17
18
 
18
-
19
19
  module PaperHouse
20
20
  #
21
21
  # Linker option utilities.
@@ -27,61 +27,51 @@ module PaperHouse
27
27
 
28
28
  def ldflags
29
29
  @ldflags ||= []
30
- [ @ldflags ].flatten.compact
30
+ [@ldflags].flatten.compact
31
31
  end
32
32
 
33
-
34
33
  #
35
34
  # List of libraries to link.
36
35
  #
37
- def library_dependencies= name
38
- @library_dependencies = [ name ].flatten.compact
36
+ def library_dependencies=(name)
37
+ @library_dependencies = [name].flatten.compact
39
38
  end
40
39
 
41
-
42
40
  #
43
41
  # List of libraries to link.
44
42
  #
45
43
  def library_dependencies
46
44
  @library_dependencies ||= []
47
- [ @library_dependencies ].flatten.compact
45
+ [@library_dependencies].flatten.compact
48
46
  end
49
47
 
50
-
51
- ############################################################################
52
48
  private
53
- ############################################################################
54
-
55
49
 
56
- def find_prerequisites task, klass_list
57
- klass_list.each do | klass |
50
+ def find_prerequisites(task, klass_list)
51
+ klass_list.each do |klass|
58
52
  maybe_enhance task, klass
59
53
  end
60
54
  end
61
55
 
62
-
63
- def maybe_enhance name, klass
64
- task = klass.find_by( name )
56
+ def maybe_enhance(name, klass)
57
+ task = klass.find_named(name)
65
58
  enhance task if task
66
59
  end
67
60
 
68
-
69
- def enhance library_task
61
+ def enhance(library_task)
70
62
  @library_dependencies ||= []
71
- @library_dependencies |= [ library_task.lname ]
72
- Rake::Task[ target_path ].enhance [ library_task.target_path ]
63
+ @library_dependencies |= [library_task.lname]
64
+ Rake::Task[target_path].enhance [library_task.target_path]
73
65
  end
74
66
 
75
-
76
67
  def l_options
77
- library_dependencies.collect do | each |
78
- "-l#{ each }"
68
+ library_dependencies.map do |each|
69
+ "-l#{each}"
79
70
  end
80
71
  end
81
72
  end
82
73
  end
83
74
 
84
-
85
75
  ### Local variables:
86
76
  ### mode: Ruby
87
77
  ### coding: utf-8-unix
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  #
2
3
  # Copyright (C) 2013 NEC Corporation
3
4
  #
@@ -15,9 +16,7 @@
15
16
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
17
  #
17
18
 
18
-
19
- require "rbconfig"
20
-
19
+ require 'rbconfig'
21
20
 
22
21
  module PaperHouse
23
22
  #
@@ -26,42 +25,34 @@ module PaperHouse
26
25
  module Platform
27
26
  include RbConfig
28
27
 
29
-
30
28
  # MACOSX or not.
31
- MAC = ( /darwin|mac os/=~ CONFIG[ "host_os" ] )
29
+ MAC = (/darwin|mac os/ =~ CONFIG['host_os'])
32
30
 
31
+ # File extension of C extensions.
32
+ SHARED_EXT = MAC ? '.bundle' : '.so'
33
33
 
34
- if MAC
35
- # File extension of C extensions.
36
- SHARED_EXT = ".bundle"
37
- # CC options for compiling shared libraries.
38
- LDSHARED = "-dynamic -bundle"
39
- # CC option for setting soname.
40
- SONAME_OPTION = "-install_name"
41
- else
42
- SHARED_EXT = ".so"
43
- LDSHARED = "-shared"
44
- SONAME_OPTION = "-soname"
45
- end
34
+ # CC options for compiling shared libraries.
35
+ LDSHARED = MAC ? '-dynamic -bundle' : '-shared'
46
36
 
37
+ # CC option for setting soname.
38
+ SONAME_OPTION = MAC ? '-install_name' : '-soname'
47
39
 
48
40
  # Include directories for compiling C extensions.
49
- RUBY_INCLUDES = if RUBY_VERSION >= "1.9.0"
41
+ RUBY_INCLUDES = if RUBY_VERSION >= '1.9.0'
50
42
  [
51
- File.join( CONFIG[ "rubyhdrdir" ], CONFIG[ "arch" ] ),
52
- File.join( CONFIG[ "rubyhdrdir" ], "ruby/backward" ),
53
- CONFIG[ "rubyhdrdir" ]
43
+ File.join(CONFIG['rubyhdrdir'], CONFIG['arch']),
44
+ File.join(CONFIG['rubyhdrdir'], 'ruby/backward'),
45
+ CONFIG['rubyhdrdir']
54
46
  ]
55
47
  else
56
- [ CONFIG[ "archdir" ] ]
48
+ [CONFIG['archdir']]
57
49
  end
58
50
 
59
51
  # Library directories for compiling C extensions.
60
- RUBY_LIBDIR = CONFIG[ "libdir" ]
52
+ RUBY_LIBDIR = CONFIG['libdir']
61
53
  end
62
54
  end
63
55
 
64
-
65
56
  ### Local variables:
66
57
  ### mode: Ruby
67
58
  ### coding: utf-8-unix