The gtkbuilder2.f90 gtk-fortran example can not run when the project is built with Intel compilers in Linux (note that it is the only system where I have Intel compilers). That issue #236 was identified two years ago.
The context
A Graphical User Interface (GUI) is event-driven: you typically write a subroutine that will be called at startup that describes and generates your GUI (the properties of your widgets, their layout, etc.). Then you write the Callback functions that will be called when an event occurs in a widget (for example when you click on a button).
The gtkbuilder2.f90
examples demonstrates another way, using the GtkBuilder API: you describe your GUI in a XML file and you call the gtk_builder_new_from_file()
function to read it and create the GUI at startup (of course, you still need to write your callback functions in your program). You can write the XML file by hand, but generally you would use a graphical tool to design your GUI: with GTK3 there was Glade, and with GTK4 a new tool is Cambalache. Or you could also use Blueprint, a new light markup language that can be compiled to a GtkBuilder XML file.
In the gtkbuilder2.ui file, the first button has a callback function named hello
that will be called (by the C library) when it is clicked on:
<object class="GtkButton" id="button1">
<property name="has-tooltip">True</property>
<property name="label">Button1</property>
<property name="tooltip-text">I will say hello...</property>
<signal name="clicked" handler="hello"/>
</object>
This example works perfectly when the project is compiled with GFortran, under all OS:
The bug
When gtk-fortran is built with Intel ifort or ifx (any version) under Linux, the example fails:
$ ./gtkbuilder2
(process:10881): Gtk-ERROR **: 10:29:36.313: failed to add UI from file gtkbuilder.ui: No function named `hello`.
But in the executable, the hello
function is present, as can be seen with that command:
$ readelf --wide --syms ./gtkbuilder2 | grep hello
818: 0000000000405270 81 FUNC GLOBAL DEFAULT 16 hello
A clue
The code of the callback function is:
subroutine hello(widget, gdata) bind(c)
!GCC$ ATTRIBUTES DLLEXPORT :: hello
type(c_ptr), value, intent(in) :: widget, gdata
print *, "Hello World!"
end subroutine hello
The !GCC$ ATTRIBUTES DLLEXPORT
directive is needed for dynamic linking under Windows. If I remove it and compile gtk-fortran with GFortran (tested in MSYS2/Windows 10), I’ve got the same error message.
I have found that Intel compilers have a similar directive in Windows (and macOS): !DIR$ ATTRIBUTES DLLEXPORT (but I have not tested it, as I have not installed Intel compilers in my MSYS2).
Do you know any directive or Intel compiler option that could allow that example to run in Linux? (thanks for reading!)