【问题标题】:Rename .o files using Makefile and gcc使用 Makefile 和 gcc 重命名 .o 文件
【发布时间】:2016-07-27 21:59:44
【问题描述】:

我在 Makefile 中有几行正在编译和生成 .o.d 文件。我想要制作两组.o.d,例如:

name.d
name_hello.d
name.o
name_hello.o

已经找到如何使用"$(@:.o=_hello.d)" 更改.d 的名称,但更改没有成功。o 也许我需要使用$@,但不知道该怎么做。

这是制作文件的代码:

$(OBJECT_DIRECTORY)/%.o: %.c
# Build header dependencies
    $(CC) $(CFLAGS) $(INCLUDEPATHS) -M $< -MF "$(@:.o=.d)" -MT $@
    $(CC) $(CFLAGS) $(INCLUDEPATHS) -M $< -MF "$(@:.o=_hello.d)" -MT $@
# Do the actual compilation
    $(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $<
    $(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $< - this line i want to change

我将arm-none-eabi-gcc.exe 用于 ARM,make.exe


更新

似乎使用单独的目标是比更改名称更受欢迎的解决方案。所以,我为它做了单独的目标。但它从未使用过。在 Makefile 的其他地方有下一行代码告诉编译器使用什么 .o 文件:

C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILENAMES:.c=.o) )

我想我需要将其更改为:

C_OBJECTS_hello = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILENAMES:.c=*_hello.o) )

请告诉如何修改C_OBJECTS以使编译器使用*_hello.o文件


更新 2

这就是C_OBJECTS 的使用方式,我想C_OBJECTS 中的某种过滤器告诉CCarm-none-eabi-gcc.exe)使用某些.o 文件。由于*_hello.o 文件未在过滤器中使用,因此它们也不会在其目标中生成。

## Link C and assembler objects to an .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out: $(BUILD_DIRECTORIES) $(C_OBJECTS) $(ASSEMBLER_OBJECTS) $(LIBRARIES)
    $(CC) $(LDFLAGS) $(C_OBJECTS) $(ASSEMBLER_OBJECTS) $(LIBRARIES) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out

我知道这是在 make help 中写的,我正在阅读它,但仍然无法找到答案


更新 3

这是我修改 'C_OBJECTS' 的方法,似乎可行:

C_OBJECTS_hello = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILENAMES:.c=_hello.o) )

【问题讨论】:

  • 但没有成功更改.o - 将其更改为什么?
  • 我的目标是同时拥有 *.o 和 *_hello.o 文件。
  • 你当然可以创建一个$(C_OBJECTS_hello) 变量,但是创建一个变量并不意味着它以后会被使用。您应该检查C_OBJECTS 现在在哪里使用,并考虑$(C_OBJECTS_hello) 的含义。我们不知道您如何使用 $(C_OBJECTS)_hello.o 有什么特别之处,所以我们的建议就差不多了。
  • 'C_OBJECTS' 由 gcc 使用,我在 'Update 2' 中对此进行了描述。感谢您的帮助@MSalters

标签: gcc makefile linker


【解决方案1】:

您确实会使用替代品。 $@ 变量扩展了所有 %.o 匹配项。这就是为什么你有一个$(@:.o=.d) 替换;对于每个 %.o 匹配项,您需要一个 .d 文件。

在这种情况下,您确实可以使用$(@:.o=_hello.o) 替换。请注意,这不是 %.c 输入的依赖项;它是辅助输出。

另一种方法是添加第二个输出$(OBJECT_DIRECTORY)/%.o $(OBJECT_DIRECTORY)/%_hello.o: %.c。在这种情况下,您不会使用$@,而是使用匹配的%$*。所以你的两个依赖文件是$(OBJECT_DIRECTORY)/$*.d$(OBJECT_DIRECTORY)/$*_hello.d

【讨论】:

  • 它甚至不是一个 secondary 输出,因为 make 根本不知道它。
  • @MaximEgorushkin:对,应该将其列为输出。
  • 请看,我更新了主题。为 *_hello.o 做了单独的目标,但从未使用过目标。
  • @VladimirTsykunov:嗯,规则告诉make如何构建*_hello.o,而不是为什么。 Make 不执行随机规则;它从预期的最终目标开始工作,以确定需要哪些中间文件。
【解决方案2】:

您的 makefile 规则生成的文件比make 知道的要多。 $(OBJECT_DIRECTORY)/%.o: %.c 表示它从 .c 构建了一个 .o,而您希望它构建 4 个文件。

你需要让make知道它的规则产生了什么文件,这样它才能构建一个完整的依赖图:

$(OBJECT_DIRECTORY)/%.o $(OBJECT_DIRECTORY)/%.d: %.c # Compile and build dependencies.
    $(CC) -c -o $@ $(CFLAGS) $(INCLUDEPATHS) -MD -MP $<

$(OBJECT_DIRECTORY)/%_hello.o $(OBJECT_DIRECTORY)/%_hello.d: %.c # Compile and build dependencies.
    $(CC) -c -o $@ $(CFLAGS) $(INCLUDEPATHS) -MD -MP $<

请注意,这些规则并未明确命名.d 输出文件,而是让编译器通过将.o 替换为.d 来确定它。

现在您有两个规则而不是一个 make 可以在使用 -j 标志时并行执行它们。

请注意,出于https://stackoverflow.com/a/7358961/412080 中所述的原因,您不需要为自动生成的依赖项制定明确的规则。

【讨论】:

  • 谢谢,这很有用,我做了两个目标,似乎可以根据需要生成两组文件。
猜你喜欢
  • 2013-08-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 2014-11-30
相关资源
最近更新 更多