c - 使用不同的 Makefile 编译和链接子文件夹
问题描述
我在 C 中有一个客户端/服务器应用程序。服务器有自己的文件夹dserver
,客户端也是如此dclient
。使用它们两个包含实用程序函数的文件,我在之前的目录的同一级别创建了另一个目录,名为common
.
我的想法是在每个子文件夹中创建每个Makefile
子文件夹(一个 in dserver
,一个 indclient
和另一个 in 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 $@
解决方案
您没有为在“通用” Makefile 中构建对象指定任何规则——这是您拥有的唯一规则。
$(OBJDIR):
mkdir -p $(OBJDIR)
您想在此之前设置一条规则,以使其构建对象,可能类似于以下内容:
all: $(OBJDIR) $(OBJECTS)
它必须在原始规则之前,就好像您没有指定要构建的内容一样,make 将执行它找到的第一条规则。
在其他目录中包含来自“common”的头文件应该可以通过使用-I../common/
.
使用“common”中的对象应该只是将它们添加到对象列表中的一种情况,即:
COMMON_OBJECTS=../common/obj/utilities.o
../server: $(OBJECTS) $(COMMON_OBJECTS)
或者将它们内置到库中,这样您就不需要知道有哪些目标文件。
另外值得注意的$(CXX)
是,用于存储 C++ 编译器的变量 - 用于使用您要使用的 C 编译器进行构建,$(CC)
并且$(CFLAGS)
.
推荐阅读
- windows - 如何正确解密帐户凭据并将其传递给 Add-LocalGroupMember 命令
- mysql - 将总和转换为百分比
- python - 具有大量点和一个约束的路由问题
- python - 我无法弄清楚如何在 scrapinghub 部署中使用 csv 文件进行列表理解
- logging - Fortify SCA 扫描在读取环境变量时报告日志伪造问题
- debugging - UnicodeString::Length() 干扰调试器显示
- javascript - Vue中使用/deep/bug
- r - 将文本转换为数字?
- azure - Azure Site Recovery 保证 Azure 到 Azure 故障转移的恢复时间目标为两小时。对于任何类型的工作负载?
- jquery - 使用不带特殊字符 + 验证格式的日期输入创建一个 from