1

I'm trying to write an etags target in make based on the dependency information generated by gcc. Is there some way of getting at all the dependencies in one go? Or, failing that, how would I write a rule that is only executed when the "tags" target is made and that passes all the source and header files to etags? I only want to index the files actually compiled (including headers). I'm aware that I can sed around in the .d files myself but I'm trying to find a more elegant and less brittle solution.

I have the following (excerpt)

DEPFILES = $(OBJFILES:.o=.d)

%.o : %.c
    @echo "Compiling $<"
    $(NO_ECHO) $(CC) $(CFLAGS) -MMD -MF $(@:.o=.d) -o $@ -c $<

%.o : %.S
    @echo "Compiling $<"
    $(NO_ECHO) $(CC) $(ASFLAGS) -MMD -MF $(@:.o=.d) -o $@ -c $<

$(TARGET) : $(OBJFILES)
    @echo "Linking $@"
    $(NO_ECHO) $(LD) $(LDFLAGS) -o $@ $(OBJFILES) $(LIBS:%=-l%)

.PHONY: clean

# Order-only dependency to make Dep/obj-directories if they are not
# present
$(OBJFILES) : | $(ALLPATHS)

$(ALLPATHS):
    $(NO_ECHO) mkdir -p $(ALLPATHS)

# Depend on the makefiles
$(OBJFILES) : $(SRC_PATH)/Makefile $(MAKECFG) $(BUILDCFG)

# Include dependency files

sinclude $(DEPFILES)

Edit : The following seems to work but I'd really like to find a more elegant solution (the double sort/uniq is just for performance).

tags : $(TARGET)
    cat $(DEPFILES) | sort | uniq | sed 's/.*:.*$$//' | tr -d '\\' | tr "\n" " " | xargs -n 1 readlink -f | sort | uniq | xargs etags -a 
4

2 回答 2

3

我来到这里寻找与原始问题相同的答案,但因为认为它没有得到充分回答并找到了不需要 sed 等的解决方案而离开了。

下面我假设一个类似于原始问题中的 Makefile 的 Makefile,它使用编译器生成 dep 文件并包含它们。

对于生成 .d 文件的编译规则,我修改了编译器选项以要求它也使标记目标依赖于目标文件的依赖关系。我添加-MQ $@ -MQ tags了选项。这些选项显式地告诉编译器依赖项的目标名称。

%.o : %.c
    $(CC) $(CFLAGS) -MMD -MF $(@:.o=.d) -o $@ -c $< -MQ $@ -MQ tags

现在我们不需要明确地给标签目标一个依赖列表,它会在我们编译时生成,并随着源文件的变化而相应地更新。就我而言,我正在使用ctags这就是我使用它的选项:

tags:
    ctags $^ -o $@

$^变量是依赖项列表。这将是源文件和头文件的列表,因为每个 .d 文件看起来像这样:

main.o tags: main.c a.h b.h

希望有帮助。

于 2018-03-10T22:08:19.880 回答
0

您需要为每个 .d 文件创建一个迷你标记文件,然后使用它来更新您的 etags 文件。请注意,这会将内容附加到文件中,而不是删除和替换,因此您可能需要偶尔远程标记文件(ctags有一个--update选项)

TAGFILES = $(OBJFILES:.o=.t)

# prune the .d files a bit to get a list of files for etags to scan
%.t: %.d
    cat $< | sed stuff > $@
    cat $@ | etags -a $@

.PHONY: tags
tags: $(TAGFILES)
于 2013-07-02T14:03:51.393 回答