NI Linux Real-Time Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Building a GUI using C and GTK

I've been able to follow the tutorial for getting C code to cross compile to the new Linux targets that support GUIs.  Now I'd like to compile code that has a GUI in it.  By searching around on the Linux target, it looks like it has a package called GTK, which I'm guessing I can use to display graphics.  I'm new to cross compiling and Linux, so I'm probably setting this up wrong - but I installed the GTK+ dev tools to my computer, included the header for the toolkit into my C code, and now I get errors when I try to compile.  The error message looks like this:

Info: Internal Builder is used for build

arm-nilrt-linux-gnueabi-gcc "-IC:\\gtk\\include\\gtk-3.0" "-IC:\\gtk\\include\\gtk-3.0" -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\testfile.o" "..\\src\\testfile.c"

In file included from C:/gtk/include/gtk-3.0/gdk/gdk.h:30:0,

                 from C:/gtk/include/gtk-3.0/gtk/gtk.h:30,

                 from ..\src\myRIOHeader9068.c:14:

C:/gtk/include/gtk-3.0/gdk/gdkconfig.h:13:18: fatal error: glib.h: No such file or directory

compilation terminated.

Any ideas on how I can cross compile C code that will let me build my own GUIs?  I don't really care that it is GTK, I only choose that cause it looked like it was already installed, and so I figured it would work.

It looks like the target has GTK2.0, where I have GTK3.0 on my computer. I thought maybe that'd be it, but I would have expected a runtime error, not a build error for that. 

0 Kudos
Message 1 of 6
(6,589 Views)

This could be little tricky to do with a cross compile on Windows because the GTK+ toolchain has dependencies, i.e. on GLib, which you'd get via your package manager dependencies on Linux but will have to track down and install by hand on Windows. I don't know how deep those dependencies go but I worry it could be a major headache to get that all set up.

Also, I see that while your goal is to target one of the new GUI-enabled targets, your pasted output is for ARM (9068, it seems) which does not support GUI (no local graphics hardware, no X11 to use a remote display), so be aware that as you get further along there may be issues with missing dependencies at run time specific to that test case.

The combination of those two observations leads me to suggest you might want to try setting up a development system that runs Linux for x86_64 like the UI-enabled NI Linux RT targets. You could run this development environment in a Linux virtual machine on your Windows box, or you could install GCC and the GTK+ dev tools on the target itself and log into it via ssh and develop that way. Then you can develop for x86_64 "natively" on your dev machine, no cross compile, and the resulting binaries should work on the NI Linux RT target. It probably sounds like a lot of trouble, and to be honest it probably is if you're not familiar with developing in Linux, but it may be less trouble than the cross-compile scenario you're pursuing.

0 Kudos
Message 2 of 6
(5,244 Views)

Thanks for the fast reply, looks like you're right on that one - I accidentally setup this project for the wrong target.  I have now switched it to the x86_64 compile toolchain.  My hello world project works just fine on that target until I add in the header file:

#include <gtk/gtk-3.0>

I also have to include the path C:\gtk\include\gtk-3.0 in my "Include" section in Eclipse to get the non recognized path error to be resolved.  The build error then gave me the name of another file that seemed to be missing glib.h (which seems to follow exactlywhat you were saying before).  I added that one and it listed a different missing file. 

After reading on the C forums for a while, it sounds like I needed to run the command:

pkg-config --cflags gtk+-3.0

This gave me back a whole bunch of header files.  I went through and added each one of them to the include section of my build in Eclipse - and now instead of generating a single error, it generates a never ending stream of errors and I have to cancel the build. 

I found another forum which seemed to suggest that adding this command to the end of the GCC Compiler and Linker lines from the project properties would fix the problem, but it doesn't seem to have made any difference:

$(pkg-config gtk+-3.0 --cflags --libs)

I guess maybe this is a general Linux and C question - but I posted here because I thought maybe the error was specifically due to interfacing with the Intel cross compilation toolchain properly. 

My new error looks something like this, but goes on forever and ever:

C:/gtk/include/glib-2.0/glib/gthreadpool.h:71:17: error: declaration for parameter 'g_thread_pool_set_max_unused_threads' but no such parameter

C:/gtk/include/glib-2.0/glib/gthreadpool.h:38:29: error: declaration for parameter 'GThreadPool' but no such parameter

In file included from C:/gtk/include/glib-2.0/glib.h:84:0,

                 from C:/gtk/include/gtk-3.0/gdk/gdkconfig.h:13,

                 from C:/gtk/include/gtk-3.0/gdk/gdk.h:30,

                 from C:/gtk/include/gtk-3.0/gtk/gtk.h:30,

                 from ../src/GTKTest.c:14:

C:/gtk/include/glib-2.0/glib/gtestutils.h:309:9: error: declaration for parameter 'g_test_assert_expected_messages_internal' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:274:3: error: declaration for parameter 'GTestLogBuffer' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:269:3: error: declaration for parameter 'GTestLogMsg' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:261:3: error: declaration for parameter 'GTestLogType' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:246:3: error: declaration for parameter 'GTestConfig' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:225:9: error: declaration for parameter 'g_assertion_message_error' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:216:9: error: declaration for parameter 'g_assertion_message_cmpnum' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:208:9: error: declaration for parameter 'g_assertion_message_cmpstr' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:203:9: error: declaration for parameter 'g_assertion_message_expr' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:198:9: error: declaration for parameter 'g_assertion_message' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:192:9: error: declaration for parameter 'g_test_trap_assertions' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:173:10: error: declaration for parameter 'g_test_rand_double_range' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:172:10: error: declaration for parameter 'g_test_rand_double' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:170:10: error: declaration for parameter 'g_test_rand_int_range' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:169:10: error: declaration for parameter 'g_test_rand_int' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:159:10: error: declaration for parameter 'g_test_trap_reached_timeout' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:158:10: error: declaration for parameter 'g_test_trap_has_passed' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:155:3: error: declaration for parameter 'GTestTrapFlags' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:146:9: error: declaration for parameter 'g_test_queue_destroy' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:145:9: error: declaration for parameter 'g_test_queue_free' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:142:9: error: declaration for parameter 'g_test_timer_last' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:141:9: error: declaration for parameter 'g_test_timer_elapsed' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:140:9: error: declaration for parameter 'g_test_timer_start' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:138:9: error: declaration for parameter 'g_test_bug' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:137:9: error: declaration for parameter 'g_test_bug_base' but no such parameter

C:/gtk/include/glib-2.0/glib/gtestutils.h:135:9: error: declaration for parameter 'g_test_message' but no such parameter

In file included from C:/gtk/include/glib-2.0/glib.h:84:0,

                 from C:/gtk/include/gtk-3.0/gdk/gdkconfig.h:13,

                 from C:/gtk/include/gtk-3.0/gdk/gdk.h:30,

                 from C:/gtk/include/gtk-3.0/gtk/gtk.h:30,

                 from ../src/GTKTest.c:14:

0 Kudos
Message 3 of 6
(5,244 Views)

You're right that it's related to cross compiling. Unfortunately syntax like $(pkg-config gtk+-3.0 --cflags --libs) in your Eclipse configuration won't work in the cross-compile scenario: that directive is literally running a command as one of the command line options to the compile, and running that command on your host won't have the desired (or probably any) effect. I suspect there are actually two reasons it won't work. First, Eclipse on Windows might not execute the snippet inside $(...) because that's Linux shell syntax that is nonsense to Windows, although Eclipse might figure it out for you. Second, Windows probably doesn't have a working version of pkg-config installed, so even if the shell syntax worked it wouldn't have anything to run.

Just to make sure I'm following correctly, when you said running that command interactively did work (and "gave [you] back a whole bunch of header files"), I am guessing you ran that on your target -- is that right? If that's right, the paths it returned to you are target paths (and they're actually directories, not files) that you'd have to adapt to the equivalent on your host. For example while I don't have GTK+ on my target to demonstrate I do have glib-2.0 and here's what I get for output from that:

admin@scot-9068:~# pkg-config --cflags glib-2.0

-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include 

I can't just copy-paste that exact string to my host compile instructions. Mapping to what I can deduce of your configuration, it looks like you'd need something like: -IC:/gtk/include/glib-2.0 -IC:/gtk/lib/glib-2.0/include (you'd want to check to make sure those directories exist and contain reasonable looking files of course).

It seems like you got most of the way to this point already, though, because your compile obviously found the GTK+ headers despite those also not being in their target path. So I'm a little confused. Is the output you pasted above starting from the top of the output? It seems like it must be missing something earlier, like a header not being found...or, maybe you just need to follow the process you already followed for GTK+ for all of its dependencies like GLib also.

0 Kudos
Message 4 of 6
(5,244 Views)

I actually got the list of includes by running the pkg-config command on my Windows machine.  Running that command from the command line on my Windows machine gives this output:

pkg-config.png

Oddly there are a few packages dupilicated there, but I stuck all of them in the list of includes in my compiler, and that's when it started the eternal generation of errors.

My Settings look like this:

Settings.png

And my build steps look like this:

Build steps.png

As for the command being in the Linux format, I'm not really sure how I would format it so that Window's recognizes it.  I tried it as follows instead and it just gives the same behavior:

`pkg-config gtk+-3.0 --cflags`

This seemed like it was going to be so much easier after I got the generic cross compilation to work... Thanks for all the input.  I just thought it'd be nice to be able to build a while application, GUI included in C.


0 Kudos
Message 5 of 6
(5,244 Views)

I'm actually pretty excited to see that pkg-config worked as well as it did on Windows -- that should make it easier to do this on Windows completely. I think all you need to do to work around the lack of support for the $(pkg-config ...) syntax in the command line options in Eclipse is what you already did -- reproduce the pkg-config output by manually entering them in the project include paths. Anything that a -I (that's a dash-capital-i) include path gets entered as you did in the include paths table. Other options need to be entered elsewhere, such as the command line you show in your second screenshot, that would include for example the -mms-bitfields option. If you had -l (that's a lowercase L, for library) or -L (library search path) that would go into the linker section.

I buried this important question last time but it's important so I wanted to check on it again: is the output you pasted above starting from the top of the output? It seems like it must be missing something earlier, like a header not being found. If there's earlier output about a missing header that would be easier to diagnose than the errors we get here. If this is all we have, you're probably going to have to start digging through the actual headers, going to the lines where the errors are reported, and looking at what the line is doing and seeing if you can follow the include paths back to where something went wrong, like maybe some conditionally compiled code is needed but is not being included due to the specific configuration used here, that sort of thing.

0 Kudos
Message 6 of 6
(5,244 Views)