ruby / rake

A make-like build utility for Ruby.

Home Page:https://ruby.github.io/rake

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

sh_show_command: Quotes are missing for an extra option including a space.

junaruga opened this issue · comments

Summary

In the following rake command to compile a native extension with rake-compiler gem, where the extra options whose value (--with-cflags='-Wundef -Werror') includes a space, in this case -Wundef -Werror is printed without quotes. And the command is different from the one actually executed and it's not reproducible.

$ bundle exec rake compile -- --with-cflags='-Wundef -Werror'
...
/home/jaruga/.local/ruby-cbeba2ed16/bin/ruby -I. -r.rake-compiler-siteconf.rb ../../../../ext/openssl/extconf.rb -- --with-cflags=-Wundef -Werror
...

I think quotes (double quotes or single quotes) are needed like the command below.

/home/jaruga/.local/ruby-cbeba2ed16/bin/ruby -I. -r.rake-compiler-siteconf.rb ../../../../ext/openssl/extconf.rb -- --with-cflags="-Wundef -Werror"

Note that @kou helped me to report this issue here at rake-compiler/rake-compiler#215 (comment).

My environment

I am using the following my environment on Fedora Linux 37. I think this issue doesn't depend on the specific version of the Ruby. I would share it with you just in case.

$ ruby -v
ruby 3.3.0dev (2023-05-25T12:45:21Z wip/mkmf-verbose-r.. cbeba2ed16) [x86_64-linux]

$ which gem
~/.local/ruby-cbeba2ed16/bin/gem
$ gem -v
3.5.0.dev

$ which bundle
~/.local/ruby-cbeba2ed16/bin/bundle

$ bundle -v
Bundler version 2.5.0.dev

Reproducing steps

Here are the reproducing steps with the ruby/openssl: https://github.com/ruby/openssl first.

$ git clone https://github.com/ruby/openssl.git

$ cd openssl

$ bundle install --standalone

$ bundle list | grep rake
  * rake (13.0.6)
  * rake-compiler (1.2.2)

Ran the rake with the rake-compiler gem. The following command is to compile the native extension setting the -Wundef -Werror as compiler flags. You see the command propagates the -Wundef -Werror to the gcc command lines. It's important to run with the rake-compiler latest stable version 1.2.2. Because it fixes rake-compiler/rake-compiler#215 related to this issue. The environment variable MAKEFLAGS reserved in the GNU make is to print the compiler command lines.

$ MAKEFLAGS="V=1" bundle exec rake compile -- --with-cflags='-Wundef -Werror'
mkdir -p tmp/x86_64-linux/openssl/3.3.0
cd tmp/x86_64-linux/openssl/3.3.0
/home/jaruga/.local/ruby-cbeba2ed16/bin/ruby -I. -r.rake-compiler-siteconf.rb ../../../../ext/openssl/extconf.rb -- --with-cflags=-Wundef -Werror
checking for rb_io_maybe_wait(0, Qnil, Qnil, Qnil) in ruby/io.h... yes
...
gcc -I. -I/home/jaruga/.local/ruby-cbeba2ed16/include/ruby-3.3.0+0/x86_64-linux -I/home/jaruga/.local/ruby-cbeba2ed16/include/ruby-3.3.0+0/ruby/backward -I/home/jaruga/.local/ruby-cbeba2ed16/include/ruby-3.3.0+0 -I../../../../ext/openssl  -DRUBY_EXTCONF_H=\"extconf.h\"    -fPIC -Wundef -Werror   -o openssl_missing.o -c ../../../../ext/openssl/openssl_missing.c
...
cp tmp/x86_64-linux/openssl/3.3.0/openssl.so tmp/x86_64-linux/stage/lib/openssl.so

$ echo $?
0

The problem is the the line /home/jaruga/.local/ruby-cbeba2ed16/bin/ruby -I. -r.rake-compiler-siteconf.rb ../../../../ext/openssl/extconf.rb -- --with-cflags=-Wundef -Werror printed at sh in the lib/rake/extensiontask.rb. Because the --with-cflags=-Wundef -Werror is different from the one actually executed, and not reproducible. The argument --with-cflags's value is -Wundef -Werror. It should be printed as --with-cflags="-Wundef -Werror" with quotes.

Debug

I debugged with debug gem. Added the gem "debug" to the ruby/openssl's Gemfile.

$ pwd
/home/jaruga/git/ruby/openssl

$ vi Gemefile

$ bundle update

Next set the breakpoint before the sh method to print and execute the command.

$ cd /home/jaruga/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-compiler-1.2.2/lib/rake

$ pwd
/home/jaruga/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-compiler-1.2.2/lib/rake

$ diff -u extensiontask.rb.orig extensiontask.rb
--- extensiontask.rb.orig	2023-05-26 20:36:06.207487491 +0200
+++ extensiontask.rb	2023-05-26 21:14:35.794188802 +0200
@@ -215,6 +215,9 @@
         end
 
         chdir tmp_path do
+          require 'debug'
+          binding.break
+
           sh *cmd
         end
       end

Went back to the ruby/openssl, and cleaned the built files.

$ pwd
/home/jaruga/git/ruby/openssl

$ rm -rf tmp lib/openssl.so

And ran the command again.

$ MAKEFLAGS="V=1" bundle exec rake compile -- --with-cflags='-Wundef -Werror'
...
(rdbg) f    # frame command
=> 219|           binding.break
=>#0	block in define_compile_tasks (2 levels) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-compiler-1.2.2/lib/rake/extensiontask.rb:219
(rdbg) p cmd    # command
=> ["/home/jaruga/.local/ruby-cbeba2ed16/bin/ruby", "-I.", "-r.rake-compiler-siteconf.rb", "../../../../ext/openssl/extconf.rb", "--", "--with-cflags=-Wundef -Werror"]
...

The lib/rake/file_utils.rb#sh calling Rake.rake_output_message sh_show_command cmd. And the cmd.join " " in the sh_show_command causes this issue. Is it a bug?

(rdbg) n    # next command
[77, 86] in ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/file_utils.rb
    77|       env = cmd.first
    78|       env = env.map { |name, value| "#{name}=#{value}" }.join " "
    79|       cmd[0] = env
    80|     end
    81| 
=>  82|     cmd.join " "
    83|   end
    84|   private :sh_show_command
    85| 
    86|   def set_verbose_option(options) # :nodoc:
(rdbg) f    # frame command
=>  82|     cmd.join " "
=>#0	FileUtils#sh_show_command(cmd=["/home/jaruga/.local/ruby-cbeba2ed16/bin...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/file_utils.rb:82
(rdbg) p cmd    # command
=> ["/home/jaruga/.local/ruby-cbeba2ed16/bin/ruby", "-I.", "-r.rake-compiler-siteconf.rb", "../../../../ext/openssl/extconf.rb", "--", "--with-cflags=-Wundef -Werror"]
(rdbg) p cmd.join " "    # command
=> "/home/jaruga/.local/ruby-cbeba2ed16/bin/ruby -I. -r.rake-compiler-siteconf.rb ../../../../ext/openssl/extconf.rb -- --with-cflags=-Wundef -Werror"

I would show you the backtrace command just in case.

(rdbg) f    # frame command
=>  82|     cmd.join " "
=>#0	FileUtils#sh_show_command(cmd=["/home/jaruga/.local/ruby-cbeba2ed16/bin...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/file_utils.rb:82
(rdbg) bt    # backtrace command
=>#0	FileUtils#sh_show_command(cmd=["/home/jaruga/.local/ruby-cbeba2ed16/bin...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/file_utils.rb:82
  #1	FileUtils#sh(cmd=["/home/jaruga/.local/ruby-cbeba2ed16/bin..., block=nil) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/file_utils.rb:51
  #2	block in define_compile_tasks (2 levels) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-compiler-1.2.2/lib/rake/extensiontask.rb:221
  #3	[C] Dir.chdir at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/fileutils.rb:240
  #4	FileUtils#chdir(dir="tmp/x86_64-linux/openssl/3.3.0", verbose=#<Object:0x00007fd7eb4ad510>, block=#<Proc:0x00007fd7ea893108 /home/jaruga/va...) at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/fileutils.rb:240
  #5	Rake::FileUtilsExt#chdir(args=["tmp/x86_64-linux/openssl/3.3.0"], options={}, block=#<Proc:0x00007fd7ea8930b8 /home/jaruga/va...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/file_utils_ext.rb:35
  #6	block {|t=<Rake::FileTask tmp/x86_64-linux/openssl/...|} in define_compile_tasks at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-compiler-1.2.2/lib/rake/extensiontask.rb:217
  #7	block {|act=#<Proc:0x00007fd7efbd8b10 /home/jaruga/va...|} in execute at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:281
  #8	[C] Array#each at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:281
  #9	Rake::Task#execute(args=#<Rake::TaskArguments >) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:281
  #10	block in invoke_with_call_chain at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:219
  #11	[C] Monitor#synchronize at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #12	Rake::Task#invoke_with_call_chain(task_args=#<Rake::TaskArguments >, invocation_chain=LL(<Rake::FileTask tmp/x86_64-linux/opens...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #13	block {|p=<Rake::FileTask tmp/x86_64-linux/openssl/...|} in invoke_prerequisites at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:243
  #14	[C] Array#each at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:241
  #15	Rake::Task#invoke_prerequisites(task_args=#<Rake::TaskArguments >, invocation_chain=LL(<Rake::FileTask tmp/x86_64-linux/opens...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:241
  #16	block in invoke_with_call_chain at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:218
  #17	[C] Monitor#synchronize at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #18	Rake::Task#invoke_with_call_chain(task_args=#<Rake::TaskArguments >, invocation_chain=LL(<Rake::Task copy:openssl:x86_64-linux:...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #19	block {|p=<Rake::FileTask tmp/x86_64-linux/openssl/...|} in invoke_prerequisites at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:243
  #20	[C] Array#each at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:241
  #21	Rake::Task#invoke_prerequisites(task_args=#<Rake::TaskArguments >, invocation_chain=LL(<Rake::Task copy:openssl:x86_64-linux:...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:241
  #22	block in invoke_with_call_chain at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:218
  #23	[C] Monitor#synchronize at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #24	Rake::Task#invoke_with_call_chain(task_args=#<Rake::TaskArguments >, invocation_chain=LL(<Rake::Task compile:openssl:x86_64-lin...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #25	block {|p=<Rake::Task copy:openssl:x86_64-linux:3.3...|} in invoke_prerequisites at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:243
  #26	[C] Array#each at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:241
  #27	Rake::Task#invoke_prerequisites(task_args=#<Rake::TaskArguments >, invocation_chain=LL(<Rake::Task compile:openssl:x86_64-lin...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:241
  #28	block in invoke_with_call_chain at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:218
  #29	[C] Monitor#synchronize at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #30	Rake::Task#invoke_with_call_chain(task_args=#<Rake::TaskArguments >, invocation_chain=LL(<Rake::Task compile:x86_64-linux => [c...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #31	block {|p=<Rake::Task compile:openssl:x86_64-linux ...|} in invoke_prerequisites at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:243
  #32	[C] Array#each at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:241
  #33	Rake::Task#invoke_prerequisites(task_args=#<Rake::TaskArguments >, invocation_chain=LL(<Rake::Task compile:x86_64-linux => [c...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:241
  #34	block in invoke_with_call_chain at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:218
  #35	[C] Monitor#synchronize at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #36	Rake::Task#invoke_with_call_chain(task_args=#<Rake::TaskArguments >, invocation_chain=LL(<Rake::Task compile => [compile:x86_64...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #37	block {|p=<Rake::Task compile:x86_64-linux => [comp...|} in invoke_prerequisites at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:243
  #38	[C] Array#each at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:241
  #39	Rake::Task#invoke_prerequisites(task_args=#<Rake::TaskArguments >, invocation_chain=LL(<Rake::Task compile => [compile:x86_64...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:241
  #40	block in invoke_with_call_chain at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:218
  #41	[C] Monitor#synchronize at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #42	Rake::Task#invoke_with_call_chain(task_args=#<Rake::TaskArguments >, invocation_chain=LL()) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:199
  #43	Rake::Task#invoke(args=[]) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/task.rb:188
  #44	Rake::Application#invoke_task(task_string="compile") at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/application.rb:160
  #45	block {|task_name="compile"|} in top_level (2 levels) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/application.rb:116
  #46	[C] Array#each at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/application.rb:116
  #47	block in top_level at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/application.rb:116
  #48	Rake::Application#run_with_threads at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/application.rb:125
  #49	Rake::Application#top_level at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/application.rb:110
  #50	block in run at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/application.rb:83
  #51	Rake::Application#standard_exception_handling at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/application.rb:186
  #52	Rake::Application#run(argv=["compile", "--", "--with-cflags=-Wundef ...) at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/lib/rake/application.rb:80
  #53	<top (required)> at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/gems/rake-13.0.6/exe/rake:27
  #54	[C] Kernel#load at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/bin/rake:25
  #55	<top (required)> at ~/var/git/ruby/openssl/bundle/ruby/3.3.0+0/bin/rake:25
  #56	[C] Kernel.load at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/cli/exec.rb:58
  #57	Bundler::CLI::Exec#kernel_load(file="/home/jaruga/var/git/ruby/openssl/bundle..., args=["compile", "--", "--with-cflags=-Wundef ...) at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/cli/exec.rb:58
  #58	Bundler::CLI::Exec#run at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/cli/exec.rb:23
  #59	Bundler::CLI#exec(args=["compile", "--", "--with-cflags=-Wundef ...) at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/cli.rb:492
  #60	Bundler::Thor::Command#run(instance=#<Bundler::CLI:0x00007fd7eb4ed160 @_initi..., args=["rake", "compile", "--", "--with-cflags=...) at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/vendor/thor/lib/thor/command.rb:27
  #61	Bundler::Thor::Invocation#invoke_command(command=#<struct Bundler::Thor::Command name="exe..., args=[["rake", "compile", "--", "--with-cflags...) at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/vendor/thor/lib/thor/invocation.rb:127
  #62	#<Class:Bundler::Thor>#dispatch(meth="exec", given_args=["rake", "compile", "--", "--with-cflags=..., given_opts=nil, config={:debug=>true, :shell=>#<Bundler::Thor::S...) at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/vendor/thor/lib/thor.rb:392
  #63	Bundler::CLI.dispatch at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/cli.rb:34
  #64	Bundler::Thor::Base::ClassMethods#start(given_args=["compile", "--", "--with-cflags=-Wundef ..., config={:debug=>true, :shell=>#<Bundler::Thor::S...) at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/vendor/thor/lib/thor/base.rb:485
  #65	Bundler::CLI.start at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/cli.rb:28
  #66	block in <top (required)> at ~/.local/ruby-cbeba2ed16/lib/ruby/gems/3.3.0+0/gems/bundler-2.5.0.dev/libexec/bundle:45
  #67	Bundler.with_friendly_errors at ~/.local/ruby-cbeba2ed16/lib/ruby/3.3.0+0/bundler/friendly_errors.rb:117
  #68	<top (required)> at ~/.local/ruby-cbeba2ed16/lib/ruby/gems/3.3.0+0/gems/bundler-2.5.0.dev/libexec/bundle:33
  #69	[C] Kernel#load at ~/.local/ruby-cbeba2ed16/bin/bundle:25
  #70	<main> at ~/.local/ruby-cbeba2ed16/bin/bundle:25