Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions lib/mruby/build.rb
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def debug_enabled?

def enable_debug
compilers.each do |c|
c.defines += %w(MRB_DEBUG)
c.internal_defines += %w(MRB_DEBUG)
c.setup_debug(self)
end
@mrbc.compile_options += ' -g'
Expand Down Expand Up @@ -225,7 +225,7 @@ def enable_cxx_exception
end
@cxx_exception_enabled = true
compilers.each { |c|
c.defines += %w(MRB_USE_CXX_EXCEPTION)
c.internal_defines += %w(MRB_USE_CXX_EXCEPTION)
c.flags << c.cxx_exception_flag
}
linker.command = cxx.command if toolchains.find { |v| v == 'gcc' }
Expand All @@ -245,7 +245,7 @@ def enable_cxx_abi
raise "cxx_exception already enabled"
end
compilers.each { |c|
c.defines += %w(MRB_USE_CXX_EXCEPTION MRB_USE_CXX_ABI)
c.internal_defines += %w(MRB_USE_CXX_EXCEPTION MRB_USE_CXX_ABI)
c.flags << c.cxx_compile_flag
c.flags = c.flags.flatten - c.cxx_invalid_flags.flatten
}
Expand Down Expand Up @@ -388,8 +388,9 @@ def defines_final!
end

# True when this build compiles with -D<name>, whether the build config
# asked for it or a gem contributed it. A gem reads this to configure
# itself against a capability another gem provides.
# asked for it, a gem contributed it, or the build added it from one of
# its own switches. A gem reads this to configure itself against a
# capability another gem provides.
#
# Until `defines_final!` the answer would depend on how far down the gem
# list the caller sits, since a gem contributes its defines when its own
Expand All @@ -406,8 +407,8 @@ def has_define?(name)
# A define may carry a value, as `FOO=1` does, so compare the name and
# not the value. The `-D` is the compiler's, added when the flags are
# assembled, and is no part of the name.
[defines, *compilers.map(&:defines)].flatten
.any? {|d| d.to_s.split('=', 2).first == name}
return true if defines.flatten.any? {|d| d.to_s.split('=', 2).first == name}
compilers.any? {|c| c.has_define?(name)}
end

def define_rules
Expand Down
23 changes: 22 additions & 1 deletion lib/mruby/build/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ def _run(options, params={})

class Command::Compiler < Command
attr_accessor :label, :flags, :include_paths, :defines, :source_exts
# Defines are held in two lists, split by who asked for them. `defines` is
# what the build config and the gems write. `internal_defines` is what the
# build adds on its own behalf, from its own switches (`enable_debug`,
# `enable_cxx_abi`) or from a toolchain. Both reach the compiler as `-D`;
# keeping them apart lets a toolchain set its own without overwriting what
# the config already wrote, and lets a caller ask for one list alone.
attr_accessor :internal_defines
attr_accessor :compile_options, :option_define, :option_include_path, :out_ext
attr_accessor :cxx_compile_flag, :cxx_exception_flag, :cxx_invalid_flags
attr_writer :preprocess_options
Expand All @@ -48,6 +55,7 @@ def initialize(build, source_exts=[], label: "CC")
@source_exts = source_exts
@include_paths = ["#{MRUBY_ROOT}/include"]
@defines = []
@internal_defines = []
@option_include_path = %q[-I"%s"]
@option_define = %q[-D"%s"]
@compile_options = %q[%{flags} -o "%{outfile}" -c "%{infile}"]
Expand All @@ -61,6 +69,18 @@ def preprocess_options
@preprocess_options ||= @compile_options.sub(/(?:\A|\s)\K-c(?=\s)/, "-E -P")
end

# True when this compiler compiles with -D<name>, whichever of the two
# lists it sits in. A gem asks this while its own mrbgem.rake body runs,
# where `Build#has_define?` refuses to answer because the gems that come
# after it have not contributed their defines yet.
def has_define?(name)
name = name.to_s
# A define may carry a value, as `FOO=1` does, so compare the name and
# not the value.
[defines, internal_defines].flatten
.any? {|d| d.to_s.split('=', 2).first == name}
end

def search_header_path(name)
header_search_paths.find do |v|
File.exist? build.filename("#{v}/#{name}").sub(/^"(.*)"$/, '\1')
Expand All @@ -73,7 +93,8 @@ def search_header(name)
end

def all_flags(_defines=[], _include_paths=[], _flags=[])
define_flags = [defines, _defines, build.defines].flatten.map{ |d| option_define % d }
define_flags = [defines, internal_defines, _defines, build.defines].flatten
.map{ |d| option_define % d }
include_path_flags = [include_paths, _include_paths].flatten.map do |f|
option_include_path % filename(f)
end
Expand Down
2 changes: 1 addition & 1 deletion mrbgems/mruby-compiler/mrbgem.rake
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ MRuby::Gem::Specification.new('mruby-compiler') do |spec|
elsif !cc.defines.include?('MRB_NO_GEMS')
cc.defines << 'MRC_TARGET_MRUBY'
end
cc.defines << 'MRC_DEBUG' if cc.defines.any? { |d| d.match?(/\AMRB_DEBUG(=|\z)/) }
cc.defines << 'MRC_DEBUG' if cc.has_define?('MRB_DEBUG')
cc.defines << 'PRISM_BUILD_MINIMAL' unless cc.defines.include?('MRC_DEBUG')
# PRISM_BUILD_MINIMAL stubs out pm_prettyprint(), so `mruby -v` can only dump
# the AST where it is compiled in
Expand Down
2 changes: 1 addition & 1 deletion tasks/toolchains/visualcpp.rake
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ MRuby::Toolchain.new(:visualcpp) do |conf, _params|
compiler.command = ENV['CXX'] || 'cl.exe'
compiler.flags = [*(ENV['CXXFLAGS'] || ENV['CFLAGS'] || compiler_flags + %w(/EHs))]
end
compiler.defines = %w(MRB_STACK_EXTEND_DOUBLING)
compiler.internal_defines |= %w(MRB_STACK_EXTEND_DOUBLING)
compiler.option_include_path = %q[/I"%s"]
compiler.option_define = '/D%s'
compiler.compile_options = %Q[/Zi /c /Fo"%{outfile}" %{flags} "%{infile}"]
Expand Down
Loading