summaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
authorRory OConnell <[email protected]>2020-08-29 17:19:32 -0700
committerYukihiro "Matz" Matsumoto <[email protected]>2020-10-12 18:20:12 +0900
commitcfe8b0c81ddf1d221e4e1c6bb41d7e4c50d59fad (patch)
treee5270906bccf31d2648d0cc763869568a40eb4f2 /lib
parent026726dd49421f93783d62f738c37d215f8119f0 (diff)
downloadmruby-cfe8b0c81ddf1d221e4e1c6bb41d7e4c50d59fad.tar.gz
mruby-cfe8b0c81ddf1d221e4e1c6bb41d7e4c50d59fad.zip
Add methods for asking about compiler features
Diffstat (limited to 'lib')
-rw-r--r--lib/mruby/build/command.rb66
1 files changed, 66 insertions, 0 deletions
diff --git a/lib/mruby/build/command.rb b/lib/mruby/build/command.rb
index 39981cc32..80c01b38f 100644
--- a/lib/mruby/build/command.rb
+++ b/lib/mruby/build/command.rb
@@ -1,4 +1,5 @@
require 'forwardable'
+require 'tempfile'
module MRuby
class Command
@@ -126,6 +127,31 @@ module MRuby
end
end
+ def compiles?(source_text)
+ infile = Tempfile.new ['', '.c']
+ infile.write source_text
+ infile.close
+ cwd = Dir.pwd
+ is_success = false
+ # Change to a tmp dir when compiling so we don't litter compiler artifacts
+ Dir.mktmpdir do |tmpdir|
+ Dir.chdir tmpdir
+ sh(command, infile.path, verbose: false) { |retval, _| is_success = retval }
+ end
+ infile.delete
+ Dir.chdir cwd
+
+ return is_success
+ end
+
+ def has_header?(header_name)
+ compiles? test_code_template header: header_name
+ end
+
+ def has_function?(function_name, with_header: nil)
+ compiles? test_code_template function: function_name, header: with_header
+ end
+
private
#
@@ -165,6 +191,46 @@ module MRuby
end.flatten.uniq
deps << MRUBY_CONFIG
end
+
+ def test_code_template(function: nil, header: nil)
+ preamble = ''
+ body = ''
+
+ if header
+ preamble += <<-TEMPLATE
+#if defined __has_include
+#if !__has_include("#{header}")
+#error "Header #{header} not found"
+#endif
+#endif
+#include <#{header}>
+ TEMPLATE
+ end
+
+ if function
+ preamble += <<-TEMPLATE
+#if defined __stub_#{function} || defined __stub___#{function}
+#{function} unavailable
+#endif
+ TEMPLATE
+
+ # This is how autoconf works when using a function prototype.
+ body += <<-TEMPLATE
+ void *a = (void*) &#{function};
+ long long b = (long long) a;
+ return (int) b;
+ TEMPLATE
+ else
+ body = 'return 0;'
+ end
+
+ <<-TEMPLATE
+#{preamble}
+int main(void) {{
+#{body}
+}}
+ TEMPLATE
+ end
end
class Command::Linker < Command