gcc glib symbol lookup error - c

I am currently programming a little C-programm that uses GLib-2.0 for its data structures.
I am compiling with the following command:
gcc -g -O3 -std=gnu99 -fPIC -shared -I/usr/local/java/jdk1.8.0_20/include \
-I/usr/local/java/jdk1.8.0_20/include/linux \
`pkg-config --cflags glib-2.0` `pkg-config --libs glib-2.0` \
-o runtimesamplingagent.so runtimesamplingagent.c
This works without problems.
However, when I run the program, I get following error:
symbol lookup error: ./runtimesamplingagent.so: undefined symbol: g_node_new
What's the cause of this?
I am pretty new to C but I would guess it's some kind of linking issue.
Any hints what could be the cause of it?
I am working on a Ubuntu 14.04 LTS 64bit machine with libglib-2.0-dev installed.

You have already included the linking option in the build command; the problem is that it is in the wrong place.
Your command looks like this:
gcc -g -O3 -std=gnu99 -fPIC -shared \
-I/usr/local/java/jdk1.8.0_20/include \
-I/usr/local/java/jdk1.8.0_20/include/linux \
`pkg-config --cflags glib-2.0` \
`pkg-config --libs glib-2.0` \ <<<
-o runtimesamplingagent.so \
runtimesamplingagent.c
In that line marked with <<<, you have already specified the options needed to link GLib. The only problem is that it is in the wrong place. You should put this at the very end, after the .c file.
So your command should look like this instead:
gcc -g -O3 -std=gnu99 -fPIC -shared \
-I/usr/local/java/jdk1.8.0_20/include \
-I/usr/local/java/jdk1.8.0_20/include/linux \
`pkg-config --cflags glib-2.0` \
-o runtimesamplingagent.so \
runtimesamplingagent.c \
`pkg-config --libs glib-2.0`

appending
-lglib-2.0
to the end of the build command, fixed it.

Related

libSDL2_gfx-1.0.so.0: cannot open shared object file: No such file or directory

Creating an SDL2 application on Ubuntu 20.04 which uses the visual shape overlays provided by SDL2_gfx. Have both SDL2 and SDL2_gfx installed, I believe properly (./configure, make, sudo make install... all successful), compilation is success, but program execution is not.
Error message:
libSDL2_gfx-1.0.so.0: cannot open shared object file: No such file or directory
**Useful commands/results/information: **
user#debian$ pkg-config --cflags sdl2
-D_reentrant -I/usr/local/include -I/usr/local/include/SDL2
user#debian$ pkg-config --cflags SDL2_gfx
-D_reentrant -I/usr/local/include/SDL2 -I/usr/local/include -I/usr/local/include/SDL2
user#debian$ pkg-config --libs sdl2
-L/usr/local/lib -Wl, -rpath,/usr/local/lib -Wl, --enable-new-dtags -lSDL2
user#debian$ pkg-config --libs SDL2_gfx
-L/usr/local/lib -lSDL2_gfx -Wl, -rpath,/usr/local/lib -Wl, --enable-new-dtags -lSDL2
Compile argument: gcc sdlTest.c -o sdlTesting -I/usr/local/include -I/usr/local/include/SDL2
-L/usr/local/lib -L/usr/local/lib -lSDL2 -lSDL2_gfx
Also the compile argument:
gcc sdlTest.c -o sdlTesting -lSDL2 -lSDL2_gfx
...somehow works as well for compilation. Build error remains the same:
Tried the standard compilation using linker commands -lSDL2 -lSDL2_gfx, expected to have a normal execution using ./sdlTesting

SDL 2 C Compiler Flags

Whenever I run the following, I get undefined references to all the SDL-related functions used in my program:
cc -lSDL2 -lGL *.o
I believe this is caused by the lack of -l linker flags.
GCC arguments are positional, put the link flags after your o files:
gcc *.o -lSDL2 -lGL
Also, if you're on a proper full Linux system I'd recommend using pkg-config to pull compiler/linker flags:
gcc -c main.c `pkg-config sdl2 --cflags`
gcc main.o `pkg-config sdl2 --libs`

Linking SDL in a C program

I have recently become interested in using SDL after having learned some basics of C. I have installed SDL_image and SDL_mixer. They are located in /usr/local/include/SDL2. I realize that you must link against the header files however I am not sure how to do it. I am getting the error that SDL_mixer or SDL_image do not exist (depending on their line order in my source code). I have tried two different compilation commands and neither work here they are:
gcc filename.c -o test -I./include -L./usr/local/include/SDL2 -lSDL2main -lSDL2 -lSDL_mixer -lSDL_image
gcc filename.c -o test -I./usr/local/include/SDL2 -L./lib -lSDL2main -lSDL2 -lSDL_mixer -lSDL_image
If anyone has any ideas I would appreciate it! Thanks in advance!
you do not want that leading period
wrong
gcc filename.c -o test -I./include -L./usr/local/include/SDL2 -lSDL2main -lSDL2 -lSDL_mixer -lSDL_image
closer - not necessarily correct yet
gcc filename.c -o test -L/usr/local/include/SDL2 -lSDL2main -lSDL2 -lSDL_mixer -lSDL_image
any path with a leading period indicates to start from current dir and go relative instead of the intended absolute path
any system has the notion of a default library path which is fine if you are using a standard install ... so no need to do a
-I/include
... sometime a library has helpers to identify and auto populate these ...
sdl and sdl2 do have such a helper ... this will give you those settings
gcc -o test filename.c `pkg-config --cflags --libs sdl2`
notice those backticks ... another syntax style would be
gcc -o test filename.c $(pkg-config --cflags --libs sdl2)
you are free to issue that stand alone just to take a peek
pkg-config --cflags --libs sdl2
... output
-D_REENTRANT -I/usr/include/SDL2 -lSDL2
Now onto your sdl mixer ... well it has a
pkg-config --cflags --libs SDL2_mixer
... output
-D_REENTRANT -I/usr/include/SDL2 -lSDL2_mixer -lSDL2
you probably do not want to mix sdl with sdl2 so replace mention of
-lSDL_mixer -lSDL_image
with
-lSDL2_mixer -lSDL2_image
as per
pkg-config --cflags --libs SDL2_image
... output
-D_REENTRANT -I/usr/include/SDL2 -lSDL2_image -lSDL2
so bundling these together
gcc -o test filename.c -lSDL2main $(pkg-config --cflags --libs sdl2) $(pkg-config --cflags --libs SDL2_mixer) $(pkg-config --cflags --libs SDL2_image)
or more simply combined to
gcc -o test filename.c -lSDL2main $(pkg-config --cflags --libs sdl2 SDL2_mixer SDL2_image )
this can be stripped down to simply the following ... yet above syntax is more robust to changes
gcc -o test filename.c -D_REENTRANT -I/usr/include/SDL2 -lSDL2main -lSDL2 -lSDL2_mixer -lSDL2_image
You can use sdl2-config to supply the appropriate flags to gcc:
gcc filename.c -o test `sdl2-config --cflags --libs`
sdl2-config --cflags produces a list of options that should be passed to the compiler, and sdl2-config --libs produces a list of libraries that should be linked to.

How to use pkg-config in Make

I want to compile the simplest GTK program.
I can compile it using the command line:
gcc $(pkg-config --cflags --libs gtk+-3.0) main.c -o main.o
However, if I use Make it doesnt work:
CFLAGS=-g -Wall -Wextra $(pkg-config --cflags)
LDFLAGS=$(pkg-config --libs gtk+-3.0)
CC=gcc
SOURCES=$(wildcard *.c)
EXECUTABLES=$(patsubst %.c,%,$(SOURCES))
all: $(EXECUTABLES)
It tells me this:
gcc -g -Wall -Wextra -c -o main.o main.c
main.c:1:21: fatal error: gtk/gtk.h: No such file or directory
#include <gtk/gtk.h>
^
compilation terminated.
<builtin>: recipe for target 'main.o' failed
make: *** [main.o] Error 1
Where do I stick $(pkg-config --cflags --libs gtk+-3.0) in the Makefile to make it compile?
Thanks very much in advance for your kind help.
There are two issues.
First, your CFLAGS line is wrong: you forgot to say gtk+-3.0 in the pkg-config part, so pkg-config will spit out an error instead:
CFLAGS=-g -Wall -Wextra $(pkg-config --cflags gtk+-3.0)
Second, and more important, $(...) is intercepted by make itself for variable substitution. In fact, you've seen this already:
SOURCES=$(wildcard *.c)
EXECUTABLES=$(patsubst %.c,%,$(SOURCES))
all: $(EXECUTABLES)
is all done by make.
There are two things you can do.
First, you can use `...` instead, which does the same thing ($(...) is newer shell syntax).
CFLAGS=-g -Wall -Wextra `pkg-config --cflags gtk+-3.0`
LDFLAGS=`pkg-config --libs gtk+-3.0`
Second, since you seem to be using GNU make, you can use the shell substitution command, which was shown in the answer Basile Starynkevitch linked above:
CFLAGS=-g -Wall -Wextra $(shell pkg-config --cflags gtk+-3.0)
LDFLAGS=$(shell pkg-config --libs gtk+-3.0)

How to set gcc RPATH without including any build paths?

I need to build a wget incomplete executable using gcc for RHEL4 that will use a specific OpenSSL shared lib. LD_LIBRARY_PATH is unset at build time.
This is quite simple by specifying:
LDFLAGS="-W1,-rpath=/usr/local/ssl/lib -L/my_build_dir/usr/local/ssl/lib"
and all is good.
But this makes the RPATH in the dynamic section of my incomplete executable:
Library rpath: [/usr/local/ssl/lib:/my_build_dir/usr/local/ssl/lib]
Is it possible using the gcc toolchain to set the RPATH to only use what is specified using the -rpath option and to ignore all library paths declared at build time?
I have looked at many SO posts today incl.:
I don't understand -Wl,-rpath -Wl, , and
What's the difference between -rpath and -L?
but nothing seems to address the issue of removing build info from the final incomplete executable.
EDIT: Here is the full command line for the final link phase.
gcc -Wall -std=c99 -m32 -march=athlon -mfpmath=sse -msse2 -O2 -pipe -s \
-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -m32 -march=athlon \
-mfpmath=sse -msse2 -O2 -pipe -s -Wl,-rpath,/usr/local/ssl/lib \
-L/my_build_dir/usr/local/ssl/lib -o wget cmpt.o connect.o convert.o \
cookies.o ftp.o css_.o css-url.o ftp-basic.o ftp-ls.o hash.o host.o \
html-parse.o html-url.o http.o init.o log.o main.o netrc.o progress.o \
ptimer.o recur.o res.o retr.o spider.o url.o warc.o utils.o exits.o
build_info.o iri.o version.o ftp-opie.o openssl.o http-ntlm.o \
../lib/libgnu.a /my_build_dir/usr/local/ssl/lib/libssl.so \
/my_build_dir/usr/local/ssl/lib/libcrypto.so -Wl,-rpath \
-Wl,/my_build_dir/usr/local/ssl/lib -ldl -lz -lidn -luuid -lrt
Thanks to the comments of nos and keltar below I can see where the issue is.
Now to work out why configure finishes up specifying the two openssl libs with their fullpath.
EDIT 2: Just to confirm that that the -rpath and -L option are working correctly.
If I rewrite the above command to remove the hard references to the build location of the openssl libs then RPATH in the incomplete executable is set to just /usr/local/ssl/lib.
Full edited command is:
gcc -Wall -std=c99 -m32 -march=athlon -mfpmath=sse -msse2 -O2 -pipe -s \
-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -m32 -march=athlon \
-mfpmath=sse -msse2 -O2 -pipe -s -Wl,-rpath,/usr/local/ssl/lib \
-L/my_build_dir/usr/local/ssl/lib -o wget cmpt.o connect.o convert.o \
cookies.o ftp.o css_.o css-url.o ftp-basic.o ftp-ls.o hash.o host.o \
html-parse.o html-url.o http.o init.o log.o main.o netrc.o progress.o \
ptimer.o recur.o res.o retr.o spider.o url.o warc.o utils.o exits.o \
build_info.o iri.o version.o ftp-opie.o openssl.o http-ntlm.o \
../lib/libgnu.a -lssl -lcrypto -ldl -lz -lidn -luuid -lrt

Resources