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
@@ -0,0 +1,94 @@
|
|
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
|
+
L::C::CompilerClang = L::C::Compiler.clone
|
26
|
+
|
27
|
+
# The Clang Compiler
|
28
|
+
module L::C::CompilerClang
|
29
|
+
def self.name
|
30
|
+
:clang
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.available?
|
34
|
+
!!find
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.find
|
38
|
+
@exe and return @exe
|
39
|
+
|
40
|
+
@exe = ::C.find_command 'clang'
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.linker
|
44
|
+
:clang
|
45
|
+
end
|
46
|
+
|
47
|
+
@@o_flags = {
|
48
|
+
:none=>'-O0',
|
49
|
+
:some=>'-O1',
|
50
|
+
:full=>'-O3',
|
51
|
+
:max =>'-O4',
|
52
|
+
}
|
53
|
+
@@of_flags = {
|
54
|
+
nil=>[],
|
55
|
+
:speed=>[],
|
56
|
+
:size=>'-Os',
|
57
|
+
}
|
58
|
+
|
59
|
+
def self.generate_flags(opt)
|
60
|
+
f = []
|
61
|
+
|
62
|
+
#f << '-emit-llvm'
|
63
|
+
|
64
|
+
f << (@@o_flags[opt.optimize ] || [])
|
65
|
+
f << (@@o_flags[opt.optimize_for] || [])
|
66
|
+
|
67
|
+
f << opt.include_dirs.map do |d|
|
68
|
+
"-I#{d}"
|
69
|
+
end
|
70
|
+
f << opt.define.map do |k, v|
|
71
|
+
if v
|
72
|
+
# -Dk if v is true else -Dk=v.
|
73
|
+
"-D#{k}#{v.equal?(true)?"":"=#{v}"}"
|
74
|
+
else
|
75
|
+
"-U#{k}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
f.flatten!
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.compile_command(opt, src, obj)
|
83
|
+
[find, '-c', *generate_flags(opt), "-o#{obj}", *src]
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.do_compile_string(opt, str, obj)
|
87
|
+
c = R::Command.new [find, '-c', '-xc', *generate_flags(opt), '-o', obj, '-']
|
88
|
+
c.stdin = str
|
89
|
+
c.run
|
90
|
+
c
|
91
|
+
end
|
92
|
+
end
|
93
|
+
L::C.compilers[:clang] = L::C::CompilerClang
|
94
|
+
D.append(:l_c_compiler, :clang)
|
@@ -0,0 +1,94 @@
|
|
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
|
+
L::C::CompilerGCC = L::C::Compiler.clone
|
26
|
+
|
27
|
+
# GNU Compiler Collection
|
28
|
+
module L::C::CompilerGCC
|
29
|
+
|
30
|
+
def self.name
|
31
|
+
:gcc
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.available?
|
35
|
+
!!find
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.find
|
39
|
+
@exe and return @exe
|
40
|
+
|
41
|
+
@exe = ::C.find_command 'gcc'
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.linker
|
45
|
+
:gcc
|
46
|
+
end
|
47
|
+
|
48
|
+
@@o_flags = {
|
49
|
+
:none=> D[:debug] ? '-Og' : '-O0',
|
50
|
+
:some=>'-O1',
|
51
|
+
:full=>'-O2',
|
52
|
+
:max =>'-O3',
|
53
|
+
}
|
54
|
+
@@of_flags = {
|
55
|
+
nil=>[],
|
56
|
+
:speed=>'-Ofast',
|
57
|
+
:size=>'-Os',
|
58
|
+
}
|
59
|
+
|
60
|
+
def self.generate_flags(opt)
|
61
|
+
f = []
|
62
|
+
|
63
|
+
f << (@@o_flags[opt.optimize ] || [])
|
64
|
+
f << (@@o_flags[opt.optimize_for] || [])
|
65
|
+
|
66
|
+
f << opt.include_dirs.map do |d|
|
67
|
+
"-I#{d}"
|
68
|
+
end
|
69
|
+
f << opt.define.map do |k, v|
|
70
|
+
if v
|
71
|
+
# -Dk if v is true else -Dk=v.
|
72
|
+
"-D#{k}#{v.eql?(true)?"":"=#{v}"}"
|
73
|
+
else
|
74
|
+
"-U#{k}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
f.flatten!
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.compile_command(opt, src, obj)
|
82
|
+
[find, '-c', *generate_flags(opt), "-o#{obj}", *src]
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.do_compile_string(opt, str, obj)
|
86
|
+
c = R::Command.new [find, '-c', '-xc', *generate_flags(opt), '-o', obj, '-']
|
87
|
+
c.stdin = str
|
88
|
+
c.run
|
89
|
+
c
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
L::C.compilers[:gcc] = L::C::CompilerGCC
|
94
|
+
D.append(:l_c_compiler, :gcc)
|
data/lib/rub/l/ld.rb
ADDED
@@ -0,0 +1,254 @@
|
|
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 'valid_array'
|
26
|
+
|
27
|
+
# Linker Library
|
28
|
+
module L::LD
|
29
|
+
# @!scope class
|
30
|
+
# All available linkers.
|
31
|
+
# @return [Hash{Symbol=>Linker}]
|
32
|
+
cattr_reader :linkers
|
33
|
+
@linkers = {}
|
34
|
+
|
35
|
+
# @!scope class
|
36
|
+
# The linker being used.
|
37
|
+
# @return [Linker]
|
38
|
+
cattr_accessor :linker
|
39
|
+
|
40
|
+
# @!scope class
|
41
|
+
# Default optimization level.
|
42
|
+
#
|
43
|
+
# This takes one of four optimization levels. The actual optimization
|
44
|
+
# done is linker dependant. For example, some linker may not have
|
45
|
+
# any optimization so all levels will be equivalent.
|
46
|
+
#
|
47
|
+
# One of the following:
|
48
|
+
# [+:none+] Perform no optimization. This should be fast and debuggable.
|
49
|
+
# [+:some+] Perform light optimization that is pretty fast.
|
50
|
+
# [+:full+] Perform a high level of optimization producing a fast binary.
|
51
|
+
# this may considerably slow down compilation.
|
52
|
+
# [+:max+] Perform all available optimizations. These may be
|
53
|
+
# experimental and very slow.
|
54
|
+
#
|
55
|
+
# This value defaults to +:full+ if +D:debug+ is set, otherwise +:none+.
|
56
|
+
#
|
57
|
+
# @return [Symbol]
|
58
|
+
cattr_accessor :optimize
|
59
|
+
|
60
|
+
# @!scope class
|
61
|
+
# A list of library search directories to be added to the default search
|
62
|
+
# path.
|
63
|
+
#
|
64
|
+
# These paths are searched in order.
|
65
|
+
#
|
66
|
+
# @return [Array<Pathname>]
|
67
|
+
cattr_accessor :library_dirs
|
68
|
+
|
69
|
+
# @!scope class
|
70
|
+
# The default for static linking.
|
71
|
+
#
|
72
|
+
# If set to true shared libraries won't be used. Defaults to false.
|
73
|
+
#
|
74
|
+
# @return [true,false]
|
75
|
+
cattr_accessor :static
|
76
|
+
|
77
|
+
# @!scope class
|
78
|
+
# Default arguments to add to the linker command.
|
79
|
+
#
|
80
|
+
# @note This adds raw arguments to the linker command and is a quick n'
|
81
|
+
# easy way to reduce portability. If you can, use the other
|
82
|
+
# options provided by this class in order to maintain portability.
|
83
|
+
#
|
84
|
+
# @return [Array<String>] A list of arguments to add.
|
85
|
+
cattr_accessor :args
|
86
|
+
|
87
|
+
@optimize = D[:debug] ? :none : :full
|
88
|
+
@library_dirs = []
|
89
|
+
@static = false
|
90
|
+
@args = []
|
91
|
+
|
92
|
+
def self.set_linker(name)
|
93
|
+
self.linker = linkers[name]
|
94
|
+
end
|
95
|
+
|
96
|
+
# An abstraction for a linker.
|
97
|
+
module Linker
|
98
|
+
# The name of the linker.
|
99
|
+
# @return [Symbol]
|
100
|
+
def self.name
|
101
|
+
:default
|
102
|
+
end
|
103
|
+
|
104
|
+
# Is this linker available on this system?
|
105
|
+
#
|
106
|
+
# @return [true,false] true if the linker is available.
|
107
|
+
def self.available?
|
108
|
+
false
|
109
|
+
end
|
110
|
+
|
111
|
+
# Return the linker's builtin library path.
|
112
|
+
#
|
113
|
+
# @return [Array<Pathname>]
|
114
|
+
def self.builtin_library_path
|
115
|
+
@builtin_library_path ||= [
|
116
|
+
'/lib/',
|
117
|
+
'/usr/lib/',
|
118
|
+
'/usr/local/lib/',
|
119
|
+
'~/.local/lib/',
|
120
|
+
].map do |l|
|
121
|
+
C.path(l)
|
122
|
+
end.uniq
|
123
|
+
end
|
124
|
+
|
125
|
+
# Return the path which to search for libraries.
|
126
|
+
#
|
127
|
+
# @return [Array<Pathname>]
|
128
|
+
def self.library_path(opt)
|
129
|
+
opt.library_dirs + builtin_library_path
|
130
|
+
end
|
131
|
+
|
132
|
+
# Generate a command to perform the link.
|
133
|
+
#
|
134
|
+
# @param files [Set<Pathname,String>,Array<Pathname,String>,Pathname,String]
|
135
|
+
# The object files to link.
|
136
|
+
# @param libs [Set<String>,Array<String>,String] Libraries to link with.
|
137
|
+
# @param out [Pathname,String] The output file.
|
138
|
+
# @param format [Symbol] The type of output to produce.
|
139
|
+
# One of:
|
140
|
+
# [+:exe+] An executable binary.
|
141
|
+
# [+:shared+] A shared library.
|
142
|
+
# @param opt [Options] An options object.
|
143
|
+
# @return [Set<Pathname>] The output file.
|
144
|
+
def self.link_command(opt, files, libs, out, format)
|
145
|
+
raise NotImplementedError
|
146
|
+
end
|
147
|
+
|
148
|
+
# Perform a link.
|
149
|
+
#
|
150
|
+
# @param (see link_command)
|
151
|
+
# @return [R::Command] the process that linked the file.
|
152
|
+
def self.do_link(opt, files, libs, out, format)
|
153
|
+
c = R::Command.new(link_command(opt, files, libs, out, format))
|
154
|
+
c.run
|
155
|
+
c
|
156
|
+
end
|
157
|
+
|
158
|
+
# Peform a test link.
|
159
|
+
#
|
160
|
+
# @param (see link_command)
|
161
|
+
# @return [true,false] true if the link succeeded.
|
162
|
+
def self.test_link(opt, files, libs, format)
|
163
|
+
c = do_link(opt, files, libs, File::NULL, format)
|
164
|
+
#p c.success?, c.stdin, c.stdout, c.stderr
|
165
|
+
c.success?
|
166
|
+
end
|
167
|
+
|
168
|
+
@@name_map = {
|
169
|
+
exe: '%s',
|
170
|
+
shared: 'lib%s.so',
|
171
|
+
static: 'lib%s.a',
|
172
|
+
}
|
173
|
+
|
174
|
+
# Generate an appropriate name.
|
175
|
+
#
|
176
|
+
# @param base [String] The basename.
|
177
|
+
# @param type [Symbol] The output format.
|
178
|
+
# @return [String] A suitable name for the output type on the
|
179
|
+
# current machine.
|
180
|
+
def self.full_name(base, type)
|
181
|
+
@@name_map[type] % base
|
182
|
+
end
|
183
|
+
|
184
|
+
# Locate a library.
|
185
|
+
#
|
186
|
+
# Locates the library that would be used with when linking.
|
187
|
+
#
|
188
|
+
# @param name [String] The basename of the library.
|
189
|
+
# @param options [Options] The options to use when linking.
|
190
|
+
# @return [Pathname] The path to the library.
|
191
|
+
def self.find_lib(opt, name)
|
192
|
+
sp = library_path(opt)
|
193
|
+
if name.to_s.include? '/'
|
194
|
+
return C.path name
|
195
|
+
end
|
196
|
+
name = full_name name, (opt.static ? :static : :shared)
|
197
|
+
|
198
|
+
sp.each do |d|
|
199
|
+
l = d + name
|
200
|
+
|
201
|
+
l.exist? and return l
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
R::Tool.load_dir(Pathname.new(__FILE__).realpath.dirname+"ld/linker/")
|
207
|
+
@linkers.keep_if do |n, l|
|
208
|
+
l.available? or next false
|
209
|
+
end
|
210
|
+
|
211
|
+
D[:l_ld_linker].map! {|l| l.to_sym}
|
212
|
+
@linker = D[:l_ld_linker].find {|l| @linkers.has_key? l}
|
213
|
+
@linker = @linkers[@linker]
|
214
|
+
|
215
|
+
class LibraryArray < Array
|
216
|
+
extend ValidArray
|
217
|
+
|
218
|
+
def self.validate(l)
|
219
|
+
L::LD.linker.find_lib(L::LD, l) or raise "Can't find library #{l}"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# Link object files.
|
224
|
+
#
|
225
|
+
# @param src [Set<Pathname,String>,Array<Pathname,String>,Pathname,String]
|
226
|
+
# The object files to link.
|
227
|
+
# @param libs [Set<String>,Array<String>,String] Libraries to link with.
|
228
|
+
# @param name [Pathname,String] The basename of the output file.
|
229
|
+
# @param format [Symbol] The type of output to produce.
|
230
|
+
# One of:
|
231
|
+
# [+:exe+] An executable binary.
|
232
|
+
# [+:shared+] A shared library.
|
233
|
+
# @param linker [Symbol] The linker to use. If nil, use the default.
|
234
|
+
# @return [Pathname] The output file.
|
235
|
+
def self.link(src, libs, name, format: :exe)
|
236
|
+
src = R::Tool.make_set_paths src
|
237
|
+
libs = R::Tool.make_set libs
|
238
|
+
|
239
|
+
libfs = libs.map {|l| linker.find_lib(self, l) or raise "Can't find library #{l}."}
|
240
|
+
|
241
|
+
out = linker.full_name name, format
|
242
|
+
out = R::Env.out_dir + 'l/ld/' + C.unique_segment(src, libs, self) + out
|
243
|
+
|
244
|
+
C::generator(src+libfs, linker.link_command(self, src, libs, out, format), out)
|
245
|
+
|
246
|
+
out
|
247
|
+
end
|
248
|
+
|
249
|
+
def self.initialize_copy(s)
|
250
|
+
super
|
251
|
+
|
252
|
+
self.library_dirs = s.library_dirs.dup
|
253
|
+
end
|
254
|
+
end
|
@@ -0,0 +1,89 @@
|
|
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
|
+
module L::LD
|
26
|
+
LinkerClang = Linker.clone
|
27
|
+
module LinkerClang
|
28
|
+
def self.name
|
29
|
+
:clang
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.available?
|
33
|
+
!!find
|
34
|
+
end
|
35
|
+
|
36
|
+
# Find the linker executable.
|
37
|
+
# @return [Pathname,nil] The path of the executable.
|
38
|
+
def self.find
|
39
|
+
C.find_command 'clang'
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.link_command(opt, files, libs, out, format)
|
43
|
+
files = R::Tool.make_set_paths files
|
44
|
+
libs = R::Tool.make_set libs
|
45
|
+
out = C.path(out)
|
46
|
+
|
47
|
+
c = [find, "-o#{out}"]
|
48
|
+
|
49
|
+
c << opt.args
|
50
|
+
|
51
|
+
c << case format
|
52
|
+
when :exe
|
53
|
+
[]
|
54
|
+
when :shared
|
55
|
+
['-shared']
|
56
|
+
else
|
57
|
+
raise "Unknown/unsupported output #{format}."
|
58
|
+
end
|
59
|
+
|
60
|
+
c << case opt.optimize
|
61
|
+
when :none
|
62
|
+
'-O0'
|
63
|
+
when :some
|
64
|
+
'-O2'
|
65
|
+
when :full
|
66
|
+
'-O3'
|
67
|
+
when :max
|
68
|
+
'-O4'
|
69
|
+
else
|
70
|
+
raise "Invalid optimization level #{opt.optimize}."
|
71
|
+
end
|
72
|
+
|
73
|
+
c << if opt.static
|
74
|
+
'-static'
|
75
|
+
else
|
76
|
+
[]
|
77
|
+
end
|
78
|
+
|
79
|
+
c << opt.library_dirs.map{|d| "-L#{d}"}
|
80
|
+
|
81
|
+
#c << libs.map{|l| "-l#{l}" }
|
82
|
+
c << libs.map{|l| "#{l}" }
|
83
|
+
c << files.to_a
|
84
|
+
|
85
|
+
c.flatten
|
86
|
+
end
|
87
|
+
end
|
88
|
+
L::LD.linkers[:clang] = LinkerClang
|
89
|
+
end
|