10

I'm having trouble compiling a simple, sample program against glib on Ubuntu. I get the following errors. I can get it to compile but not link with the -c flag, which I believe means I have the glib headers installed, but it's not finding the shared object code. See also the Make file below.

$> make re
gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include  -lglib-2.0       re.c   -o re
/tmp/ccxas1nI.o: In function `print_uppercase_words':
re.c:(.text+0x21): undefined reference to `g_regex_new'
re.c:(.text+0x41): undefined reference to `g_regex_match'
re.c:(.text+0x54): undefined reference to `g_match_info_fetch'
re.c:(.text+0x6e): undefined reference to `g_print'
re.c:(.text+0x7a): undefined reference to `g_free'
re.c:(.text+0x8b): undefined reference to `g_match_info_next'
re.c:(.text+0x97): undefined reference to `g_match_info_matches'
re.c:(.text+0xa7): undefined reference to `g_match_info_free'
re.c:(.text+0xb3): undefined reference to `g_regex_unref'
collect2: ld returned 1 exit status
make: *** [re] Error 1

Makefile used:

# Need to installed libglib2.0-dev some system specific install that will
# provide a value for pkg-config
INCLUDES=$(shell pkg-config --libs --cflags glib-2.0)
CC=gcc $(INCLUDES)
PROJECT=re

# Targets
full: clean compile

clean:
    rm $(PROJECT)

compile:
    $(CC) $(PROJECT).c -o $(PROJECT)

.c code being compiled:

#include <glib.h>

void print_upppercase_words(const gchar *string)
{
  /* Print all uppercase-only words. */

  GRegex *regex;
  GMatchInfo *match_info;

  regex = g_regex_new("[A-Z]+", 0, 0, NULL);
  g_regex_match(regex, string, 0, &match_info);

  while (g_match_info_matches(match_info))
    {
      gchar *word = g_match_info_fetch(match_info, 0);
      g_print("Found %s\n", word);
      g_free(word);
      g_match_info_next(match_info, NULL);
    }

  g_match_info_free(match_info);
  g_regex_unref(regex);
}

int main()
{
  gchar *string = "My body is a cage.  My mind is THE key.";

  print_uppercase_words(string);
}

Strangely, when I run glib-config, it doesn't like that command, though I don't know how to tell Bash or Make how to just use one over the other when it complains that gdlib-config is in these two packages.

$> glib-config
No command 'glib-config' found, did you mean:
 Command 'gdlib-config' from package 'libgd2-xpm-dev' (main)
 Command 'gdlib-config' from package 'libgd2-noxpm-dev' (main)
glib-config: command not found
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
lucidquiet
  • 6,124
  • 7
  • 51
  • 88

2 Answers2

29

Libraries at the end of the compiler command:

gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include re.c -o re -lglib-2.0

From GCC Link Options:

-llibrary
-l library
    Search the library named library when linking. 
    (The second alternative with the library as a separate argument
    is only for POSIX compliance and is not recommended.)

    It makes a difference where in the command you write this option;
    the linker searches and processes libraries and object files in the
    order they are specified.
    Thus, `foo.o -lz bar.o' searches library `z' after file foo.o but
    before bar.o. If bar.o refers to functions in `z', those functions
    may not be loaded.
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • 1
    That's called single-pass linking: https://computation.llnl.gov/casc/components/docs/users_guide/node319.html – John Zwinck Apr 01 '12 at 18:24
  • Well, I've read that while researching this problem, and I've tried all of these: gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0 re.c -o re gcc -lglib-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include re.c -o re gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include re.c -o re -lglib-2.0 I don't think the order is actually changing anything. I thought that the -lglib-2.0 flag should point to the .so files -- but I don't think it is finding the .so files. – lucidquiet Apr 01 '12 at 18:59
  • 1
    So what was the solution, I don't understand? – FreelanceConsultant Jul 19 '14 at 17:03
  • 1
    Just to make it clear, it is necessary that all "-l" parameters are appended to the *end* of the compiling command. This means that "`pkg-config --libs glib-2.0`" (which generates the *lowercase L* parameters) should be last in the command, while "`pkg-config --cflags glib-2.0`" (which generates the *uppercase I* parameters) should appear ***before*** the ".c" source file. – Rui Pimentel Jan 19 '16 at 13:07
  • For those who are experiencing this problem in the Codeblocks (Code::Blocks) environment, all you need to do is put ``pkg-config --cflags glib-2.0`` under "Compiler settings >> Other options" on the "Project build options" dialog and ``pkg-config --libs glib-2.0`` under "Linker settings >> Other linker options". Beware that these settings might apply to the whole project or one of the target profiles ("Debug" / "Release" / etc.), depending on what is selected on the left panel. Also, if anyone else's getting similar problems with GTK+, it is possible to just replace "glib-2.0" with "gtk+-3.0". – Rui Pimentel Jan 19 '16 at 13:24
3
gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include re.c -o re -lglib-2.0

Uh -- hell -- I've tried so many things and probably got them all a little wrong, but I tried the above just now, and it worked.... soooo solved.

lucidquiet
  • 6,124
  • 7
  • 51
  • 88