f10w
f10w

Reputation: 1586

Building shared libraries with Makefile

I have a project that I want to build a shared library for it. The following Makefile works:

libfastpd.so: fastpd.cpp
    $(CXX) -std=c++11 -fPIC -c fastpd.cpp -o fastpd.o
    $(CXX) -std=c++11 -fPIC -c graph.cpp -o graph.o
    $(CXX) -std=c++11 -fPIC -c LinkedBlockList.cpp -o LinkedBlockList.o
    $(CXX) -std=c++11 -fPIC -c maxflow.cpp -o maxflow.o
    $(CXX) -std=c++11 -shared  -Wl,-soname,libfastpd.so -o libfastpd.so fastpd.o graph.o LinkedBlockList.o maxflow.o

clean:
    rm *.o *.so

Then I came across this recipe in Cogswell et al.'s C++ Cookbook: https://www.oreilly.com/library/view/c-cookbook/0596007612/ch01s18.html and decided to improve my Makefile based on that:

# Specify extensions of files to delete when cleaning
CLEANEXTS   = o so

# Specify the source files, the target files, 
# and the install directory 
SOURCES  = fastpd.cpp graph.cpp LinkedBlockList.cpp maxflow.cpp
OUTPUTFILE  = libfastpd.so
INSTALLDIR  = ./


.PHONY: all
all: $(OUTPUTFILE)

# Build lib*.so from all the *.o;
# subst is the search-and-replace 
# function demonstrated in Recipe 1.16
$(OUTPUTFILE): $(subst .cpp,.o,$(SOURCES)) 
    $(CXX) -shared -fPIC $(LDFLAGS) -o $@ $^

.PHONY: install
install:
    mkdir -p $(INSTALLDIR)
    cp -p $(OUTPUTFILE) $(INSTALLDIR)

.PHONY: clean 
clean:
    for file in $(CLEANEXTS); do rm -f *.$$file; done

# Generate dependencies of .ccp files on .hpp files
include $(subst .cpp,.d,$(SOURCES))

%.d: %.cpp
    $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
    sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$

Running this file I obtained the following error:

/usr/bin/ld: fastpd.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC fastpd.o: error adding symbols: Bad value

Checking the terminal output, I observed that the following commands were executed:

g++    -c -o fastpd.o fastpd.cpp
g++    -c -o graph.o graph.cpp
g++    -c -o LinkedBlockList.o LinkedBlockList.cpp
g++    -c -o maxflow.o maxflow.cpp

No -fPIC!

My question is: Which lines of the Makefile execute these commands and how to add -fPIC to them?

Any references to good ressources to understand the entire Makefile above would be very much appreciated as well!

Thank you very much in advance for your help!

Upvotes: 0

Views: 1550

Answers (1)

G.M.
G.M.

Reputation: 12879

Which lines of the Makefile execute these commands... ?

The short answer is none. The rule...

$(OUTPUTFILE): $(subst .cpp,.o,$(SOURCES)) 
        $(CXX) -shared -fPIC $(LDFLAGS) -o $@ $^

only specifies the link time dependencies and command. The -fPIC option needs to be specified when you compile the source file but you haven't provided any rule to build a .o from a .cpp so make falls back on its implicit rule which (for the purposes of this example) is essentially...

%.o: %.cpp
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<

So the obvious solution is to add -fPIC to CXXFLAGS...

CXXFLAGS += -fPIC

Upvotes: 2

Related Questions