0
votes

I have a problem with creating a Makefile for my program. First of all I'll point how my program's directory hast to look like:

  • *.o files has to be in main program directory
  • *.c files are in src directory
  • *.h files are in include directory
  • bin folder is for executable file
  • lib folder is a place for library files

As I mentioned above I have *.c *.h files already placed in src and include directories. Makefile is located in main program directory. My makefile has to contain vpath or VPATH. Using gcc I have to build the whole project. pj, pp, pg, pr are functions .c files. First of all I have to create object files using gcc -fPIC -c than from pj.o and pp.o I have to build static library using ar rs than build shared library from pg.o and pr.o using gcc -shared. All libjp.a and libhgr.so should be placed in lib folder. After that i have to build the whole program using gcc -o $@ $^ -L./lib -I./include and place executable file in bin directory. It's actually not working it's only building the first lib - libjp.a Here is my makefile:

.PHONY: clean
.SUFFIXES: .c .o .a .so
vpath %.c src
vpath %.h include
%.o: %.c
    gcc -w -fPIC -c $<
lib/libjp.a: pj.o pp.o
    ar rs $@ $<
lib/libgr.so: pg.o pr.o
    gcc -w -shared -o $@ $<
%: %.o
    gcc -o $@ $^ -L./lib -I./include
program: program.o lib/libjp.a lib/libgr.so
program.o: program.c libjp.h libgr.h
pj.o: pj.c
pp.o: pp.c
pg.o: pg.c
pr.o: pr.c
clean:
    rm -f program *.o *.a *.so

Thank you for your time and help :)

1
What happens when you try to build these files using the command line (i.e. without Make)?Beta
@Beta If they all are in same directory its compiling fine; 1) Shared library gcc -c program.c gcc -w -fPIC -c pg.c -o pg.o gcc -w -fPIC -c pr.c -o pr.o gcc -shared -o libgr.so pg.o pr.o 2) Static library gcc -c pj.c gcc -c pp.c ar rs libjp.a pj.o pp.o 3) Compiling: gcc program.o -o program libgr.so libjp.a It's compiling, and i can run it i mean it's working.szeejdi
And can you run the executable when the shared library is in lib/? Part of the problem seems to be that the executable cannot find the shared library. There is more than one way to fix this, but I don't know whether you have a solution in place.Beta
@Beta one of the errors i get when i try to run the executable file is that it can't find libs. I fixed this by simply copying libs which i created to the /lib folder (not /home/usr/download/program/lib but /lib) it fixed this but i guess it's not the best solution. I don't know how to force my compiler and linker to look for libs in lib folder in /home/usr/download/program/lib which is place where i want to place libs for this specific program.szeejdi

1 Answers

2
votes

You cannot use VPATH to locate derived (generated) files. VPATH can only be used with source files. So, these two lines, and all the associated infrastructure that goes with them, will not work as you expect:

vpath %.so lib
vpath %.a lib

If you want to understand this more fully you can read http://make.mad-scientist.net/papers/how-not-to-use-vpath/

Second, rules like this:

%.a: pj.o pp.o
        ar rs $@ $^
        mv *.a ./lib

violate the second rule of makefiles. If you want a target to be created in a subdirectory, then the name of the target must be the full name, in the subdirectory. And there's no point in using pattern rules if you're going to list the prerequisites explicitly in the pattern. You can use something like:

lib/libjp.a: pj.o pp.o
        ar rs $@ $^
lib/libgr.so: pg.o pr.o
        gcc -w -shared -o $@ $^

which means you have to change references to it:

program: program.o lib/libjp.a lib/libgr.so

and lines like this should be removed:

libjp.a: pj.o pp.o
libgr.so: pg.o pr.o

There may be other similar changes needed.