我试图让我的makefile编译一个需要-std=c99
才能运行的文件。在这种情况下,它可以通过"for循环"。
这是我的代码,(它在"$(CC)"之前使用了"tab"):
CC = gcc
CFLAGS = -c -std=c99
...
Download.o : Download.c
$(CC) $(CFLAGS) Download.c
Download.c 包含用于从 Web 下载元素的方法
错误信息
$ make
gcc -c -std=c99 Download.c
gcc Download.c -o Program
Download.c: In function ‘downloadImageparts’:
Download.c:11:2: error: ‘for’ loop initial declarations are only allowed in C99 mode
Download.c:11:2: note: use option -std=c99 or -std=gnu99 to compile your code
Download.c:13:3: error: ‘for’ loop initial declarations are only allowed in C99 mode
make: *** [comp] Error 1
Attemt to debug
如果我在终端中运行gcc -c -std=c99 Download.c
它工作正常。
在 Linux 中运行时会出现此问题。
解决:
我创建了一个虚拟项目来展示我的讲师,试图解决我的问题。在虚拟项目中,所有代码都可以正常工作。出于某种原因,我的代码可以在原地工作,但在另一个地方不起作用。如果有人阅读本文时遇到与我相同的问题,并希望看到一个示例项目。让我知道,我会在这里编写代码。谢谢
你看错了规则。 Download.c
实际上编译得很好,但链接阶段是错误的。
$ 使gcc -c -std=c99 Download.c # 编译gcc 下载.c -o 程序 # 链接
修复链接程序的生成规则。 它可能看起来像这样:
Program: a.o b.o c.o
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
当你使用它时,我建议一个更完整的Makefile看起来像这样:
all: Program
clean:
rm -f Program *.o
.PHONY: all clean
# -c is implicit, you don't need it (it *shouldn't* be there)
# CC is also implicit, you don't need it
CFLAGS := -std=c99 -g -Wall -Wextra
Program: a.o b.o c.o
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
# Make will automatically generate the necessary commands
# You just need to name which headers each file depends on
# (You can make the dependencies automatic but this is simpler)
a.o: a.c header.h
b.o: b.c header.h header2.h
c.o: c.c header.h
如何做错的例子
链接器标志实际上相当敏感! 请务必完全按照我写的格式输入上面的行,不要假设您写的内容是等效的。 以下是一些略有不同的错误命令示例,不应使用:
# WRONG: program must depend on *.o files, NOT *.c files
Program: a.c b.c c.c
$(CC) ...
# WRONG: -c should not be in CFLAGS
CFLAGS := -c -std=c99
Program: a.o b.o c.o
# WRONG: $(CFLAGS) should not be here
# you are NOT compiling, so they do not belong here
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
# WRONG: $(LIBS) MUST come at the end
# otherwise linker may fail to find symbols
$(CC) $(LDFLAGS) -o $@ $(LIBS) $^
# WRONG: do not list *.o files, use $^ instead
# otherwise it is easy to get typos here
$(CC) $(LDFLAGS) -o $@ a.o b.o c.o $(LIBS)
# WRONG: $(LDFLAGS) must be at the beginning
# it only applies to what comes after, so you
# MUST put it at the beginning
$(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
# WRONG: -c flag disables linking
# but we are trying to link!
$(CC) $(LDFLAGS) -c -o $@ $^ $(LIBS)
# WRONG: use $(CC), not gcc
# Don't sabotage your ability to "make CC=clang" or "make CC=gcc-4.7"
gcc $(LDFLAGS) -o $@ $^ $(LIBS)
# WRONG: ld does not include libc by default!
ld $(LDFLAGS) -o $@ $^ $(LIBS)
如果我在 makefile 中使用空格而不是制表符,我会看到相同的结果,并且 make
的输出显示未使用该规则:
$ make
cc -c -o Download.o Download.c
Download.c: In function ‘main’:
Download.c:4:3: error: ‘for’ loop initial declarations are only allowed in C99 mode
Download.c:4:3: note: use option -std=c99 or -std=gnu99 to compile your code
make: *** [Download.o] Error 1
尝试在以 gcc
开头的行之前使用制表符。
看到原始问题的更新后:
$ make
gcc -c -std=c99 Download.c
gcc Download.c -o Program
第一行(编译)不显示任何错误。
这是第二行,它重新编译Download.c
失败。
我认为您想链接.o
文件以在此处创建可执行Program
,正如迪特里希·埃普所建议的那样。