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

Windows support #27

Open
daniel-rikowski opened this issue Nov 15, 2015 · 16 comments
Open

Windows support #27

daniel-rikowski opened this issue Nov 15, 2015 · 16 comments

Comments

@daniel-rikowski
Copy link

I know that ruby-qml doesn't officially support Windows, but I tried it anyway.

After some experimenting I was able to compile libqmlbind and rubyqml-plugin, but the final compilation of the extension fails.

In file included from C:/Ruby/Ruby22/lib/ruby/gems/2.2.0/gems/qml-1.0.2/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind.h:6:0,
                 from qml.h:6,
                 from application.h:3,
                 from application.c:1:
C:/Ruby/Ruby22/lib/ruby/gems/2.2.0/gems/qml-1.0.2/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/interface.h:12:71: error: expected '{' before ')' token
C:/Ruby/Ruby22/lib/ruby/gems/2.2.0/gems/qml-1.0.2/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/interface.h:12:62: error: two or more data types in declaration specifiers
application.c: In function 'application_initialize':
application.c:39:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
application.c:48:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
make: *** [application.o] Error 1

Commenting out the offending lines leads to the same error message at other places, too.

This doesn't look like a platform problem. Is there any hope for Windows compatibility? Is there something I can do?

My environment: Windows 10, Ruby 2.2.3, Qt 5.5.1

@seanchas116
Copy link
Owner

After some experimenting I was able to compile libqmlbind and rubyqml-plugin

Thanks! How did you manage to compile them? I'd like to reproduce the issue.

@daniel-rikowski
Copy link
Author

  1. Install Ruby and DevKit (obviously)
  2. Install Qt into c:\Qt, (paths with spaces won't work!) Also I choose the MinGW edition, not the VS ones.
  3. Install the gem with gem install qml -- --with-qmake=C:\Qt\5.5\mingw492_32\bin\qmake
  4. The code in extconf.rb finishes without error, i.e. both libqmlbind and rubyqml-plugin are compiled and the final Makefile is generated.
  5. The final compilation fails (error as above)

I tried to tinker with the C code and calling make afterwards. (Instead of calling gem install again)
It looks like the compiler is confused about a struct declaration...

@suy
Copy link

suy commented Nov 15, 2015

I think I know what it is. On interface.h line 12 there is an argument named interface. There is some awful Windows header that does #define interface struct. Try to add a simple #undef interface before that line, and see if it compiles.

@daniel-rikowski
Copy link
Author

That worked!

Now only the linker has a problem:

c:/devkit/mingw/i686-w64-mingw32/bin/ld.exe: cannot find -lqmlbind

I guess this has something to do with extconf.rb not setting the correct flags, i.e. the TODO part:

case
when QML::Platform.mac?
  lib_path = qmlbind_dir + 'libqmlbind.dylib'
  system "install_name_tool -id #{lib_path} #{lib_path}"
when QML::Platform.windows?
  # TODO
else
  $LDFLAGS << " -Wl,-rpath #{qmlbind_dir}"
end

Applying the flags from the else branch in the Makefile doesn't help...

@daniel-rikowski
Copy link
Author

Changing
$LDFLAGS << " -L#{qmlbind_dir} -lqmlbind" to
$LDFLAGS << " -L#{qmlbind_dir}/release -lqmlbind" works!

Thanks @suy for providing the solution!

Now I'll check if it actually works 😟

@daddie888
Copy link

Hello Daniel, I'm a fan of Qt, QML and Ruby and I'm on Windows, so did you get it to work eventually ? Mind to share ?

@daniel-rikowski
Copy link
Author

I could compile and link all the libraries, but I could not get any application to start, because qml.so doesn't find all required DLLs at runtime. Unfortunately there are only generic error messages and DependencyWalker only got me so far...

I eventually settled for GTK, which works on Windows out of the box (http://ruby-gnome2.osdn.jp)

@arloan
Copy link

arloan commented Aug 5, 2016

Hi, daniel, what are the names of the DLL files missing?

@daniel-rikowski
Copy link
Author

I don't know, that is the problem 😄 Even Dependency Walker can't tell me. (At least I didn't found it)

The error message is "The specified procedure could not be found" when loading qml.so. That means that either qml.so (unlikely) or one of its dependent modules (most likely) tries to call a library method which isn't there.

But no information on the library or procedure in question...

@arloan
Copy link

arloan commented Aug 5, 2016

@daniel-rikowski
I managed to compile ruby-qml on Windows 7 with Qt 5.7, but failed to run a simple ruby script with it. I'd like to mension that I have to use mingw-gcc 5.3 comes with Qt 5.7 to compile at least libqmlbind, or else qmlbind.dll will not load.

The error is a little difference with yours, this is it:

d:\bullshit\ruby>ruby bs03.rb
d:/rubies/ruby-2.1.6-i386-mingw32/lib/ruby/gems/2.1.0/gems/qml-1.0.2/lib/qml/qml.rb:1:in`require_relative': 126: The specified module could not be found.   -d:/rubies/ruby-2.1.6-i386-mingw32/lib/ruby/gems/2.1.0/gems/qml-1.0.2/ext/qml/qml.so (LoadError)
        from d:/rubies/ruby-2.1.6-i386-mingw32/lib/ruby/gems/2.1.0/gems/qml-1.0.2/lib/qml/qml.rb:1:in `<top (required)>'
        from d:/rubies/ruby-2.1.6-i386-mingw32/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from d:/rubies/ruby-2.1.6-i386-mingw32/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from d:/rubies/ruby-2.1.6-i386-mingw32/lib/ruby/gems/2.1.0/gems/qml-1.0.2/lib/qml.rb:3:in`<top (required)>'
        from d:/rubies/ruby-2.1.6-i386-mingw32/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:133:in `require'
        from d:/rubies/ruby-2.1.6-i386-mingw32/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:133:in `rescue in require'
        from d:/rubies/ruby-2.1.6-i386-mingw32/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:40:in `require'
        from bs03.rb:1:in `<main>'

It's strange since depends.exe tells no real loading error, as shown below:
image

Maybe I should compile Qt 5.7 myself with devkit 4.7.2 which used by ruby 2.0 and above for Windows.

@daniel-rikowski
Copy link
Author

tl;dr: It works. 😀 I used the wrong MinGW runtime libraries.

qml

@arloan Your notes gave me the right idea.

This is what I did before:

  • I also used the gcc shipped with Qt (configured by --with-qmake=C:\Qt\5.5\mingw492_32\bin\qmake)
  • I also got your error ("The specified module could not be found.")
  • From my past experience with Ruby extensions I reckoned the MinGW runtime libraries are missing (e.g. libstdc, libgcc, ...) and I copied them into my script directory.
  • Then the "missing module" error was gone and instead I got the "missing procedure" error, so at least I was on the right track.

Now you mentioning the different MinGW version made me rethink the various compilers involved:

  • There is libqmlbind / qmlbind.dll which is compiled by the Qt compiler (directly from extconf.rb via qmake)
  • Then there is qml.so which is compiled by the Ruby / DevKit compiler. (after extconf.rb with make)

But it is only qmlbind.dll which needs the runtime libraries, specifically the ones from the Qt compiler. My error was using the Ruby / DevKit versions. So the required files were there but since DevKit is older than the Qt ones there were some exports missing.

Thank you all for your input! I was about to play some Fallout 4 this weekend, but this is even better 😉

@arloan
Copy link

arloan commented Aug 6, 2016

@daniel-rikowski
I also finally get it work this morning, and I'm re-producing the whole steps from the very begining to write a memo or blog for this procedure. I'm not very familiar with Git and Gem, so @seanchas116 may have to make things out by yourself, ;-)

My situation is more complex.
Daniel, libqmlbind is still compiled by DevKit 4.7.2, I think. Qmake is just used to generate Makefiles for libqmlbind from the file qmlbind.pro in Gem. You're lucky since you're using old Qt version 5.5, built by mingw-gcc 4.9.2, which is some how compatible with mingw-gcc 4.7.2 of DevKit. While I'm using the newest Qt 5.7.0 built by mingw-gcc 5.3.0, which is not compatible with 4.7.2 in exception handling mechanism (DW2 vs sjlj), makes qmlbind.dll cannot be loaded, see below:
qmlbind

So I had to compile libqmlbind by manual, using Qt's MinGW command line environment. I'm still in finding an automatic way to handle this.

The qml.so depends on qmlbind.dll, while after the gem is compiled and installed, qmlbind.dll still remains in the libqmlbind/qmlbind/release directory, so qml.so still cannot load by require 'qml'. Simply copy qmlbind.dll to the directory which qml.so resides during installation does not make sense, since this is not the way the Windows DLL loading process goes. See here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx#search_order_for_desktop_applications
qmlbind.dll it self depends on Qt's runtime library, so I finally copied qmlbind.dll to Qt's bin folder and add the folder into system PATH list.

Another problem comes with Qt 5.7.0 and my sandybridge GPU, when I run a qml script, Qt reports some render errors:

QOpenGLShader::link: Failed to create D3D shaders.

shader compilation failed: 
"Failed to create D3D shaders.\n"
QOpenGLShader::link: Failed to create D3D shaders.
Failed to create D3D shaders.

The app window's client area becomes black brick-ed when resized, and render errors continue bumping out. See below:
resized

I have to copy and replace libEGL.dll and libGLESv2.dll in Qt's bin folder, with the same files come from Qt creator 3.4.2.

Finally, ruby-qml is happy. :-)

@daddie888
Copy link

Hi Daniel and Arloan, nice work. QML has always interested me but on the
site of Ruby-Qml they state you need OSX or Linux and reading this mail
makes it obvious that it is not easy to install it in Windows, so I wonder
where I can find the versions and steps involved ? Would you mind to share
please ? Is there a way to port the compiled program ? I have QT installed
with Ruby 2.3 on Windows 7 but haven't much experience with the compilers
and dependencies.

Peter

2016-08-06 15:04 GMT+02:00 daniel-rikowski [email protected]:

tl;dr: It works. 😀 I used the wrong MinGW runtime libraries.

[image: qml]
https://cloud.githubusercontent.com/assets/1169363/17456834/c69953f6-5be4-11e6-863f-814b3d0abc97.png

@arloan https://github.com/arloan Your notes gave me the right idea.

This is what I did before:

  • I also used the gcc shipped with Qt (configured by
    --with-qmake=C:\Qt\5.5\mingw492_32\bin\qmake)
  • I also got your error ("The specified module could not be found.")
  • From my past experience with Ruby extensions I reckoned the MinGW
    runtime libraries are missing (e.g. libstdc, libgcc, ...) and I copied them
    into my script directory.
  • Then the "missing module" error was gone and instead I got the
    "missing procedure" error, so at least I was on the right track.

Now you mentioning the different MinGW version made me rethink the
various compilers involved:

  • There is libqmlbind / qmlbind.dll which is compiled by the Qt
    compiler (directly from extconf.rb via qmake)
  • Then there is qml.so which is compiled by the Ruby / DevKit
    compiler. (after extconf.rb with make)

But it is only qmlbind.dll which needs the runtime libraries, specifically
the ones from the Qt compiler. My error was using the Ruby / DevKit
versions. So the required files were there but since DevKit is older than
the Qt ones there were some exports missing.

Thank you all for your input! I was about to play some Fallout 4 this
weekend, but this is even better 😉


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#27 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABpXqqs0ZYwkBDEr02dsAyWfHn4VIyJZks5qdIZ2gaJpZM4Gic9M
.

@arloan
Copy link

arloan commented Aug 6, 2016

I wrote a blog for this whole procedure.

@daniel-rikowski
Copy link
Author

Very nice blog post!

Judging from bug reports (e.g. QTBUG-53680) the 3D shader problem in Qt 5.7 might also be fixed by updating DirectX.

@arloan
Copy link

arloan commented Aug 7, 2016

Yeah, I know that, but I'm too lazy to update DirectX. ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants