-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13328 from chrisroberts/windows-ext
Patch MakeMakefile for extension builds
- Loading branch information
Showing
3 changed files
with
141 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |