为什么我的项目不会在没有清洁的情

时间:2011-07-04 00:31:40

标签: c++ linker makefile

我刚开始使用makefile,我已经为我的项目编写了一个有两个目标的文件。如果我运行一个新的make,一切正常。但是如果我之后没有清理,并且我编辑并保存一个源文件,例如,然后我再次运行make,我的项目只编译我编辑的源文件,然后不尝试将我的源链接到一个新的可执行文件。

换句话说:我第一次运行时会为每个来源获取$(CC) -c <sourcefile>,然后$(CC) -o <sourceobject1> <sourceobject2>...并且一切正常。但是,如果我然后去编辑源文件,并尝试再次制作,我只会获得$(CC) -c <editedsourcefile>,之后没有链接!至少make并没有尝试再次编译我的所有源文件,但为什么不将它链接到一个新的可执行文件?这是预期的行为吗?

奖金问题:将目标文件移动到目标规则顶部的mv *.o是否有更好的方法将目标文件移动到子目录中?我查看了this answer,但我不明白发生了什么,也无法弄清楚如何使用两个目标来适应我的情况。

这是我的makefile:

CC = clang++
OPTFLAGS = -O3 -flto -m64
CFLAGS = -Wall -c $(OPTFLAGS)
LFLAGS = -Wall $(OPTFLAGS)
MAKE = make
RM = \rm -f
TARGET-DIR = build
OBJ-DIR = $(TARGET-DIR)/obj
OBJS = $(addprefix $(OBJ-DIR)/, MCTS.o NodePool.o Node.o FastMath.o \
       Board.o Patterns.o FastSet.o FastHash.o FastHash2.o FastHashMap.o)
GTP-OBJS = $(addprefix $(OBJ-DIR)/, GtpPlayer.o)
GTP-TARGET = $(TARGET-DIR)/go-gtp
TEST-OBJS = $(addprefix $(OBJ-DIR)/, TestsMain.o MCTSTests.o NodePoolTests.o \
        NodeTests.o FastMathTests.o BoardTests.o FastSetTests.o \
        FastHashTests.o FastHash2Tests.o FastHashMapTests.o)
TEST-TARGET = $(TARGET-DIR)/go-test

.PHONY : all 
all : $(GTP-TARGET) $(TEST-TARGET)

$(GTP-TARGET) : $(GTP-OBJS) $(OBJS)
    mv *.o $(OBJ-DIR)
    $(CC) $(LFLAGS) $(GTP-OBJS) $(OBJS) -o $(GTP-TARGET)

$(OBJ-DIR)/GtpPlayer.o : GtpPlayer.hpp GtpPlayer.cpp mcts/MCTS.hpp
    $(CC) $(CFLAGS) GtpPlayer.cpp

$(OBJ-DIR)/MCTS.o : mcts/MCTS.hpp mcts/MCTS.cpp mcts/NodePool.hpp
    $(CC) $(CFLAGS) mcts/MCTS.cpp

$(OBJ-DIR)/NodePool.o : mcts/NodePool.hpp mcts/NodePool.cpp mcts/Node.hpp
    $(CC) $(CFLAGS) mcts/NodePool.cpp

$(OBJ-DIR)/Node.o : mcts/Node.hpp mcts/Node.cpp mcts/FastMath.hpp board/Board.hpp
    $(CC) $(CFLAGS) mcts/Node.cpp

$(OBJ-DIR)/FastMath.o : mcts/FastMath.hpp mcts/FastMath.cpp
    $(CC) $(CFLAGS) mcts/FastMath.cpp

$(OBJ-DIR)/Board.o : board/Board.hpp board/Board.cpp board/Patterns.hpp struct/FastSet.hpp struct/FastHash.hpp
    $(CC) $(CFLAGS) board/Board.cpp

$(OBJ-DIR)/Patterns.o : board/Patterns.hpp board/Patterns.cpp  struct/FastHash2.hpp struct/FastHashMap.hpp
    $(CC) $(CFLAGS) board/Patterns.cpp

$(OBJ-DIR)/FastSet.o : struct/FastSet.hpp struct/FastSet.cpp
    $(CC) $(CFLAGS) struct/FastSet.cpp

$(OBJ-DIR)/FastHash.o : struct/FastHash.hpp struct/FastHash.cpp
    $(CC) $(CFLAGS) struct/FastHash.cpp

$(OBJ-DIR)/FastHash2.o : struct/FastHash2.hpp struct/FastHash2.cpp
    $(CC) $(CFLAGS) struct/FastHash2.cpp

$(OBJ-DIR)/FastHashMap.o : struct/FastHashMap.hpp struct/FastHashMap.cpp
    $(CC) $(CFLAGS) struct/FastHashMap.cpp

$(TEST-TARGET) : $(TEST-OBJS) $(OBJS)
    mv *.o $(OBJ-DIR)
    $(CC) $(LFLAGS) $(TEST-OBJS) $(OBJS) -o $(TEST-TARGET)

$(OBJ-DIR)/TestsMain.o : test/TestsMain.cpp test/MCTSTests.hpp test/NodePoolTests.hpp \
          test/NodeTests.hpp test/FastMathTests.hpp test/BoardTests.hpp \
          test/FastSetTests.hpp test/FastHashTests.hpp test/FastHash2Tests.hpp test/FastHashMapTests.hpp
    $(CC) $(CFLAGS) test/TestsMain.cpp

$(OBJ-DIR)/MCTSTests.o : test/MCTSTests.hpp test/MCTSTests.cpp mcts/MCTS.hpp
    $(CC) $(CFLAGS) test/MCTSTests.cpp

$(OBJ-DIR)/NodePoolTests.o : test/NodePoolTests.hpp test/NodePoolTests.cpp
    $(CC) $(CFLAGS) test/NodePoolTests.cpp

$(OBJ-DIR)/NodeTests.o : test/NodeTests.hpp test/NodeTests.cpp
    $(CC) $(CFLAGS) test/NodeTests.cpp

$(OBJ-DIR)/FastMathTests.o : test/FastMathTests.hpp test/FastMathTests.cpp
    $(CC) $(CFLAGS) test/FastMathTests.cpp

$(OBJ-DIR)/BoardTests.o : test/BoardTests.hpp test/BoardTests.cpp
    $(CC) $(CFLAGS) test/BoardTests.cpp

$(OBJ-DIR)/FastSetTests.o : test/FastSetTests.hpp test/FastSetTests.cpp
    $(CC) $(CFLAGS) test/FastSetTests.cpp

$(OBJ-DIR)/FastHashTests.o : test/FastHashTests.hpp test/FastHashTests.cpp
    $(CC) $(CFLAGS) test/FastHashTests.cpp

$(OBJ-DIR)/FastHash2Tests.o : test/FastHash2Tests.hpp test/FastHash2Tests.cpp
    $(CC) $(CFLAGS) test/FastHash2Tests.cpp

$(OBJ-DIR)/FastHashMapTests.o : test/FastHashMapTests.hpp test/FastHashMapTests.cpp
    $(CC) $(CFLAGS) test/FastHashMapTests.cpp

.PHONY : clean
clean : 
    $(RM) $(OBJ-DIR)/*.o

.PHONY : distclean
distclean :
    $(MAKE) clean
    $(RM) $(GTP-TARGET) $(TEST-TARGET)

.PHONY : again
again:
    $(MAKE) distclean
    $(MAKE) $(GTP-TARGET)
    $(MAKE) $(TEST-TARGET)

.PHONY : tar
tar: 
    tar cfv $(GTP-TARGET).tar $(GTP-OBJS) $(OBJS)
    tar cfv $(TEST-TARGET).tar $(TEST-OBJS) $(OBJS)

示例输出:

$ make
clang++ -Wall -c -O3 -flto -m64 GtpPlayer.cpp
clang++ -Wall -c -O3 -flto -m64 mcts/MCTS.cpp
clang++ -Wall -c -O3 -flto -m64 mcts/NodePool.cpp
clang++ -Wall -c -O3 -flto -m64 mcts/Node.cpp
clang++ -Wall -c -O3 -flto -m64 mcts/FastMath.cpp
clang++ -Wall -c -O3 -flto -m64 board/Board.cpp
clang++ -Wall -c -O3 -flto -m64 board/Patterns.cpp
clang++ -Wall -c -O3 -flto -m64 struct/FastSet.cpp
clang++ -Wall -c -O3 -flto -m64 struct/FastHash.cpp
clang++ -Wall -c -O3 -flto -m64 struct/FastHash2.cpp
clang++ -Wall -c -O3 -flto -m64 struct/FastHashMap.cpp
mv *.o build/obj
clang++ -Wall -O3 -flto -m64 build/obj/GtpPlayer.o build/obj/MCTS.o build/obj/NodePool.o build/obj/Node.o build/obj/FastMath.o build/obj/Board.o build/obj/Patterns.o build/obj/FastSet.o build/obj/FastHash.o build/obj/FastHash2.o build/obj/FastHashMap.o -o build/go-gtp
clang++ -Wall -c -O3 -flto -m64 test/TestsMain.cpp
clang++ -Wall -c -O3 -flto -m64 test/MCTSTests.cpp
clang++ -Wall -c -O3 -flto -m64 test/NodePoolTests.cpp
clang++ -Wall -c -O3 -flto -m64 test/NodeTests.cpp
clang++ -Wall -c -O3 -flto -m64 test/FastMathTests.cpp
clang++ -Wall -c -O3 -flto -m64 test/BoardTests.cpp
clang++ -Wall -c -O3 -flto -m64 test/FastSetTests.cpp
clang++ -Wall -c -O3 -flto -m64 test/FastHashTests.cpp
clang++ -Wall -c -O3 -flto -m64 test/FastHash2Tests.cpp
clang++ -Wall -c -O3 -flto -m64 test/FastHashMapTests.cpp
mv *.o build/obj
clang++ -Wall -O3 -flto -m64 build/obj/TestsMain.o build/obj/MCTSTests.o build/obj/NodePoolTests.o build/obj/NodeTests.o build/obj/FastMathTests.o build/obj/BoardTests.o build/obj/FastSetTests.o build/obj/FastHashTests.o build/obj/FastHash2Tests.o build/obj/FastHashMapTests.o build/obj/MCTS.o build/obj/NodePool.o build/obj/Node.o build/obj/FastMath.o build/obj/Board.o build/obj/Patterns.o build/obj/FastSet.o build/obj/FastHash.o build/obj/FastHash2.o build/obj/FastHashMap.o -o build/go-test

现在,如果我编辑并保存Board.cpp并再次运行make,我会得到:

$ make
clang++ -Wall -c -O3 -flto -m64 board/Board.cpp

链接命令怎么了?我想要一个新的目标!

2 个答案:

答案 0 :(得分:2)

它不会链接,因为较新的obj文件不在OBJ_DIR中,而是在它们被移动之前的任何地方(当前目录?)。查看可执行文件和目标文件,并正确地断定可执行文件比OBJ_DIR中的目标文件更新。

让编译器首先在OBJ_DIR中生成它们(使用-o)或将mv命令移动到生成目标文件的每个规则(不推荐),以便在运行规则之后, OBJ_DIR中的obj文件已更新。

答案 1 :(得分:1)

使用$(CC)-o $ @将目标文件输出到所需目录(并删除目标规则中的mv * .o命令)解决了我的问题。一切都按预期连接。

感谢Gregsarnold在评论中解释了如何执行此操作。

我的makefile现在看起来像这样:

CC = clang++
CFLAGS = -Wall -O3 -flto -m64
MAKE = make
RM = \rm -f
TARGET-DIR = build
OBJ-DIR = $(TARGET-DIR)/obj
OBJS = $(addprefix $(OBJ-DIR)/, MCTS.o NodePool.o Node.o FastMath.o \
       Board.o Patterns.o FastSet.o FastHash.o FastHash2.o FastHashMap.o)
GTP-OBJS = $(addprefix $(OBJ-DIR)/, GtpPlayer.o)
GTP-TARGET = $(TARGET-DIR)/go-gtp
TEST-OBJS = $(addprefix $(OBJ-DIR)/, TestsMain.o MCTSTests.o NodePoolTests.o \
        NodeTests.o FastMathTests.o BoardTests.o FastSetTests.o \
        FastHashTests.o FastHash2Tests.o FastHashMapTests.o)
TEST-TARGET = $(TARGET-DIR)/go-test

.PHONY : all 
all : $(GTP-TARGET) $(TEST-TARGET)

$(GTP-TARGET) : $(GTP-OBJS) $(OBJS)
    $(CC) $(CFLAGS) $^ -o $@

$(OBJ-DIR)/GtpPlayer.o : GtpPlayer.cpp
    $(CC) -c $(CFLAGS) $< -o $@

$(OBJ-DIR)/%.o : mcts/%.cpp
    $(CC) -c $(CFLAGS) $< -o $@

$(OBJ-DIR)/%.o : board/%.cpp
    $(CC) -c $(CFLAGS) $< -o $@

$(OBJ-DIR)/%.o : struct/%.cpp
    $(CC) -c $(CFLAGS) $< -o $@

$(TEST-TARGET) : $(TEST-OBJS) $(OBJS)
    $(CC) $(CFLAGS) $^ -o $@

$(OBJ-DIR)/%.o : test/%.cpp
    $(CC) -c $(CFLAGS) $< -o $@

.PHONY : clean
clean : 
    $(RM) $(OBJ-DIR)/*.o

.PHONY : distclean
distclean :
    $(MAKE) clean
    $(RM) $(GTP-TARGET) $(TEST-TARGET)

.PHONY : again
again:
    $(MAKE) distclean
    $(MAKE) $(GTP-TARGET)
    $(MAKE) $(TEST-TARGET)

.PHONY : tar
tar: 
    tar cfv $(GTP-TARGET).tar $(GTP-OBJS) $(OBJS)
    tar cfv $(TEST-TARGET).tar $(TEST-OBJS) $(OBJS)