metacc 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb94d9b47a11ec5a78ea57ae19417e6423287918287f675e43579af8015e4c63
4
- data.tar.gz: b1237b3e41f2ae7ae68066441d742892ca77fd0427dc3e7b8f02b7f92049e535
3
+ metadata.gz: d68166f1cf0263814b009c61e2b615ee36521656734bb4ef0b0e48677751fafa
4
+ data.tar.gz: 12133182cb6f8b899714eb7fdbc95868ecdbfd40fe80bbe43084ed79d0fa5e88
5
5
  SHA512:
6
- metadata.gz: 4774d4160c9939259634b2625b28a2975360c477c56c53ac689b4208defb698c4fbcbccf829f540583dfb94cf801fc62664e94cc900f52c64c28bfd6f763247c
7
- data.tar.gz: dfd5493d3789ea3f18dbd1d7a6a15c345fe6eaeb262e022af7a79039bdd7b2707416312fc08e1ca86b333d91520dbb41457f6be5006d30157af934d4fe8b1497
6
+ metadata.gz: d3257e9318b06bfdc812d3a344dc3bece65e22199e4bbc68f3c5f9867593d8b1c4fa8e9376078abf0a056d75f6fa4a8782716152d50f24e6c0a314632f27d3d1
7
+ data.tar.gz: c413d78b53e7a7486a895e1595ec064173cca98235cd35ae595dcd31af9f95b4c526ce8c47b452b53955615ba0166e341a3b9e071508d457580479ca4397fb1f
data/lib/metacc/cli.rb CHANGED
@@ -12,28 +12,28 @@ module MetaCC
12
12
  class CLI
13
13
 
14
14
  WARNING_CONFIGS = {
15
- "all" => :warn_all,
15
+ "all" => :warn_all,
16
16
  "error" => :warn_error
17
17
  }
18
18
 
19
19
  SANITIZERS = {
20
- nil => :sanitize_default,
20
+ nil => :sanitize_default,
21
21
  "memory" => :sanitize_memory,
22
- "thread" => :sanitize_thread,
22
+ "thread" => :sanitize_thread
23
23
  }
24
24
 
25
25
  TARGETS = {
26
26
  "sse4.2" => :sse4_2,
27
- "avx" => :avx,
28
- "avx2" => :avx2,
27
+ "avx" => :avx,
28
+ "avx2" => :avx2,
29
29
  "avx512" => :avx512,
30
30
  "native" => :native
31
31
  }.freeze
32
32
 
33
33
  STANDARDS = {
34
- "c11" => :c11,
35
- "c17" => :c17,
36
- "c23" => :c23,
34
+ "c11" => :c11,
35
+ "c17" => :c17,
36
+ "c23" => :c23,
37
37
  "c++11" => :cxx11,
38
38
  "c++14" => :cxx14,
39
39
  "c++17" => :cxx17,
@@ -44,11 +44,11 @@ module MetaCC
44
44
 
45
45
  # Maps --x<name> CLI option names to xflags toolchain-class keys.
46
46
  XFLAGS = {
47
- "xmsvc" => MSVC,
48
- "xgnu" => GNU,
49
- "xclang" => Clang,
47
+ "xmsvc" => MSVC,
48
+ "xgnu" => GNU,
49
+ "xclang" => Clang,
50
50
  "xclangcl" => ClangCL,
51
- "xtinycc" => TinyCC
51
+ "xtinycc" => TinyCC
52
52
  }.freeze
53
53
 
54
54
  def initialize(driver: Driver.new)
@@ -128,7 +128,7 @@ module MetaCC
128
128
  "Enable sanitizer(s)",
129
129
  " --sanitize => address, undefined, leak",
130
130
  " --sanitize=memory => memory",
131
- " --sanitize=thread => thread",
131
+ " --sanitize=thread => thread"
132
132
  ) do |value|
133
133
  options[:flags] << SANITIZERS[value]
134
134
  end
@@ -142,10 +142,10 @@ module MetaCC
142
142
  parser.on("--lto", "Enable link time optimization") do
143
143
  options[:flags] << :lto
144
144
  end
145
- parser.on("--omit-frame-pointer") do |value|
145
+ parser.on("--omit-frame-pointer") do
146
146
  options[:flags] << :omit_frame_pointer
147
147
  end
148
- parser.on("--strict-aliasing") do |value|
148
+ parser.on("--strict-aliasing") do
149
149
  options[:flags] << :strict_aliasing
150
150
  end
151
151
 
@@ -155,13 +155,13 @@ module MetaCC
155
155
  parser.on("-m", "--arch=ARCH", "Target architecture") do |value|
156
156
  options[:flags] << TARGETS[value]
157
157
  end
158
- parser.on("--pic", "Generate position independent code") do |value|
158
+ parser.on("--pic", "Generate position independent code") do
159
159
  options[:flags] << :pic
160
160
  end
161
- parser.on("--no-rtti", "Disable runtime type information") do |value|
161
+ parser.on("--no-rtti", "Disable runtime type information") do
162
162
  options[:flags] << :no_rtti
163
163
  end
164
- parser.on("--no-exceptions", "Disable exceptions (and unwinding info)") do |value|
164
+ parser.on("--no-exceptions", "Disable exceptions (and unwinding info)") do
165
165
  options[:flags] << :no_exceptions
166
166
  end
167
167
 
@@ -171,10 +171,10 @@ module MetaCC
171
171
  parser.on("--static", "Produce a static library") do
172
172
  options[:flags] << :static
173
173
  end
174
- parser.on("--shared", "Produce a shared library") do |value|
174
+ parser.on("--shared", "Produce a shared library") do
175
175
  options[:flags] << :shared
176
176
  end
177
- parser.on("--shared-compat", "Produce a shared library with full LD_PRELOAD compatability") do |value|
177
+ parser.on("--shared-compat", "Produce a shared library with full LD_PRELOAD compatability") do
178
178
  options[:flags] << :shared_compat
179
179
  end
180
180
  parser.on("-c", "Compile only (produce object files without linking)") do
@@ -216,23 +216,28 @@ module MetaCC
216
216
 
217
217
  def validate_options!(flags, output_path, link:, run:)
218
218
  if !link && output_path
219
- raise OptionParser::InvalidOption, "cannot specify output path (-o) in compile only mode (-c)"
219
+ raise OptionParser::InvalidOption,
220
+ "cannot specify output path (-o) in compile only mode (-c)"
220
221
  end
221
222
 
222
223
  if link && !output_path
223
- raise OptionParser::InvalidOption, "must specify an output path (-o)"
224
+ raise OptionParser::InvalidOption,
225
+ "must specify an output path (-o)"
224
226
  end
225
227
 
226
228
  if run && (!link || %i[static shared shared_compat].any? { |f| flags.include?(f) })
227
- raise OptionParser::InvalidOption, "--run cannot be used with -c, --static, --shared, or --shared-compat"
229
+ raise OptionParser::InvalidOption,
230
+ "--run cannot be used with -c, --static, --shared, or --shared-compat"
228
231
  end
229
232
 
230
233
  if !link && %i[static shared shared_compat].any? { |f| flags.include?(f) }
231
- raise OptionParser::InvalidOption, "compile only mode (-c) cannot be used with --static, --shared, or --shared-compat"
234
+ raise OptionParser::InvalidOption,
235
+ "compile only mode (-c) cannot be used with --static, --shared, or --shared-compat"
232
236
  end
233
237
 
234
238
  if flags.include?(:debug_info) && flags.include?(:strip)
235
- raise OptionParser::InvalidOption, "--debug-info (-g) cannot be combined with --strip (-s)"
239
+ raise OptionParser::InvalidOption,
240
+ "--debug-info (-g) cannot be combined with --strip (-s)"
236
241
  end
237
242
  end
238
243
 
@@ -246,9 +251,9 @@ module MetaCC
246
251
  options.delete(:libs)
247
252
  result = @driver.compile(input_paths, **options)
248
253
  end
249
- if options[:dry_run]
250
- puts result.map { |cmd| cmd.join(" ") }
251
- end
254
+ return unless options[:dry_run]
255
+
256
+ puts(result.map { |cmd| cmd.join(" ") })
252
257
  end
253
258
 
254
259
  end
data/lib/metacc/driver.rb CHANGED
@@ -21,18 +21,23 @@ module MetaCC
21
21
  DBG_SANITIZE_FLAGS = Set.new(%i[sanitize_default sanitize_memory sanitize_thread]).freeze
22
22
 
23
23
  ALL_FLAGS = Set.new([
24
- *%i[
25
- warn_all warn_error
26
- debug_info
27
- omit_frame_pointer strict_aliasing
28
- no_rtti no_exceptions
29
- pic shared shared_compat static strip
30
- ],
31
- *LANGUAGE_STD_FLAGS,
32
- *ARCHITECTURE_FLAGS,
33
- *OPTIMIZATION_FLAGS,
34
- *DBG_SANITIZE_FLAGS
35
- ]).freeze
24
+ :warn_all,
25
+ :warn_error,
26
+ :debug_info,
27
+ :omit_frame_pointer,
28
+ :strict_aliasing,
29
+ :no_rtti,
30
+ :no_exceptions,
31
+ :pic,
32
+ :shared,
33
+ :shared_compat,
34
+ :static,
35
+ :strip,
36
+ *LANGUAGE_STD_FLAGS,
37
+ *ARCHITECTURE_FLAGS,
38
+ *OPTIMIZATION_FLAGS,
39
+ *DBG_SANITIZE_FLAGS
40
+ ]).freeze
36
41
 
37
42
  # The detected toolchain (a Toolchain subclass instance).
38
43
  attr_reader :toolchain
@@ -62,13 +67,13 @@ module MetaCC
62
67
  # @raise [CompileError] if the underlying toolchain executable returns a non-zero exit status
63
68
  def compile(
64
69
  input_files,
65
- flags: [],
66
- xflags: {},
70
+ flags: [],
71
+ xflags: {},
67
72
  include_paths: [],
68
- defs: [],
69
- env: {},
70
- working_dir: ".",
71
- dry_run: false
73
+ defs: [],
74
+ env: {},
75
+ working_dir: ".",
76
+ dry_run: false
72
77
  )
73
78
  flags = translate_flags(flags)
74
79
  flags.concat(xflags[@toolchain.class] || [])
@@ -105,18 +110,18 @@ module MetaCC
105
110
  def compile_and_link(
106
111
  input_files,
107
112
  output_path,
108
- flags: [],
109
- xflags: {},
113
+ flags: [],
114
+ xflags: {},
110
115
  include_paths: [],
111
- defs: [],
112
- link_paths: [],
113
- libs: [],
114
- env: {},
115
- working_dir: ".",
116
- dry_run: false
116
+ defs: [],
117
+ link_paths: [],
118
+ libs: [],
119
+ env: {},
120
+ working_dir: ".",
121
+ dry_run: false
117
122
  )
118
- output_type = if flags.include?(:shared) then :shared
119
- elsif flags.include?(:static) then :static
123
+ output_type = if flags.include?(:shared) then :shared
124
+ elsif flags.include?(:static) then :static
120
125
  else :executable
121
126
  end
122
127
  output_path = apply_default_extension(output_path, output_type)
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rbconfig"
4
+
5
+ module MetaCC
6
+
7
+ module Platform
8
+
9
+ def self.windows?
10
+ @windows ||= RbConfig::CONFIG["host_os"].match?(/mswin|mingw32|windows/)
11
+ end
12
+
13
+ def self.cygwin?
14
+ @cygwin ||= RbConfig::CONFIG["host_os"].match?(/cygwin/)
15
+ end
16
+
17
+ def self.apple?
18
+ @apple ||= RbConfig::CONFIG["host_os"].match?(/darwin/)
19
+ end
20
+
21
+ def self.executable_ext
22
+ if windows? || cygwin?
23
+ ".exe"
24
+ elsif apple?
25
+ ".dylib"
26
+ else
27
+ ""
28
+ end
29
+ end
30
+
31
+ def self.executable_ext
32
+ windows? || cygwin? ? ".exe" : ""
33
+ end
34
+
35
+ def self.shared_library_ext
36
+ if windows? || cygwin?
37
+ ".dll"
38
+ elsif apple?
39
+ ".dylib"
40
+ else
41
+ ".so"
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rbconfig"
4
3
  require "tempfile"
4
+ require_relative "platform"
5
5
 
6
6
  module MetaCC
7
7
 
@@ -78,7 +78,7 @@ module MetaCC
78
78
  # The output mode (object files, shared library, static library, or
79
79
  # executable) is determined by the translated flags.
80
80
  def compile_command(
81
- input_files,
81
+ _input_files,
82
82
  flags:,
83
83
  include_paths:,
84
84
  defs:
@@ -87,8 +87,8 @@ module MetaCC
87
87
  end
88
88
 
89
89
  def compile_and_link_commands(
90
- input_files,
91
- output_file,
90
+ _input_files,
91
+ _output_file,
92
92
  flags:,
93
93
  include_paths:,
94
94
  defs:,
@@ -105,20 +105,11 @@ module MetaCC
105
105
  # @param output_type [:objects, :shared, :static, :executable]
106
106
  # @return [String]
107
107
  def default_extension(output_type)
108
- host_os = RbConfig::CONFIG["host_os"]
109
108
  case output_type
110
109
  when :objects then ".o"
111
- when :static then ".a"
112
- when :shared
113
- if host_os.match?(/mswin|mingw|cygwin/)
114
- ".dll"
115
- elsif host_os.match?(/darwin/)
116
- ".dylib"
117
- else
118
- ".so"
119
- end
120
- when :executable
121
- host_os.match?(/mswin|mingw|cygwin/) ? ".exe" : ""
110
+ when :static then ".a" # MingGW uses .a, not .lib
111
+ when :shared then MetaCC::Platform.shared_library_ext
112
+ when :executable then MetaCC::Platform.executable_ext
122
113
  else
123
114
  raise ArgumentError, "unknown output_type: #{output_type.inspect}"
124
115
  end
@@ -178,6 +169,30 @@ module MetaCC
178
169
  [[c, *flags, *inc_flags, *def_flags, *input_files, *lib_path_flags, *lib_flags, "-o", output_file]]
179
170
  end
180
171
 
172
+ def self.platform_flags
173
+ if MetaCC::Platform.windows?
174
+ {
175
+ # MingGW doesn't have full UBsan support, but it can trap on detected errors.
176
+ # It does not support the address or leak sanitizers.
177
+ sanitize_default: ["-fsanitize=undefined", "-fsanitize-undefined-trap-on-error"],
178
+ # MingGW doesn't support the thread sanitizer
179
+ sanitize_thread: []
180
+ }
181
+ elsif MetaCC::Platform.apple?
182
+ # gcc's support for sanitizers on OSX/iOS is *very* spotty.
183
+ # So we disable everything.
184
+ {
185
+ sanitize_default: [],
186
+ sanitize_thread: []
187
+ }
188
+ else
189
+ # Otherwise assume Linux/BSD and keep the default
190
+ {}
191
+ end
192
+ end
193
+
194
+ private_class_method :platform_flags
195
+
181
196
  GNU_FLAGS = {
182
197
  o0: ["-O0"],
183
198
  o1: ["-O1"],
@@ -217,7 +232,7 @@ module MetaCC
217
232
  static: ["-static"],
218
233
  strip: ["-Wl,--strip-unneeded"],
219
234
  debug: ["-D_GLIBCXX_DEBUG", "-fasynchronous-unwind-tables"]
220
- }.freeze
235
+ }.merge(platform_flags).freeze
221
236
 
222
237
  end
223
238
 
@@ -240,10 +255,26 @@ module MetaCC
240
255
  super("clang", search_paths:)
241
256
  end
242
257
 
258
+ def self.platform_flags
259
+ if MetaCC::Platform.windows?
260
+ {
261
+ # The leak sanitizer is not supported on Windows
262
+ sanitize_default: ["-fsanitize=address,undefined"],
263
+ # The thread sanitizer is not supported on Windows
264
+ sanitize_thread: []
265
+ }
266
+ else
267
+ # For all other platforms, stick with the defaults
268
+ {}
269
+ end
270
+ end
271
+
272
+ private_class_method :platform_flags
273
+
243
274
  CLANG_FLAGS = GNU_FLAGS.merge(
244
- lto: ["-flto=thin"],
245
- sanitize_memory: ["-fsanitize=memory"]
246
- ).freeze
275
+ lto: ["-flto=thin"],
276
+ sanitize_memory: ["-fsanitize=memory"]
277
+ ).merge(platform_flags)
247
278
 
248
279
  def flags
249
280
  CLANG_FLAGS
@@ -324,7 +355,7 @@ module MetaCC
324
355
  sanitize_memory: [],
325
356
  sanitize_thread: [],
326
357
  no_rtti: ["/GR-"],
327
- no_exceptions: ["/EHs-", "/EHc-"],
358
+ no_exceptions: ["/EHs-", "/EHc-", "/D_HAS_EXCEPTIONS=0"],
328
359
  pic: [],
329
360
  omit_frame_pointer: ["/Oy"],
330
361
  no_omit_frame_pointer: ["/Oy-"],
@@ -402,7 +433,7 @@ module MetaCC
402
433
  #
403
434
  # Parses the output of `vcvarsall.bat … && set` and merges the resulting
404
435
  # environment variables into the current process's ENV.
405
- def MSVC.vcvarsall(devenv_path)
436
+ def self.vcvarsall(devenv_path)
406
437
  # See https://stackoverflow.com/a/19929778
407
438
  return if ENV.key?("DevEnvDir")
408
439
 
@@ -418,7 +449,7 @@ module MetaCC
418
449
  Tempfile.create(["vcvarsall", ".bat"]) do |file|
419
450
  # Write a stub batch file that run vcvarsall.bat and dumps the
420
451
  # environment to stdout
421
- file.puts %Q{"#{vcvarsall.gsub('"', '""')}" x64 && set}
452
+ file.puts %("#{vcvarsall.gsub('"', '""')}" x64 && set)
422
453
  file.flush
423
454
 
424
455
  # Run the stub batch file
@@ -470,7 +501,7 @@ module MetaCC
470
501
  end
471
502
 
472
503
  def compile_and_link_commands(input_files, output_file, **options)
473
- commands = super(input_files, output_file, **options)
504
+ commands = super
474
505
  if options[:flags].include?(:static)
475
506
  object_files = input_files.map { |f| f.sub(/\.c\z/, ".o") }
476
507
  commands << [@ar, "rcs", output_file, *object_files]
@@ -533,7 +564,4 @@ module MetaCC
533
564
 
534
565
  end
535
566
 
536
- class AutoToolchain
537
- end
538
-
539
567
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module MetaCC
4
4
 
5
- VERSION = "0.4.0"
5
+ VERSION = "0.5.0"
6
6
 
7
7
  end
data/lib/metacc.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "metacc/driver"
4
3
  require "metacc/version"
4
+ require "metacc/platform"
5
+ require "metacc/toolchain"
6
+ require "metacc/driver"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metacc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Praneeth Sadda
@@ -22,6 +22,7 @@ files:
22
22
  - lib/metacc.rb
23
23
  - lib/metacc/cli.rb
24
24
  - lib/metacc/driver.rb
25
+ - lib/metacc/platform.rb
25
26
  - lib/metacc/toolchain.rb
26
27
  - lib/metacc/version.rb
27
28
  homepage: https://github.com/psadda/metacc
@@ -38,7 +39,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
38
39
  requirements:
39
40
  - - ">="
40
41
  - !ruby/object:Gem::Version
41
- version: 3.2.0
42
+ version: 3.4.0
42
43
  required_rubygems_version: !ruby/object:Gem::Requirement
43
44
  requirements:
44
45
  - - ">="