jitsu 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,13 +1,18 @@
1
- = jitsu
1
+ = Jitsu
2
2
 
3
3
  Ninja (https://github.com/martine/ninja) is an excellent build system, but
4
4
  Ninja files are hard to write, by design. Jitsu is a simple meta build system
5
5
  that writes Ninja files for you from YAML project descriptions.
6
6
 
7
- For now, simple executables and static libraries are supported. See the
8
- features dir for examples and http://ilkka.github.com/jitsu for docs.
7
+ For now, only C++ and simple executables and static and dynamic libraries are
8
+ supported. See the features dir for examples and http://ilkka.github.com/jitsu
9
+ for docs.
9
10
 
10
- == Contributing to jitsu
11
+ == Using Jitsu
12
+
13
+ See the howto[link:howto.html].
14
+
15
+ == Contributing to Jitsu
11
16
 
12
17
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
13
18
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
data/Rakefile CHANGED
@@ -45,4 +45,5 @@ Cucumber::Rake::Task.new(:features)
45
45
  task :default => :spec
46
46
 
47
47
  require 'yard'
48
- YARD::Rake::YardocTask.new
48
+ yardtask = YARD::Rake::YardocTask.new
49
+ yardtask.after = Proc.new { system "cucumber -f html -o doc/howto.html" }
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.2.0
@@ -58,7 +58,7 @@ Feature: Build C++ programs
58
58
  dependencies:
59
59
  - lib.a
60
60
  lib.a:
61
- type: library
61
+ type: static_library
62
62
  sources:
63
63
  - lib.cpp
64
64
  """
@@ -67,3 +67,49 @@ Feature: Build C++ programs
67
67
  And I run "./hello"
68
68
  Then the output should be "Hello World" with a newline
69
69
 
70
+ Scenario: Build a dynamic library
71
+ Given a directory
72
+ And a file "lib.h" with contents
73
+ """
74
+ #include <string>
75
+
76
+ std::string greeting();
77
+ """
78
+ And a file "lib.cpp" with contents
79
+ """
80
+ #include "lib.h"
81
+
82
+ std::string greeting() {
83
+ return std::string("Hello World");
84
+ }
85
+ """
86
+ And a file "main.cpp" with contents
87
+ """
88
+ #include <iostream>
89
+
90
+ extern std::string greeting();
91
+
92
+ int main(int argc, char* argv[]) {
93
+ std::cout << greeting() << std::endl;
94
+ return 0;
95
+ }
96
+ """
97
+ And a file "build.jitsu" with contents
98
+ """
99
+ ---
100
+ targets:
101
+ lib.so:
102
+ type: dynamic_library
103
+ sources:
104
+ - lib.cpp
105
+ blah:
106
+ type: executable
107
+ sources:
108
+ - main.cpp
109
+ dependencies:
110
+ - lib.so
111
+ """
112
+ When I run jitsu
113
+ And I run "ninja all"
114
+ And I run "env LD_PRELOAD=./lib.so ./blah"
115
+ Then the output should be "Hello World" with a newline
@@ -2,6 +2,7 @@ require 'tmpdir'
2
2
 
3
3
  Given /^a directory$/ do
4
4
  @tmpdir = Dir.mktmpdir
5
+ puts "Tempdir for this scenario: #{@tmpdir}"
5
6
  end
6
7
 
7
8
  Given /^a file "([^"]*)" with contents$/ do |filename, contents|
@@ -23,6 +24,7 @@ When /^I run "([^"]*)"$/ do |command|
23
24
  Dir.chdir @tmpdir do |dir|
24
25
  parts[0] = File.expand_path(parts[0]) if parts[0].index(/\//)
25
26
  @output = `#{parts.join(' ')}`
27
+ $?.should == 0
26
28
  end
27
29
  end
28
30
 
data/jitsu.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{jitsu}
8
- s.version = "0.1.3"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ilkka Laukkanen"]
12
- s.date = %q{2011-02-14}
12
+ s.date = %q{2011-02-15}
13
13
  s.default_executable = %q{jitsu}
14
14
  s.description = %q{Jitsu is a frontend or meta build system for Ninja
15
15
  (http://github.com/martine/ninja), a lightning-fast but
@@ -42,7 +42,8 @@ buildfiles.
42
42
  "jitsu.gemspec",
43
43
  "lib/jitsu.rb",
44
44
  "spec/jitsu_spec.rb",
45
- "spec/spec_helper.rb"
45
+ "spec/spec_helper.rb",
46
+ "watchr_srcipt.rb"
46
47
  ]
47
48
  s.homepage = %q{http://github.com/ilkka/jitsu}
48
49
  s.licenses = ["GPLv3"]
data/lib/jitsu.rb CHANGED
@@ -64,29 +64,90 @@ EOS
64
64
  data['targets'].each do |target,conf|
65
65
  f.write "\n"
66
66
  sources = conf['sources']
67
- sources.each do |src|
68
- f.write "build #{source_to_object src}: cxx #{src}\n"
69
- if conf['cxxflags']
70
- f.write " cxxflags = #{conf['cxxflags']}\n"
71
- end
72
- end
73
- f.write "build #{target}: "
74
- case conf['type']
75
- when 'executable'
76
- f.write "link #{sources_to_objects(sources).join(' ')}"
77
- f.write(' ' + conf['dependencies'].join(' ')) if conf['dependencies']
78
- when 'library'
79
- f.write "archive #{sources_to_objects(sources).join(' ')}"
80
- end
81
- f.write "\n"
67
+ objects = sources_to_objects(sources).join(' ')
68
+ Jitsu.send "handle_#{conf['type']}".to_sym, f, target, sources, objects, conf
82
69
  end
70
+ f.write("\nbuild all: phony || #{data['targets'].keys.join(' ')}\n")
71
+ end
72
+ end
73
+
74
+ # Output build rules for a list of sources.
75
+ #
76
+ # @param out [IO] the output stream where output is written.
77
+ # @param sources [Enumerable] a list of sourcefile names to output rules
78
+ # for.
79
+ # @param conf [Hash] the entire build spec hash for this target.
80
+ def self.output_sources(out, sources, conf)
81
+ cxxflags = conf['cxxflags']
82
+ sources.each do |src|
83
+ out.write "build #{source_to_object src}: cxx #{src}\n"
84
+ out.write " cxxflags = #{cxxflags}\n" if cxxflags
83
85
  end
84
86
  end
85
87
 
88
+ # Output build rules for one executable target.
89
+ #
90
+ # @param out [IO] the output stream where output is written.
91
+ # @param target [String] the filename of the target.
92
+ # @param sources [Enumerable] a list of sourcefile names to output rules
93
+ # for.
94
+ # @param objects [Enumerable] a list of all object files for the target.
95
+ # @param conf [Hash] the entire build spec hash for this target.
96
+ def self.handle_executable(out, target, sources, objects, conf)
97
+ output_sources(out, sources, conf)
98
+ out.write "build #{target}: link #{objects}"
99
+ out.write " #{conf['dependencies'].join(' ')}" if conf['dependencies']
100
+ out.write "\n"
101
+ out.write " ldflags = #{conf['ldflags']}\n" if conf['ldflags']
102
+ end
103
+
104
+ # Output build rules for one static library target.
105
+ #
106
+ # @param out [IO] the output stream where output is written.
107
+ # @param target [String] the filename of the target.
108
+ # @param sources [Enumerable] a list of sourcefile names to output rules
109
+ # for.
110
+ # @param objects [Enumerable] a list of all object files for the target.
111
+ # @param conf [Hash] the entire build spec hash for this target.
112
+ def self.handle_static_library(out, target, sources, objects, conf)
113
+ output_sources(out, sources, conf)
114
+ out.write "build #{target}: archive #{objects}"
115
+ out.write " #{conf['dependencies'].join(' ')}" if conf['dependencies']
116
+ out.write "\n"
117
+ end
118
+
119
+ # Output build rules for one dynamic library target.
120
+ #
121
+ # @param out [IO] the output stream where output is written.
122
+ # @param target [String] the filename of the target.
123
+ # @param sources [Enumerable] a list of sourcefile names to output rules
124
+ # for.
125
+ # @param objects [Enumerable] a list of all object files for the target.
126
+ # @param conf [Hash] the entire build spec hash for this target.
127
+ def self.handle_dynamic_library(out, target, sources, objects, conf)
128
+ conf['cxxflags'] ||= '${cxxflags}'
129
+ conf['cxxflags'] += ' -fPIC'
130
+ output_sources(out, sources, conf)
131
+ out.write "build #{target}: link #{objects}"
132
+ out.write " #{conf['dependencies'].join(' ')}" if conf['dependencies']
133
+ out.write "\n"
134
+ conf['ldflags'] ||= '${ldflags}'
135
+ conf['ldflags'] += " -shared -Wl,-soname,#{target}"
136
+ out.write " ldflags = #{conf['ldflags']}\n"
137
+ end
138
+
139
+ # Convert sourcefile name to corresponding object file name.
140
+ #
141
+ # @param src [String] source file path.
142
+ # @return [String] object file path.
86
143
  def self.source_to_object(src)
87
144
  src.gsub /\.[Cc]\w+$/, '.o'
88
145
  end
89
146
 
147
+ # Convert a list of sourcefile names to corresponding object file names.
148
+ #
149
+ # @param srcs [Enumerable] source file paths.
150
+ # @return [Enumerable] object file paths.
90
151
  def self.sources_to_objects(srcs)
91
152
  srcs.map { |src| source_to_object src }
92
153
  end
data/spec/jitsu_spec.rb CHANGED
@@ -59,7 +59,7 @@ targets:
59
59
  dependencies:
60
60
  - test2
61
61
  test2:
62
- type: library
62
+ type: static_library
63
63
  sources:
64
64
  - test2.cpp
65
65
  cxxflags: -ansi -pedantic
@@ -84,7 +84,7 @@ targets:
84
84
  dependencies:
85
85
  - aaa2
86
86
  aaa2:
87
- type: library
87
+ type: dynamic_library
88
88
  sources:
89
89
  - aaa2.cpp
90
90
  cxxflags: -ansi -pedantic
@@ -108,14 +108,18 @@ targets:
108
108
  sources:
109
109
  - aaa1a.cpp
110
110
  - aaa1b.cpp
111
- cxxflags: -g -Wall
112
111
  dependencies:
113
112
  - aaa2.a
113
+ - aaa3.so
114
114
  aaa2.a:
115
- type: library
115
+ type: static_library
116
116
  sources:
117
117
  - aaa2.cpp
118
118
  cxxflags: -ansi -pedantic
119
+ aaa3.so:
120
+ type: dynamic_library
121
+ sources:
122
+ - aaa3.cpp
119
123
  EOS
120
124
  end
121
125
  data = Jitsu.read Jitsu.jitsufile
@@ -145,27 +149,37 @@ EOS
145
149
  # the targets are reversed on 1.8.7 :p
146
150
  if RUBY_VERSION.start_with? '1.8'
147
151
  ninjafile += <<-EOS
152
+ build aaa3.o: cxx aaa3.cpp
153
+ cxxflags = ${cxxflags} -fPIC
154
+ build aaa3.so: link aaa3.o
155
+ ldflags = ${ldflags} -shared -Wl,-soname,aaa3.so
156
+
148
157
  build aaa2.o: cxx aaa2.cpp
149
158
  cxxflags = -ansi -pedantic
150
159
  build aaa2.a: archive aaa2.o
151
160
 
152
161
  build aaa1a.o: cxx aaa1a.cpp
153
- cxxflags = -g -Wall
154
162
  build aaa1b.o: cxx aaa1b.cpp
155
- cxxflags = -g -Wall
156
- build aaa1: link aaa1a.o aaa1b.o aaa2.a
163
+ build aaa1: link aaa1a.o aaa1b.o aaa2.a aaa3.so
164
+
165
+ build all: phony || aaa3.so aaa2.a aaa1
157
166
  EOS
158
167
  else
159
168
  ninjafile += <<-EOS
160
169
  build aaa1a.o: cxx aaa1a.cpp
161
- cxxflags = -g -Wall
162
170
  build aaa1b.o: cxx aaa1b.cpp
163
- cxxflags = -g -Wall
164
- build aaa1: link aaa1a.o aaa1b.o aaa2.a
171
+ build aaa1: link aaa1a.o aaa1b.o aaa2.a aaa3.so
165
172
 
166
173
  build aaa2.o: cxx aaa2.cpp
167
174
  cxxflags = -ansi -pedantic
168
175
  build aaa2.a: archive aaa2.o
176
+
177
+ build aaa3.o: cxx aaa3.cpp
178
+ cxxflags = ${cxxflags} -fPIC
179
+ build aaa3.so: link aaa3.o
180
+ ldflags = ${ldflags} -shared -Wl,-soname,aaa3.so
181
+
182
+ build all: phony || aaa1 aaa2.a aaa3.so
169
183
  EOS
170
184
  end
171
185
  File.open('build.ninja', 'r').read.should == ninjafile
data/watchr_srcipt.rb ADDED
@@ -0,0 +1,12 @@
1
+ def run_specs
2
+ system("rake spec")
3
+ end
4
+
5
+ def run_features
6
+ system("rake features")
7
+ end
8
+
9
+ watch('(lib|bin|spec|features)/(.*\.rb|[^.])') do |md|
10
+ run_specs && run_features
11
+ end
12
+
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: jitsu
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.3
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ilkka Laukkanen
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-02-14 00:00:00 +02:00
13
+ date: 2011-02-15 00:00:00 +02:00
14
14
  default_executable: jitsu
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -125,6 +125,7 @@ files:
125
125
  - lib/jitsu.rb
126
126
  - spec/jitsu_spec.rb
127
127
  - spec/spec_helper.rb
128
+ - watchr_srcipt.rb
128
129
  has_rdoc: true
129
130
  homepage: http://github.com/ilkka/jitsu
130
131
  licenses:
@@ -139,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
139
140
  requirements:
140
141
  - - ">="
141
142
  - !ruby/object:Gem::Version
142
- hash: -901234259
143
+ hash: 564580019
143
144
  segments:
144
145
  - 0
145
146
  version: "0"