gpt4 book ai didi

c++ - 如何使用自动依赖生成器编写 make 文件

转载 作者:太空宇宙 更新时间:2023-11-04 04:26:44 30 4
gpt4 key购买 nike

扩展我之前的问题 how to write a makefile for structured file system :

文件结构:

.
├── Headers
│   ├── function.h
│   └── test.h
├── makefile
├── README.md
└── Sources
├── function.c
├── main.c
└── test.c

我正在尝试编写一个读取 #include<...> 的 makefile在任何给定的源文件上并根据需要进行编译。

原来我曾经有一个看起来像这样的make文件:

INC_DIR = Headers
SRC_DIR = Sources
OBJ_DIR = Objects
#CXXFLAGS = -c -Wall -I. -IHeaders
CXXFLAGS = -c -Wall -I. -IHeaders
CC = gcc

SRCS = $(SRC_DIR)/*.c
OBJS = $(OBJ_DIR)/*.o
#The wildcard and patsubt commads will come handy

DEPS = $(INC_DIR)/*.h
#need to use an automatic dependency generator

output: $(OBJ_DIR)/main.o $(OBJ_DIR)/function.o
$(CC) $^ -o $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(DEPS)
$(CC) $(CXXFLAGS) $< -o $@


run: output
./output

clean:
rm $(OBJ_DIR)/*.o
rm output
-@echo "Clean completed"

这意味着对于 output 的每个源文件取决于我必须将该对象添加到这一行。

output: $(OBJ_DIR)/main.o $(OBJ_DIR)/function.o $(OBJ_DIR)/test.o
$(CC) $^ -o $@

如果任何其他源文件依赖于一个或多个源,则必须添加额外的规则。

要解决这个问题:这是我从 Auto-Dependency Generation 收集到的信息和 4.14 Generating Prerequisites Automatically

正如社区成员所提到的,我对依赖生成以及如何使用生成的文件有不同的理解。

DEP_DIR = .d
$(shell mkdir -p $(DEP_DIR) >/dev/null)

DEPFLAGS = -MT $@ -MMD -MP -MF $(DEP_DIR)/$*.Td

INC_DIR = Headers
SRC_DIR = Sources
OBJ_DIR = Objects
$(shell mkdir -p $(OBJ_DIR) >/dev/null)
CXXFLAGS = -c -Wall -I. -IHeaders
CC = gcc

SRCS = $(SRC_DIR)/*.c
OBJS = $(OBJ_DIR)/*.o
#The wildcard and patsubt commads will come handy

#DEPS = $(INC_DIR)/*.h

MAKEDEPEND = $(CC) $(CXXFLAGS) $< \
| sed -n 's/^\# *[0-9][0-9]* *"\([^"]*\)".*/$*.o: \1/p' \
| sort | uniq > $*.Td

COMPILE.c = $(CC) $(DEPFLAGS) $(CXXFLAGS)
#need to use an automatic dependency generator

#%.d: %.c
# @set -e; rm -f $@; \
# $(CC) -MP -MD $(CXXFLAGS) $< > $@.$$$$; \
# sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
# rm -f $@.$$$$

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(DEP_DIR)/%.d
@$(MAKEDEPEND); \
cp $*.Td $*.d; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.Td >> $*.d; \
rm -f $*.Td
#$(COMPILE.c) -o $@ $<
$(CC) $(CXXFLAGS) $(DEPFLAGS) $< -o $@

-include $(SRCS:.c=.d)

$(DEP_DIR)/%.d: ;
.PRECIOUS: $(DEP_DIR)/%.d

output: $(OBJS)
$(CC) $^ -o $@

run: output
./output

clean:
rm -r $(OBJ_DIR)
rm -r $(DEP_DIR)
rm output
-@echo "Clean completed"

make时的错误被执行的是:

$ make
gcc -c -Wall -I. -IHeaders -MT Objects/*.o -MMD -MP -MF .d/*.Td Sources/function.c -o Objects/*.o
gcc Objects/*.o -o output
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
makefile:48: recipe for target 'output' failed
make: *** [output] Error 1

所以,我希望能实现自动依赖检测和编译。我认为错误在于检测依赖项的方式以及为给定源文件生成依赖项的方式。

最佳答案

在我看来,您似乎在尝试结合多种不同的方式来生成依赖信息,但这是行不通的。高级帖子讨论了解决问题的多种方法:您需要选择一个而不是尝试将它们一起使用。

如果您想使用高级方法,请按照顶部“TL;DR”部分或底部“组合编译和依赖项生成”部分中的说明使用它。如果您使用的是 GCC,则不需要 MAKEDEPENDsed 等。

高级帖子说你的规则应该是这样的:

COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d

%.o : %.c
%.o : %.c $(DEPDIR)/%.d
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)

就是这样。

关于c++ - 如何使用自动依赖生成器编写 make 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40826006/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com