Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 由于“重新编译”;预处理器定义";在a.h 我的问题_C_Linux_Makefile_Dependencies - Fatal编程技术网

C 由于“重新编译”;预处理器定义";在a.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文件发生更改时(

我用一个makefile编译了多个目标,到目前为止效果很好。我的问题是,其中一个目标共享一个.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文件在不同的文件夹中,并相应地生成它们?@Beta
addprefix
似乎是我的命令。我会测试它。@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)