Project

General

Profile

Actions

Bug #22438

open

mkmf.rb do not work with /home mounted with noexec

Bug #22438: mkmf.rb do not work with /home mounted with noexec

Added by mbideau (Michael Bideau) about 10 hours ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 3.3.8 (2025-04-09 revision b200bad6cd) [x86_64-linux-gnu]
[ruby-core:127103]

Description

When trying to install a vagrant plugin (here vagrant-libvirt), it uses the file mkmf.rb (here /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb) and this fail with the following error message:

Vagrant failed to install the requested plugin because development tools
are required for installation but are not currently installed on this
machine. Please install development tools and then try this command
again.

It is the user facing error message that is from the following underlying command:

/opt/vagrant/embedded/bin/ruby --verbose extconf.rb
checking for pkg-config for libvirt... /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:480:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.

	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:573:in `try_link0'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:591:in `try_link'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:683:in `try_ldflags'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:1896:in `block in pkg_config'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:983:in `block in checking_for'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:344:in `block (2 levels) in postpone'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:314:in `open'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:344:in `block in postpone'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:314:in `open'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:340:in `postpone'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:982:in `checking_for'
	from /opt/vagrant/embedded/lib/ruby/3.3.0/mkmf.rb:1862:in `pkg_config'
	from extconf.rb:5:in `<main>'

The mentioned try_do function is where the issue is.
Here is its code (as the ruby version 3.3.8):

  def try_do(src, command, *opts, &b)
    unless have_devel?
      raise <<MSG
The compiler failed to generate an executable file.
You have to install development tools first.
MSG
    end
    begin
      src = create_tmpsrc(src, &b)
      xsystem(command, *opts)
    ensure
      log_src(src)
    end
  end

Which is called by try_link0 function that has the following code:

  def try_link0(src, opt="", *opts, &b) # :nodoc:
    exe = CONFTEST+$EXEEXT
    cmd = link_command("", opt)
    if $universal
      require 'tmpdir'
      Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
        begin
          ENV["TMPDIR"] = tmpdir
          try_do(src, cmd, *opts, &b)
        ensure
          ENV["TMPDIR"] = oldtmpdir
        end
      end
    else
      try_do(src, cmd, *opts, &b)
    end and File.executable?(exe) or return nil
    exe
  ensure
    MakeMakefile.rm_rf(*Dir["#{CONFTEST}*"]-[exe])
  end

So you can see, if my understanding is correct, that the environment variableTMPDIR, despite being set, is never used/honored to execute the command.
The command is still running in the current working directory, and the TMPDIR is ignored/useless.

In my case the current working directory is ~/.vagrant.d/gems/3.3.8/gems/ruby-libvirt-0.8.4/ext/libvirt which is in my /home mounted with noexec.
This makes File.executable?(exe) (exe is the compiled file) returning false because the source and the compiled file (even if they are just to test) end up in my working directory and not in the temporary directory specified with the environment variable TMPDIR which have exec permission.

So I suggest to always use a temporary directory to execute all the tests contained in this code file mkmf.rb and to actually honor TMPDIR when defined.

No data to display

Actions

Also available in: PDF Atom