C 由于“重新编译”;预处理器定义";在a.h 我的问题
我用一个makefile编译了多个目标,到目前为止效果很好。我的问题是,其中一个目标共享一个.h文件(C 由于“重新编译”;预处理器定义";在a.h 我的问题,c,linux,makefile,dependencies,C,Linux,Makefile,Dependencies,我用一个makefile编译了多个目标,到目前为止效果很好。我的问题是,其中一个目标共享一个.h文件(hash.h),该文件根据宏而变化:HASHTABLE\u使用\u列表 因此,当运行Makefile时,所有内容都会被编译,但是practica2\u list\u bench应该使用定义了HASHTABLE\u using\u list的版本,最终链接到一个旧的.o对象,而该对象是在没有它的情况下编译的 它最终导致整个程序内存损坏,并导致一个漂亮的SIGSEV 很明显,每当.h文件发生更改时(
hash.h
),该文件根据宏而变化:HASHTABLE\u使用\u列表
因此,当运行Makefile时,所有内容都会被编译,但是practica2\u list\u bench
应该使用定义了HASHTABLE\u using\u list
的版本,最终链接到一个旧的.o
对象,而该对象是在没有它的情况下编译的
它最终导致整个程序内存损坏,并导致一个漂亮的SIGSEV
很明显,每当.h文件发生更改时(在本例中,它通过指定宏进行更改),我必须以某种方式告诉Makefile重新编译
这是我所有的Makefile:
。第二次扩展:
#这是生成可执行文件的makefile
#如果符合-ansi,我们应该使用
#-Wno error=隐式函数声明-Wno隐式函数声明
CFLAGS=-Wall-Werror-g
LFLAGS=-lm
INCLUDE_BENCH=-I$(CURDIR)-Ibenchmark
文件=
文件=
目标=实践2
电流=
名称=$(目标)
名称\u BENCH=$(目标)\u BENCH
名称\u列表=$(目标)\u列表\u工作台
.虚假的:空无一物的替补名单
全部:无替补名单
bare:FILES\u C=main.C parsing.C linked list.C hash.C
裸:FILES\u O=$(subst.c、.O、$(FILES\u c))
bench:FILES_C=benchmark/main_bench.C parsing.C benchmark/benchmark.C linked list.C hash.C
工作台:CFLAGS+=$(包括工作台)
工作台:当前=_工作台
bench:FILES\u O=$(subst.c、.O、$(FILES\u c))
列表:FILES_C=benchmark/main_bench.C parsing.C benchmark/benchmark.C linked list.C benchmark/hash_list.C
列表:CFLAGS+=-DHASHTABLE\u使用列表$(包括工作台)
列表:当前=\u列表
列表:FILES\u O=$(subst.c、.O、$(FILES\u c))
清洁:
-/bin/rm-f*.o benchmark/*.o$(NAME)$(NAME\u BENCH)$(NAME\u LIST)
%.o:%.c哈希值.h
gcc$(CFLAGS)-c$<-o$@
空工作台列表:$$(文件)
gcc$(文件)-O$(名称$(当前))$(LFLAGS)
我完全没有主意了。我很难想出这个“多目标”“第二次扩展”版本,我不知道从现在起我应该如何继续
请注意,可能会进行一些改进,但这是我将在解决后解决的另一个问题
谢谢大家! 您需要依赖于
Makefile
上的.o
文件。这样,如果您编辑Makefile以包含-D..
或不包含.o
文件,则将重新编译.o
文件 头文件不会更改,您正在定义一个宏,它告诉编译器以不同的方式预处理头文件。您有两个选项:Make可以使用一个额外的文件来跟踪您上次生成的可执行文件,可以使用两个不同的名称保存每个对象文件的两个版本,可以维护两个对象目录来保存两个可执行文件的对象文件,或者您可以每次重新生成所有可执行文件(粗糙但有效)。什么听起来不错?@Beta我想应该有单独的文件夹。我如何在文件的每个条目前加上一些文本?如FILES\u O=$(prepend objs/,$(subs.c,.O,$(FILES\u c))
?GCC将足够智能地“检测”那些.o文件在不同的文件夹中,并相应地生成它们?@Betaaddprefix
似乎是我的命令。我会测试它。@Beta完成并正常工作,谢谢。我会用最终版本回答自己。这不是我最后要做的,而是w/e。这也不是我问题的答案。我会接受它,因为没有给出更好的答案。我解决了是的,我花了很多时间阅读你的问题,真的花了我一些时间。你会相信吗,我显然还没有理解它,并提供了一个不同问题的答案。我真是太傻了!你应该多发几个这样的问题,这样我就可以练习我的理解能力。别搞错了请理解我,我不是说你没有付出努力,也不是说你错了。我接受你的答案是因为它确实是正确的,并提供了一些见解。但是,这无助于解释为什么我不能在每次更改标志时重新编译,就像在定义中一样。再说一次,你的答案并不是愚蠢的,如果我说了,我很抱歉t、 我很匆忙,没有足够的时间来解释我自己。我希望你能理解并原谅我。
.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)