add failure messages for failed configuration checks - close #119

This commit is contained in:
Josh Holtrop 2020-10-12 21:01:04 -04:00
parent bbe9563ceb
commit 5bac91f92f
4 changed files with 86 additions and 42 deletions

View File

@ -0,0 +1,5 @@
configure do
check_c_compiler "foo123c", fail: false, on_fail: "Install the foo123 package"
check_d_compiler "foo123d", fail: false
check_cxx_compiler "foo123cxx", on_fail: lambda {puts "Install the foo123cxx package"}
end

View File

@ -246,6 +246,15 @@ configure do
end
```
Global configuration options may be supplied to the compiler checks as well.
Example:
```ruby
configure do
check_c_compiler "x86_64-elf-gcc", on_fail: "Install x86_64-elf cross toolchain first!"
end
```
###> Checking for a Header File
The following methods can be used to check for the presence of a header file:
@ -272,18 +281,6 @@ end
Optionally specifies an array of paths to look for the header file in.
##### `:fail`
If the `:fail` option is set to `false`, then the absence of the header file
will not result in the configure option failing.
The `:fail` option defaults to `true` if the `:set_define` option is not
defined, and defaults to `false` if the `:set_define` option is defined.
##### `:set_define`
If set, a build define of the specified String will be added to the
`CPPDEFINES` construction variable array if the requested header is found.
###> Checking for a D Import
The `check_d_import` method can be used to check for the presence of D import.
@ -327,18 +324,6 @@ end
Optionally specifies an array of paths to look for the library in.
##### `:fail`
If the `:fail` option is set to `false`, then the absence of the library
will not result in the configure option failing.
The `:fail` option defaults to `true` if the `:set_define` option is not
defined, and defaults to `false` if the `:set_define` option is defined.
##### `:set_define`
If set, a build define of the specified String will be added to the
`CPPDEFINES` construction variable array if the requested library is found.
##### `:use`
If not set, the library will be used by default in all `Environment` objects.
@ -387,18 +372,6 @@ used to look for package configuration flags for the specified package.
If the `:program` option is given, the program specified will be used to look
for configuration flags.
##### `:fail`
If the `:fail` option is set to `false`, then the absence of the package or
program requested will not result in the configure option failing.
The `:fail` option defaults to `true` if the `:set_define` option is not
defined, and defaults to `false` if the `:set_define` option is defined.
##### `:set_define`
If set, a build define of the specified String will be added to the
`CPPDEFINES` construction variable array if the requested package is found.
##### `:use`
If not set, the library will be used by default in all `Environment` objects.
@ -457,6 +430,46 @@ configure do
end
```
###> Global Configuration Check Options
#### `:fail`
If the `:fail` option is set to `false`, then the absence of the package or
program requested will not result in the configure option failing.
The `:fail` option defaults to `true` if the `:set_define` option is not
defined, and defaults to `false` if the `:set_define` option is defined.
#### `:on_fail`
The `:on_fail` option can be set to a String or a Proc object. If the
configuration operation fails (or would fail), the given message is printed
or the Proc is called.
Examples:
```ruby
configure do
check_c_compiler "special-gcc", on_fail: "First install special gcc!"
end
configure do
package_hint = lambda do
puts "The following packages must be installed to build this project:"
puts "- libsdl2-dev"
puts "- libsdl2-image-dev"
puts "- libsdl2-net-dev"
end
check_lib "SDL2", on_fail: package_hint
check_lib "SDL2_image", on_fail: package_hint
check_lib "SDL2_net", on_fail: package_hint
end
```
#### `:set_define`
If set, a build define of the specified String will be added to the
`CPPDEFINES` construction variable array if the requested package is found.
##> Build Operations
The `build` block is used to create Environments and register build targets.

View File

@ -62,6 +62,10 @@ module Rscons
# @return [void]
def check_c_compiler(*ccc)
$stdout.write("Checking for C compiler... ")
options = {}
if ccc.last.is_a?(Hash)
options = ccc.slice!(-1)
end
if ccc.empty?
# Default C compiler search array.
ccc = %w[gcc clang]
@ -69,7 +73,7 @@ module Rscons
cc = ccc.find do |cc|
test_c_compiler(cc)
end
complete(cc ? 0 : 1, success_message: cc)
complete(cc ? 0 : 1, options.merge(success_message: cc))
end
# Check for a working C++ compiler.
@ -80,6 +84,10 @@ module Rscons
# @return [void]
def check_cxx_compiler(*ccc)
$stdout.write("Checking for C++ compiler... ")
options = {}
if ccc.last.is_a?(Hash)
options = ccc.slice!(-1)
end
if ccc.empty?
# Default C++ compiler search array.
ccc = %w[g++ clang++]
@ -87,7 +95,7 @@ module Rscons
cc = ccc.find do |cc|
test_cxx_compiler(cc)
end
complete(cc ? 0 : 1, success_message: cc)
complete(cc ? 0 : 1, options.merge(success_message: cc))
end
# Check for a working D compiler.
@ -98,6 +106,10 @@ module Rscons
# @return [void]
def check_d_compiler(*cdc)
$stdout.write("Checking for D compiler... ")
options = {}
if cdc.last.is_a?(Hash)
options = cdc.slice!(-1)
end
if cdc.empty?
# Default D compiler search array.
cdc = %w[gdc ldc2]
@ -105,7 +117,7 @@ module Rscons
dc = cdc.find do |dc|
test_d_compiler(dc)
end
complete(dc ? 0 : 1, success_message: dc)
complete(dc ? 0 : 1, options.merge(success_message: dc))
end
# Check for a package or configure program output.
@ -387,11 +399,15 @@ module Rscons
else
!options[:set_define]
end
color = should_fail ? :red : :yellow
Ansi.write($stdout, color, "#{fail_message}\n")
if options[:on_fail].is_a?(String)
$stdout.puts(options[:on_fail])
elsif options[:on_fail].is_a?(Proc)
options[:on_fail].call
end
if should_fail
Ansi.write($stdout, :red, "#{fail_message}\n")
raise ConfigureFailure.new
else
Ansi.write($stdout, :yellow, "#{fail_message}\n")
end
end
end

View File

@ -2222,6 +2222,16 @@ EOF
end
end
context "on_fail option" do
it "prints on_fail messages and calls on_fail procs on failure" do
test_dir "configure"
result = run_rscons(rsconscript: "on_fail.rb", op: %w[configure])
expect(result.status).to_not eq 0
expect(result.stdout).to match /Install the foo123 package/
expect(result.stdout).to match /Install the foo123cxx package/
end
end
it "does everything" do
test_dir "configure"
create_exe "pkg-config", "echo '-DMYPACKAGE'"