Add patches for MakeMakefile
Provides patches for MakeMakefile and modifies the Ruby path provided when building extensions to allow loading the custom mkmf.rb file. The patches perform inspection of flag values and quote any Windows paths found that are not already quoted. This resolves issues where builds fail due to spaces in compiler and linker flags on Windows.
This commit is contained in:
parent
b3c9f0d522
commit
606f825eaa
116
lib/vagrant/patches/builder/mkmf.rb
Normal file
116
lib/vagrant/patches/builder/mkmf.rb
Normal file
@ -0,0 +1,116 @@
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
# This custom mkmf.rb file is used on Windows platforms
|
||||
# to handle common path related build failures where
|
||||
# a space is included in the path. The default installation
|
||||
# location being in Program Files results in most many
|
||||
# extensions failing to build. These patches will attempt
|
||||
# to find unquoted paths in flags and quote them prior to
|
||||
# usage.
|
||||
|
||||
# Start with locating the real mkmf.rb file and
|
||||
# loading it
|
||||
mkmf_paths = $LOAD_PATH.find_all { |x|
|
||||
!x.start_with?(__dir__) &&
|
||||
File.exist?(File.join(x, "mkmf.rb"))
|
||||
}.uniq
|
||||
|
||||
# At this point the path collection should only consist
|
||||
# of a single entry. If there's more than one, load all
|
||||
# of them but include a warning message that more than
|
||||
# one was encountered. If none are found, then something
|
||||
# bad is going on so just bail.
|
||||
if mkmf_paths.size > 1
|
||||
$stderr.puts "WARNING: Multiple mkmf.rb files located: #{mkmf_paths.inspect}"
|
||||
elsif mkmf_paths.empty?
|
||||
raise "Failed to locate mkmf.rb file"
|
||||
end
|
||||
|
||||
mkmf_paths.each do |mpath|
|
||||
require File.join(mpath, "mkmf.rb")
|
||||
end
|
||||
|
||||
# Attempt to detect and quote Windos paths found within
|
||||
# the given string of flags
|
||||
#
|
||||
# @param [String] flags Compiler/linker flags
|
||||
# @return [String] flags with paths quoted
|
||||
def flag_cleaner(flags)
|
||||
parts = flags.split(" -")
|
||||
parts.map! do |p|
|
||||
if p !~ %r{[A-Za-z]:(/|\\)}
|
||||
next p
|
||||
elsif p =~ %r{"[A-Za-z]:(/|\\).+"$}
|
||||
next p
|
||||
end
|
||||
|
||||
p.gsub(%r{([A-Za-z]:(/|\\).+)$}, '"\1"')
|
||||
end
|
||||
|
||||
parts.join(" -")
|
||||
end
|
||||
|
||||
# Check values defined for CFLAGS, CPPFLAGS, LDFLAGS,
|
||||
# and INCFLAGS for unquoted Windows paths and quote
|
||||
# them.
|
||||
def clean_flags!
|
||||
$CFLAGS = flag_cleaner($CFLAGS)
|
||||
$CPPFLAGS = flag_cleaner($CPPFLAGS)
|
||||
$LDFLAGS = flag_cleaner($LDFLAGS)
|
||||
$INCFLAGS = flag_cleaner($INCFLAGS)
|
||||
end
|
||||
|
||||
# Since mkmf loads the MakeMakefile module directly into the
|
||||
# current scope, apply patches directly in the scope
|
||||
def vagrant_create_makefile(*args)
|
||||
clean_flags!
|
||||
|
||||
ruby_create_makefile(*args)
|
||||
end
|
||||
alias :ruby_create_makefile :create_makefile
|
||||
alias :create_makefile :vagrant_create_makefile
|
||||
|
||||
def vagrant_append_cflags(*args)
|
||||
result = ruby_append_cflags(*args)
|
||||
clean_flags!
|
||||
result
|
||||
end
|
||||
alias :ruby_append_cflags :append_cflags
|
||||
alias :append_cflags :vagrant_append_cflags
|
||||
|
||||
def vagrant_append_cppflags(*args)
|
||||
result = ruby_append_cppflags(*args)
|
||||
clean_flags!
|
||||
result
|
||||
end
|
||||
alias :ruby_append_cppflags :append_cppflags
|
||||
alias :append_cppflags :vagrant_append_cppflags
|
||||
|
||||
def vagrant_append_ldflags(*args)
|
||||
result = ruby_append_ldflags(*args)
|
||||
clean_flags!
|
||||
result
|
||||
end
|
||||
alias :ruby_append_ldflags :append_ldflags
|
||||
alias :append_ldflags :vagrant_append_ldflags
|
||||
|
||||
def vagrant_cc_config(*args)
|
||||
clean_flags!
|
||||
ruby_cc_config(*args)
|
||||
end
|
||||
alias :ruby_cc_config :cc_config
|
||||
alias :cc_config :vagrant_cc_config
|
||||
|
||||
def vagrant_link_config(*args)
|
||||
clean_flags!
|
||||
ruby_link_config(*args)
|
||||
end
|
||||
alias :ruby_link_config :link_config
|
||||
alias :link_config :vagrant_link_config
|
||||
|
||||
# Finally, always append the flags that Vagrant has
|
||||
# defined via the environment
|
||||
append_cflags(ENV["CFLAGS"]) if ENV["CFLAGS"]
|
||||
append_cppflags(ENV["CPPFLAGS"]) if ENV["CPPFLAGS"]
|
||||
append_ldflags(ENV["LDFLAGS"]) if ENV["LDFLAGS"]
|
||||
23
lib/vagrant/patches/rubygems.rb
Normal file
23
lib/vagrant/patches/rubygems.rb
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
# This allows for effective monkey patching of the MakeMakefile
|
||||
# module when building gem extensions. When gem extensions are
|
||||
# built, the extconf.rb file is executed as a separate process.
|
||||
# To support monkey patching the MakeMakefile module, the ruby
|
||||
# executable path is adjusted to add a custom load path allowing
|
||||
# a customized mkmf.rb file to load the proper mkmf.rb file, and
|
||||
# then applying the proper patches.
|
||||
if Gem.win_platform?
|
||||
Gem.class_eval do
|
||||
class << self
|
||||
def vagrant_ruby
|
||||
cmd = ruby_ruby
|
||||
"#{cmd} -I\"#{Vagrant.source_root.join("lib/vagrant/patches/builder")}\""
|
||||
end
|
||||
|
||||
alias_method :ruby_ruby, :ruby
|
||||
alias_method :ruby, :vagrant_ruby
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user