为什么我的项目在没有清理的情况下无法链接?

发布于 2024-11-18 02:06:48 字数 6752 浏览 1 评论 0原文

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

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

额外问题:是否有比将 mv *.o 粘贴在目标规则顶部更好的方法将我的目标文件移动到子目录中?我看过这个答案,但是我不明白发生了什么,也不知道如何使其适应我的有两个目标的情况。

这是我的 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

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

I am just getting started with makefiles, and I have written one for my project that has two targets. If I run a new make everything works fine. But if I don't clean after that, and I edit and save one source file, for example, and then I run make again, my project only compiles the source file I edited and then makes no attempt to link my sources into a new executable.

In other words: The first time I run make I get $(CC) -c <sourcefile> for each source, and then $(CC) -o <sourceobject1> <sourceobject2>... and everything works. But if I then go and edit a sourcefile, and try to make again, I just get $(CC) -c <editedsourcefile>, and no linking after that! At least make is not trying to compile all my source files again, but why isn't it linking me a new executable? Is this the expected behavior?

Bonus question: Is there a nicer way to move my object files into a subdirectory than sticking mv *.o at the top of my target rule? I have looked at this answer, but I didn't understand what was going on and couldn't figure out how to adapt it to my case with two targets.

Here is my 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)

Example output:

$ 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

Now if I edit and save Board.cpp for example and run make again, I get this:

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

What happened to the linking command? I want a new target!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

掩饰不了的爱 2024-11-25 02:06:48

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

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

It won't link because the newer obj files are not in OBJ_DIR but in wherever they are before they are moved (current directory?). Make looks at the executable and the object files and correctly concludes that the executable is newer than the object files in OBJ_DIR.

Make the compiler generate them in OBJ_DIR in the first place (use -o) or move the mv command to each of the rules generating the object files (not recommended) so that the after running the rule, the obj file in OBJ_DIR is updated.

維他命╮ 2024-11-25 02:06:48

使用 $(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) 
lt; -o $@

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

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

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

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

$(OBJ-DIR)/%.o : test/%.cpp
    $(CC) -c $(CFLAGS) 
lt; -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)

Outputting my object files to the desired directory with $(CC) -o $@ (and removing the mv *.o commands in my target rules) solves my problem. Everything links as expected now.

Thanks to Greg and sarnold who explained how to do this in the comments.

My makefile now looks like this:

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) 
lt; -o $@

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

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

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

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

$(OBJ-DIR)/%.o : test/%.cpp
    $(CC) -c $(CFLAGS) 
lt; -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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文