Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
junaruga opened this issue May 26, 2023 · 0 comments
Open

Comments

@junaruga
Copy link
Member

junaruga commented May 26, 2023

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant