A long-standing bug in a gtk-fortran example with Intel compilers

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"/>

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)
	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!)

I use “!DEC$ ATTRIBUTES STDCALL,REFERENCE,ALIAS:‘hello’, DLLEXPORT :: hello” for intel, so to enable using both you would need a macro like:

#ifdef __GNUC__

the directives should be OS agnostic

Thanks @hkvzjal for your post,

I have tried on my Linux Ubuntu:

  subroutine hello(widget, gdata) bind(c)
    type(c_ptr), value, intent(in) :: widget, gdata

    print *, "Hello World!"
  end subroutine hello

But building it with ifx fails:

[ 97%] Building Fortran object examples/CMakeFiles/gtkbuilder2.dir/gtkbuilder2.f90.o
ifx: remark #10440: Note that use of a debug option without any optimization-level option will turnoff most compiler optimizations similar to use of '-O0'
/tmp/gtk-fortran-intel/examples/gtkbuilder2.f90(59): remark #7841: DLL IMPORT/EXPORT is not supported on this platform.   [DLLEXPORT]
/tmp/gtk-fortran-intel/examples/gtkbuilder2.f90(59): error #8143: The BIND(C) attribute for this symbol conflicts with a DEC$ ATTRIBUTES ALIAS, DECORATE, CVF, C, [NO_]MIXED_STR_LEN_ARG or REFERENCE attribute for this symbol.   [HELLO]
compilation aborted for /tmp/gtk-fortran-intel/examples/gtkbuilder2.f90 (code 1)

If I remove the warning about DLLEXPORT, the other error remains. I am obliged to remove both REFERENCE and ALIAS:'hello' to compile successfully. But the remaining directive !DEC$ ATTRIBUTES STDCALL :: hello does not fix the error when running the executable.

I am now exploring this page:
but I don’t know if something there can help me and be compatible with bind(c)