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
29 changes: 1 addition & 28 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ load "#{MRUBY_ROOT}/tasks/presym.rake"
load "#{MRUBY_ROOT}/tasks/test.rake"
load "#{MRUBY_ROOT}/tasks/benchmark.rake"
load "#{MRUBY_ROOT}/tasks/doc.rake"
load "#{MRUBY_ROOT}/tasks/install.rake"

##############################
# generic build targets, rules
Expand Down Expand Up @@ -67,34 +68,6 @@ task :deep_clean => %w[clean doc:clean] do
puts "Cleaned up mrbgems build folder"
end

PREFIX = ENV['PREFIX'] || ENV['INSTALL_PREFIX'] || '/usr/local'

desc "install compiled products"
task :install => :install_bin do
if host = MRuby.targets['host']
install_D host.libmruby_static, File.join(PREFIX, "lib", File.basename(host.libmruby_static))
# install mruby.h and mrbconf.h
Dir.glob(File.join(MRUBY_ROOT, "include", "*.h")) do |src|
install_D src, File.join(PREFIX, "include", File.basename(src))
end
Dir.glob(File.join(MRUBY_ROOT, "include", "mruby", "*.h")) do |src|
install_D src, File.join(PREFIX, "include", "mruby", File.basename(src))
end
Dir.glob(File.join(File.join(MRUBY_ROOT, "build", "host", "include", "mruby", "presym", "*.h"))) do |src|
install_D src, File.join(PREFIX, "include", "mruby", "presym", File.basename(src))
end
end
end

desc "install compiled executable (on host)"
task :install_bin => :all do
if host = MRuby.targets['host']
Dir.glob(File.join(MRUBY_ROOT, "bin", "*")) do |src|
install_D src, File.join(PREFIX, "bin", File.basename(src))
end
end
end

desc "run all pre-commit hooks against all files"
task :check do
sh "pre-commit run --all-files"
Expand Down
50 changes: 50 additions & 0 deletions doc/guides/compile.md
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,56 @@ LDFLAGS = `$(MRB_CONFIG) --ldflags`
LIBS = `$(MRB_CONFIG) --libs`
```

## Install

To install the files in the `bin`, `include` and `lib` directories generated by the "host" build target into a system directory, do the following:

```console
$ rake install
```

If there are multiple build targets in the build configuration file, to install the products of all build targets, do the following:

```console
$ rake install:full
```

To install only one of several build targets, e.g., the "its-mine" build target, do the following:

```console
$ rake install:full:its-mine
```

To install only the executable files, do the following:

```console
$ rake install_bin # only "host" build target
$ rake install:bin # all build targets
$ rake install:bin:its-mine # only "its-mine" build target
```

### Installation Directory

The installation directory is `/usr/local` for the "host" build target and `/usr/local/mruby/<build-name>` for the others.
To change them, you can set the environment variable `PREFIX` or use `MRuby::Build#install_prefix = dir` in your build configuration file.

The `PREFIX` environment variable affects all build targets and changes the `/usr/local` part.

The `MRuby::Build#install_prefix` can be set for each individual build target.
In this case, the environment variable `PREFIX` is ignored.

Also, if the environment variable `DESTDIR` is set, it will prepend to the path obtained by `install_prefix` to determine the final write directory.
This is intended for temporary file expansion by the user's package work.

---

To summarize:

- The default value of the environment variable `PREFIX` is `/usr/local`.
- For the "host" build target, the default value of `MRuby::Build#install_prefix` is `<PREFIX>`.
- For a build target other than "host", the default value of `MRuby::Build#install_prefix` is `<PREFIX>/mruby/<build-name>`.
- If the environment variable `DESTDIR` is set, the actual write directory is `<DESTDIR>/<MRuby::Build#install_prefix>`.

## Tips

- If you see compilation troubles, try `rake clean` first.
55 changes: 52 additions & 3 deletions lib/mruby/build.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
require "mruby/core_ext"
require "mruby/build/load_gems"
require "mruby/build/command"
autoload :Find, "find"

module MRuby
autoload :Gem, "mruby/gem"
autoload :Lockfile, "mruby/lockfile"
autoload :Presym, "mruby/presym"

INSTALL_PREFIX = ENV['PREFIX'] || ENV['INSTALL_PREFIX'] || '/usr/local'
INSTALL_DESTDIR = ENV['DESTDIR'] || ''

class << self
def targets
@targets ||= {}
Expand Down Expand Up @@ -97,6 +101,7 @@ def initialize(name='host', build_dir=nil, internal: false, &block)
@file_separator = '/'
@build_dir = "#{build_dir}/#{@name}"
@gem_clone_dir = "#{build_dir}/repos/#{@name}"
@install_prefix = nil
@defines = []
@cc = Command::Compiler.new(self, %w(.c), label: "CC")
@cxx = Command::Compiler.new(self, %w(.cc .cxx .cpp), label: "CXX")
Expand Down Expand Up @@ -370,14 +375,35 @@ def define_rules
end
end

def define_installer(src)
dst = "#{self.class.install_dir}/#{File.basename(src)}"
def define_installer_outline(src, dst)
file dst => src do
install_D src, dst
_pp "GEN", src.relative_path, dst.relative_path
mkdir_p(File.dirname(dst))
yield dst
end
dst
end

if ENV['OS'] == 'Windows_NT'
def define_installer(src)
dst = "#{self.class.install_dir}/#{File.basename(src)}".pathmap("%X.bat")
define_installer_outline(src, dst) do
File.write dst, <<~BATCHFILE
@echo off
call "#{src}" %*
BATCHFILE
end
end
else
def define_installer(src)
dst = "#{self.class.install_dir}/#{File.basename(src)}"
define_installer_outline(src, dst) do
File.unlink(dst) if File.exist?(dst)
File.symlink(src, dst)
end
end
end

def define_installer_if_needed(bin)
exe = exefile("#{build_dir}/bin/#{bin}")
host? ? define_installer(exe) : exe
Expand Down Expand Up @@ -485,6 +511,29 @@ def internal?
@internal
end

def each_header_files(&block)
return to_enum(__method__) unless block

basedir = File.join(MRUBY_ROOT, "include")
Find.find(basedir) do |d|
next unless File.file? d
yield d
end

@gems.each { |g| g.each_header_files(&block) }

self
end

def install_prefix
@install_prefix || (self.name == "host" ? MRuby::INSTALL_PREFIX :
File.join(MRuby::INSTALL_PREFIX, "mruby/#{self.name}"))
end

def install_prefix=(dir)
@install_prefix = dir&.to_s
end

protected

attr_writer :presym
Expand Down
21 changes: 21 additions & 0 deletions lib/mruby/core_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,27 @@ def relative_path
def remove_leading_parents
Pathname.new(".#{Pathname.new("/#{self}").cleanpath}").cleanpath.to_s
end

def replace_prefix_by(dirmap)
[self].replace_prefix_by(dirmap)[0]
end
end

class Array
# Replace the prefix of each string that is a file path that contains in its own array.
#
# dirmap is a hash whose elements are `{ "path/to/old-prefix" => "path/to/new-prefix", ... }`.
# If it does not match any element of dirmap, the file path is not replaced.
def replace_prefix_by(dirmap)
dirmap = dirmap.map { |older, newer| [File.join(older, "/"), File.join(newer, "/")] }
dirmap.sort!
dirmap.reverse!
self.flatten.map do |e|
map = dirmap.find { |older, newer| e.start_with?(older) }
e = e.sub(map[0], map[1]) if map
e
end
end
end

def install_D(src, dst)
Expand Down
13 changes: 13 additions & 0 deletions lib/mruby/gem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,19 @@ def version_ok?(req_versions)
end
end.all?
end

def each_header_files(&block)
return to_enum(__method__) unless block

self.export_include_paths.flatten.uniq.compact.each do |dir|
Find.find(dir) do |d|
next unless File.file? d
yield d
end
end

self
end
end # Specification

class Version
Expand Down
18 changes: 16 additions & 2 deletions mrbgems/mruby-bin-config/mrbgem.rake
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@ MRuby::Gem::Specification.new('mruby-bin-config') do |spec|
else
mruby_config_dir = "#{build.build_dir}/bin"
end
mruby_config = name + (ENV['OS'] == 'Windows_NT' ? '.bat' : '')

if ENV['OS'] == 'Windows_NT'
suffix = '.bat'
refvar = '%\\1%'
else
suffix = ''
refvar = '${\\1}'
end

mruby_config = name + suffix
mruby_config_path = "#{mruby_config_dir}/#{mruby_config}"
make_cfg = "#{build.build_dir}/lib/libmruby.flags.mak"
tmplt_path = "#{__dir__}/#{mruby_config}"
Expand All @@ -24,11 +33,16 @@ MRuby::Gem::Specification.new('mruby-bin-config') do |spec|

directory mruby_config_dir

file mruby_config_path => [mruby_config_dir, make_cfg, tmplt_path] do |t|
file mruby_config_path => [__FILE__, mruby_config_dir, make_cfg, tmplt_path] do |t|
config = Hash[File.readlines(make_cfg).map!(&:chomp).map! {|l|
l.gsub!(/\$\((\w+)\)/, refvar)
l.gsub('\\"', '"').split(' = ', 2).map! {|s| s.sub(/^(?=.)/, 'echo ')}
}]
tmplt = File.read(tmplt_path)
tmplt.sub!(%r((?<=\A#!/bin/sh\n\n)), <<~SETDIR)
MRUBY_PACKAGE_DIR=$(dirname "$(dirname "$(readlink -f "$0")")")

SETDIR
File.write(t.name, tmplt.gsub(/(#{Regexp.union(*config.keys)})\b/, config))
chmod(0755, t.name)
end
Expand Down
12 changes: 12 additions & 0 deletions mrbgems/mruby-bin-config/mruby-config.bat
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
@echo off

call :init "%~dp0."
goto top

:init
rem call init2 for treatments last directory separator
call :init2 "%~dp1."
goto :eof

:init2
set MRUBY_PACKAGE_DIR=%~f1
goto :eof

:top
shift
if "%0" equ "" goto :eof
Expand Down
33 changes: 33 additions & 0 deletions tasks/install.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
desc "install compiled products (on host)"
task :install => "install:full:host"

desc "install compiled executable (on host)"
task :install_bin => "install:bin:host"

desc "install compiled products (all build targets)"
task "install:full"

desc "install compiled executable (all build targets)"
task "install:bin"

MRuby.each_target do |build|
next if build.internal?

prefix = File.join(MRuby::INSTALL_DESTDIR, build.install_prefix)

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,lib}/**/*")) do |path|
install_D path, File.join(prefix, path.relative_path_from(build.build_dir)) if File.file? path
end
end

task "install:bin" => "install:bin:#{build.name}"

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
end
end
end
Loading