繁体   English   中英

使用不同的Makefile编译和链接子文件夹

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM