在当前目录下,我有以下文件。
election.c election.h extended_map.c extended_map.h main.c test_utilities.c utilities.c utilities.h
另外,我在当前目录下有一个内部文件夹,叫作 mtm_map
其中包括 map.c map.h
我创建了一个makefile,运行时正常。
make main.o
make extended_map.o
make election.o
make utilities.o
make clean
但运行时却失败了
-bash-4.2$ make map.o
cc -c -o map.o map.c
map.c: In function ‘getIndexOfKey’:
map.c:36:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int i = 0; i < map->size; i++)
^
map.c:36:5: note: use option -std=c99 or -std=gnu99 to compile your code
map.c: In function ‘initializeElements’:
map.c:59:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int i=initial_index;i<last_index;i++)
^
map.c: In function ‘mapCopy’:
map.c:165:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int i = 0; i < map->size; i++)
^
map.c: In function ‘mapGet’:
map.c:239:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int i = 0; i < map->size; i++)
^
make: *** [map.o] Error 1
makefile:
CC = gcc
OBJS = main.o ./mtm_map/map.o extended_map.o election.o utilities.o
EXEC = election
DEBUG_FLAG = -DNDEBUG
COMP_FLAG = -std=c99 -Wall -pedantic-errors -Werror
$(EXEC) : $(OBJS)
$(CC) $(DEBUG_FLAG) $(OBJS) -o $@
main.o: main.c ./mtm_map/map.h election.h test_utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
map.o: ./mtm_map/map.c ./mtm_map/map.h utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
extended_map.o: extended_map.c extended_map.h ./mtm_map/map.h utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
election.o: election.c election.h ./mtm_map/map.h extended_map.h utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
utilities.o: utilities.c utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
clean:
rm -f $(OBJS) $(EXEC)
有什么建议可以解决这个问题吗?请注意,我希望map.o是在当前目录下创建的(而不是在当前目录下创建的) mtm_map
)
你所显示的错误不可能来自于运行你提供的makefile。
当你运行 make map.o
你是在上层目录下运行,还是在下面的 mtm_map
目录? 如果是后者,那就可以解释了。
你这里有很多问题。 首先,如果你真的想要 map.o
文件存在于顶层目录中,那么您设置的 OBJS
是错误的;这。
OBJS = main.o ./mtm_map/map.o extended_map.o election.o utilities.o
^^^^^^^^^^
应该是。
OBJS = main.o map.o extended_map.o election.o utilities.o
第二,你应该一直用 -o $@
我相信这一点在过去几天你在SO上提出的类似问题中已经至少提到了两次)在你的规则中。
最后,你应该使用 $<
不 $*.c
当你在规则中引用源文件时,前者会扩展到第一个先决条件,包括它的完整路径。 在规则中引用源文件时,前者扩展到第一个先决条件,包括它的完整路径。$*
中只扩展到茎,而不包括路径。
所以你的makefile应该是这样的。
CC = gcc
OBJS = main.o map.o extended_map.o election.o utilities.o
EXEC = election
DEBUG_FLAG = -DNDEBUG
COMP_FLAG = -std=c99 -Wall -pedantic-errors -Werror
$(EXEC) : $(OBJS)
$(CC) $(DEBUG_FLAG) $(OBJS) -o $@
main.o: main.c ./mtm_map/map.h election.h test_utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) -o $@ $<
map.o: ./mtm_map/map.c ./mtm_map/map.h utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) -o $@ $<
extended_map.o: extended_map.c extended_map.h ./mtm_map/map.h utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) -o $@ $<
election.o: election.c election.h ./mtm_map/map.h extended_map.h utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) -o $@ $<
utilities.o: utilities.c utilities.h
$(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) -o $@ $<
clean:
rm -f $(OBJS) $(EXEC)
你的Make没有正确使用 $(COMP_FLAG)
你在里面定义的。
通常有一个 CFLAGS
变量来做,用隐含的规则来编译源文件,所以我将重写你的 Makefile
为了消除你在其中包含的大量冗余代码。
# I use the ?= operator, so you can redefine the compiler with make CC=clang ...
CC ?= gcc
EXEC = election
TOCLEAN = $(EXEC)
# NDEBUG is a compilation option, not a linking one. The purpose of MY_CFLAGS is
# to allow you to define extra CFLAGS to be used on source code compilation.
CFLAGS = -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG $(MY_CFLAGS)
OBJS = main.o mtm_map/map.o extended_map.o election.o utilities.o
# you can add files to clean in a more complex makefile
TOCLEAN += $(OBJS)
$(EXEC): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
clean:
rm -f $(TOCLEAN)
# Extra dependencies (the dependency a.o : a.c is automatic)
main.o: mtm_map/map.h election.h utilities.h
mtm_map/map.o: mtm_map/map.h utilities.h
extended_map.o: extended_map.h mtm_map/map.h utilities.h
election.o: election.h mtm_map/map.h extended_map.h utilities.h
utilities.o: utilities.h
这样就能正确地建立你的项目。
如果你决定一些源文件必须驻留在Makefile所在的目录之外的其他目录中,那么你必须考虑你是想让对象文件在你的目录中还是在源文件所在的目录中。 我遵循了我认为你想要的(将所有源文件放在 这个 目录可能导致名称冲突,因为不同目录中的两个文件可能有相同的名称),但你也必须使用对象的路径(就像我在这里使用的那样)。
还有另一种选择,就是制作一个构建目录,所以所有的文件都是以复制或源码中使用的层次结构来构建的,但这也有一些其他的缺点,因为你必须重写自动规则,以重建你之前的目录结构。 但这也有一些其他的缺点,因为你必须重写自动规则,以便重建你在尝试将文件放入其中之前的目录结构。