Recently, I decided to start doing some C. In the past, I’ve used GLib in my C programs, and I’m a fan. I decided that I’d like to use GLib in my current endeavors. All that said, before I can use it, I have to be able to build it. Unfortunately, nothing in my life just works, so it took some configuring.
In my last post, I talked about creating a Makefile, and walked through it. I forgot one huge thing though: pkg-config!
Previously in DMP Photobooth, I used pkg-config to manage my library compiler flags. To that end, let’s make some changes to the Makefile I wrote previously. First, let’s refer back to what I wrote before:
COMPILE_FLAGS = -c -g -Wall -Wextra -std=c11 $(OPTIMIZE_LEVEL) LINK_FLAGS = -g -Wall -Wextra -std=c11 $(OPTIMIZE_LEVEL) LINKER_LIBS = -lSDL2 -ldl -lGL
It’s pretty straightforward. I have a compile flag set for compiling a .o, and for compiling a program. I also have a LINKER_LIBS variable to pass to the compile command. This isn’t part of the COMPLIE/LINK_FLAGS because the sources and object code being compiled must appear first or GCC complains. Now, let’s take a look at the new snippet:
COMPILE_FLAGS = -c -g -Wall -Wextra -std=c11 $(OPTIMIZE_LEVEL) \ $(shell pkg-config --cflags $(PKG_CONFIG_LIBS)) LINK_FLAGS = -g -Wall -Wextra -std=c11 $(OPTIMIZE_LEVEL) \ $(shell pkg-config --cflags $(PKG_CONFIG_LIBS)) PKG_CONFIG_LIBS = glib-2.0 gl sdl2 MANUAL_LIBS = -ldl LINKER_LIBS = $(MANUAL_LIBS) $(shell pkg-config --libs $(PKG_CONFIG_LIBS))
Things are getting just a bit more complicated now. You’ll notice there are three LIBS related variables. PKG_CONFIG_LIBS is the list of libraries to be passed to the pkg-config command. MANUAL_LIBS, as the name implies, is a list of manually configured -l strings. For the life of me, I couldn’t figure out what to pass to pkg-config to get it to spit out
-ldl, so I’m forced to do it this way.
Regardless, LINKER_LIBS now contains the MANUAL_LIBS, and the output of
$(shell pkg-config --libs $(PKG_CONFIG_LIBS)) which produces the necessary -l strings for all the PKG_CONFIG_LIBS.
On top of that, I’ve added the output of
$(shell pkg-config --cflags $(PKG_CONFIG_LIBS)) to the COMPILE_FLAGS and LINK_FLAGS. This will ensure that if any pkg-config library needs special compiler flags, that they get used.
Great, now that’s done. A quick
make, and everything seems to be working. We’re in business! …right?
If only it could be that easy. I created a new source and entered the following:
Flycheck wasn’t convinced though; it put some red jaggies under this, and a quick mouse over of the error shows that flycheck doesn’t think that file exists. I began getting deja vu. After some googling, I determined that I can add arbitrary paths to
flycheck-clang-include-path (I’m using the flycheck clang checker, if you’re using gcc this variable is going to be different. I’m guessing
flycheck-gcc-include-path) to rectify the issue. To do this, enter:
M-x customize-variable [ENTER] flycheck-clang-include-path [ENTER]
This will get you a customize window for this variable. I added the following:
…and things seem to be working fine. That said, I imagine if I get more involved in the GLib stack, I’m going to have to add all of these guys:
Not a huge deal, but I’ll cross that bridge when I come to it.
Tired of creating console applications in C? Me too. Normally, when it comes time to create a GUI application I turn to good old Java Swing. This is fine and all, but how can I be a proper hoity-toity C programmer who scoffs at the very notion of Java if I can’t even create a proper C GUI app? Clearly, this will not do…
While I do have some experience with QT in the past, I’ve decided to go with GTK. QT is a C++-only toolkit, and I’m not a huge fan of C++. QT also introduces a bunch of magic keywords and requires the use of a special pre-compiler. Meanwhile, GTK is a C library, and requires no fancy pre-compiler. But before I can do anything, I need to configure my environment…
First, the easy part. You need to make sure you have the GTK development headers installed. If you’re running Ubuntu, this is a simple apt-get:
sudo apt-get install libgtk-3-dev
Now, the hard part. First, we need to launch netbeans. Click Tools -> Options and click C/C++. Click on the Code Assistance tab. Ensure you have the C Compiler tab selected, and the correct toolchain is selected in Tool Collection dropdown. Next, open a new terminal. Enter:
pkg-config --cflags gtk+-3.0
Did you see that gigantic list of paths? You’d better believe that you’re adding all of those to your Include Directories. For each folder, you need to click Add, enter the path in the File Name field, and click Select. When you’re done, your Include Directories should look similar to this:
Click OK when you’re done. Now, it’s time to create a new project. Click File -> New Project… Select C/C++ and Select C/C++ Application. Click Next >. Give your project a name. Ensure that C is selected in the dropdown next to Create Main File, and ensure you have the correct toolchain selected in the Tool Collection dropdown. Click Finish.
Now, it’s time to configure our project properties. Right click your newly created project and click Properties. Click on Build -> C Compiler. Remember in the code completion section when we typed that command and got that gigantic list? Luckily for us, unlike Netbeans, GCC knows what to do with that. In the Compilation Line -> Additional Options field, enter:
`pkg-config --cflags gtk+-3.0`
Note that those are `back qoutes`, not ‘single quotes’. To be clear, it’s the quote located on the ~ button. Next, click Build -> Linker. In the Compilation Line -> Additional Options field, enter:
`pkg-config --libs gtk+-3.0
Note that this line is –libs, not –cflags. If you enter this command, minus backquotes, on the command line, you’ll see it give a list of libraries instead of include paths. When you are done, click OK.
Open up your main.c source file. At the top of the file, enter:
Wait for it…
Did Yellow Jaggies appear? Congratulations, you’ve come across the same problem that’s had me troubleshooting for the last 4 hours, and that’s made me give up on GTK several times before. Luckily for you, I have the solution.
Hold Ctrl+Alt and click on include. This should open up the header with the missing inclusion. Find the red jaggies. Open a terminal and enter:
sudo find / -name MISSING_HEADER.h
If the file is not located at the correct spot, try re-installing the library. However, if it is found and in the correct position, then the issue is with code completion. Return to netbeans and click Tools -> Options and click C/C++. Click on the Code Assistance tab. Ensure you have the C Compiler tab selected, and the correct toolchain is selected in Tool Collection dropdown. Locate the offending library, and click Up until it’s at the top of the group of libraries that you just added. Click OK
Did the yellow jaggies go away? Congratulations, you’re done. Otherwise, you get to keep doing this until it works.
When All of That is Done…
Now, it’s time to try it out. For now, you can just copy and paste the Hello World implementation from the GTK+3 Reference Manual. Copy and paste the whole thing, overwriting your existing main function, build it, and run it. If all is well, you should see a window like this:
Pour yourself a glass of wine, and grab a tiny piece of cheese. You are one step closer to lording over the Java Plebians!