43

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?

Edit

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.

Rodrigo de Azevedo
  • 1,097
  • 9
  • 17
Homunculus Reticulli
  • 65,167
  • 81
  • 216
  • 341
  • 1
    I think you're missing `-shared` in the `CFLAGS`, and `ld` attempts to create an executable this way. – Blagovest Buyukliev Nov 11 '11 at 15:18
  • I'd use `$(wildcard src/*.c)` instead of `$(shell echo src/*.c)`, but I'm wondering if there are any serious differences. – sidyll Nov 11 '11 at 15:20
  • A more appropriate title for this question would be "Creating a shared library - what's wrong with these compile and link options?" You're presenting this as a problem with your makefile, but there's nothing wrong with it. It delivers exactly what you're asking of it. – eriktous Nov 11 '11 at 19:56
  • Kindly check link also http://stackoverflow.com/a/43347369/1485176 – akD Apr 11 '17 at 13:43

5 Answers5

36

The solution was to modify the XXFLAGS as follows:

FLAGS        = # -std=gnu99 -Iinclude
CFLAGS       = -fPIC -g #-pedantic -Wall -Wextra -ggdb3
LDFLAGS      = -shared
Homunculus Reticulli
  • 65,167
  • 81
  • 216
  • 341
17

Compile with -shared:

gcc -o libfoo.so module1.o module2.o -shared

(This also works on MingW under Windows to produce DLLs.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 2
    Well, if you know how to write a makefile, then you know where to put your compiler options... `-shared` is a linker option, so I'd add it to `LDFLAGS`. *Edit* Whoops, you don't *have* `LDFLAGS`. I recommend creating that variable and adding it to the link command. – Kerrek SB Nov 11 '11 at 15:25
  • Given that this is a question on stackoverflow, not everyone coming here will know how to write a makefile, or know where to put compiler options, so clarifying the basics like this absolutely makes sense. – SomeoneElse Mar 06 '23 at 18:15
10

Example for C++ files. I've also included a clean target.

.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) $(CPPFLAGS) $(OBJECTS) -o $@ $(LDFLAGS)
janw
  • 8,758
  • 11
  • 40
  • 62
rgb122
  • 136
  • 1
  • 4
1

Since you try to build so file, you probably need -shared.

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
0

this is my goto makefile rule for so files:

%.so: %.o ; $(LINK.c) $(LDFLAGS) -shared $^ -o $@

can be used like so

CFLAGS+=-fPIC

libmyfoo.so:  # create from libmyfoo.o

# or 

libmyfoo.so: myfoo.o  # create from myfoo.o 
ThorSummoner
  • 16,657
  • 15
  • 135
  • 147