Skip to content

Commit

Permalink
cmake: only use MSYS/NMake generators when available
Browse files Browse the repository at this point in the history
When cross-compiling Windows targets with `cmake` in a Linux
environment, the MSYS generator may not be available. Supplying `-G
MSYS` will cause the build to fail.

`cmake --help` will output the available generators. Before including
the `-G` option, check that the generator is available.

Closes #127
  • Loading branch information
stanhu committed Jul 17, 2023
1 parent 5084a2a commit 7dc1ffa
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
15 changes: 13 additions & 2 deletions lib/mini_portile2/mini_portile_cmake.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'mini_portile2/mini_portile'
require 'open3'

class MiniPortileCMake < MiniPortile
def configure_prefix
Expand All @@ -11,9 +12,9 @@ def initialize(name, version, **kwargs)
end

def configure_defaults
if MiniPortile.mswin?
if MiniPortile.mswin? && generator_available?('NMake')
['-G', 'NMake Makefiles']
elsif MiniPortile.mingw?
elsif MiniPortile.mingw? && generator_available?('MSYS')
['-G', 'MSYS Makefiles']
else
[]
Expand Down Expand Up @@ -48,4 +49,14 @@ def make_cmd
def cmake_cmd
(ENV["CMAKE"] || @cmake_command || "cmake").dup
end

private

def generator_available?(generator_type)
stdout_str, status = Open3.capture2("#{cmake_cmd} --help")

raise 'Unable to determine whether CMake supports #{generator_type} Makefile generator' unless status.success?

stdout_str.include?("#{generator_type} Makefiles")
end
end
42 changes: 41 additions & 1 deletion test/test_cmake.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def test_install
end
end

class TestCMakeConfig < TestCase
class TestCMakeConfig < TestCMake
def test_make_command_configuration
MiniPortile.stub(:mswin?, false) do
without_env("MAKE") do
Expand All @@ -77,6 +77,30 @@ def test_make_command_configuration
end
end

def test_configure_defaults_with_unix_makefiles
Open3.stub(:capture2, cmake_help_mock('Unix')) do
MiniPortile.stub(:mingw?, true) do
assert_equal([], @recipe.configure_defaults)
end
end
end

def test_configure_defaults_with_msys_makefiles
Open3.stub(:capture2, cmake_help_mock('MSYS')) do
MiniPortile.stub(:mingw?, true) do
assert_equal(['-G', 'MSYS Makefiles'], @recipe.configure_defaults)
end
end
end

def test_configure_defaults_with_nmake_makefiles
Open3.stub(:capture2, cmake_help_mock('NMake')) do
MiniPortile.stub(:mswin?, true) do
assert_equal(['-G', 'NMake Makefiles'], @recipe.configure_defaults)
end
end
end

def test_cmake_command_configuration
without_env("CMAKE") do
assert_equal("cmake", MiniPortileCMake.new("test", "1.0.0").cmake_cmd)
Expand All @@ -87,4 +111,20 @@ def test_cmake_command_configuration
assert_equal("asdf", MiniPortileCMake.new("test", "1.0.0", cmake_command: "xyzzy").cmake_cmd)
end
end

private

def cmake_help_mock(generator_type)
open3_mock = MiniTest::Mock.new
cmake_script = <<~SCRIPT
echo "The following generators are available on this platform (* marks default):"
echo "* #{generator_type} Makefiles = Generates standard #{generator_type.upcase} makefiles."
SCRIPT

exit_status = MiniTest::Mock.new
exit_status.expect(:success?, true)
expected_output = [cmake_script, exit_status]
open3_mock.expect(:call, expected_output, ['cmake --help'])
open3_mock
end
end

0 comments on commit 7dc1ffa

Please sign in to comment.