ruby / fiddle

A libffi wrapper for Ruby.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"already initialized constant" warnings

XhmikosR opened this issue · comments

Microsoft Windows [Version 10.0.19042.630]
(c) 2020 Microsoft Corporation. All rights reserved.

C:\Users\xmr\Desktop>ruby -v && gem -v
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x64-mingw32]
3.1.4

C:\Users\xmr\Desktop>gem update --system
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_VOID
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_VOIDP
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_CHAR
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_SHORT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_INT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_LONG
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_LONG_LONG
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_FLOAT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_DOUBLE
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_SIZE_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_SSIZE_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_PTRDIFF_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_INTPTR_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::TYPE_UINTPTR_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_VOIDP
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_CHAR
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_SHORT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_INT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_LONG
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_LONG_LONG
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_FLOAT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_DOUBLE
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_SIZE_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_SSIZE_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_PTRDIFF_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_INTPTR_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::ALIGN_UINTPTR_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::WINDOWS
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_VOIDP
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_CHAR
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_SHORT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_INT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_LONG
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_LONG_LONG
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_FLOAT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_DOUBLE
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_SIZE_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_SSIZE_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_PTRDIFF_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_INTPTR_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::SIZEOF_UINTPTR_T
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::RUBY_FREE
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::BUILD_RUBY_PLATFORM
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::Function::DEFAULT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::Handle::NEXT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::Handle::DEFAULT
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::Handle::RTLD_GLOBAL
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::Handle::RTLD_LAZY
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::Handle::RTLD_NOW
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.so: warning: already initialized constant Fiddle::NULL
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.rb:55: warning: already initialized constant Fiddle::RTLD_GLOBAL
C:/Ruby27-x64/lib/ruby/2.7.0/fiddle.rb:53: warning: previous definition of RTLD_GLOBAL was here
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.rb:56: warning: already initialized constant Fiddle::RTLD_LAZY
C:/Ruby27-x64/lib/ruby/2.7.0/fiddle.rb:54: warning: previous definition of RTLD_LAZY was here
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/fiddle-1.0.2/lib/fiddle.rb:57: warning: already initialized constant Fiddle::RTLD_NOW
C:/Ruby27-x64/lib/ruby/2.7.0/fiddle.rb:55: warning: previous definition of RTLD_NOW was here
Latest version already installed. Done.

We can't use Fiddle gem with Ruby installed by RubyInstaller for now.
Because RubyInstaller requires built-in Fiddle before RubyGems is required.

See also:

Could you report this to https://github.com/oneclick/rubyinstaller2 ?

Thanks for notifying me! I didn't think about using fiddle as a gem.

Any thoughts how to solve this? As a last resort we could switch to a custom C extension instead of using fiddle for RubyInstaller's internal use.

Can we use the following approach?

  1. Initialize RubyGems
  2. Require Fiddle
  3. Initialize DLL path

FYI: the current approach:

  1. Require Fiddle
  2. Initialize DLL path
  3. Initialize RubyGems

I am also getting some warnings on my Linux system, though much less verbose, so I don't believe this strictly related to RubyInstaller, though the underlying cause may still be the same.

The project I am working on is a C extension that uses rb_require("fiddle") internally so that I can get the instance of the Fiddle::Pointer class as a VALUE to be used in a few API calls. Obviously the Ruby code also requires Fiddle in order to use the Ruby instances, which results in the following warnings:

/home/eric/.gem/ruby/2.7.0/gems/fiddle-1.0.3/lib/fiddle.rb:55: warning: already initialized constant Fiddle::RTLD_GLOBAL
/usr/lib/ruby/2.7.0/fiddle.rb:53: warning: previous definition of RTLD_GLOBAL was here
/home/eric/.gem/ruby/2.7.0/gems/fiddle-1.0.3/lib/fiddle.rb:56: warning: already initialized constant Fiddle::RTLD_LAZY
/usr/lib/ruby/2.7.0/fiddle.rb:54: warning: previous definition of RTLD_LAZY was here
/home/eric/.gem/ruby/2.7.0/gems/fiddle-1.0.3/lib/fiddle.rb:57: warning: already initialized constant Fiddle::RTLD_NOW
/usr/lib/ruby/2.7.0/fiddle.rb:55: warning: previous definition of RTLD_NOW was here

I don't get the wall of text that OP is getting, but the last few constants wrapping dl load flags is the same.

@ForeverZer0 Could you show how to reproduce your case on fresh Linux system?

@kou

Use Bundler to generate some boilerplate for a gem with a C extension

├── bin
│   ├── console
│   └── setup
├── CODE_OF_CONDUCT.md
├── ext
│   └── test_project
│       ├── extconf.rb
│       ├── test_project.c
│       └── test_project.h
├── Gemfile
├── lib
│   ├── test_project
│   │   ├── test_project.so
│   │   └── version.rb
│   └── test_project.rb
├── LICENSE.txt
├── Rakefile
├── README.md
├── test_project.gemspec

test_project.c

#include "test_project.h"

VALUE rb_mTestProject;

void Init_test_project(void)
{
  rb_mTestProject = rb_define_module("TestProject");
  rb_require("fiddle");
}

test_project.rb

# No warnings if done here
# require 'fiddle'

require_relative "test_project/version"
require_relative "test_project/test_project"

# Warnings if done here
require 'fiddle'

I did notice that if the require 'fiddle' line is BEFORE requiring the C extension, there is no warning. Obviously it is best practice to require standard lbrary gems prior to local/3rd-party ones, though this is not often followed, nor even possible in some scenarios given how flexible Ruby is with metaprogramming.

I can obviously fix this by simply checking if Fiddle is already defined prior to requiring it in C, though it was not doing it it prior to today when I ran gem update, and I noticed Fiddle was updated.

I got it.
It'll be fixed by replacing rb_require("fiddle") with rb_funcall(rb_mKernel, rb_intern("require"), 1, rb_str_new_cstr("fiddle")).
rb_require() doesn't care about RubyGems. It always requires non-gemed Fiddle.

Ah, I see, I was not aware of that distinction, though the above fix resulted in the same behavior for me. Changing the order of requires in the .rb file fixes the issue in my current project, so it was not big deal, and better enforces good practices I was not following xD.

Could you try rb_funcall(rb_cObject, rb_intern("require"), 1, rb_str_new_cstr("fiddle"))?

@kou
Just tried it, and it that variation works using rb_cObject. It did not emit any warnings, regardless which order I required the files.

It seems the warnings are gone for me with the latest gem version.