diff --git a/doc/guides/compile.md b/doc/guides/compile.md index b98cd147b..b0804e52c 100644 --- a/doc/guides/compile.md +++ b/doc/guides/compile.md @@ -637,6 +637,33 @@ To summarize: - For a build target other than "host", the default value of `MRuby::Build#install_prefix` is `/mruby/`. - If the environment variable `DESTDIR` is set, the actual write directory is `/`. +### Excluded files + +In some cases there are files that you do not want to install. +In such cases, add a file path filter to the array object `MRuby::Build#install_excludes` to exclude them. + +The following is an object that can be defined as a file path filter. +The `path` variable that appears is a relative path based on `MRuby::Build#build_dir`. + +- string objects: files matched by `string.match?(path)` are excluded. +- regexp object: files matched by `regexp.match?(path)` are excluded. +- proc object: files which return true with `proc.call(path)` are excluded. + +```ruby +# exclude bin/mrbc +conf.install_excludes << exefile("bin/mrbc") + +# exclude all files under lib/ directory +conf.install_excludes << %r(^lib/) + +# exclude bin/mrbtest, but in this case it is recommended to use string instead of proc +conf.install_excludes << proc { |path| + path == exefile("bin/mrbtest") +} +``` + +By default, it contains only a proc object to exclude `libmruby_core`. + ## Tips - If you see compilation troubles, try `rake clean` first. diff --git a/lib/mruby/build.rb b/lib/mruby/build.rb index aa58db621..c43c698f0 100644 --- a/lib/mruby/build.rb +++ b/lib/mruby/build.rb @@ -77,6 +77,7 @@ module MRuby include LoadGems attr_accessor :name, :bins, :exts, :file_separator, :build_dir, :gem_clone_dir, :defines, :libdir_name attr_reader :products, :libmruby_core_objs, :libmruby_objs, :gems, :toolchains, :presym, :mrbc_build, :gem_dir_to_repo_url + attr_reader :install_excludes alias libmruby libmruby_objs @@ -103,6 +104,7 @@ module MRuby @gem_clone_dir = "#{build_dir}/repos/#{@name}" @libdir_name = (self.kind_of?(MRuby::CrossBuild) ? nil : ENV["MRUBY_SYSTEM_LIBDIR_NAME"]) || "lib" @install_prefix = nil + @install_excludes = [] @defines = [] @cc = Command::Compiler.new(self, %w(.c), label: "CC") @cxx = Command::Compiler.new(self, %w(.cc .cxx .cpp), label: "CXX") @@ -135,6 +137,13 @@ module MRuby @toolchains = [] @gem_dir_to_repo_url = {} + # Add lambda instead of string because libdir_name or lib may be changed by user configuration + libmruby_core_name = nil + @install_excludes << ->(file) { + libmruby_core_name ||= File.join(libdir_name, libfile("libmruby_core")) + file == libmruby_core_name + } + MRuby.targets[@name] = current = self end @@ -533,12 +542,20 @@ EOS @install_prefix = dir&.to_s end + def list_install_excludes + install_excludes.flatten.flat_map { |e| + e.kind_of?(Proc) ? e.call(self) : e + }.map { |e| + File.join(build_dir, e) + } + end + protected attr_writer :presym def create_mrbc_build - exclusions = %i[@name @build_dir @gems @enable_test @enable_bintest @internal] + exclusions = %i[@name @build_dir @gems @enable_test @enable_bintest @internal @install_excludes] name = "#{@name}/mrbc" MRuby.targets.delete(name) build = self.class.new(name, internal: true){} diff --git a/tasks/install.rake b/tasks/install.rake index 8c2847372..3980d5940 100644 --- a/tasks/install.rake +++ b/tasks/install.rake @@ -14,12 +14,16 @@ MRuby.each_target do |build| next if build.internal? prefix = File.join(MRuby::INSTALL_DESTDIR, build.install_prefix) + exclude_filter = build.install_excludes.flatten task "install:full" => "install:full:#{build.name}" task "install:full:#{build.name}" => "install:bin:#{build.name}" do Dir.glob(File.join(build.build_dir.gsub(/[\[\{\*\?]/, "\\\0"), "{include,#{libdir_name}}/**/*")) do |path| - install_D path, File.join(prefix, path.relative_path_from(build.build_dir)) if File.file? path + next unless File.file? path + file = path.relative_path_from(build.build_dir) + next if exclude_filter.any? { |filter| filter.respond_to?(:call) ? filter.call(file) : filter.match?(file) } + install_D path, File.join(prefix, file) end end @@ -27,7 +31,10 @@ MRuby.each_target do |build| task "install:bin:#{build.name}" => "all" do Dir.glob(File.join(build.build_dir.gsub(/[\[\{\*\?]/, "\\\0"), "{bin,host-bin}/**/*")) do |path| - install_D path, File.join(prefix, path.relative_path_from(build.build_dir)) if File.file? path + next unless File.file? path + file = path.relative_path_from(build.build_dir) + next if exclude_filter.any? { |filter| filter.respond_to?(:call) ? filter.call(file) : filter.match?(file) } + install_D path, File.join(prefix, file) end end end