J'essaie de créer un Makefile artisanal très basique pour créer une bibliothèque partagée pour illustrer un point.
Voici ce que j'ai jusqu'à présent:
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)
Lorsque j'exécute make
, il tente de créer une application - et ld
échoue car il ne peut pas résoudre main()
.
Le problème semble être avec CFLAGS
- J'ai spécifié -fPIC
Mais cela ne fonctionne pas - qu'est-ce que je fais mal?
J'ai ajouté l'indicateur -shared
Comme suggéré, lorsque j'exécute make
, j'ai eu cette erreur:
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
Ce qui semble suggérer de revenir à -fPIC
Uniquement.
BTW, mon nouveau paramètre CFLAGS
est:
CFLAGS = -fPIC -shared -pedantic -Wall -Wextra -march=native -ggdb3
J'utilise gcc v4.4.3 sur Ubuntu 10.0.4.
La solution a été de modifier les XXFLAGS comme suit:
FLAGS = # -std=gnu99 -Iinclude
CFLAGS = -fPIC -g #-pedantic -Wall -Wextra -ggdb3
LDFLAGS = -shared
Compiler avec -shared
:
gcc -o libfoo.so module1.o module2.o -shared
(Cela fonctionne également sur MingW sous Windows pour produire des DLL.)
Exemple pour les fichiers C++. Également inclus une cible propre
.PHONY : clean
CPPFLAGS= -fPIC -g
LDFLAGS= -shared
SOURCES = $(Shell echo *.cpp)
HEADERS = $(Shell echo *.h)
OBJECTS=$(SOURCES:.cpp=.o)
FIKSENGINE_LIBDIR=../../../../lib
FIKSENGINE_INCDIR=../../../../include
TARGET=$(FIKSENGINE_LIBDIR)/tinyxml.so
all: $(TARGET)
clean:
rm -f $(OBJECTS) $(TARGET)
$(TARGET) : $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $@ $(LDFLAGS)
Puisque vous essayez de créer un fichier so
, vous aurez probablement besoin de -shared
.