rub 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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