为什么这个makefile总是执行$(LIB)配方?

时间:2018-12-22 09:14:04

标签: makefile cygwin

我正在通过编写一个简单的基于新建字段基于makefile的项目来学习/加强对makefile的理解。

我的项目树的结构如下:

.
│   makefile
│
├───dep
├───exe
├───include
│       b.h
│       c.h
│
├───lib
├───obj
└───src
        a.cpp
        b.cpp
        c.cpp

所以我的意图/目标是:

  1. 在项目根目录下有一个makefile

  2. 具有源,头文件,目标文件,库,依赖文件和 每个可执行文件都位于项目根目录的自己的子目录中。

  3. src/中恰好一个源文件将实现int main(...)

  4. makefile应该编译所有源文件,除了那些 对int main(...)中的目标文件实现obj/

  5. makefile应该将所有目标文件归档到lib/

  6. 中的lib中。
  7. makefile应该通过链接链接将实现int main(...)的源文件直接编译为exe/中的可执行文件。 创建的库。

我想我已经用这个makefile实现了我想要的:

SRCDIR = ./src
INCDIR = ./include
OBJDIR = ./obj
LIBDIR = ./lib
EXEDIR = ./exe
DEPDIR = ./dep

EXE = foo
EXESRC = $(SRCDIR)/a.cpp

DEP = $(DEPDIR)/$(EXE).dep

CXX = g++
CXXFLAGS = -g
AR = ar

# List of *.cpp in $(SRCDIR) that are not $(EXE)
LIBSRC = $(filter-out $(EXESRC),$(wildcard $(SRCDIR)/*.cpp))

# Replace {$(SRCDIR)/a.cpp $(SRCDIR)/b.cpp} w/ {$(OBJDIR)/a.o $(OBJDIR)/b.o} etc
OBJS = $(patsubst %.cpp,%.o,$(patsubst $(SRCDIR)%,$(OBJDIR)%,$(LIBSRC)))

LIB = $(LIBDIR)/lib$(EXE).a

bin: $(EXEDIR)/$(EXE)

$(EXEDIR)/$(EXE): $(EXEDIR) $(EXESRC) $(LIB)
        $(CXX) -o $(EXEDIR)/$(EXE) $(CXXFLAGS) -I$(INCDIR) $(EXESRC) -L$(LIBDIR) -l$(EXE)

$(LIB): $(OBJDIR) $(OBJS) $(LIBDIR)
        $(AR) ur $(LIB) $(OBJS)

$(EXEDIR):
        mkdir $(EXEDIR)

$(LIBDIR):
        mkdir $(LIBDIR)

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(DEP)
        $(CXX) $(CXXFLAGS) -I$(INCDIR) -o $@ -c $<

$(OBJDIR):
        mkdir $(OBJDIR)

$(DEP): $(DEPDIR)
        makedepend -- $(CXXFLAGS) -I$(INCDIR) -- $(LIBSRC) $(EXESRC) -f- 2>/dev/null > $(DEP)
        sed -i 's,$(SRCDIR),$(OBJDIR),' $(DEP)

$(DEPDIR):
        mkdir $(DEPDIR)

-include $(DEP)

但是观察到“ make bin”的输出连续运行两次:

> make bin
mkdir ./dep
makedepend -- -g -I./include -- ./src/c.cpp ./src/b.cpp ./src/a.cpp -f- 2>/dev/null > ./dep/foo.dep
sed -i 's,./src,./obj,' ./dep/foo.dep
mkdir ./exe
mkdir ./obj
g++ -g -I./include -o obj/c.o -c src/c.cpp
g++ -g -I./include -o obj/b.o -c src/b.cpp
mkdir ./lib
ar ur ./lib/libfoo.a ./obj/c.o ./obj/b.o
ar: creating ./lib/libfoo.a
g++ -o ./exe/foo -g -I./include ./src/a.cpp -L./lib -lfoo
> 
> make bin
ar ur ./lib/libfoo.a ./obj/c.o ./obj/b.o

问题:

为什么当我连续多次运行“ make bin”时,makefile总是执行$(LIB)配方吗?

根据我对makefile的不稳定理解,当目标的依赖关系比目标的依赖关系新时,会发生这种情况。在这种情况下,我认为这意味着$(LIBDIR)$(LIB)更新。但是为什么会这样呢?根据预期,根据第一个“ make bin”的输出,在{em> $(LIBDIR)之前创建$(LIB)

我想我不了解makefile中是否有需要纠正的内容,或者我不了解文件系统计时的内容。最终,我正在尝试消除粗糙的边缘,所以在这个问题上,我想了解需要纠正的内容,以便使makefile可以更正确地了解何时没有需要更新的内容,尤其是为什么$(LIBDIR)当make配方的输出暗示(对我而言)并非如此时,它比$(LIB)更新。

>ls --full-time -ld lib/libfoo.a
-rw-r--r-- 1 User None 81448 2018-12-22 00:42:07.188906200 -0800 lib/libfoo.a
>
>ls --full-time -ld lib/
drwxr-xr-x+ 1 User None 0 2018-12-22 00:42:07.204531200 -0800 lib/

构建环境为cygwin。

0 个答案:

没有答案