【问题标题】:Recompile due to "preprocessor define" on a .h由于 .h 上的“预处理器定义”而重新编译
【发布时间】:2014-12-18 10:30:29
【问题描述】:

我的问题

我正在用一个 makefile 编译多个目标,到目前为止效果很好。我的问题是其中一个目标共享一个 .h 文件 (hash.h),该文件根据宏进行更改:HASHTABLE_USING_LISTS

所以,当 Makefile 运行时,所有东西都被编译,但是 practica2_list_bench,它应该使用定义了 HASHTABLE_USING_LISTS 的版本,最终链接到一个旧的 .o 对象,该对象在没有它的情况下编译。

最终导致整个程序的内存损坏和漂亮的SIGSEV

很明显,我必须以某种方式告诉 Makefile 在 .h 文件更改时重新编译(在这种情况下,它通过指定该宏来更改)。

这是我所有的 Makefile:

.SECONDEXPANSION:
# This is the makefile that generates the executable

# If compiing with -ansi, we should use
#   -Wno-error=implicit-function-declaration -Wno-implicit-function-declaration

CFLAGS = -Wall -Werror -g
LFLAGS = -lm

INCLUDE_BENCH = -I$(CURDIR) -Ibenchmark

FILES_O         =
FILES_C         =

TARGET          = practica2
CURRENT         = 

NAME            = $(TARGET)
NAME_BENCH      = $(TARGET)_bench
NAME_LIST       = $(TARGET)_list_bench

.PHONY: bare bench list
all: bare bench list

bare: FILES_C   = main.c parsing.c linked-list.c hash.c
bare: FILES_O   = $(subst .c,.o,$(FILES_C))

bench: FILES_C  = benchmark/main_bench.c parsing.c benchmark/benchmark.c linked-list.c hash.c
bench: CFLAGS   += $(INCLUDE_BENCH)
bench: CURRENT  = _BENCH
bench: FILES_O  = $(subst .c,.o,$(FILES_C))

list: FILES_C   = benchmark/main_bench.c parsing.c benchmark/benchmark.c linked-list.c benchmark/hash_list.c
list: CFLAGS    += -DHASHTABLE_USING_LISTS $(INCLUDE_BENCH)
list: CURRENT   = _LIST
list: FILES_O   = $(subst .c,.o,$(FILES_C))

clean:
    -/bin/rm -f *.o benchmark/*.o $(NAME) $(NAME_BENCH) $(NAME_LIST)

%.o: %.c hash.h
    gcc $(CFLAGS) -c $< -o $@

bare bench list: $$(FILES_O)
    gcc $(FILES_O) -o $(NAME$(CURRENT)) $(LFLAGS)

我完全没有想法。想出这个“多目标”“第二次扩展”版本时遇到了很多麻烦,我不知道从这里开始我应该如何继续。

请注意,可能会进行一些改进,但这是我将在解决后解决的另一个问题。

谢谢!

【问题讨论】:

  • 头文件没有改变,你定义了一个宏,告诉编译器以不同的方式预处理头文件。您有两个选择: Make 可以使用一个额外的文件来跟踪您上次构建的可执行文件,您可以将每个目标文件的两个版本保存在两个不同的名称下,您可以维护两个目标目录来保存目标文件两个可执行文件,或者您可以每次都重建所有可执行文件(粗略但有效)。什么听起来不错?
  • @Beta 我想拥有单独的文件夹将是要走的路。我将如何在 FILES_O 上的每个条目前面加上一些文本?如FILES_O = $(prepend objs/,$(subs .c,.o,$(FILES_C)))? GCC 会足够聪明地“检测”那些位于不同文件夹中的 .o 文件并相应地生成它们?
  • @Beta addprefix 似乎是我的命令。我会测试一下。
  • @Beta 完成并正常工作,谢谢。我会用最终版本回答自己

标签: c linux makefile dependencies


【解决方案1】:

您需要将您的.o 文件依赖于Makefile。这样,如果您编辑 Makefile 以包含 -D... 或不包含,.o 文件将被重新编译。

【讨论】:

  • 这不是我最终做的,而是 w/e。这也不是我问题的答案。我会接受它,因为没有给出更好的答案。我用另一种方法解决了!
  • 是的...我花了很多时间阅读您的问题,真的花了我一些时间。你会相信吗,我显然仍然无法理解它并为另一个问题提供了答案。我是多么的愚蠢!你应该多发几个这样的问题,这样我就可以练习我的理解能力了。
  • 别误会,我不是说你不努力,也不是说你错了。我接受了您的回答,因为它确实是正确的并且提供了一些洞察力。但是,这无助于为什么我无法在更改标志时重新编译 Make,就像在定义中一样。再说一次,你的回答并不愚蠢,如果我确实这么说,我很抱歉,我很着急,我没有足够的时间来解释自己。希望您能理解并原谅我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-30
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
  • 2015-07-27
相关资源
最近更新 更多