2011-07-04 47 views
1

我刚刚开始使用makefiles,并且为我的项目编写了一个,其中包含两个目标。如果我运行一个新的make everything一切正常。但是,如果在此之后我不清理,并且我编辑并保存了一个源文件,然后再次运行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 

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

+4

为什么你四处移动'* .o'文件?如果你在没有移动的情况下尝试你的makefile文件呢? (显然你必须改变几件事情才能使它工作。)这绝对是一种非标准的做事方式。 “我希望我的'.o'文件到别的地方”的问题通常包括告诉编译器直接在那个地方生成它们,而不是在makefile中移动它们(这一定会混淆make)。 –

+1

不相关,但您可以将大部分规则简化为'$(OBJ_DIR)/%。0:test /%。hpp test /%。cpp'。 – Maxpm

+1

如果向编译器命令添加“-o $ @”,它们会自动将对象发送到对象目录中(因为您的目标期望它:'$(OBJ-DIR)/ FastHash2.o')。这会让你删除我认为给你带来额外麻烦的'mv'命令。我不完全确定如何解决链接器问题,但我认为移动整个Makefile以仅列出依赖关系将有助于更容易地发现。 – sarnold

回答

2

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

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

+0

感谢您解释我的方法失败的原因。我只是不知道命令输出目标文件到我想要的目录。 – Imran

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 [email protected] 

$(OBJ-DIR)/GtpPlayer.o : GtpPlayer.cpp 
    $(CC) -c $(CFLAGS) $< -o [email protected] 

$(OBJ-DIR)/%.o : mcts/%.cpp 
    $(CC) -c $(CFLAGS) $< -o [email protected] 

$(OBJ-DIR)/%.o : board/%.cpp 
    $(CC) -c $(CFLAGS) $< -o [email protected] 

$(OBJ-DIR)/%.o : struct/%.cpp 
    $(CC) -c $(CFLAGS) $< -o [email protected] 

$(TEST-TARGET) : $(TEST-OBJS) $(OBJS) 
    $(CC) $(CFLAGS) $^ -o [email protected] 

$(OBJ-DIR)/%.o : test/%.cpp 
    $(CC) -c $(CFLAGS) $< -o [email protected] 

.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) 
相关问题