我无法使用 makefile 构建 .o 文件(“没有规则来创建目标 X,Y 需要”)

问题描述 投票:0回答:1

我正在开发一个结构如下的 C++ 项目:

/root
--/Client
----/build
----/include
----/src
--/Common
----/include
----/src
--/Server
----/build
----/include
----/src
--Makefile

理想情况下,我想从单个 makefile 编译和构建服务器和客户端。 .o 文件将在 /build 文件夹中生成,而可执行文件将在 /root 中 makefile 必须从目标 /Common 文件

编译文件

所以我想出了这个(抱歉搞砸了):

CC := g++
CFLAGS := -Wall -Wextra -I./Common/include -I./Server/include -I./Client/include
LDFLAGS := -lws2_32

CLIENT_SRC_DIR := ./Client/src
CLIENT_BUILD_DIR := ./Client/build
CLIENT_BIN_DIR := ./Client/bin
CLIENT_EXE := ./Client/bin/client.exe

SERVER_SRC_DIR := ./Server/src
SERVER_BUILD_DIR := ./Server/build
SERVER_BIN_DIR := ./Server/bin
SERVER_EXE := ./Server/bin/server.exe

COMMON_SRC_DIR := ./Common/src
COMMON_BUILD_DIR := ./Common/build

CLIENT_SRCS := $(wildcard $(CLIENT_SRC_DIR)/*.cpp)
CLIENT_OBJS := $(patsubst $(CLIENT_SRC_DIR)/%.cpp,$(CLIENT_BUILD_DIR)/%.o,$(CLIENT_SRCS))

SERVER_SRCS := $(wildcard $(SERVER_SRC_DIR)/*.cpp)
SERVER_OBJS := $(patsubst $(SERVER_SRC_DIR)/%.cpp,$(SERVER_BUILD_DIR)/%.o,$(SERVER_SRCS))

COMMON_SRCS := $(wildcard $(COMMON_SRC_DIR)/*.cpp)

.PHONY: all clean fclean dirs

all: client server

client: $(CLIENT_EXE)

server: $(SERVER_EXE)

$(CLIENT_EXE): $(CLIENT_OBJS)
    $(CC) $(CFLAGS) -o $@ $(CLIENT_OBJS) $(LDFLAGS);

$(SERVER_EXE): $(SERVER_OBJS) | $(SERVER_BIN_DIR)
    $(CC) $(CFLAGS) -o $@ $(SERVER_OBJS) $(LDFLAGS);

$(CLIENT_BUILD_DIR)/%.o: $(CLIENT_SRC_DIR)/%.cpp $(COMMON_SRC_DIR)/%.cpp
    $(CC) $(CFLAGS) $^ -o $@;

$(SERVER_BUILD_DIR)/%.o: $(SERVER_SRC_DIR)/%.cpp $(COMMON_SRC_DIR)/%.cpp
    $(CC) $(CFLAGS) $^ -o $@;

dirs:
    mkdir "$(CLIENT_BUILD_DIR)"; 
    mkdir "$(CLIENT_BIN_DIR)"; 
    mkdir "$(SERVER_BUILD_DIR)"; 
    mkdir "$(SERVER_BIN_DIR)";

clean:
    rm -r $(CLIENT_BUILD_DIR) $(SERVER_BUILD_DIR);

fclean: clean
    rm -r $(CLIENT_BIN_DIR) $(SERVER_BIN_DIR);

re: fclean all

不幸的是,我收到的消息是:

make: *** No rule to make target 'Client/build/main.o', needed by 'Client/bin/client.exe'.  Stop.
我知道当文件丢失时会出现此消息,但由于我使用 % 通配符,它不会工作吗?

我真的很难弄清楚这个问题,谢谢所有帮助我的人!

c++ makefile
1个回答
0
投票

你的规则试图同时做太多事情。 看看下面的规则:

$(CLIENT_BUILD_DIR)/%.o: $(CLIENT_SRC_DIR)/%.cpp $(COMMON_SRC_DIR)/%.cpp
    $(CC) $(CFLAGS) $^ -o $@;

我们正在尝试构建

$(CLIENT_BUILD_DIR)/main.o
,因此
%
部分是
main
。 将其代入规则:

$(CLIENT_BUILD_DIR)/main.o: $(CLIENT_SRC_DIR)/main.cpp $(COMMON_SRC_DIR)/main.cpp
    $(CC) $(CFLAGS) $^ -o $@;

哎呀:你依赖的

$(COMMON_SRC_DIR)/main.cpp
不存在。

我想您编写此规则的目的是说“.cpp 文件可以来自 either 目录”。在这种情况下,您只需编写两个规则,每个规则对应一个可能的来源:

$(CLIENT_BUILD_DIR)/%.o: $(CLIENT_SRC_DIR)/%.cpp
    $(CC) $(CFLAGS) $^ -o $@;

$(CLIENT_BUILD_DIR)/%.o: $(COMMON_SRC_DIR)/%.cpp
    $(CC) $(CFLAGS) $^ -o $@;

$(SERVER_BUILD_DIR)/%.o: $(SERVER_SRC_DIR)/%.cpp
    $(CC) $(CFLAGS) $^ -o $@;

$(SERVER_BUILD_DIR)/%.o: $(COMMON_SRC_DIR)/%.cpp
    $(CC) $(CFLAGS) $^ -o $@;

顺便说一句:编译 C++ 代码时应该使用

$(CXX)
$(CXXFLAGS)

© www.soinside.com 2019 - 2024. All rights reserved.