rub 0.4.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.
- checksums.yaml +7 -0
- data/lib/rub/c.rb +276 -0
- data/lib/rub/d.rb +252 -0
- data/lib/rub/dirs.rb +30 -0
- data/lib/rub/help.rb +178 -0
- data/lib/rub/init.rb +91 -0
- data/lib/rub/l.rb +40 -0
- data/lib/rub/l/c.rb +476 -0
- data/lib/rub/l/c/compiler/clang.rb +94 -0
- data/lib/rub/l/c/compiler/gcc.rb +94 -0
- data/lib/rub/l/ld.rb +254 -0
- data/lib/rub/l/ld/linker/clang.rb +89 -0
- data/lib/rub/l/ld/linker/gcc.rb +89 -0
- data/lib/rub/l/ld/linker/ld.rb +91 -0
- data/lib/rub/l/template.rb +92 -0
- data/lib/rub/l/test.rb +256 -0
- data/lib/rub/l/util.rb +163 -0
- data/lib/rub/r.rb +42 -0
- data/lib/rub/r/command.rb +293 -0
- data/lib/rub/r/env.rb +71 -0
- data/lib/rub/r/i/commandline.rb +192 -0
- data/lib/rub/r/i/runner.rb +78 -0
- data/lib/rub/r/persist.rb +71 -0
- data/lib/rub/r/target.rb +250 -0
- data/lib/rub/r/targetgenerator.rb +80 -0
- data/lib/rub/r/tool.rb +159 -0
- data/lib/rub/r/version-git.rb +62 -0
- data/lib/rub/r/version.rb +145 -0
- metadata +127 -0
data/lib/rub/l/util.rb
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
# Copyright 2013 Kevin Cox
|
2
|
+
|
3
|
+
################################################################################
|
4
|
+
# #
|
5
|
+
# This software is provided 'as-is', without any express or implied #
|
6
|
+
# warranty. In no event will the authors be held liable for any damages #
|
7
|
+
# arising from the use of this software. #
|
8
|
+
# #
|
9
|
+
# Permission is granted to anyone to use this software for any purpose, #
|
10
|
+
# including commercial applications, and to alter it and redistribute it #
|
11
|
+
# freely, subject to the following restrictions: #
|
12
|
+
# #
|
13
|
+
# 1. The origin of this software must not be misrepresented; you must not #
|
14
|
+
# claim that you wrote the original software. If you use this software in #
|
15
|
+
# a product, an acknowledgment in the product documentation would be #
|
16
|
+
# appreciated but is not required. #
|
17
|
+
# #
|
18
|
+
# 2. Altered source versions must be plainly marked as such, and must not be #
|
19
|
+
# misrepresented as being the original software. #
|
20
|
+
# #
|
21
|
+
# 3. This notice may not be removed or altered from any source distribution. #
|
22
|
+
# #
|
23
|
+
################################################################################
|
24
|
+
|
25
|
+
require 'singleton'
|
26
|
+
|
27
|
+
D.resolve_path :pefix
|
28
|
+
|
29
|
+
# General purpose build tools.
|
30
|
+
module L::Util
|
31
|
+
class TargetUninstall < C::TargetTag
|
32
|
+
include Singleton
|
33
|
+
|
34
|
+
def initialize
|
35
|
+
super :uninstall
|
36
|
+
@files = Set.new
|
37
|
+
|
38
|
+
register
|
39
|
+
end
|
40
|
+
|
41
|
+
def add(f)
|
42
|
+
f = R::Tool.make_set_paths f
|
43
|
+
|
44
|
+
@files.merge f
|
45
|
+
|
46
|
+
f
|
47
|
+
end
|
48
|
+
|
49
|
+
def build
|
50
|
+
R::run(['rm', '-fv']+@files.to_a, "Removing installed files.", importance: :med)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
TargetUninstall.instance.description = 'Remove installed targets.' # Make the target.
|
54
|
+
|
55
|
+
# Uninstall a file.
|
56
|
+
#
|
57
|
+
# Adds the file to the :uninstall tag.
|
58
|
+
#
|
59
|
+
# @param what [Set<Pathname,String>,Array<Pathname,String>,Pathname,String]
|
60
|
+
# The files to remove.
|
61
|
+
# @return [void]
|
62
|
+
def self.uninstall(what)
|
63
|
+
what = R::Tool.make_set_paths what
|
64
|
+
|
65
|
+
what.each do |f|
|
66
|
+
TargetUninstall.instance.add f
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Create a link
|
71
|
+
#
|
72
|
+
# @param target [Pathname,String] The file the link points to.
|
73
|
+
# @param name [Pathname,String] The location of the link.
|
74
|
+
# @param type [:sym,:hard] The type of link to create.
|
75
|
+
# @param expand_target [true,false] Whether or not to make target an
|
76
|
+
# absolute path. This allows the creation
|
77
|
+
# of relative links.
|
78
|
+
# @return [Pathname] The path of the link.
|
79
|
+
def self.link(target, name, type = :sym, expand_target: true)
|
80
|
+
target = expand_target ? C.path(target) : target
|
81
|
+
name = C.path name
|
82
|
+
|
83
|
+
C.generator(
|
84
|
+
[], #target,
|
85
|
+
['ln', '-f', (type == :sym ? '-s' : nil), target, name].compact,
|
86
|
+
name,
|
87
|
+
desc: 'Linking'
|
88
|
+
)
|
89
|
+
name
|
90
|
+
end
|
91
|
+
|
92
|
+
# Install a file to a specific location.
|
93
|
+
#
|
94
|
+
# @see #install
|
95
|
+
#
|
96
|
+
# Similar to {#install} but the basename is not used as the name in the new
|
97
|
+
# location. If from is a dirtectory it is installed and renamed but it's
|
98
|
+
# contents are preserved with the same names.
|
99
|
+
#
|
100
|
+
# @param from [Set<Pathname,String>,Array<Pathname,String>,Pathname,String]
|
101
|
+
# The files to install.
|
102
|
+
# @param to [Pathname,String] Where to install them. If not
|
103
|
+
# absolute it is relative to +D:prefix+
|
104
|
+
# @param mode [Numeric] The permissions (specified in base ten) for the
|
105
|
+
# file. If nil the current permissions are kept.
|
106
|
+
# @param require [Set<Pathname,String>,Array<Pathname,String>,Pathname,String]
|
107
|
+
# Files that must be present before installing the file.
|
108
|
+
# @return [Array<Pathname>] The installed files.
|
109
|
+
def self.install_to(from, to, mode: nil, require: [])
|
110
|
+
from = C.path(from)
|
111
|
+
to = Pathname.new(to).expand_path(D :prefix)
|
112
|
+
|
113
|
+
if from.directory?
|
114
|
+
return install(from.children, to)
|
115
|
+
end
|
116
|
+
|
117
|
+
C.generator(
|
118
|
+
Set[from].merge(require),
|
119
|
+
['install', "-D#{mode!=nil ? "m#{mode}" : "" }", from, to],
|
120
|
+
to,
|
121
|
+
desc: 'Installing'
|
122
|
+
).each do |o|
|
123
|
+
C.tag(:all ).require(from)
|
124
|
+
C.tag(:install).require(to)
|
125
|
+
end
|
126
|
+
uninstall to
|
127
|
+
|
128
|
+
Set[from]
|
129
|
+
end
|
130
|
+
|
131
|
+
# Install a file
|
132
|
+
#
|
133
|
+
# Installs +what+ into the directory +where+. Source files are added to
|
134
|
+
# the +=all+ tag and installed files are added to the +=install+ tag.
|
135
|
+
#
|
136
|
+
# @param what [Set<Pathname,String>,Array<Pathname,String>,Pathname,String]
|
137
|
+
# The files to install.
|
138
|
+
# @param where [Pathname,String] The directory to install them to. If not
|
139
|
+
# absolute it is relative to +D:prefix+
|
140
|
+
# @param mode [Numeric] The permissions (specified in base ten) for the
|
141
|
+
# file. If nil the current permissions are kept.
|
142
|
+
# @param require [Set<Pathname,String>,Array<Pathname,String>,Pathname,String]
|
143
|
+
# Files that must be present before installing the file.
|
144
|
+
# @return [Array<Pathname>] The installed files.
|
145
|
+
#
|
146
|
+
# @example
|
147
|
+
# exe = L::C.program(srcs, ['pthread'], 'bitmonitor-test')
|
148
|
+
# L::Util.install exe, 'bin/', mode: 755
|
149
|
+
#
|
150
|
+
def self.install(what, where, mode: nil, require: [])
|
151
|
+
what = R::Tool.make_set_paths what
|
152
|
+
where = Pathname.new(where)
|
153
|
+
require = R::Tool.make_set_paths require
|
154
|
+
|
155
|
+
what.map do |f|
|
156
|
+
if f.directory?
|
157
|
+
install(f.children, where+f.basename)
|
158
|
+
else
|
159
|
+
install_to(f, where+f.basename)
|
160
|
+
end
|
161
|
+
end.flatten.to_set
|
162
|
+
end
|
163
|
+
end
|
data/lib/rub/r.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Copyright 2013 Kevin Cox
|
2
|
+
|
3
|
+
################################################################################
|
4
|
+
# #
|
5
|
+
# This software is provided 'as-is', without any express or implied #
|
6
|
+
# warranty. In no event will the authors be held liable for any damages #
|
7
|
+
# arising from the use of this software. #
|
8
|
+
# #
|
9
|
+
# Permission is granted to anyone to use this software for any purpose, #
|
10
|
+
# including commercial applications, and to alter it and redistribute it #
|
11
|
+
# freely, subject to the following restrictions: #
|
12
|
+
# #
|
13
|
+
# 1. The origin of this software must not be misrepresented; you must not #
|
14
|
+
# claim that you wrote the original software. If you use this software in #
|
15
|
+
# a product, an acknowledgment in the product documentation would be #
|
16
|
+
# appreciated but is not required. #
|
17
|
+
# #
|
18
|
+
# 2. Altered source versions must be plainly marked as such, and must not be #
|
19
|
+
# misrepresented as being the original software. #
|
20
|
+
# #
|
21
|
+
# 3. This notice may not be removed or altered from any source distribution. #
|
22
|
+
# #
|
23
|
+
################################################################################
|
24
|
+
|
25
|
+
# Rub internals.
|
26
|
+
#
|
27
|
+
# Internal functions intended for library developers only.
|
28
|
+
module R; end
|
29
|
+
module R::I; end
|
30
|
+
|
31
|
+
require_relative 'r/tool'
|
32
|
+
require_relative 'r/env'
|
33
|
+
require_relative 'r/version'
|
34
|
+
require_relative 'r/command'
|
35
|
+
|
36
|
+
require_relative 'r/i/runner'
|
37
|
+
require_relative 'r/i/commandline'
|
38
|
+
|
39
|
+
require_relative 'r/persist'
|
40
|
+
|
41
|
+
require_relative 'r/target'
|
42
|
+
require_relative 'r/targetgenerator'
|
@@ -0,0 +1,293 @@
|
|
1
|
+
# Copyright 2013 Kevin Cox
|
2
|
+
|
3
|
+
################################################################################
|
4
|
+
# #
|
5
|
+
# This software is provided 'as-is', without any express or implied #
|
6
|
+
# warranty. In no event will the authors be held liable for any damages #
|
7
|
+
# arising from the use of this software. #
|
8
|
+
# #
|
9
|
+
# Permission is granted to anyone to use this software for any purpose, #
|
10
|
+
# including commercial applications, and to alter it and redistribute it #
|
11
|
+
# freely, subject to the following restrictions: #
|
12
|
+
# #
|
13
|
+
# 1. The origin of this software must not be misrepresented; you must not #
|
14
|
+
# claim that you wrote the original software. If you use this software in #
|
15
|
+
# a product, an acknowledgment in the product documentation would be #
|
16
|
+
# appreciated but is not required. #
|
17
|
+
# #
|
18
|
+
# 2. Altered source versions must be plainly marked as such, and must not be #
|
19
|
+
# misrepresented as being the original software. #
|
20
|
+
# #
|
21
|
+
# 3. This notice may not be removed or altered from any source distribution. #
|
22
|
+
# #
|
23
|
+
################################################################################
|
24
|
+
|
25
|
+
# A high level interface for executing commands.
|
26
|
+
class R::Command
|
27
|
+
# @!attribute [r] cmd
|
28
|
+
# @return [Array<String>] The command to run.
|
29
|
+
attr_reader :cmd
|
30
|
+
|
31
|
+
# @!attribute [r] env
|
32
|
+
#
|
33
|
+
# Control the environment of the spawned process. Values from this
|
34
|
+
# hash will be added to the processes environment. If a value is
|
35
|
+
# nil the key will be removed from the processes environment. These
|
36
|
+
# values are overlaid on the existing environment unless {#clearenv}
|
37
|
+
# is set.
|
38
|
+
#
|
39
|
+
# @return [Hash{String=>String,nil}] The environment variables.
|
40
|
+
attr_reader :env
|
41
|
+
|
42
|
+
# @!attribute [rw] stdin
|
43
|
+
# @return [String] The string to use as input to the command.
|
44
|
+
attr_accessor :stdin
|
45
|
+
# @!attribute [r] stdout
|
46
|
+
# @return [String] The output produced by the command.
|
47
|
+
# @!attribute [r] stderr
|
48
|
+
# @return [String] The error output produced by the command.
|
49
|
+
attr_reader :stdout, :stderr
|
50
|
+
|
51
|
+
# @!attribute [r] status
|
52
|
+
#
|
53
|
+
# Available after {#block} has returned.
|
54
|
+
#
|
55
|
+
# @return [Process::Status,nil] The processes exit status.
|
56
|
+
attr_reader :status
|
57
|
+
|
58
|
+
# @!attribute [rw] clearenv
|
59
|
+
# If set, the executed command will not inherit environment variables
|
60
|
+
# from Rub. Only the values in {#env} will be present in the
|
61
|
+
# environment.
|
62
|
+
#
|
63
|
+
# Defaults to false.
|
64
|
+
#
|
65
|
+
# @return [true,false] If true don't inherit the environment.
|
66
|
+
attr_accessor :clearenv
|
67
|
+
# @!attribute [rw] mergeouts
|
68
|
+
# @return [true,false] If true merge {#stdout} into {#stderr}.
|
69
|
+
attr_accessor :mergeouts
|
70
|
+
|
71
|
+
# Create a new command to run.
|
72
|
+
#
|
73
|
+
# @param cmd [Array<String,#to_s>] The command that will be run.
|
74
|
+
def initialize(cmd)
|
75
|
+
@env = {}
|
76
|
+
|
77
|
+
@clearenv = false
|
78
|
+
@mergeouts = false
|
79
|
+
|
80
|
+
@cmd = cmd.map{|a| a.to_s}
|
81
|
+
end
|
82
|
+
|
83
|
+
# Start the command.
|
84
|
+
#
|
85
|
+
# Executes the command. The command will run in the background. If you
|
86
|
+
# want to wait for the command to complete call {#block}.
|
87
|
+
#
|
88
|
+
# @note Calling this command a second time before {#block} returns
|
89
|
+
# produces undefined behaviour. A {Command} can be run multiple
|
90
|
+
# times but it must finish before being run again.
|
91
|
+
def start
|
92
|
+
@status = nil
|
93
|
+
|
94
|
+
@stdinr, @stdinw = IO.pipe
|
95
|
+
@stdoutr, @stdoutw = IO.pipe
|
96
|
+
@stderrr, @stderrw = IO.pipe
|
97
|
+
|
98
|
+
@stdout = ""
|
99
|
+
@stderr = ""
|
100
|
+
@status = nil
|
101
|
+
|
102
|
+
args = [
|
103
|
+
@env,
|
104
|
+
*@cmd.map{|a| a.to_s},
|
105
|
+
:unsetenv_others=>@clearenv,
|
106
|
+
:in =>@stdinr,
|
107
|
+
:out=>@stdoutw,
|
108
|
+
:err=>(@mergeouts?@stdoutw:@stderrw),
|
109
|
+
]
|
110
|
+
|
111
|
+
#p "args: #{args}"
|
112
|
+
@pid = spawn(*args)
|
113
|
+
|
114
|
+
@stdinr.close
|
115
|
+
|
116
|
+
@stdinw.write @stdin
|
117
|
+
|
118
|
+
@stdinw.close
|
119
|
+
@stdoutw.close
|
120
|
+
@stderrw.close
|
121
|
+
|
122
|
+
@pid
|
123
|
+
end
|
124
|
+
|
125
|
+
# Run the command and block until completion.
|
126
|
+
#
|
127
|
+
# Equivalent to calling {#start} then {#block}.
|
128
|
+
#
|
129
|
+
# @return [true,false] Whether the command completed successfully.
|
130
|
+
def run
|
131
|
+
start
|
132
|
+
block
|
133
|
+
end
|
134
|
+
|
135
|
+
# Wait for a command to finish.
|
136
|
+
#
|
137
|
+
# Block until a currently running process finishes. Behaviour is
|
138
|
+
# undefined if the command is not currently running ({#start} has been
|
139
|
+
# called since the last {#block}).
|
140
|
+
#
|
141
|
+
# After this call returns {#status} will be available.
|
142
|
+
#
|
143
|
+
# @return [true,false] Whether the command completed successfully.
|
144
|
+
def block
|
145
|
+
@stdout = @stdoutr.read
|
146
|
+
@stderr = @stderrr.read
|
147
|
+
|
148
|
+
#puts "Blocking on #{@pid} #{@cmd.join' '}"
|
149
|
+
pid, @status = Process.wait2 @pid
|
150
|
+
#puts "Done #{@cmd.join' '}"
|
151
|
+
|
152
|
+
@stdoutr.close
|
153
|
+
@stderrr.close
|
154
|
+
|
155
|
+
success?
|
156
|
+
end
|
157
|
+
|
158
|
+
# Check if the command was successful
|
159
|
+
#
|
160
|
+
# @return [true,false] true if the command executed successfully
|
161
|
+
# otherwise false.
|
162
|
+
# @note If the command has not been executed or has not completed this
|
163
|
+
# returns false.
|
164
|
+
def success?
|
165
|
+
!!( @status and @status.exitstatus == 0 )
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Run a command as part of the build.
|
170
|
+
#
|
171
|
+
# The command will be run and status will be printed.
|
172
|
+
#
|
173
|
+
# @param cmd [Array<String,#to_s>] The command to execute.
|
174
|
+
# @param desc [String] The verb describing what the command is doing.
|
175
|
+
# @param importance [Symbol] The importance of this step. Affects printing.
|
176
|
+
# @return [true,false] true if the command was successful.
|
177
|
+
def R.run(cmd, desc, importance: :med)
|
178
|
+
cmd = cmd.dup
|
179
|
+
|
180
|
+
bs = R::BuildStep.new
|
181
|
+
bs.desc = desc
|
182
|
+
bs.cmd = cmd
|
183
|
+
bs.importance = importance
|
184
|
+
|
185
|
+
cpath = C.find_command cmd[0]
|
186
|
+
if not cpath
|
187
|
+
raise "Could not find #{cmd[0]}. Please install it or add it to your path."
|
188
|
+
end
|
189
|
+
cmd[0] = cpath
|
190
|
+
cmd.map!{|a| a.to_s}
|
191
|
+
|
192
|
+
c = R::Command.new(cmd)
|
193
|
+
c.mergeouts = true
|
194
|
+
|
195
|
+
c.run
|
196
|
+
|
197
|
+
bs.out = c.stdout
|
198
|
+
bs.status = c.status.exitstatus
|
199
|
+
|
200
|
+
bs.print
|
201
|
+
|
202
|
+
c.success?
|
203
|
+
end
|
204
|
+
|
205
|
+
# Manages reporting build progress.
|
206
|
+
class R::BuildStep
|
207
|
+
# The verb describing this step.
|
208
|
+
# @return [String]
|
209
|
+
attr_accessor :desc
|
210
|
+
|
211
|
+
# The command to execute.
|
212
|
+
# @return [Array<String>]
|
213
|
+
attr_accessor :cmd
|
214
|
+
|
215
|
+
# The command output.
|
216
|
+
# @return [String]
|
217
|
+
attr_accessor :out
|
218
|
+
|
219
|
+
# The exit status of the command.
|
220
|
+
# @return [Process::Status]
|
221
|
+
attr_accessor :status
|
222
|
+
|
223
|
+
# The command's importance.
|
224
|
+
# @return [Symbol] :low, :medium or :high
|
225
|
+
attr_reader :importance
|
226
|
+
|
227
|
+
# Set the command's importance.
|
228
|
+
# @param i [Symbol] :low, :medium or :high
|
229
|
+
# @return [Symbol] +i+
|
230
|
+
def importance=(i)
|
231
|
+
@importance = i
|
232
|
+
case i
|
233
|
+
when :low
|
234
|
+
@importancei = 1
|
235
|
+
when :med
|
236
|
+
@importancei = 2
|
237
|
+
when :high
|
238
|
+
@importancei = 3
|
239
|
+
else
|
240
|
+
$stderr.puts "Unknown importance #{i.inspect}, defaulting to :high."
|
241
|
+
@importancei = 3
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
# Constructor
|
246
|
+
#
|
247
|
+
# @param cmd [Array<String>] The command executed.
|
248
|
+
# @param out [String] The output generated.
|
249
|
+
# @param desc [String] A verb describing the event.
|
250
|
+
def initialize(cmd=[], out="", desc="", status=0)
|
251
|
+
@cmd = cmd
|
252
|
+
@out = out
|
253
|
+
@desc = desc
|
254
|
+
@status = status
|
255
|
+
|
256
|
+
# For some reason self is needed.
|
257
|
+
self.importance = :high
|
258
|
+
end
|
259
|
+
|
260
|
+
# Format the command.
|
261
|
+
#
|
262
|
+
# Format's the command in the prettiest way possible. Theoretically
|
263
|
+
# this command could be pasted into a shell and execute the desired
|
264
|
+
# command.
|
265
|
+
#
|
266
|
+
# @param cmd [Array<String>] The command.
|
267
|
+
def format_cmd(cmd)
|
268
|
+
cmd.map do |e|
|
269
|
+
if /[~`!#$&*(){};'"]/ =~ e
|
270
|
+
"'#{e.sub(/['"]/, '\\\1')}'"
|
271
|
+
else
|
272
|
+
e
|
273
|
+
end
|
274
|
+
end.join(' ')
|
275
|
+
end
|
276
|
+
|
277
|
+
# Print the result.
|
278
|
+
def print
|
279
|
+
@importancei < 2 and return
|
280
|
+
|
281
|
+
puts "\e[#{status==0 ? '' : '31;'}1m#{@desc}\e[0m"
|
282
|
+
puts format_cmd @cmd unless @cmd.empty?
|
283
|
+
Kernel::print @out
|
284
|
+
|
285
|
+
if status != 0
|
286
|
+
if cmd.empty?
|
287
|
+
puts "\e[31;1mProcess failed.\e[0m"
|
288
|
+
else
|
289
|
+
puts "\e[31;1mProcess returned status #{status}\e[0m"
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|