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.
@@ -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)
@@ -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