I am trying to create a very basic hand crafted Makefile to create a shared library to illustrate a point.
This is what I have so far:
SHELL = /bin/sh CC = gcc FLAGS = -std=gnu99 -Iinclude CFLAGS = -fPIC -pedantic -Wall -Wextra -march=native -ggdb3 DEBUGFLAGS = -O0 -D _DEBUG RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program TARGET = example.so SOURCES = $(shell echo src/*.c) HEADERS = $(shell echo include/*.h) OBJECTS = $(SOURCES:.c=.o) PREFIX = $(DESTDIR)/usr/local BINDIR = $(PREFIX)/bin all: $(TARGET) $(TARGET): $(OBJECTS) $(CC) $(FLAGS) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) $(OBJECTS)
When I run make
, it attempts to build an application - and ld
fails because it can't resolve main()
.
Problem seems to be with CFLAGS
- I have specified -fPIC
but that is not working - what am I doing wrong?
I added the -shared
flag as suggested, when I run make
, I got this error:
gcc -std=gnu99 -Iinclude -fPIC -shared -pedantic -Wall -Wextra -march=native -ggdb3 -O0 -D _DEBUG -o example.so src/example.o /usr/bin/ld: src/example.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC src/example.o: could not read symbols: Bad value collect2: ld returned 1 exit status make: *** [example.so] Error 1
Which seems to be suggesting to revert back to -fPIC
only.
BTW, my new CFLAGS
setting is:
CFLAGS = -fPIC -shared -pedantic -Wall -Wextra -march=native -ggdb3
I am running gcc v4.4.3 on Ubuntu 10.0.4.
As already mentioned here, the thing you probably want is the linker option -rpath . Like that, you can set a default search path for the binary. Looks like you even already use -rpath in your makefile, but you specify the wrong path: LIBS = -L$(LIB) -lfuse -lsqlite3 -lkw_taglib -ltag_c -ltag -Wl,-rpath=.
a , in which case you also need to add -lmine to the linker line (after the object files that reference the library). You have a file libmine that is a static archive, in which case you simply list it as a file ./libmine with no -L in front. You have a file libmine. a in the current directory that you want to pick up.
In addition, if you want to dynamically link libraries, you need to tell the linker where they are. -L/dir/containing -lc . If you don't want to set a LD_LIBRARY_PATH when executing, you'll need to set rpath , -Wl,--rpath=/path/containing . Points for pointing out what --rpath does.
The solution was to modify the XXFLAGS as follows:
FLAGS = # -std=gnu99 -Iinclude CFLAGS = -fPIC -g #-pedantic -Wall -Wextra -ggdb3 LDFLAGS = -shared
Compile with -shared
:
gcc -o libfoo.so module1.o module2.o -shared
(This also works on MingW under Windows to produce DLLs.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With