Git Product home page Git Product logo

qt5.cr's Introduction

Qt5 bindings for Crystal

Bindings for the Qt5 Framework using bindgen.

Table of Contents

Project Goals

  • Just Works™ - Drop the dependency into a project, and use it
  • Providing an API that feels native to Crystal
  • Focus on the GUI components (i.e. QtCore, QtGui, QtWidgets)

Installation

If you just want to develop a Crystal app which uses Qt5, use the master-ready-to-use branch. It contains pre-built/pre-generated bindings for certain platform and Qt combinations. If that branch contains the pre-generated bindings for your platform, which you can verify in the subdirectory ext/, you won't need bindgen at all.

dependencies:
  qt5:
    github: Papierkorb/qt5.cr
    branch: master-ready-to-use

If you want the bindings to be generated for the current system, or if you want to generate bindings for new platform and Qt combinations, use the master branch:

dependencies:
  qt5:
    github: Papierkorb/qt5.cr
    branch: master

In any case, your users will be required to have the Qt5 libraries on their system because this project defaults to binding to Qt libraries dynamically. (See more on this under License below.)

Additional development dependencies

Using your system's package manager:

  • ArchLinux pacman -S qt5-base
  • Debian/Ubuntu/Devuan apt-get install qtbase5-dev cmake llvm-dev clang libclang-dev libz-dev libstdc++-dev

You also need cmake.

User perspective

Sample Crystal-Qt5 code

Have a look in samples/!

A short Hello World snippet looks like this:

require "qt5"

qApp = Qt::Application.new

label = Qt::Label.new "Hello from Crystal/Qt!"
label.show

Qt::Application.exec

hello-qt

Locale

By default Qt sets the locale to the system locale when an application class (like Qt::Application) is instantiated. However, this causes stdlib Crystal functions like to_f to behave unexpectedly, e.g., using a different character as decimal separator (also see the discussion of this PR). Therefore, in contrast to the behaviour of the C++ classes of Qt, qt5.cr resets the numeric locale to "C" after creating an application class instance (this follows an advice from Qt itself).

Developer perspective

Generating the bindings

If you want to work on qt5.cr itself or you want to generate bindings for new versions, then as mentioned you need to use branch master and run the generation yourself.

These steps can be followed from a project using qt5.cr, or from within qt5.cr itself. For the latter, you can just go to lib/bindgen and do git checkout master instead of modifying shard.yml.

Important: For this you'll also have to meet the dependencies of bindgen.

Naming scheme

As qt5.cr supports many different versions of Qt on different platforms, generated bindings follow a naming scheme. The scheme contains 4 components as follows:

KERNEL - LIB_C - ARCH - qtVERSION, e.g. linux-gnu-x86_64-qt5.13

Where:

  • KERNEL is the OS kernel, e.g. linux, darwin, windows
  • LIB_C is the lib C name, e.g. gnu, musl, win32
  • ARCH is the architecture, e.g. i686, x86_64, arm
  • VERSION is the Qt version, e.g. 5.9, 5.12, 5.15

The naming scheme is not strictly enforced. However, it should always end with -qtVERSION!

(Re)generating all Qt5 binding versions

The master-ready-to-use branch contains a number of prebuilt bindings. The following process was used to build them:

  1. Cd into the qt5.cr directory, switch to the master branch
  2. Edit support/generate_bindings.cr and enable all versions for which you want to generate the bindings
  3. Run crystal support/generate_bindings.cr
  4. Commit the files in ext/ to the master-ready-to-use branch

The build process will automatically download, unpack, build, and generate all configured versions of Qt5. It'll store the downloaded and unpacked Qt5 versions to directory called download_cache/. Subsequent invocations of that script will use these cached assets.

The first run may take a long time, and each version of Qt5 will take up about 4GB of disk space.

(Re)generating a specific Qt5 binding version

  1. Use the master branch of qt5.cr in your shard.yml
  2. Decide which version of Qt to use, and build the scheme (See above)
  3. Export the binding scheme: export BINDING_PLATFORM=linux-gnu-x86_64-qt5.13
  4. If you're not using your system's Qt: export QMAKE=/path/to/qmake
  5. Run bindgen as usual: lib/bindgen/tool.sh qt.yml --stats
  6. Verify with crystal spec

Future things to do

  • Forwarding qHash() of wrapped types (to Object#hash)
  • Integration with LibEvent: Right now, Qt blocks the whole thread.
  • The rest of the billion Qt classes of interest
  • Everything in the to be done category
  • Integration for the Qt Designer UI designer
  • Integration for Qt Linguist
    • Localization/Translation for your applications!
  • UI test library, with adapter for spec
    • Also, actual tests - Let's catch whacko bugs right in the CI!
  • Automated copy (and adaption) of the Qt documentation, for easy Crystal-specific docs
    • The Qt Docs license should allow this if done correctly

Platform Support

System Status Qt version OOTB?
ArchLinux Works always 5.12 YES
Ubuntu 17.04 Works 5.9 YES
Ubuntu 16.04 Works 5.5 YES
MacOS Help wanted ? ?
Windows Help wanted ? ?
Other systems Help wanted ? ?

Ready-to-use Qt versions: 5.5 to 5.12

(This list needs updating)

Contributing

  1. Open a new issue on the project to discuss what you're going to do and possibly receive comments
  2. Read bindgen's STYLEGUIDE.md for some tips
  3. Then do the rest, PR and all. You know the drill :)

Contributors

License

The Qt bindings, including the generated and manually-written parts, are subject to the MPL-2 license. You can find a copy attached of the full license text in the LICENSE file.

This project claims no copyright on the Qt framework or of any of its trademarks, source, or any other assets.

A note on Qt's license

A common misconception is that you have to pay for Qt to use it in closed-source applications.

This project assumes you'll link to Qt dynamically. In this case, you can use Qt free of charge including for closed-source, commercial applications under the terms of the LGPL.

You can build closed-source applications using Crystal, this shard, and Qt for free.

Note: This section is to combat this misconception, the authors of qt5.cr are in no way responsible to check if the same terms apply in your jurisdiction.

qt5.cr's People

Contributors

byteit101 avatar codenoid avatar docelic avatar f-fr avatar faustinoaq avatar foliea avatar hertzdevil avatar kalinon avatar papierkorb avatar shalokshalom avatar zawertun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qt5.cr's Issues

Marshalling polymorphic Crystal wrappers in QObject

Once a Crystal wrapper type reaches C++, it loses its Crystal type information because only @unwrap remains, which is the pointer to the original C++ instance; something must keep track of the Crystal instance in a C++ instance. QObject, the base class of most virtual classes, doesn't offer any void * instance variable, but it has dynamic properties. So my idea is:

  • Rename CrystalVariant to a different name like CrystalAny, since it can store any Crystal value, but isn't really a drop-in replacement for QVariant;
  • Wrap QVariant normally, removing the entire type configuration in config/types.yml;
  • Expose qvariant_to_crystal and crystal_to_qvariant to Crystal manually;
  • Somewhere during initialization of every instance derived from Qt::Object, convert the instance into a Qt::Variant storing a CrystalAny;
  • Store that variant into a dynamic property called _bindgen_value for example (since Crystal wrappers never call super in their #initialize methods, this will be stored exactly once), most likely through a code body hook;
  • Define Qt::Object#to_crystal(T.class) in src/qt5/object.cr, which reads the dynamic property and converts it back to a Crystal value of type T, and similarly for the non-throwing #to_crystal?. Suppose that MyWidget < Qt::Widget < Qt::Object. Then calling #to_crystal?(MyWidget) would be something like:
def to_crystal?(_t : MyWidget.class) : MyWidget?
  # `any` shall refer to the receiver itself (same `@unwrap` if valid)
  any = qvariant_to_crystal(self.property("_bindgen_value"))

  # `CrystalAny` itself does not store polymorphic values; attempt every class down the hierarchy
  # if given type argument is a union type, repeat the part for each alternative
  case any.type_id
  # early return
  when Nil.crystal_instance_type_id         then nil

  # the following part shall be macro-ized
  when MyWidget.crystal_instance_type_id    then any.to(MyWidget)
  when Qt::Widget.crystal_instance_type_id  then any.to(Qt::Widget).as?(MyWidget)
  when Qt::Object.crystal_instance_type_id  then any.to(Qt::Object).as?(MyWidget)
  when ::Reference.crystal_instance_type_id then any.to(::Reference).as?(MyWidget)
  when ::Object.crystal_instance_type_id    then any.to(::Object).as?(MyWidget)

  # nothing matches
  else nil
  end
end

#to_crystal works even for descendents of abstract wrapper types. If MyGraphicsItem, Qt::GraphicsItemImpl < Qt::GraphicsItem:

scene : Qt::GraphicsScene
scene.items.each do |item|
  # `item` is a `Qt::GraphicsItemImpl`
  # if `item` is in fact a `MyGraphicsItem`, the first `any.to` will succeed;
  # otherwise, next check will be against `Qt::GraphicsItem`, which can be
  # downcast to `MyGraphicsItem`, so no syntax error occurs
  if my_item = item.to_crystal?(MyGraphicsItem)
    # item.to_unsafe == my_item.to_unsafe
  end
end

This will be helpful whenever a Qt function returns a Qt object where subclassing is expected. It also makes Qt::Variant usable (to be fair I see no problems with Qt's original interface, but more importantly the type shouldn't give the impression that Crystal types are already integrated within the Qt meta-object system).

Any thoughts on this?

Undefined method 'mapping' for YAML:Module

Hello, today I tried to use the Qt5 library with crystal, I followed the instruction, but when I tried to run the example from the website, this don’t work, I have this strange error:

~/Documents/Programmation/Pokémon ❯❯❯ crystal build Test.cr 
Showing last frame. Use --error-trace for full trace.

In lib/qt5/src/qt5/binding.cr:7:20

 7 | {% use_binding = run("#{__DIR__}/../../support/decide_binding_fast.cr") %}
                      ^--
Error: Error executing run (exit code: 1): '/home/zohran/Documents/Programmation/Pokémon/lib/qt5/src/qt5/../../support/decide_binding_fast.cr' 


stdout:

    


stderr:

    Showing last frame. Use --error-trace for full trace.
    
    In support/decide_binding_slow.cr:7:8
    
     7 | YAML.mapping(find_paths: Bindgen::FindPath::Configuration)
              ^------
    Error: undefined method 'mapping' for YAML:Module
    Unhandled exception: Support script decide_binding_slow.cr failed (Exception)
      from ???
      from ???
      from __crystal_main
      from main
      from __libc_start_main
      from _start
      from ???

Test.rc:

require "qt5"

qApp = Qt::Application.new

label = Qt::Label.new "Hello from Crystal/Qt!"
label.show

Qt::Application.exec

QStringList not mapped

This is making it much more difficult to do stuff, such as: Qt::Completer.new(["Option 1", "Option 2"], parent) must be replaced with a full blown model.

SEGV in operator delete() after DeferredDelete event

Setup

require "qt5"
qApp = Qt::Application.new
mwin = Qt::MainWindow.new
mwin.resize(1200,600)
class TestDelegate < Qt::StyledItemDelegate
	def initialize()
		super(nil)
	end
	def create_editor(parent, view, index)
		@avoidgc = edit = Qt::DateTimeEdit.new(parent)
		edit.display_format = "yyyy-MM-dd"
		edit.calendar_popup = true
		return edit
	end
end
centralwidget = Qt::Widget.new(mwin)
gridLayout = Qt::GridLayout.new(centralwidget)
tableWidget = Qt::TableWidget.new(centralwidget)
tableWidget.row_count = 3
tableWidget.column_count = 3

tableWidget.item_delegate = lavoidgc = TestDelegate.new
		
gridLayout.add_widget(tableWidget, 0, 0, 1, 1)
mwin.central_widget = centralwidget
mwin.show
Qt::Application.exec

Steps

  1. Use my PR with TableWidget: #38
  2. Compile & run the code
  3. Edit any cell
  4. Press enter/click off to accept the value
  5. Boom!

Output

free(): invalid pointer

Thread 1 "demo" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50	../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff65267bb in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff6511535 in __GI_abort () at abort.c:79
#2  0x00007ffff6568508 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff667328d "%s\n") at ../sysdeps/posix/libc_fatal.c:181
#3  0x00007ffff656ec1a in malloc_printerr (str=str@entry=0x7ffff667143b "free(): invalid pointer") at malloc.c:5341
#4  0x00007ffff657042c in _int_free (av=<optimized out>, p=<optimized out>, have_lock=<optimized out>) at malloc.c:4165
#5  0x00005555558f25c4 in BgInherit_DateTimeEdit::~BgInherit_DateTimeEdit() (this=0x7ffff3680d80, __in_chrg=<optimized out>) at qt_binding_linux-gnu-x86_64-qt5.11.cpp:10895
#6  0x00007ffff7b73090 in QObject::event(QEvent*) (this=0x7ffff3680d80, e=<optimized out>) at kernel/qobject.cpp:1242
#7  0x00007ffff6e9a96b in QWidget::event(QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#8  0x00007ffff6ff0409 in QAbstractSpinBox::event(QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#9  0x00007ffff6f69c09 in QDateTimeEdit::event(QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#10 0x00005555558a3ccb in BgInherit_DateTimeEdit::event(QEvent*) (this=0x7ffff3680d80, event=0x55555613eb00) at qt_binding_linux-gnu-x86_64-qt5.11.cpp:10957
#11 0x00007ffff6e5c4c1 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#12 0x00007ffff6e63970 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#13 0x00005555558b1a62 in BgInherit_Application::notify(QObject*, QEvent*) (this=0x7ffff367bf80, unnamed_arg_0=0x7ffff3680d80, unnamed_arg_1=0x55555613eb00) at qt_binding_linux-gnu-x86_64-qt5.11.cpp:19551
#14 0x00007ffff7b49489 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x7ffff3680d80, event=0x55555613eb00)
    at ../../include/QtCore/5.11.3/QtCore/private/../../../../../src/corelib/thread/qthread_p.h:307
#15 0x00007ffff7b4c46b in QCoreApplication::sendEvent(QObject*, QEvent*) (event=0x55555613eb00, receiver=<optimized out>) at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:234
#16 0x00007ffff7b4c46b in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=0x0, event_type=0, data=0x555555c53db0) at kernel/qcoreapplication.cpp:1744
#17 0x00007ffff7b9b103 in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=0x555555e7f2f0) at kernel/qeventdispatcher_glib.cpp:276
#18 0x00007ffff5cc1f2e in g_main_dispatch (context=0x7fffe8004ff0) at ../../../glib/gmain.c:3182
#19 0x00007ffff5cc1f2e in g_main_context_dispatch (context=context@entry=0x7fffe8004ff0) at ../../../glib/gmain.c:3847
#20 0x00007ffff5cc21c8 in g_main_context_iterate (context=context@entry=0x7fffe8004ff0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../../../glib/gmain.c:3920
#21 0x00007ffff5cc225c in g_main_context_iteration (context=0x7fffe8004ff0, may_block=may_block@entry=1) at ../../../glib/gmain.c:3981
#22 0x00007ffff7b9a727 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x555555e7f2d0, flags=...) at kernel/qeventdispatcher_glib.cpp:422
#23 0x00007fffeea70491 in  () at /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
#24 0x00007ffff7b4815b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7fffffffd750, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:140
#25 0x00007ffff7b50132 in QCoreApplication::exec() () at ../../include/QtCore/../../src/corelib/global/qflags.h:120
#26 0x0000555555808c94 in bg_QApplication_exec_STATIC_() () at qt_binding_linux-gnu-x86_64-qt5.11.cpp:19803
#27 0x00005555557bc516 in exec () at ./demo/lib/qt5/src/qt5/binding/binding_linux-gnu-x86_64-qt5.11.cr:25578
#28 0x0000555555739b4d in __crystal_main () at ./demo/src/main.cr:36
#29 0x00005555557e2f46 in main_user_code () at /usr/share/crystal/src/crystal/main.cr:105
#30 0x00005555557e2db5 in main () at /usr/share/crystal/src/crystal/main.cr:91
#31 0x0000555555744d16 in main () at /usr/share/crystal/src/crystal/main.cr:114

Note that frame 5 is in a call to operator delete(void*)@plt

(gdb) x/30i 0x00005555558f25b8
   0x5555558f25b8 <BgInherit_DateTimeEdit::~BgInherit_DateTimeEdit()+24>:	mov    -0x8(%rbp),%rax
   0x5555558f25bc <BgInherit_DateTimeEdit::~BgInherit_DateTimeEdit()+28>:	mov    %rax,%rdi
   0x5555558f25bf <BgInherit_DateTimeEdit::~BgInherit_DateTimeEdit()+31>:	callq  0x555555729e30 <_ZdlPv@plt>
=> 0x5555558f25c4 <BgInherit_DateTimeEdit::~BgInherit_DateTimeEdit()+36>:	leaveq 
   0x5555558f25c5 <BgInherit_DateTimeEdit::~BgInherit_DateTimeEdit()+37>:	retq   

The QT event on frame 6 is 52 (DeferredDelete)

Qt signal handlers are not using type converters

Consider for example void QWidget::windowTitleChanged(const QString &title) and the following snippet

require "qt5"

qApp = Qt::Application.new
wnd = Qt::Widget.new
wnd.on_window_title_changed do |str|
  puts str
end
wnd.window_title = "string arg test"
wnd.show
Qt::Application.exec

This might or might not crash, and will most likely print a bunch of garbage, because str is not really a String but a Qt::Binding::CrystalString instead. The definition of on_window_title_changed is

module Qt
  lib Binding
    fun bg_QWidget_CONNECT_windowTitleChanged_CrystalProc_void_const_QString_R(_self_ : QWidget*, _proc_ : CrystalProc) : QMetaObjectConnection*
  end

  class Widget
    def on_window_title_changed(&_proc_ : Proc(String, Void)) : SignalConnection
      SignalConnection.new(unwrap: Binding.bg_QWidget_CONNECT_windowTitleChanged_CrystalProc_void_const_QString_R(self, BindgenHelper.wrap_proc(_proc_)))
    end
  end
end

The underlying C++ function is

extern "C" QMetaObject::Connection * bg_QWidget_CONNECT_windowTitleChanged_CrystalProc_void_const_QString_R(QWidget * _self_, CrystalProc<void, const CrystalString> _proc_) {
  return new (UseGC) QMetaObject::Connection (QObject::connect(_self_, (void(QWidget::*)(const QString &))&QWidget::windowTitleChanged, [_proc_](const QString & title){ _proc_(qstring_to_crystal(title)); }));
}

which also stops at Qt::Binding::CrystalString. Casting the string to that type inside the handler doesn't seem to work, but this will:

handler = ->(str : Qt::Binding::CrystalString) do
  puts Qt::Converter::QString.unwrap(str)
end
Qt::SignalConnection.new(unwrap: Qt::Binding.bg_QWidget_CONNECT_windowTitleChanged_CrystalProc_void_const_QString_R(wnd, Qt::BindgenHelper.wrap_proc(handler)))

and the converter Qt::Converter::QString is specified right at the top of config/types.yml:

types: # Type rewrite rules
  QString: # Convert QString instances using that:
    converter: Qt::Converter::QString

All this suggests that _proc_ is implicitly converted from Proc(String, Void) in Crystal to CrystalProc<void, const CrystalString> in C++, and the converter is never invoked. This is tested on linux-gnu-x86_64-qt5.12 + Clang 9 but the same should apply to all Qt bindings.

Renewed maintenance of qt5.cr

Hello @acoolstraw, @dscottboggs , @kalinon , @glenux , @ZaWertun, @gilmartaj, @codenoid, @foliea

Same as for bindgen (Papierkorb/bindgen#23), I would like to work on qt5.cr so that it builds/works again.

Any interest or contributions from you would be much appreciated - either in the form of PRs or general comments/insights (possibly added to this thread or whatever is more appropriate).

Let's try to build a critical mass here so that we succeed in updating the Qt bindings.

(For example, reviewing your existing PRs or updating your forks to the latest version of bindgen so that it is easier to identify your own changes/improvements would be a great start, and we could coordinate from there.)

Also let's please keep any patches/PRs small and isolated so that they are easier to review and agree on.

Thanks!

Qt 5.14 errors

Initial output of trying to build for Qt 5.14:

=> Generating bindings for all platforms
(1/1) Generating linux-gnu-x86_64-qt5.14
Invalid alias name "QAbstractSpinBox::StepType" at Qt::Binding::QAbstractSpinBox::StepType
Invalid alias name "Qt::HighDpiScaleFactorRoundingPolicy" at Qt::Binding::Qt::HighDpiScaleFactorRoundingPolicy
Invalid alias name "QTextDocument::MarkdownFeatures" at Qt::Binding::QTextDocument::MarkdownFeatures
Invalid alias name "QGradient::Preset" at Qt::Binding::QGradient::Preset
Invalid alias name "QTextBlockFormat::MarkerType" at Qt::Binding::QTextBlockFormat::MarkerType
Result type QAbstractSpinBox::StepType is unreachable at Qt::Binding#stepType()
Argument 2 has unreachable type QAbstractSpinBox::StepType at Qt::Binding#setStepType(stepType)
Result type QAbstractSpinBox::StepType is unreachable at Qt::Binding#stepType()
Argument 2 has unreachable type QAbstractSpinBox::StepType at Qt::Binding#setStepType(stepType)
Argument 1 has unreachable type Qt::HighDpiScaleFactorRoundingPolicy at Qt::Binding.setHighDpiScaleFactorRoundingPolicy(policy)
Result type Qt::HighDpiScaleFactorRoundingPolicy is unreachable at Qt::Binding.highDpiScaleFactorRoundingPolicy()
Argument 2 has unreachable type QTextDocument::MarkdownFeatures at Qt::Binding#toMarkdown(features)
Argument 2 has unreachable type QTextDocument::MarkdownFeatures at Qt::Binding#toMarkdown(features)
Argument 3 has unreachable type QTextDocument::MarkdownFeatures at Qt::Binding#setMarkdown(markdown, features)
Argument 6 has unreachable type QGradient::Preset at Qt::Binding#fillRect(x, y, w, h, preset)
Argument 3 has unreachable type QGradient::Preset at Qt::Binding#fillRect(r, preset)
Argument 3 has unreachable type QGradient::Preset at Qt::Binding#fillRect(r, preset)
Argument 2 has unreachable type QTextBlockFormat::MarkerType at Qt::Binding#setMarker(marker)
Result type QTextBlockFormat::MarkerType is unreachable at Qt::Binding#marker()
Result type Binding::QAbstractSpinBox::StepType is unreachable at Qt::SpinBox#stepType()
Argument 1 has unreachable type Binding::QAbstractSpinBox::StepType at Qt::SpinBox#setStepType(stepType)
Result type Binding::QAbstractSpinBox::StepType is unreachable at Qt::DoubleSpinBox#stepType()
Argument 1 has unreachable type Binding::QAbstractSpinBox::StepType at Qt::DoubleSpinBox#setStepType(stepType)
Argument 1 has unreachable type Binding::Qt::HighDpiScaleFactorRoundingPolicy at Qt::GuiApplication.setHighDpiScaleFactorRoundingPolicy(policy)
Result type Binding::Qt::HighDpiScaleFactorRoundingPolicy is unreachable at Qt::GuiApplication.highDpiScaleFactorRoundingPolicy()
Argument 1 has unreachable type Binding::QTextDocument::MarkdownFeatures at Qt::TextEdit#toMarkdown(features)
Argument 1 has unreachable type Binding::QTextDocument::MarkdownFeatures at Qt::TextDocument#toMarkdown(features)
Argument 2 has unreachable type Binding::QTextDocument::MarkdownFeatures at Qt::TextDocument#setMarkdown(markdown, features)
Argument 5 has unreachable type Binding::QGradient::Preset at Qt::Painter#fillRect(x, y, w, h, preset)
Argument 2 has unreachable type Binding::QGradient::Preset at Qt::Painter#fillRect(r, preset)
Argument 2 has unreachable type Binding::QGradient::Preset at Qt::Painter#fillRect(r, preset)
Argument 1 has unreachable type Binding::QTextBlockFormat::MarkerType at Qt::TextBlockFormat#setMarker(marker)
Result type Binding::QTextBlockFormat::MarkerType is unreachable at Qt::TextBlockFormat#marker()
Found 33 errors. Aborting.
Failed to build linux-gnu-x86_64-qt5.14 using Qt5.14 on x86_64-unknown-linux-gnu - Abort.

tempfile not available on crystal 0.27.0

It seems that tempfile is no more:

[renich@introdesk qt5]$ crystal build src/qt5.cr
Error in src/qt5.cr:1: while requiring "qt5"

require "qt5" # Require it!
^

in lib/qt5/src/qt5.cr:5: while requiring "./qt5/binding"

require "./qt5/binding"
^

in lib/qt5/src/qt5/binding.cr:6: expanding macro

{% begin %}
^

in lib/qt5/src/qt5/binding.cr:7: Error executing run (exit code: 1): /home/renich/Desktop/crystal/qt5/lib/qt5/src/qt5/../../support/decide_binding_fast.cr 

stdout:

    


stderr:

    Error in support/decide_binding_slow.cr:1: while requiring "bindgen/library"
    
    require "bindgen/library"
    ^
    
    in lib/bindgen/src/bindgen/library.cr:4: while requiring "tempfile": can't find file 'tempfile'
    
    If you're trying to require a shard:
    - Did you remember to run `shards install`?
    - Did you make sure you're running the compiler in the same directory as your shard.yml?
    
    require "tempfile"
    ^
    
    Unhandled exception: Support script decide_binding_slow.cr failed (Exception)
      from ???
      from ???
      from __crystal_main
      from main
      from __libc_start_main
      from _start
      from ???



  {% use_binding = run("#{__DIR__}/../../support/decide_binding_fast.cr") %}
                   ^~~

BTW, in Fedora, you only need to dnf -y install qt5-devel.

Error when trying to compile the example.

When trying to compile the example i get the following error:

Error in src/test.cr:2: while requiring "qt5"
require "qt5" # Require it!
^
in lib/qt5/src/qt5.cr:5: while requiring "./qt5/binding"
require "./qt5/binding"
^
in lib/qt5/src/qt5/binding.cr:6: expanding macro
{% begin %}
^
in lib/qt5/src/qt5/binding.cr:7: Error executing run (exit code: 1): /home/jonathan/Documents/Crystal/test/lib/qt5/src/qt5/../../support/decide_binding_fast.cr 
stdout:

stderr:
    Error in support/decide_binding_slow.cr:1: while requiring "bindgen/library"
    require "bindgen/library"
    ^
    in lib/bindgen/src/bindgen/library.cr:11: while requiring "./*"
    require "./*"
    ^
    in lib/bindgen/src/bindgen/find_path.cr:2: Good news: Crystal#5445 is fixed, see this file!
    require "./find_path/*"
    ^
    Support script decide_binding_slow.cr failed (Exception)
      from ???
      from __crystal_main
      from main
      from __libc_start_main
      from ../sysdeps/x86_64/start.S:122:0 in '_start'
      from ???
  {% use_binding = run("#{__DIR__}/../../support/decide_binding_fast.cr") %}
                   ^~~

qt5/binding file is missing

   1 require "./qt5/version"
   2 require "./qt5/glue"
   3 require "./qt5/point"
   4 require "./qt5/binding" # missing
   5 require "./qt5/*"
ayam:trypapierqt ruby$ cd lib/qt5/src/qt5
Oderlo-pro:qt5 ruby$ tree
.
├── application.cr
├── glue.cr
├── layout.cr
├── object.cr
├── painter.cr
├── point.cr
└── version.cr

Building Qt 5.12 bindings on Debian 9

While 5.13 works, 5.12 results in 2 errors:

  1. qt-everywhere-src-5.12.0/qtbase/src/corelib/global/qrandom.cpp:455:62: error: no matching function for call to ‘std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::mersenne_twister_engine(QRandomGenerator::SystemGenerator&)’
    455 | new (&rng->storage.engine()) RandomEngine(self()->sys);

In file included from /usr/include/c++/9/random:49,
from download_cache/qt-everywhere-src-5.12.0/qtbase/src/corelib/global/qrandom.h:45,
from download_cache/qt-everywhere-src-5.12.0/qtbase/src/corelib/global/qrandom.cpp:43:
/usr/include/c++/9/bits/random.h:530:9: note: candidate: ‘template<class _Sseq, class> std::mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::mersenne_twister_engine(_Sseq&)’
530 | mersenne_twister_engine(_Sseq& __q)

  1. /usr/include/c++/9/bits/random.h:491:8: required by substitution of ‘template<class _UIntType, long unsigned int __w, long unsigned int __n, long unsigned int __m, long unsigned int __r, _UIntType __a, long unsigned int __u, _UIntType __d, long unsigned int __s, _UIntType __b, long unsigned int __t, _UIntType __c, long unsigned int __l, _UIntType __f> template using _If_seed_seq = typename std::enable_if<std::__detail::__is_seed_seq<_Sseq, std::mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>, _UIntType>::value>::type [with _Sseq = QRandomGenerator::SystemGenerator; _UIntType = unsigned int; long unsigned int __w = 32; long unsigned int __n = 624; long unsigned int __m = 397; long unsigned int __r = 31; _UIntType __a = 2567483615; long unsigned int __u = 11; _UIntType __d = 4294967295; long unsigned int __s = 7; _UIntType __b = 2636928640; long unsigned int __t = 15; _UIntType __c = 4022730752; long unsigned int __l = 18; _UIntType __f = 1812433253]’
    /usr/include/c++/9/bits/random.h:528:32: required from here
    /usr/include/c++/9/bits/random.h:197:13: error: no type named ‘result_type’ in ‘struct QRandomGenerator::SystemGenerator’
    197 | using __is_seed_seq = _and<

Instructions for new binding versions give error/5.11 does't work on Debian

Using the following steps on Debian 10 (stable) which has qt 5.11:

  1. crystal init app test
  2. In its shard.yml:
name: test
version: 0.1.0

targets:
  test:
    main: src/test.cr

crystal: 0.35.1

license: MIT
 
dependencies:
  qt5:
    github: Papierkorb/qt5.cr
    branch: master
  1. Run shards
  2. In src/test.cr you can put the hello world code:
require "qt5"

qApp = Qt::Application.new
 
label = Qt::Label.new "Hello from Crystal/Qt!"
label.show

Qt::Application.exec
  1. export BINDING_PLATFORM=linux-gnu-x86_64-qt5.11 as per readme
  2. lib/bindgen/tool.sh qt.yml --stats => ERROR. I think that the readme should be updated as the rest of the instructions are in the test project perspective.
  3. (retry with correct path) lib/bindgen/tool.sh lib/qt5/qt.yml --stats
Ambiguous call at Qt::ComboBox#CONNECT_activated(_proc_)
Ambiguous call at Qt::ComboBox#CONNECT_activated(_proc_)
Ambiguous call at Qt::ComboBox#CONNECT_highlighted(_proc_)
Ambiguous call at Qt::ComboBox#CONNECT_highlighted(_proc_)
Ambiguous call at Qt::ComboBox#CONNECT_currentIndexChanged(_proc_)
Ambiguous call at Qt::ComboBox#CONNECT_currentIndexChanged(_proc_)
Enum doesn't have any constants at Qt::AbstractSpinBox::StepType
Ambiguous call at Qt::SpinBox#CONNECT_valueChanged(_proc_)
Ambiguous call at Qt::SpinBox#CONNECT_valueChanged(_proc_)
Ambiguous call at Qt::DoubleSpinBox#CONNECT_valueChanged(_proc_)
Ambiguous call at Qt::DoubleSpinBox#CONNECT_valueChanged(_proc_)
Ambiguous call at Qt::ButtonGroup#CONNECT_buttonClicked(_proc_)
Ambiguous call at Qt::ButtonGroup#CONNECT_buttonClicked(_proc_)
Ambiguous call at Qt::ButtonGroup#CONNECT_buttonPressed(_proc_)
Ambiguous call at Qt::ButtonGroup#CONNECT_buttonPressed(_proc_)
Ambiguous call at Qt::ButtonGroup#CONNECT_buttonReleased(_proc_)
Ambiguous call at Qt::ButtonGroup#CONNECT_buttonReleased(_proc_)
Ambiguous call at Qt::ButtonGroup#CONNECT_buttonToggled(_proc_)
Ambiguous call at Qt::ButtonGroup#CONNECT_buttonToggled(_proc_)
Enum doesn't have any constants at Qt::Gradient::Preset
Found 20 errors.  Aborting.
  1. shards build
There was a problem expanding macro 'macro_140669267411392'

Code in lib/qt5/src/qt5/binding.cr:6:1

 6 | {% begin %}
     ^
Called macro defined in lib/qt5/src/qt5/binding.cr:6:1

 6 | {% begin %}

Which expanded to:

 > 1 | 
 > 2 |   
 > 3 |   require "./binding/binding_linux-gnu-x86_64-qt5.11"
         ^
Error: can't find file './binding/binding_linux-gnu-x86_64-qt5.11' relative to '[...snip...]'

What else is missing from the instructions that I need to do to get this working?

Error compiling hello world.

Using shards.yml with:

dependencies:
  qt5:
    github: Papierkorb/qt5.cr
    branch: master-ready-to-use

and https://raw.githubusercontent.com/Papierkorb/qt5.cr/master/samples/hello_world.cr with require "qt5" instead of require "../src/qt5".

I got this on shards build:

$ shards build --error-trace
Dependencies are satisfied
Building: crystalqt
Error target crystalqt failed to compile:
In src/crystalqt.cr:1:1

 1 | require "qt5"
     ^
Error: while requiring "qt5"


In lib/qt5/src/qt5.cr:5:1

 5 | require "./qt5/binding"
     ^
Error: while requiring "./qt5/binding"


In lib/qt5/src/qt5/binding.cr:6:1

 6 | {% begin %}
     ^
Error: expanding macro


There was a problem expanding macro 'macro_139658193954784'

Called macro defined in lib/qt5/src/qt5/binding.cr:6:1

 6 | {% begin %}

Which expanded to:

 > 1 | 
 > 2 |   
 > 3 |   require "./binding/binding_linux-gnu-x86_64-qt5.13"
Error: can't find file './binding/binding_linux-gnu-x86_64-qt5.13' relative to '/tmp/crystalqt/lib/qt5/src/qt5'

Tested with:

Crystal 0.31.1 (2019-10-21)

LLVM: 9.0.0
Default target: x86_64-pc-linux-gnu

on ArchLinux.

clang: error: no such file or directory: '/lib/qt5/src/qt5/../../ext/binding.a'

I'm trying to run a sample project using qt5.cr:

require "qt5"

# Create the application first
qApp = Qt::Application.new

# We'll use a normal widget as window
window = Qt::Widget.new
window.window_title = "Hello, World!"

# We need to give it a layout
layout = Qt::VBoxLayout.new
window.layout = layout

# Create a label and a button, and push it into the layout
button = Qt::PushButton.new "Click me!"
label = Qt::Label.new "Click the button!"

layout << button << label

# On every press on `button`, we want to change the label.
counter = 0

button.on_pressed do # This is how you connect to the `pressed` signal
  counter += 1
  label.text = "You pressed #{counter} times!"
end

# We're ready for showtime
window.show

# And now, start it!
Qt::Application.exec

When I do crystal src/crystal_qt5.cr (crystal_qt5 is the name of my project), I get an error:

clang: error: no such file or directory: '.../lib/qt5/src/qt5/../../ext/binding.a'
Error: execution of command failed with code: 1: `cc "${@}" -o '.../.cache/crystal/crystal-run-crystal_qt5.tmp'  -rdynamic  .../lib/qt5/src/qt5/../../ext/binding.a -lstdc++ -lQt5Core -lQt5Gui -lQt5Widgets -lpcre -lgc -lpthread /usr/local/Cellar/crystal-lang/0.23.1/src/ext/libcrystal.a -levent -liconv -ldl -L/usr/lib -L/usr/local/lib`

I have Qt5 installed on my MacBook, which is running Mac OS X.

(... is my user configuration stuff, which is omitted.)

Crystal 1.0.0-dev breaks several QGraphicsItem subclasses

Crystal 1.0 strengthened checks on abstract def implementations, so the classes Qt::GraphicsSimpleTextItem, Qt::GraphicsPixmapItem, and Qt::GraphicsTextItem will fail there. The reason is that the corresponding C++ method declarations have different default values for the widget argument:

class QGraphicsItem
{
public:
    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) = 0;
};

class QGraphicsPixmapItem : public QGraphicsItem
{
public:
    // no default value for widget
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
};

// ditto for QGraphicsSimpleTextItem and QGraphicsTextItem

Other subclasses like Qt::GraphicsLineItem work because the default values match:

class QGraphicsLineItem : public QGraphicsItem
{
public:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
};

For now the workaround is to redefine the offending methods whenever the module is included:

module Qt
  class GraphicsSimpleTextItem
    def paint(painter : Painter, option : Binding::QStyleOptionGraphicsItem*, widget : Widget? = nil) : Void
      Binding.bg_QGraphicsSimpleTextItem_paint_QPainter_X_const_QStyleOptionGraphicsItem_X_QWidget_X(self, painter, option, widget)
    end
  end

  class GraphicsPixmapItem
    def paint(painter : Painter, option : Binding::QStyleOptionGraphicsItem*, widget : Widget? = nil) : Void
      Binding.bg_QGraphicsPixmapItem_paint_QPainter_X_const_QStyleOptionGraphicsItem_X_QWidget_X(self, painter, option, widget)
    end
  end

  class GraphicsTextItem
    def paint(painter : Painter, option : Binding::QStyleOptionGraphicsItem*, widget : Widget? = nil) : Void
      Binding.bg_QGraphicsTextItem_paint_QPainter_X_const_QStyleOptionGraphicsItem_X_QWidget_X(self, painter, option, widget)
    end
  end
end

Without these redefinitions, those methods would take a plain widget : Widget argument, and Crystal will complain about missing implementations, e.g. Error: abstract `def Qt::GraphicsItem#paint(painter : Painter, option : ::Pointer(Binding::QStyleOptionGraphicsItem), widget : Widget | ::Nil = nil)` must be implemented by Qt::GraphicsSimpleTextItem.

Build error -- missing method in YAML

stderr:

Showing last frame. Use --error-trace for full trace.

In support/decide_binding_slow.cr:7:8

 7 | YAML.mapping(find_paths: Bindgen::FindPath::Configuration)
          ^------
Error: undefined method 'mapping' for YAML:Module
Unhandled exception: Support script decide_binding_slow.cr failed (Exception)
  from /home/mistergibson/.cache/crystal/home-mistergibson-Documents-Development-gxg.dev-gxg.cr-lib-qt5-src-qt5-..-..-support-decide_binding_fast.cr/macro_run in '??'
  from /home/mistergibson/.cache/crystal/home-mistergibson-Documents-Development-gxg.dev-gxg.cr-lib-qt5-src-qt5-..-..-support-decide_binding_fast.cr/macro_run in '??'
  from /home/mistergibson/.cache/crystal/home-mistergibson-Documents-Development-gxg.dev-gxg.cr-lib-qt5-src-qt5-..-..-support-decide_binding_fast.cr/macro_run in '__crystal_main'
  from /home/mistergibson/.cache/crystal/home-mistergibson-Documents-Development-gxg.dev-gxg.cr-lib-qt5-src-qt5-..-..-support-decide_binding_fast.cr/macro_run in 'main'
  from /lib/x86_64-linux-gnu/libc.so.6 in '__libc_start_main'
  from /home/mistergibson/.cache/crystal/home-mistergibson-Documents-Development-gxg.dev-gxg.cr-lib-qt5-src-qt5-..-..-support-decide_binding_fast.cr/macro_run in '_start'
  from ???

crystal deps has been removed

When trying to install the shard using shards install I get

Fetching https://github.com/Papierkorb/qt5.cr.git
Fetching https://github.com/Papierkorb/bindgen.git
Fetching https://github.com/Papierkorb/toka.git
Installing qt5 (0.1.0)
Installing bindgen (0.6.1)
Postinstall crystal deps
Failed crystal deps:
Please use 'shards': 'crystal deps' has been removed

GC frees objects and signal handlers

Consider the following simple example, a window with a single button whose clicked signal triggers the GC (in this example explicitly for illustration, but it may run automatically as well and cause the same problem).

require "qt5"

class MyWidget < Qt::Widget
  def initialize
    super

    # Variant 1: no instance variables *CRASHES*
    button = Qt::PushButton.new("Press Me")
    button.on_clicked do
      puts "Click"
      a = [0] * 10000000 # just to trigger the GC sooner
      GC.collect
    end

    layout = Qt::VBoxLayout.new
    layout.add_widget(button)
    self.layout = layout

    resize(400, 300)
  end
end

qApp = Qt::Application.new
win = MyWidget.new
win.show
Qt::Application.exec

The program crashes after clicking a few times on the button (3 times in may case). The reason seems to be (if I understand everything correctly) that the GC frees the objects instantiated in the constructor, namely the button, the layout AND the call (i.e. the proc bound to on_clicked). Given that Qt is a C++ library with different memory management strategies, this may not be that surprising (although certainly unexpected for a Crystal-dev without knowledge of the C++-Qt-stuff).

Anyway, a simple workaround would be to keep a reference to the objects in instance variables (just the code of initialize):

    # Variant 2: button and layout in instance variables *CRASHES*
    @button = Qt::PushButton.new("Press Me")
    @button.on_clicked do
      puts "Click"
      a = [0] * 10000000 # just to trigger the GC sooner
      GC.collect
    end

    @layout = Qt::VBoxLayout.new
    @layout.add_widget(@button)
    self.layout = @layout

Unfortunately, this also crashes. It took me some time to find out (because it was not obvious to me): connecting the callback to the clicked signal via the on_clicked method creates an internal object (somewhere in the bindgen generated binding code) and no reference to that object seems to be stored somewhere. The problem is that there does not seem to be a way the get this reference. Therefore I copied the binding code directly:

    # Variant 3: button, layout and callback in instance variable *WORKS*
    @button = Qt::PushButton.new("Press Me")
    @cb = Proc(Bool, Void).new do
      puts "Click"
      a = [0] * 10000000 # just to trigger the GC sooner
      GC.collect
    end
    Qt::Binding.bg_QAbstractButton_CONNECT_clicked_CrystalProc_void__bool_(@button, Qt::BindgenHelper.wrap_proc(@cb))

    @layout = Qt::VBoxLayout.new
    @layout.add_widget(@button)
    self.layout = @layout

    resize(400, 300)

Just to make sure that it is not sufficient to store only the callback, the following variant (which stores the callback but neither the button nor the layout) also crashed (after a few more clicks, 10 or so):

    # Variant 4: callback in instance variable *CRASHES* (after 10 clicks or so)
    button = Qt::PushButton.new("Press Me")
    cb = Proc(Bool, Void).new do
      puts "Click"
      a = [0] * 10000000 # just to trigger the GC sooner
      GC.collect
    end
    Qt::Binding.bg_QAbstractButton_CONNECT_clicked_CrystalProc_void__bool_(button, Qt::BindgenHelper.wrap_proc(cb))

    layout = Qt::VBoxLayout.new
    layout.add_widget(button)
    self.layout = layout

So may main questions is: is there another proper way to work with signals? Did I do something totally wrong? I could not find anything about memory management in docs (but I may have overlooked) ...

I've used the current master branch and Qt 5.15 on linux.

Crystal 1.2 issue

Hi!

Something was changed between Crystal 1.1.1 and 1.2.0 (currently in development).

Can't run any sample.

Output:

Showing last frame. Use --error-trace for full trace.

In src/qt5/binding/binding_.cr:49833:3

 49833 | class GraphicsSimpleTextItem < AbstractGraphicsShapeItem
         ^
Error: abstract `def Qt::AbstractGraphicsShapeItem#paint(painter : Painter, option : StyleOptionGraphicsItem, widget : Widget | ::Nil = nil)` must be implemented by Qt::GraphicsSimpleTextItem

Can be "fixed" by commenting line src/qt5/binding/binding_.cr:47974

abstract def paint(painter : Painter, option : StyleOptionGraphicsItem, widget : Widget? = nil) : Void

--ldflags: command not found

Hello, I seen today the problem with YAML error was solve. I tried to use again Qt on Gentoo, but I had again one error.


In lib/qt5/src/qt5/binding.cr:7:20

 7 | {% use_binding = run("#{__DIR__}/../../support/decide_binding_fast.cr") %}
                      ^--
Error: Error executing run (exit code: 1): '/home/zohran/Documents/Programmation/Test Crystal Qt/lib/qt5/src/qt5/../../support/decide_binding_fast.cr' 


stdout:

    


stderr:

    --: line 1: --ldflags: command not found
    Failed to find llvm version
    
    Failed to find one or more paths.  See above for details.
    Unhandled exception: Support script decide_binding_slow.cr failed (Exception)
      from ???
      from ???
      from __crystal_main
      from main
      from ???
      from __libc_start_main
      from _start
      from ???

Segmentation fault when exiting the built HelloWorld example

Hello, first congratulation for such a work and for the simplicity of your README. (The only drawback is that you don't mention the need to install the libgc-dev package).

I've built the HelloWorld sample on LinuxMint 18.3 64bit, but when exiting the application (reproduced after several compilation-launch), I get a segmentation fault. I don't know if this come from Crystal or from the qt binding

$ ./hello_world 
Invalid memory access (signal 11) at address 0x7f4459776889
[0x5aa796] *CallStack::print_backtrace:Int32 +118
[0x59f66b] __crystal_sigfault_handler +75

And again, great work.

Error when running `support/generate_bindings.cr` on crystal-0.26.1

Error (using branch master-ready-to-use):

...
in support/generate_bindings.cr:126: 'File.each_line' is expected to be invoked with a block, but no block was given

    File.each_line(pro_file)

Error could be fixed with following patch:

diff --git a/support/generate_bindings.cr b/support/generate_bindings.cr
index 7e90250..d975a90 100644
--- a/support/generate_bindings.cr
+++ b/support/generate_bindings.cr
@@ -123,7 +123,7 @@ def get_qt_modules_from_qtpro(version)
   pro_file = "#{version.path}/qt.pro"

   if File.exists? pro_file
-    File.each_line(pro_file)
+    File.read_lines(pro_file)
       .grep(/^addModule\(qt/)
       .map{|x| x[/addModule\(qt([^,)]+)/, 1]?}
       .to_a

random invalid memory access

Invalid memory access (signal 11) at address 0x0
[0x1037a652b] *CallStack::print_backtrace:Int32 +107
[0x103789966] __crystal_sigfault_handler +262
[0x7fff71c1542d] _sigtramp +29
[0x7fff3ae8452f] _ZNSt3__16__treeIPN2CI4NodeENS_4lessIS3_EENS_9allocatorIS3_EEE7destroyEPNS_11__tree_nodeIS3_PvEE +19
[0x7fff3ae84542] _ZNSt3__16__treeIPN2CI4NodeENS_4lessIS3_EENS_9allocatorIS3_EEE7destroyEPNS_11__tree_nodeIS3_PvEE +38
[0x7fff3ae84536] _ZNSt3__16__treeIPN2CI4NodeENS_4lessIS3_EENS_9allocatorIS3_EEE7destroyEPNS_11__tree_nodeIS3_PvEE +26
[0x7fff3ae72440] _ZNK2CI4Node18unique_child_countEv +114
[0x7fff3b0adb86] ___ZNK2CI11ProgramNode21compute_kernel_digestEPKNS_7ContextE_block_invoke +308
[0x7fff3b0acb28] ___ZNK2CI11ProgramNode33traverse_graph_preorder_stoppableEU13block_pointerFbPNS_4NodeES2_iiiE_block_invoke +127
[0x7fff3ae5d0fb] _ZN2CI11GraphObject27traverse_preorder_stoppableEPS0_S1_iiU13block_pointerFbS1_S1_iiE +219
[0x7fff3ae722fa] _ZNK2CI11ProgramNode33traverse_graph_preorder_stoppableEU13block_pointerFbPNS_4NodeES2_iiiE +138
[0x7fff3ae7218d] _ZNK2CI11ProgramNode21compute_kernel_digestEPKNS_7ContextE +171
[0x7fff3ae71e16] _ZN2CI11ProgramNode28create_program_and_argumentsEPNS_7ContextEPKc +526
[0x7fff3ae5bcbc] _ZN2CI11GraphObject15traverse_uniqueEPS0_U13block_pointerFvS1_S1_iiiE +220
[0x7fff3ae696b0] _ZN2CIL14recursive_tileEPNS_10RenderTaskEPNS_7ContextEPKNS_17RenderDestinationEPKcPNS_4NodeERK6CGRectNS_11PixelFormatERKNS_12swizzle_infoEU13block_pointerFPNS_8TileTaskEPNS_11ProgramNodeESB_E +1175
[0x7fff3ae68e1d] _ZN2CIL15tile_node_graphEPNS_7ContextEPKNS_17RenderDestinationEPKcPNS_4NodeERK6CGRectNS_11PixelFormatERKNS_12swizzle_infoEU13block_pointerFPNS_8TileTaskEPNS_11ProgramNodeES9_E +475
[0x7fff3ae68953] _ZN2CI16image_get_bitmapEPNS_7ContextEPNS_5ImageE6CGRectP12CGColorSpacePNS_6BitmapEPKNS_17RenderDestinationE +1939
[0x7fff3ae68165] _ZNK2CI14RenderToBitmap6renderEPNS_5ImageEPNS_7ContextE +451
[0x7fff3ae67a39] -[CIContext(CIRenderDestination) _startTaskToRender:toDestination:forPrepareRender:forClear:error:] +3699
[0x7fff3ae66bbf] -[CIContext(CIRenderDestination) startTaskToRender:toDestination:error:] +31
[0x7fff3ae6691f] -[CIContext(CIRenderDestination) startTaskToRender:fromRect:toDestination:atPoint:error:] +190
[0x7fff3ae57496] -[CIContext(createCGImage) _createCGImage:fromRect:format:colorSpace:deferred:] +4062
[0x7fff5351ff40] _ZNK11CUIRenderer35CreateImageByApplyingEffectsToImageEPK13CUIDescriptorlPK9__CFArrayP7CGImagedhhR11CGBlendModeb +14324
[0x7fff5351b723] _ZNK11CUIRenderer11CreateImageE6CGRectlPK13CUIDescriptorhPP7CGImagePxPhP11CGBlendMode +5589
[0x7fff53519e85] _ZNK11CUIRenderer9DrawImageE6CGRectlPK13CUIDescriptor +147
[0x7fff5351944f] _ZN20CUICoreThemeRenderer13DrawMenuTitleEPK13CUIDescriptorR13CUIReturnInfo +813
[0x7fff53518565] _ZN11CUIRenderer4DrawE6CGRectP9CGContextPK14__CFDictionaryPS5_ +1785
[0x7fff53517e3a] CUIDraw +278
[0x7fff38f100c2] _HIThemeCUIDrawWithOptions +107
[0x7fff38f1003c] _HIThemeCUIDrawWithRenderer +173
[0x7fff38f0f3b4] _HIThemeDrawAppleMenuTitle +510
[0x7fff38f0ba1d] _ZN13HIMenuBarView8DrawOnceE6CGRectS0_bbP9CGContext +1089
[0x7fff38f0b56d] _ZN13HIMenuBarView8DrawSelfEsPK9__HIShapeP9CGContext +689
[0x7fff38f0af3e] _ZN13HIMenuBarView24DrawWithoutCustomizationEsPK9__HIShapeP9CGContext +82
[0x7fff38f0aed6] _ZN13HIMenuBarView22DrawingDelegateHandlerEP25OpaqueEventHandlerCallRefP14OpaqueEventRefPv +258
[0x7fff38eef711] _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec +1419
[0x7fff38eeeae0] _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec +338
[0x7fff38eee983] SendEventToEventTargetWithOptions +45
[0x7fff38f0aa4b] _ZN6HIView8SendDrawEsP13OpaqueGrafPtrPK9__HIShapeP9CGContext +325
[0x7fff38f0a4be] _ZN6HIView23RecursiveDrawCompositedEPK9__HIShapeS2_jPS_P9CGContexthd +582
[0x7fff38f0a709] _ZN6HIView23RecursiveDrawCompositedEPK9__HIShapeS2_jPS_P9CGContexthd +1169
[0x7fff38f09ef9] _ZN6HIView14DrawCompositedEsP13OpaqueGrafPtrPK9__HIShapejPS_P9CGContext +815
[0x7fff38f09bbb] _ZN6HIView6RenderEjP9CGContext +51
[0x7fff38f092e9] _ZN10WindowData20PrepareForVisibilityEv +153
[0x7fff38f5f464] _ShowHideWindows +286
[0x7fff38f08d30] ShowHide +35
[0x7fff38ef8f0b] _ZN9MBWindows18GetWindowOnDisplayEjh +289
[0x7fff38ef8cef] _ZN15MenuBarInstance15ForEachWindowDoEhU13block_pointerFbP15OpaqueWindowPtrjE +183
[0x7fff38ef8bef] _ZN15MenuBarInstance28SetBoundsAndUpdateResolutionEv +103
[0x7fff38ef876a] _ZN15MenuBarInstance4ShowE21MenuBarAnimationStylehhhh +280
[0x7fff38ef81a1] _ZN15MenuBarInstance21UpdateAggregateUIModeE21MenuBarAnimationStylehhh +805
[0x7fff38ef7daa] _ZN15MenuBarInstance16ForEachMenuBarDoEU13block_pointerFvPS_E +46
[0x7fff38ef7d4a] _ZL25UpdateAllAggregateUIModes21MenuBarAnimationStyleh +126
[0x7fff38ef7cb6] SetSystemUIMode +165
[0x7fff3793a9de] -[NSApplication _setPresentationOptions:instance:flags:] +1093
[0x1086d230e] qt_plugin_instance +2334
[0x1086d191e] ???
[0x10442c526] _ZN27QPlatformIntegrationFactory6createERK7QStringRK11QStringListRiPPcS2_ +198
[0x104438d59] _ZN22QGuiApplicationPrivate25createPlatformIntegrationEv +2473
[0x10443a06b] _ZN22QGuiApplicationPrivate21createEventDispatcherEv +27
[0x104b4215f] _ZN23QCoreApplicationPrivate4initEv +1567
[0x104435289] _ZN22QGuiApplicationPrivate4initEv +57
[0x103e6fa3a] _ZN19QApplicationPrivate4initEv +26
[0x1038bf5cd] _ZN21BgInherit_ApplicationCI212QApplicationERiPPci +61
[0x10383267b] _ZN21BgInherit_ApplicationCI112QApplicationERiPPci +43
[0x10383260f] bg_QApplication__CONSTRUCT_int_R_char_XX_int +95
[0x1037f4c86] *Qt::Application#initialize:Pointer(Void) +38
[0x1037f4c40] *Qt::Application::new:Qt::Application +144
[0x103778c3f] __crystal_main +1055
[0x1038002e9] *Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil +9
[0x10380018b] *Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32 +43
[0x103784439] main +9

Screen Shot 2020-03-19 at 10 03 42 AM

at address 0x0 nil point exception?
sometimes crash enter system and cause restart.

Building simple example on Fedora 28

I succeeded building simple example after adding /usr/lib64 to QT_LIBS_DIR in file config/find_paths.yml (I have Fedora x64).
Part of find_paths.yml after change:

  QT_LIBS_DIR:
    try:
      - shell: "{QMAKE} -query QT_INSTALL_LIBS"
      - "{QTDIR}/lib"
      - "/usr/lib"
      - "/usr/lib64"
      - "/usr/local/lib"

Error by running hello world

Hello, I tried to run the hello world with the shard file including qt5.cr but I'm getting this error

while requiring "qt5" (Exception) Unhandled exception: Error opening file 'crystal' with mode 'r': No such file or directory (Errno) Failed to raise an exception: END_OF_STACK [0x55756f7a67e6] ??? [0x55756ee8e10b] __crystal_raise +43 [0x55756ee8f915] ??? [0x55756ee9ff6f] ??? [0x55756ee99a8c] ??? [0x55756ee98d79] ??? [0x55756ee95798] ??? [0x55756eec870d] ??? [0x55756ee921cd] main +45 [0x7fb2ed1c2223] __libc_start_main +243 [0x55756ee8a4ce] _start +46 [0x0] ???

Any solutions ?

Problems with Macs os m1 platform

  1. Should add spoved to dependencies into shards.yml
dependencies:
  qt5:
    github: Papierkorb/qt5.cr
    branch: master
  spoved:
    github: spoved/spoved.cr
  1. lib/bindgen/clang/find_clang.cr5.
    Variables have problems with llvm_version (command nod found) and also change should add llvm/bin into the PATH.
makefile_variables_content = <<-VARS
  CLANG_BINARY := #{clang}
  CLANG_INCLUDES := #{system_include_dirs.map { |x| "-I#{File.expand_path(x)}" }.join(' ')}
  CLANG_LIBS := #{get_lib_args(clang_libs + llvm_libs).join(' ')}

  LLVM_CONFIG_BINARY := #{llvm_config}
  # LLVM_VERSION_MAJOR := #{llvm_version.split(/\./).first}
  LLVM_VERSION_MAJOR := "14"
  # LLVM_VERSION := #{llvm_version}
  LLVM_VERSION := "14.0.6"
  LLVM_CXX_FLAGS := #{llvm_cxx_flags}
  LLVM_LD_FLAGS := #{llvm_ld_flags}
  LLVM_LIBS := #{get_lib_args(llvm_libs).join(" ")}
  VARS
write_if_changed(makefile_variables, makefile_variables_content)
  1. Compilation problem with: lib/bindgen/clang/src/record_match_handler.cpp and lib/bindgen/clang/src/record_match_handler.cpp.

linę 92:

// if (typeInfo.AlignIsRequired) bitSize += typeInfo.Align; // was that - but method does not exist
if (typeInfo.isAlignRequired()) bitSize += typeInfo.Align; // switch to compile
	klass.byteSize = bitSize / 8;
  1. Compilation problem with: lib/bindgen/clang/src/preprocessor_handler.cpp and lib/bindgen/clang/include/regex.hpp
    Does not find
#include <pcre.h>

but file exists:

export LDFLAGS="-L$HOMEBREW_PREFIX/opt/pcre/lib"
export CPPFLAGS="-I$HOMEBREW_PREFIX/opt/pcre/include"
  1. No configuration for Mac OS => lib/qt5/support/generate_bindings.cr
configurations = [
#      OS       LIBC   ARCH      Qt   Patch   Clang target triplet      Ptr  Endian
#  { "linux", "gnu", "x86_64", "5.5",  "0", "x86_64-unknown-linux-gnu", 8, "little" },
#  { "linux", "gnu", "x86_64", "5.6",  "0", "x86_64-unknown-linux-gnu", 8, "little" },
#  { "linux", "gnu", "x86_64", "5.7",  "0", "x86_64-unknown-linux-gnu", 8, "little" },
#  { "linux", "gnu", "x86_64", "5.8",  "0", "x86_64-unknown-linux-gnu", 8, "little" },
#  { "linux", "gnu", "x86_64", "5.9",  "0", "x86_64-unknown-linux-gnu", 8, "little" },
#  { "linux", "gnu", "x86_64", "5.10", "0", "x86_64-unknown-linux-gnu", 8, "little" },
#  { "linux", "gnu", "x86_64", "5.11", "2", "x86_64-unknown-linux-gnu", 8, "little" },
#  { "linux", "gnu", "x86_64", "5.12", "0", "x86_64-unknown-linux-gnu", 8, "little" },
#   { "linux", "gnu", "x86_64", "5.13", "0", "x86_64-unknown-linux-gnu", 8, "little" },
#  { "linux", "gnu", "x86_64", "5.14", "0", "x86_64-unknown-linux-gnu", 8, "little" },
#  { "linux", "gnu", "x86_64", "5.15", "0", "x86_64-unknown-linux-gnu", 8, "little" },
#  {"darwin", "unknown", "x86_64", "5.13", "x86_64-apple-darwin19.6.0", 8, "little"},
#  {"darwin", "unknown", "x86_64", "5.15", "x86_64-apple-darwin19.6.0", 8, "little"},
  {"darwin", "unknown", "aarch64", "5.15", "0", "", 8, "little"}#  binding_darwin-unknown-aarch64-qt5.15
]
  1. Failure generate bindings
 crystal lib/qt5/support/generate_bindings.cr
-- Build files have been written to: /Users/marcin/Documents/crystal_projects/qt_sample/lib/bindgen/clang
Consolidate compiler generated dependencies of target parser
[  7%] Linking CXX executable parser
ld: library not found for -lclangTidyMPIModule
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [parser] Error 1
make[1]: *** [CMakeFiles/parser.dir/all] Error 2
make: *** [all] Error 2
  Bindgen requires a full installation of Clang, its libraries and development
  headers.  Please install these first, and restart this script.
  You can also manually run 'cmake . && make' in clang/ for debugging this issue.
  Full path to clang/: /Users/marcin/Documents/crystal_projects/qt_sample/lib/bindgen/clang/
Failed to build darwin-unknown-aarch64-qt5.15 using Qt5.15 on  - Abort.


```bash
clang --version
Homebrew clang version 14.0.6
Target: arm64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /opt/homebrew/opt/llvm/bin
  1. Cannot build via shards
shards build
Dependencies are satisfied
Building: shards
Error target shards failed to compile:
Showing last frame. Use --error-trace for full trace.

There was a problem expanding macro 'macro_4450161088'

Code in lib/qt5/src/qt5/binding.cr:6:1

 6 | {% begin %}
     ^
Called macro defined in lib/qt5/src/qt5/binding.cr:6:1

 6 | {% begin %}

Which expanded to:

 > 1 | 
 > 2 |   
 > 3 |   require "./binding/binding_darwin-unknown-aarch64-qt5.15"
         ^
Error: can't find file './binding/binding_darwin-unknown-aarch64-qt5.15' relative to '/Users/marcin/Documents/crystal_projects/qt_sample/lib/qt5/src/qt5/binding.cr'
  1. lib/qt5/config/find_paths.yml not support latest version (=14)
  LLVM_CONFIG_BINARY:
    kind: Executable
    optional: false
    try:
      - llvm-config
    version:
      min: "4"
      max: "14" # was 11
      variable: LLVM_VERSION
      command: "% --version"
      regex: "^([0-9]+)."
    error_message: Failed to find llvm version

Problem to regenerate a specific qt5 binding

Hello, I'm a Gentoo Linux user and today I tried to regenerate a specific qt5 bindings to try qt5 with crystal, but when the process started, it stopped and I had an error:

Full log:

 zohran  ~  Documents  Programmation  PGM  BINDGEN_DYNAMIC=1 lib/bindgen/tool.sh qt.yml --stats
** clang/parser not found.  Building now.
-- Found LLVM: 13.0.1
-- Using LLVMConfig.cmake in: /usr/lib/llvm/13/lib64/cmake/llvm
-- LLVM Major version: 13
-- Setting std version: c++14
-- LLVM Tools Dir: /usr/lib/llvm/13/bin
-- Using clang++ exec: /usr/lib/llvm/13/bin/clang++
-- Found llvm-config bin: /usr/lib/llvm/13/bin/llvm-config
-- Using llvm-config exec: /usr/lib/llvm/13/bin/llvm-config
-- Include LLVM dirs: /usr/lib/llvm/13/include
-- Add LLVM definitions: -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-- Run: crystal find_clang.cr -- --clang /usr/lib/llvm/13/bin/clang++ --llvm-config /usr/lib/llvm/13/bin/llvm-config --quiet
-- Run: crystal find_clang.cr -- --print-clang-libs --clang /usr/lib/llvm/13/bin/clang++ --llvm-config /usr/lib/llvm/13/bin/llvm-config --quiet
-- Run: crystal find_clang.cr -- --print-llvm-libs --clang /usr/lib/llvm/13/bin/clang++ --llvm-config /usr/lib/llvm/13/bin/llvm-config --quiet
-- CMake System Name: Linux
-- Configuring done
-- Generating done
-- Build files have been written to: /home/zohran/Documents/Programmation/PGM/lib/bindgen/clang
Consolidate compiler generated dependencies of target parser
[  7%] Building CXX object CMakeFiles/parser.dir/src/bindgen.cpp.o
/home/zohran/Documents/Programmation/PGM/lib/bindgen/clang/src/bindgen.cpp:18:38: error: calling a protected constructor of class 'clang::tooling::CommonOptionsParser'
        clang::tooling::CommonOptionsParser op(argc, argv, BindgenCategory);
                                            ^
/usr/lib/llvm/13/include/clang/Tooling/CommonOptionsParser.h:76:3: note: declared protected here
  CommonOptionsParser(
  ^
1 error generated.
make[2]: *** [CMakeFiles/parser.dir/build.make:76 : CMakeFiles/parser.dir/src/bindgen.cpp.o] Erreur 1
make[1]: *** [CMakeFiles/Makefile2:164 : CMakeFiles/parser.dir/all] Erreur 2
make: *** [Makefile:91 : all] Erreur 2
  Bindgen requires a full installation of Clang, its libraries and development
  headers.  Please install these first, and restart this script.
  You can also manually run 'cmake . && make' in clang/ for debugging this issue.
  Full path to clang/: /home/zohran/Documents/Programmation/PGM/lib/bindgen/clang/
 zohran  ~  Documents  Programmation  PGM  1  ls
lib  shard.lock  shard.yml
 zohran  ~  Documents  Programmation  PGM  cd lib/
bindgen/ qt5/     spoved/  toka/    
 zohran  ~  Documents  Programmation  PGM  cd lib/qt5/
config/  ext/     images/  lib/     samples/ spec/    src/     support/ 
 zohran  ~  Documents  Programmation  PGM  cd lib/
bindgen/ qt5/     spoved/  toka/    
 zohran  ~  Documents  Programmation  PGM  cd lib/bindgen/
assets/  ci/      clang/   images/  lib/     samples/ spec/    src/     
 zohran  ~  Documents  Programmation  PGM  cd lib/bindgen/clang/
 zohran  …  lib  bindgen  clang  cmake . && make
-- Found LLVM: 13.0.1
-- Using LLVMConfig.cmake in: /usr/lib/llvm/13/lib64/cmake/llvm
-- LLVM Major version: 13
-- Setting std version: c++14
-- LLVM Tools Dir: /usr/lib/llvm/13/bin
-- Using clang++ exec: /usr/lib/llvm/13/bin/clang++
-- Found llvm-config bin: /usr/lib/llvm/13/bin/llvm-config
-- Using llvm-config exec: /usr/lib/llvm/13/bin/llvm-config
-- Include LLVM dirs: /usr/lib/llvm/13/include
-- Add LLVM definitions: -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-- Run: crystal find_clang.cr -- --clang /usr/lib/llvm/13/bin/clang++ --llvm-config /usr/lib/llvm/13/bin/llvm-config --quiet
CMake Error at crystal.cmake:28 (message):
  You're missing the LLVM and/or Clang executables or development libraries.

  

  If you've installed the binaries in a non-standard location:

    1) Make sure that `llvm-config` or `llvm-config-*` is set with --llvm_config FILE or is in PATH. The first binary found which satisfies version will be used.
    2) In rare cases if clang++ isn't found or is incorrect, you can also specify it with --clang FILE.

  

  If your distro does not support static libraries like openSUSE then set env
  var BINDGEN_DYNAMIC=1.

  This will use .so instead of .a libraries during linking.

  

  If you are missing the packages, please install them:

    ArchLinux: pacman -S llvm clang gc libyaml
    Ubuntu: apt install clang-4.0 libclang-4.0-dev zlib1g-dev libncurses-dev libgc-dev llvm-4.0-dev libpcre3-dev
    CentOS: yum install crystal libyaml-devel gc-devel pcre-devel zlib-devel clang-devel
    openSUSE: zypper install llvm clang libyaml-devel gc-devel pcre-devel zlib-devel clang-devel ncurses-devel
    Mac OS: brew install crystal bdw-gc gmp libevent libxml2 libyaml llvm

Call Stack (most recent call first):
  CMakeLists.txt:4 (include)


-- Configuring incomplete, errors occurred!
See also "/home/zohran/Documents/Programmation/PGM/lib/bindgen/clang/CMakeFiles/CMakeOutput.log".
 zohran  …  lib  bindgen  clang  1  

And clang and llvm are installed with the following setup:

[I] sys-devel/clang
     Available versions:  
     (11)   11.1.0(11/11.1)^t
     (12)   12.0.1^t
     (13)   13.0.0^t (~)13.0.1^t
     (14)   **14.0.0_rc1^t **14.0.0.9999*l^t
     (15)   **15.0.0.9999*l^t
       {debug default-compiler-rt default-libcxx default-lld doc llvm-libunwind +pie +static-analyzer test xml ABI_MIPS="n32 n64 o32" ABI_S390="32 64" ABI_X86="32 64 x32" LLVM_TARGETS="AArch64 AMDGPU ARC ARM AVR BPF CSKY Hexagon Lanai LoongArch M68k MSP430 Mips NVPTX PowerPC RISCV Sparc SystemZ VE WebAssembly X86 XCore" PYTHON_SINGLE_TARGET="python3_8 python3_9 python3_10"}
     Installed versions:  13.0.1(13)^t(03:25:51 18/02/2022)(default-compiler-rt default-lld llvm-libunwind static-analyzer -debug -default-libcxx -doc -test -xml ABI_MIPS="-n32 -n64 -o32" ABI_S390="-32 -64" ABI_X86="32 64 -x32" LLVM_TARGETS="AArch64 AMDGPU ARM AVR BPF Hexagon Lanai MSP430 Mips NVPTX PowerPC RISCV Sparc SystemZ WebAssembly X86 XCore -ARC -CSKY -M68k -VE" PYTHON_SINGLE_TARGET="python3_9 -python3_8 -python3_10")
     Homepage:            https://llvm.org/
     Description:         C language family frontend for LLVM

[I] sys-devel/llvm
     Available versions:  
     (11)   11.1.0^t
     (12)   12.0.1^t
     (13)   13.0.0^t (~)13.0.1^t
     (14)   **14.0.0_rc1^t **14.0.0.9999*l^t
     (15)   **15.0.0.9999*l^t
       {+binutils-plugin debug doc exegesis +gold libedit +libffi ncurses test xar xml z3 ABI_MIPS="n32 n64 o32" ABI_S390="32 64" ABI_X86="32 64 x32" LLVM_TARGETS="AArch64 AMDGPU ARC ARM AVR BPF CSKY Hexagon Lanai LoongArch M68k MSP430 Mips NVPTX PowerPC RISCV Sparc SystemZ VE WebAssembly X86 XCore"}
     Installed versions:  13.0.1(13)^t(12:56:23 04/02/2022)(binutils-plugin libffi ncurses -debug -doc -exegesis -libedit -test -xar -xml -z3 ABI_MIPS="-n32 -n64 -o32" ABI_S390="-32 -64" ABI_X86="32 64 -x32" LLVM_TARGETS="AArch64 AMDGPU ARM AVR BPF Hexagon Lanai MSP430 Mips NVPTX PowerPC RISCV Sparc SystemZ WebAssembly X86 XCore -ARC -CSKY -M68k -VE")
     Homepage:            https://llvm.org/
     Description:         Low Level Virtual Machine

I missed to install something ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.