我的Makefile总是构建所有文件

时间:2015-10-05 11:09:21

标签: c makefile freebsd

这是在使用PMake而不是GMake的FreeBSD上运行。

这是我的第一个Makefile。我使用Google来帮助创建这个以及诸如“PMake - A Tutorial”之类的资源。我无法解决的唯一问题是,每次运行Makefile时,即使没有更改,它也会编译每个文件。

我有四个目录。 src用于我的源文件,包括我的头文件,obj用于输出,bin用于可执行文件。

我正在做的是扫描源文件夹并创建用于源和对象以及标头的文件列表。通常我运行'make debug'进行调试,然后运行'make myservice'。

如果我运行'make clean','make debug'和'make debug',它将清理我的文件夹,制作所有文件,然后继续重制所有文件而不是什么都不做。

根据我的搜索,我倾向于$(OBJ)规则是问题,但我不太明白。为了构建我的目标和调试规则,他们需要知道如何构建对象。

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)

编辑 - 新的Makefile

新的Makefile。如果没有更改,则不会重建。没有调试,仍然会解决调试问题。

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)

编辑 - 使用Makefile

添加条件用于调试目的。

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)

1 个答案:

答案 0 :(得分:1)

第二个make debug无法执行任何操作,debug是虚假目标,而不是实际输出文件,至少链接阶段将重新运行。

此外,使用-g -O0重新运行链接阶段不会使用调试信息重新编译源文件,也不会重新编译。

顺便提一下,$(TARGET)规则也是虚假规则,它会生成$(BINDIR)/$(TARGET),而不是$(TARGET)

您应该使用不同的规则重写makefile,以便在调试和释放模式的不同目录中创建对象和二进制输出文件。 gmake模式可以让您轻松编写,我不会为此目的了解pmakecmake