diff options
| author | Rory OConnell <[email protected]> | 2020-08-29 17:19:32 -0700 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-10-12 18:20:12 +0900 |
| commit | cfe8b0c81ddf1d221e4e1c6bb41d7e4c50d59fad (patch) | |
| tree | e5270906bccf31d2648d0cc763869568a40eb4f2 | |
| parent | 026726dd49421f93783d62f738c37d215f8119f0 (diff) | |
| download | mruby-cfe8b0c81ddf1d221e4e1c6bb41d7e4c50d59fad.tar.gz mruby-cfe8b0c81ddf1d221e4e1c6bb41d7e4c50d59fad.zip | |
Add methods for asking about compiler features
| -rw-r--r-- | lib/mruby/build/command.rb | 66 |
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 |
