我在C中有一个客户端/服务器应用程序。服务器具有自己的文件夹dserver
,与客户端dclient
相同。使用这两个文件中的一些包含实用程序功能的文件,我在先前目录的同一级别上创建了另一个目录,名为common
。
我的想法是在每个子文件夹中创建一个Makefile
(一个在dserver
中,一个在dclient
中,另一个在common
中),然后创建一个Makefile
在主目录中,该目录将运行另一个Makefiles
,如下所示:
all:
+$(MAKE) -C common
+$(MAKE) -C dserver
+$(MAKE) -C dclient
第一个问题是common/Makefile
不应创建可执行文件,而只能创建为客户端和服务器创建可执行文件所需的目标文件。以我为例:
CXX = gcc
SOURCEDIR := ./
SOURCES := $(wildcard $(SOURCEDIR)/*.c)
OBJDIR=$(SOURCEDIR)/obj
OBJECTS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.o, $(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.d, $(SOURCES))
# ADD MORE WARNINGS!
WARNING := -Wall -Wextra
$(OBJDIR)/%.o: $(SOURCEDIR)/%.c Makefile | $(OBJDIR)
$(CXX) $(WARNING) -MMD -MP -c $< -o $@
$(OBJDIR):
mkdir -p $(OBJDIR)
我的问题是它正在创建OBJDIR
指定的对象目录,而不是对象文件*.o
指定的:
第二,在客户端和服务器Makefile
中,我都应在common
中包括文件的路径,然后在编译common
的结果中引用目标文件以构建目标文件。可执行文件。因此,以dserver/Makefile
为例,我添加了行INC_PATH = -I../common/
,并在编译中将其引用为$(CXX) $(WARNING) -MMD -MP -c $(INC_PATH) $< -o $@
。但是,在代码中,我不得不做#include "../common/utilities.h"
。
是否可以在Makefile中包含路径,以便在代码中仅允许执行#include "utilities.h"
?
而且,假设common
有自己的对象目录,其中包含客户机和服务器都需要的目标文件,如何构建,例如服务器可执行文件同时引用common
中的目标文件目录以及server
目录中包含的特定目录?
dserver/Makefile
类似(dclient/Makefile
具有相同的结构):
CXX = gcc
INC_PATH = -I../common/
SOURCEDIR := ./
SOURCES := $(wildcard $(SOURCEDIR)/*.c)
OBJDIR=./obj
OBJECTS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.o, $(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.d, $(SOURCES))
# ADD MORE WARNINGS!
WARNING := -Wall -Wextra
# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean
# The first rule is the default, ie. "make",
# "make all" and "make parking" mean the same
all: server
clean:
$(RM) $(OBJECTS) $(DEPENDS) server
# Linking the executable from the object files
# $^ # "src.c src.h" (all prerequisites)
../server: $(OBJECTS)
$(CXX) $(WARNING) $(INC_PATH) $^ -o $@
#$(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) $^ -o $@ $(LIBS)
-include $(DEPENDS)
$(OBJDIR):
mkdir -p $(OBJDIR)
$(OBJDIR)/%.o: $(SOURCEDIR)/%.c Makefile | $(OBJDIR)
$(CXX) $(WARNING) -MMD -MP -c $(INC_PATH) $< -o $@
答案 0 :(得分:0)
您没有在“通用” Makefile中指定用于构建对象的任何规则-这是您唯一的规则。
$(OBJDIR):
mkdir -p $(OBJDIR)
您想在此之前放置一条规则,以使所有规则都可以构建对象,也许类似于:
all: $(OBJDIR) $(OBJECTS)
它必须走在原始规则之前,就像您没有指定要构建的内容一样,make会执行发现的第一个规则。
通过使用-I../common/
,在其他目录中包含来自“ common”的头文件应该可以正常工作。
使用“ common”中的对象只是将它们添加到对象列表中的一种情况,即:
COMMON_OBJECTS=../common/obj/utilities.o
../server: $(OBJECTS) $(COMMON_OBJECTS)
或者将它们内置到库中,这样您就不必知道对象文件了。
另外,值得注意的是$(CXX)
是用于存储C ++编译器的变量-用于与要使用$(CC)
和$(CFLAGS)
的C编译器一起构建。