Reputation: 286
This is running on FreeBSD which uses PMake instead of GMake.
This is my first Makefile. I used Google a lot to help create this as well as sources such as 'PMake — A Tutorial'. The only problem I can't solve is that every time I run the Makefile, it will compile every file even when there are no changes.
I have four directories. src for my source files, include for my headers, obj for the output and bin for the executable.
What I'm doing is scanning the source folder and creating a list of files to use for both the source and object as well as the headers. Typically I run 'make debug' for debugging and 'make myservice' otherwise.
If I run 'make clean', 'make debug', and 'make debug' it will clean my folders, make all files and then proceed to remake all files instead of doing nothing.
Based on my searching, I'm leaning towards the $(OBJ) rule being the problem, but I don't quite get that. In order for my target and debug rules to build they need to know how to build the objects.
CC = clang
BINDIR = $(.CURDIR)/bin
OBJDIR = $(.CURDIR)/obj
SRCDIR = $(.CURDIR)/src
INCDIR = $(.CURDIR)/include
CFLAGS = -Wall -I/usr/local/include -I$(INCDIR)
LFLAGS = -lm -lpq -lpthread
LIBDIR = -L/usr/local/lib
_SRC != ls $(SRCDIR)/*.c
SRC = ${_SRC:T}
INC != ls $(INCDIR)/*.h
OBJ = ${SRC:S/src/obj/g:.c=.o}
TARGET = myservice
$(TARGET): $(OBJ)
$(CC) -o $(BINDIR)/$@ $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS)
debug: $(OBJ)
$(CC) -g -O0 -o $(BINDIR)/$(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS)
$(OBJ) : $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h
$(CC) -c $< $(CFLAGS)
.PHONY: clean
clean:
rm -rf $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
edit - New Makefile
New Makefile. Doesn't rebuild if no changes. Has no debug, still issues figuring out debug.
CC = clang
BINDIR = $(.CURDIR)/bin
OBJDIR = $(.CURDIR)/obj
SRCDIR = $(.CURDIR)/src
INCDIR = $(.CURDIR)/include
CFLAGS = -Wall -I/usr/local/include -I$(INCDIR)
LFLAGS = -lm -lpq -lpthread
LIBDIR = -L/usr/local/lib
TARGET = $(BINDIR)/myservice
_SRC != ls $(SRCDIR)/*.c
SRC = ${_SRC:T}
INC != ls $(INCDIR)/*.h
OBJ = ${SRC:S/src/obj/g:.c=.o}
$(TARGET): $(OBJ)
$(CC) -o $(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS)
$(OBJ) : $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -rf $(OBJDIR)/*.o $(TARGET)
edit - Working Makefile
Added if conditional for debugging purposes.
CC = clang
BINDIR = $(.CURDIR)/bin
OBJDIR = $(.CURDIR)/obj
SRCDIR = $(.CURDIR)/src
INCDIR = $(.CURDIR)/include
CFLAGS = -Wall -I/usr/local/include -I$(INCDIR)
.if make(debug)
CFLAGS += -g -O0
.endif
LFLAGS = -lm -lpq -lpthread
LIBDIR = -L/usr/local/lib
TARGET = $(BINDIR)/myservice
_SRC != ls $(SRCDIR)/*.c
SRC = ${_SRC:T}
INC != ls $(INCDIR)/*.h
OBJ = ${SRC:S/src/obj/g:.c=.o}
all: $(TARGET)
debug: $(TARGET)
$(TARGET): $(OBJ)
$(CC) -o $(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS)
$(OBJ): $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -rf $(OBJDIR)/*.o $(TARGET)
Upvotes: 2
Views: 594
Reputation: 144550
The second make debug
cannot do nothing, debug
is phony target, not an actual output file, at least the link phase will be re-run.
Furthermore, re-running the link phase with -g -O0
would not recompile you source files with debug information and no optimizations.
Incidentally, the $(TARGET)
rule is a phony rule too, it produces $(BINDIR)/$(TARGET)
, not $(TARGET)
.
You should rewrite your makefile with different rules to make object and binary output files in different directories for debug and release modes. gmake
patterns make this easy to write, I don't know about pmake
or cmake
for this purpose.
Upvotes: 1