【问题标题】:compile headers dependencies with makefile使用 makefile 编译头文件依赖项
【发布时间】:2014-07-08 02:33:31
【问题描述】:

我正在用 C 编程语言编写一个 UDP 客户端服务器应用程序;我想在依赖项发生变化时自动编译 2 个源文件和 3 个头文件,所以我决定使用 make 实用程序。

makefile 目标被称为 "edit"

    edit : server_UDP.o  client_UDP.o \
            gcc -o edit server_UDP.o  client_UDP.o \


    client_UDP.o : client_UDP.c cliHeader_UDP.h  wrapHeader.h
            gcc -c client_UDP.c

    server_UDP.o : server_UDP.c servHeader_UDP.h  wrapHeader.h
            gcc -c  server_UDP.c

当我在 wrapHeader.h 中更改几行代码时,它不会触发重新编译。

当 wrapHeader.h 发生更改以重新编译 server_UDP 和 client_UDP 时,如何修改编辑 makefile 规则?

**note : wrapHeader.h 是主标题

cliHeader_UDP.h:包括“wrapHeader.h”

servHeader_UDP.h:包括“wrapHeader.h”

【问题讨论】:

  • gcc 和 Gnu make 都有一个 fantastic 功能集,当设置为彼此协同工作时,将完全按照您的要求进行. gcc -MM 编译器开关将几乎 为您生成一个make 兼容的目标。有关如何完成此操作的信息以及一些要试用的示例代码,请参阅 gnu make at this website 的在线文档,特别注意 this section

标签: c gcc makefile gnu


【解决方案1】:

我认为你想要的是制作依赖文件。

您可以使用“-MMD -MP”参数指定编译器为您生成一个依赖文件,这会在同一文件夹中创建一个与源文件同名但扩展名为 *.d 的新文件作为您的来源。

依赖文件包含代码所依赖的所有头文件,如果它使用的头文件被修改,这将导致 GNU make 编译您的源文件。

启用makefile的示例依赖文件:

# Makefile

CC   := gcc
LD   := g++

# The output executable.
BIN   := program

# Toolchain arguments.
CFLAGS    := 
CXXFLAGS  := $(CFLAGS)
LDFLAGS   := 

# Project sources.
C_SOURCE_FILES := mysourcefile1.c src/myothersrc.c
C_OBJECT_FILES := $(patsubst %.c,%.o,$(C_SOURCE_FILES))

# The dependency file names.
DEPS := $(C_OBJECT_FILES:.o=.d)

all: $(BIN)

clean:
    $(RM) $(C_OBJECT_FILES) $(DEPS) $(BIN)

rebuild: clean all

$(BIN): $(C_OBJECT_FILES)
    $(LD) $(C_OBJECT_FILES) $(LDFLAGS) -o $@

%.o: %.c
    $(CC) -c -MMD -MP $< -o $@ $(CFLAGS)

# Let make read the dependency files and handle them.
-include $(DEPS)

这应该适用于您的情况:

SOURCES := server_UDP.c client_UDP.c
OBJECTS := $(patsubst %.c,%.o,$(SOURCES))

DEPS := $(OBJECTS:.o=.d)

edit: $(OBJECTS)
    gcc -o edit $(OBJECTS)

%.o: %.c
    gcc -c $< -o $@

-include $(DEPS)

【讨论】:

  • mmmm 我浏览了有用的链接,但我没有搞清楚,因为我是 makefile 实用程序的新手,所以 Dylan McKay 可能是我的编辑文件中的一个示例,如何让代码理解更多,因为我很困惑。 ..
  • 但我想了解更多关于 makefile ,什么是 patsubst 和什么是 OBJECTS := $(patsubst %.c,%.o,$(SOURCES)) DEPS := $(OBJECTS:. o=.d)
  • patsubst 是 GNU make 提供的一个函数,它用另一个模式替换一个模式。当您调用 $(patsubst %.c,%.o,$(SOURCES)) 时,实际上是在“SOURCES”变量中的每个文件中将 .c 扩展名替换为 .o
  • deps 的事情基本上是一样的,事实上你可以做一个与 DEPS 做同样事情的声明 := $(OBJECTS:.o=.d) 但使用 patsubst。 $(OBJECTS:.o=.d) 表达式只是将“OBJECTS”变量中的“.o”替换为“.d”
  • 感谢您的帮助,但它仍然无法按我的意愿工作。当我更改 wrapperHeader 时没有任何改变,我可以向您发送文件以测试我昨天尝试的文件,大约 3H:30m 但仍然同样的结果......这对我来说将是很大的恩惠......
【解决方案2】:

您没有说 edit.c 包含您的两个特定标题,但我想它必须,如果它链接到对象。

这正是 makepp 发挥其优势之一的场景:如果您遵循约定,对于每个需要链接的 .o 文件,都有一个相应名称的包含语句(在您的情况下,是client_UDP.h & server_UDP.h) 然后makepp会自己解决所有问题,除了将头文件检测为依赖项。

这甚至可以递归地工作,所以如果你有一个wrapHeader.cedit.c 中没有相应的包含语句),它将被自动编译和链接。

所以您不需要生成文件。但是如果你想避免每次都调用makepp edit,那么你可以创建一个单行

edit:

如果你有更复杂的需求,你只需要学习 make 语法。但是,如果您这样做,则没有限制。除了做 GNU make 能做的几乎所有事情,还有更多有用的事情,你甚至可以通过一些 Perl 编程来扩展你的 makefile。

【讨论】:

  • no edit 是 makefile 命令的文件,client_UDP 和 server_udp 不是 Headers ..... 它的源代码
  • 对不起,我不明白你在说什么。如果你想去我们的sourceforge forums,我们可以讨论更多。如果您更喜欢其中一种,您还可以用世界语、德语或法语写作。
猜你喜欢
  • 2011-01-24
  • 1970-01-01
  • 2013-04-27
  • 1970-01-01
  • 2019-03-19
  • 2016-02-22
  • 2018-06-19
  • 1970-01-01
  • 2017-10-03
相关资源
最近更新 更多