Makefile合并棋子目标文件报错及.o文件单独存储相关问题
编译错误原因
你遇到的未定义引用报错由两个问题共同导致:
- 你的
chesspieces.o编译命令缺少-c参数:GCC默认不带-c时会直接执行完整的编译+链接流程,尝试生成可执行文件,此时找不到Position、Square等类的实现,就会抛出未定义引用错误。 - 单个
.o目标文件只能对应单个源文件的编译结果,你无法将多个.cc源文件直接编译为一个.o文件,这种合并多个目标文件的需求应该用静态库实现。
依赖相关疑问解答
不需要在chesspieces相关规则中添加position.o、square.o这类依赖:这类依赖属于链接阶段的依赖,你已经在最终的Chess规则中添加了,编译阶段不需要重复引入。
正确修改方案
用静态库替代你设想的chesspieces.o即可实现精简Chess规则的需求,示例写法如下:
# 定义棋子类目标文件集合 CHESS_PIECE_OBJS = pawn.o rook.o king.o queen.o bishop.o knight.o piece.o # 生成棋子类静态库 libchesspieces.a: $(CHESS_PIECE_OBJS) ar rcs $@ $^ # 修改后的Chess规则 Chess: main.o board.o player.o chess.o square.o position.o libchesspieces.a $(CC) $^ $(OUTPUT)
.o文件存放到单独目录的方案
将所有.o文件存放到单独文件夹不会引发额外编译问题,只要写对路径规则即可,参考示例:
# 定义.o文件存放目录 OBJ_DIR = ./build # 自动给所有目标文件添加目录前缀 OBJS = $(addprefix $(OBJ_DIR)/, main.o board.o player.o chess.o square.o position.o $(CHESS_PIECE_OBJS)) # 模式规则:指定源文件到目标文件的编译规则,自动创建目录 $(OBJ_DIR)/%.o: ./src/%.cc @mkdir -p $(dir $@) $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ # 静态库也存放到build目录 $(OBJ_DIR)/libchesspieces.a: $(filter $(OBJ_DIR)/%.o, $(OBJS)) ar rcs $@ $^ # 最终的Chess规则 Chess: $(OBJS) $(OBJ_DIR)/libchesspieces.a $(CC) $^ $(OUTPUT)
注意规则中的@mkdir -p $(dir $@)会自动创建目标文件对应的目录,避免编译时找不到路径的报错。
内容的提问来源于stack exchange,提问作者laegil
相关产品推荐
相关产品推荐

