0

I am trying to write what I thought would be quite a simple Makefile and I'm just baffled! I'm not a makefile writer, but I thought I understood them enough to be able to get a simple one working.

Okay, I have a small project in a directory and also in this directory is a libs directory containing many .c files. What I'm trying to do is write a makefile that will build the contents of the /libs directory into a static lib file in the /libs directory and then compile a few source files in the / directory and link it against the built .a file.

I'm sure someone's going to suggest "why not use cmake", but that's not answer I'm looking for (waves hand like a Jedi.. ehehehehe)

CC = gcc
CFLAGS = -Wall
SOURCES = lzx.c csum.c dirs.c listner.c tree.c
OBJECTS = $(SOURCES:.c=.o)
TARGETLIB = libs/mylib.a
TARGET = TestApp

libs/%.o : libs/%.c
    $(CC) $CFLAGS -c $<

$(TARGETLIB) : $(OBJECTS)
    ar rcs $@ $^

$(TARGET) :
    $(CC) $CFLAGS Source1.cpp Source2.cpp -llibs/mylib.a -o $@

My understanding was that the first recipe, would compile all the .c files into objects, but it seems to compile the first .c file and then stop.

Any help anyone could give me would be appreciated.

The Welder
  • 916
  • 6
  • 24
  • See [this](http://stackoverflow.com/a/16751650/841108) & [that](http://stackoverflow.com/a/26689798/841108) examples. Use a recent `make` with `make --trace` or [remake](http://bashdb.sourceforge.net/remake/) `-x`. Use $([patsubst](https://www.gnu.org/software/make/manual/html_node/Text-Functions.html)...); or have an inner `libs/Makefile` and use `$(MAKE) -C libs` – Basile Starynkevitch Feb 22 '16 at 14:39
  • Thanks Basile, but I've already looked at those examples and although they're close, they don't quite do what I'm trying to do. My main problem is with %.o : %.c which in my head should compile all the .c files in the libs/ directory, but actually only compiles the first file in the list and then fails for a reason I cannot explain. make --trace is a good idea though. – The Welder Feb 22 '16 at 16:02
  • So `libs/` contains `lzx.c csum.c dirs.c listner.c tree.c`, and those are the files you want to compile and combine to form `libs/mylib.a`, is that right? – Beta Feb 22 '16 at 19:24
  • +Beta yes, I want to compile the .c files in the libs directory into a mylib.a file in the libs directory. Once the .a fine is created, it can then be linked against the other files in the root directory of the project. – The Welder Feb 23 '16 at 01:20

1 Answers1

2

Since Your final app is TARGET, You should make it first Makefile rule. And since it also depends on TARGETLIB it should be given as dependency, like so:

$(TARGET): $(TARGETLIB)
    $(CC) $(CFLAGS) Source1.cpp Source2.cpp -Lmylib -o $@

next I assume that *.c files You mentioned are lib files. Thus You will need a prefix to them, since You want to specify them by hand, not via wildcard or rule.

OBJECTS = $(addprefix(libs, $(SOURCES)):.c=.o)

and last thing that comes to my mind is library name, which supposed to be libSOMENAME.a (well, linker searches for this name in path and -Lotherpaths). So we have:

TARGETLIB = libs/libmylib.a

summing it all up:

CC = gcc
CFLAGS = -Wall
SOURCES = lzx.c csum.c dirs.c listner.c tree.c
OBJECTS = $(addprefix(libs, $(SOURCES)):.c=.o)
TARGETLIB = libs/libmylib.a
TARGET = TestApp

$(TARGET) : $(TARGETLIB)
    $(CC) $(CFLAGS) Source1.cpp Source2.cpp -static -L./libs -lmylib -o $@

$(TARGETLIB) : $(OBJECTS)
    ar rcs $@ $^

And yes, this could be written much better, but I assume if You wanted to learn more about Makefiles or linker, and not just shown where You made mistakes, You'd know how to find manual pages.

JustMe
  • 710
  • 4
  • 16
  • Thank you for your advice and help and it's true, I could have spent a lot more time going through the make manual rather than asking my questions here. I was rather hoping this was going to be a five minute thing rather than it being so arduous. I did try adapting the examples that I found online, but it's obvious now that some of my preconceptions on makefiles are just wrong. – The Welder Feb 23 '16 at 01:13