[英]Compiling and linking subfolders using different Makefiles
我在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
的I都应该包括路径中的文件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 $@
您没有在“通用” Makefile中指定用于构建对象的任何规则-这是您唯一的规则。
$(OBJDIR):
mkdir -p $(OBJDIR)
您想在此之前放置一条规则,以使所有规则都能构建对象,也许类似于:
all: $(OBJDIR) $(OBJECTS)
它必须走在原始规则之前,就像您没有指定要构建的内容一样,make会执行它找到的第一个规则。
通过使用-I../common/
,在其他目录中包含来自“ common”的头文件应该可以正常工作。
使用“普通”中的对象只是将它们添加到对象列表的一种情况,即:
COMMON_OBJECTS=../common/obj/utilities.o
../server: $(OBJECTS) $(COMMON_OBJECTS)
或将它们内置到库中,这样您就不必知道那里有什么目标文件。
同样值得注意的是, $(CXX)
是用于存储C ++编译器的变量-与要使用$(CC)
和$(CFLAGS)
的C编译器一起构建。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.