Module: Jitsu
- Defined in:
- lib/jitsu.rb,
lib/jitsu/errors.rb
Overview
Jitsu, a meta build system for Ninja Copyright © 2011 Ilkka Laukkanen <[email protected]>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <www.gnu.org/licenses/>.
Defined Under Namespace
Classes: JitsuError, SyntaxError
Constant Summary collapse
- JITSU_FILE_NAME =
'build.jitsu'
- NINJA_FILE_NAME =
'build.ninja'
Class Method Summary collapse
-
.handle_dynamic_library(out, target, sources, targets) ⇒ Object
Output build rules for one dynamic library target.
-
.handle_executable(out, target, sources, targets) ⇒ Object
Output build rules for one executable target.
-
.handle_libtool_library(out, target, sources, targets) ⇒ Object
Output build rules for one libtool library target.
-
.handle_static_library(out, target, sources, targets) ⇒ Object
Output build rules for one static library target.
-
.jitsufile ⇒ String
Get path to jitsu file.
-
.libtool_needed_for(targets) ⇒ Boolean
Check if any of the targets needs libtool.
-
.ninja ⇒ String
Get path to ninja.
-
.output(data) ⇒ Object
Output jitsu build specification as build.ninja file(s).
-
.output_sources(out, sources, target) ⇒ Object
Output build rules for a list of sources.
-
.read(jitsufile) ⇒ Hash
Read a jitsu file and output the build specification.
-
.source_to_ltobject(src) ⇒ String
Convert sourcefile name to corresponding libtool object file name.
-
.source_to_object(src) ⇒ String
Convert sourcefile name to corresponding object file name.
-
.sources_to_ltobjects(srcs) ⇒ Enumerable
Convert a list of sourcefile names to corresponding libtool object file names.
-
.sources_to_objects(srcs) ⇒ Enumerable
Convert a list of sourcefile names to corresponding object file names.
-
.work ⇒ Object
Process jitsufiles in current directory.
Class Method Details
.handle_dynamic_library(out, target, sources, targets) ⇒ Object
Output build rules for one dynamic library target.
for.
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/jitsu.rb', line 196 def self.handle_dynamic_library(out, target, sources, targets) target['cxxflags'] ||= '${cxxflags}' target['cxxflags'] += ' -fPIC' output_sources(out, sources, target) out.write "build #{target['name']}: link #{sources_to_objects(sources).join ' '}" out.write " #{target['dependencies'].join(' ')}" if target['dependencies'] out.write "\n" target['ldflags'] ||= '${ldflags}' target['ldflags'] += " -shared -Wl,-soname,#{target['name']}" out.write " ldflags = #{target['ldflags']}\n" end |
.handle_executable(out, target, sources, targets) ⇒ Object
Output build rules for one executable target.
for.
163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/jitsu.rb', line 163 def self.handle_executable(out, target, sources, targets) output_sources(out, sources, target) libtool = libtool_needed_for targets.select { |tgt| target['dependencies'] and target['dependencies'].include? tgt['name'] } rule = libtool ? "ltlink" : "link" out.write "build #{target['name']}: #{rule} #{sources_to_objects(sources).join ' '}" out.write " #{target['dependencies'].join(' ')}" if target['dependencies'] out.write "\n" out.write " ldflags = #{target['ldflags']}\n" if target['ldflags'] end |
.handle_libtool_library(out, target, sources, targets) ⇒ Object
Output build rules for one libtool library target.
for.
215 216 217 218 219 220 221 222 223 |
# File 'lib/jitsu.rb', line 215 def self.handle_libtool_library(out, target, sources, targets) output_sources(out, sources, target) out.write "build #{target['name']}: ltlink #{sources_to_ltobjects(sources).join ' '}" out.write " #{target['dependencies'].join(' ')}" if target['dependencies'] out.write "\n" target['ldflags'] ||= '${ldflags}' target['ldflags'] += " -rpath /usr/local/lib" out.write " ldflags = #{target['ldflags']}\n" end |
.handle_static_library(out, target, sources, targets) ⇒ Object
Output build rules for one static library target.
for.
182 183 184 185 186 187 |
# File 'lib/jitsu.rb', line 182 def self.handle_static_library(out, target, sources, targets) output_sources(out, sources, target) out.write "build #{target['name']}: archive #{sources_to_objects(sources).join ' '}" out.write " #{target['dependencies'].join(' ')}" if target['dependencies'] out.write "\n" end |
.jitsufile ⇒ String
Get path to jitsu file. Search starting from current working directory upwards.
49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/jitsu.rb', line 49 def self.jitsufile dir = '.' prev = nil until prev and File.(prev) == File.(dir) do candidate = Dir[File.join dir, JITSU_FILE_NAME].first if candidate and File.readable? candidate return candidate.gsub /^\.\//, '' end prev = dir dir = File.join(dir, '..') end end |
.libtool_needed_for(targets) ⇒ Boolean
Check if any of the targets needs libtool.
81 82 83 |
# File 'lib/jitsu.rb', line 81 def self.libtool_needed_for(targets) not targets.select { |target| target['type'] == 'libtool_library' }.empty? end |
.ninja ⇒ String
Get path to ninja.
40 41 42 43 |
# File 'lib/jitsu.rb', line 40 def self.ninja candidates = ENV['PATH'].split(/:/).map { |d| File.join d, 'ninja' } candidates.select { |n| File.executable? n }.first end |
.output(data) ⇒ Object
Output jitsu build specification as build.ninja file(s).
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/jitsu.rb', line 89 def self.output(data) File.open NINJA_FILE_NAME, 'w' do |f| libtool = libtool_needed_for data['targets'] f.write "cxxflags =\nldflags =\ncxx = g++\nld = g++\nar = ar\n" if libtool f.write "libtool = libtool\n" end f.write "\nrule cxx\ndescription = CC ${in}\ndepfile = ${out}.d\ncommand = ${cxx} -MMD -MF ${out}.d ${cxxflags} -c ${in} -o ${out}\n\nrule link\ndescription = LD ${out}\ncommand = ${ld} ${ldflags} -o ${out} ${in}\n\nrule archive\ndescription = AR ${out}\ncommand = ${ar} rT ${out} ${in}\n" if libtool_needed_for data['targets'] f.write "\nrule ltcxx\ndescription = CC ${in}\ndepfile = ${out}.d\ncommand = ${libtool} --quiet --mode=compile ${cxx} -MMD -MF ${out}.d ${cxxflags} -c ${in}\n\nrule ltlink\ndescription = LD ${out}\ncommand = ${libtool} --quiet --mode=link ${ld} ${ldflags} -o ${out} ${in}\n" end data['targets'].each do |target| f.write "\n" sources = target['sources'] Jitsu.send "handle_#{target['type']}".to_sym, f, target, sources, data['targets'] end f.write("\nbuild all: phony || #{data['targets'].map { |t| t['name'] }.join(' ')}\n") end end |
.output_sources(out, sources, target) ⇒ Object
Output build rules for a list of sources.
for.
145 146 147 148 149 150 151 152 153 154 |
# File 'lib/jitsu.rb', line 145 def self.output_sources(out, sources, target) cxxflags = target['cxxflags'] libtool = target['type'] == 'libtool_library' rule = (libtool ? "ltcxx" : "cxx") sources.each do |src| object = (libtool ? source_to_ltobject(src) : source_to_object(src)) out.write "build #{object}: #{rule} #{src}\n" out.write " cxxflags = #{cxxflags}\n" if cxxflags end end |
.read(jitsufile) ⇒ Hash
Read a jitsu file and output the build specification.
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/jitsu.rb', line 66 def self.read(jitsufile) schema = YAML.load_file(File.join(File.dirname(__FILE__), 'schema.yaml')) validator = Kwalify::Validator.new(schema) parser = Kwalify::Yaml::Parser.new(validator) doc = parser.parse(File.read(jitsufile)) if parser.errors and not parser.errors.empty? raise Jitsu::SyntaxError.new(jitsufile, "Syntax errors in Jitsufile", parser.errors) end doc end |
.source_to_ltobject(src) ⇒ String
Convert sourcefile name to corresponding libtool object file name.
245 246 247 |
# File 'lib/jitsu.rb', line 245 def self.source_to_ltobject(src) src.gsub /\.[Cc]\w+$/, '.lo' end |
.source_to_object(src) ⇒ String
Convert sourcefile name to corresponding object file name.
229 230 231 |
# File 'lib/jitsu.rb', line 229 def self.source_to_object(src) src.gsub /\.[Cc]\w+$/, '.o' end |
.sources_to_ltobjects(srcs) ⇒ Enumerable
Convert a list of sourcefile names to corresponding libtool object file names.
254 255 256 |
# File 'lib/jitsu.rb', line 254 def self.sources_to_ltobjects(srcs) srcs.map { |src| source_to_ltobject src } end |
.sources_to_objects(srcs) ⇒ Enumerable
Convert a list of sourcefile names to corresponding object file names.
237 238 239 |
# File 'lib/jitsu.rb', line 237 def self.sources_to_objects(srcs) srcs.map { |src| source_to_object src } end |
.work ⇒ Object
Process jitsufiles in current directory.
33 34 35 |
# File 'lib/jitsu.rb', line 33 def self.work Jitsu.output(Jitsu.read(Jitsu.jitsufile)) end |