即使使用 -Wall,GCC 也会以错误 1 退出。不解释为什么?
GCC exiting with an error 1 even with -Wall. No explanation why?
所以我试图重新编译我几周前的一个项目,令我惊讶的是我不断收到一个错误。我最初使用 MinGW 和 Eclipse CDT 编译它。我在 GCC 上启用了 -Wall 标志,所以我假设如果代码有问题,我会得到比抛出 make error 1 更有用的信息。因此,我怀疑问题可能在于我如何格式化 make 文件。幸运的是,我在上次推送提交时确实编译了项目并且二进制文件仍在回购协议中。不过,我会很感激一些帮助,以便我可以继续改进
项目。
编辑:当我执行 -all 时,它只是拒绝编译。
这是生成文件。我希望它像我一样简单,遵循一些不正确的语法:
CC=gcc -I../Include -L..\Lib
override CFLAGS+=-Wall -O3 #$(shell pkg-config --cflags fftw3)
#override LDFLAGS+=#$(shell pkg-config --libs fftw3 glib-2.0) -lm
.PHONY: all clean
all: lvdoenc lvdodec
lvdoenc: lvdoenc.o lvdomain.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -I../Include -L../Lib -lfftw3
lvdodec: lvdodec.o lvdomain.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -I../Include -L../Lib -lfftw3
%.o: %.c
$(CC) -c $(CFLAGS) -o $@ $^
lvdoenc.c: lvdocommon.h
lvdodec.c: lvdocommon.h
clean:
rm -f lvdoenc lvdodec lvdomain.o lvdoenc.o lvdodec.o
这是我的回购 link:
https://github.com/Skylion007/LVDOWin
更新:使用一些答案,我已经确认是 GCC 正在退出并出现错误 1,我不知道为什么。
更新 2:它没有向 syserr 打印任何内容。
下面的makefile更符合您项目的需要
但是,它不使用:
#$(shell pkg-config --libs fftw3 glib-2.0)
您需要重新添加。
注意在定义宏时使用':=',这样宏只需要计算一次,而不是每次都被引用。
可能需要针对您的系统修改 SHELL 宏和 CC 宏的路径。
SHELL := /usr/bin/sh
CC := /usr/bin/gcc
#CFLAGS := -c -Wall -Wextra -pedantic -std=c99 -O3 #$(shell pkg-config --cflags fftw3)
CFLAGS := -c -Wall -Wextra -pedantic -std=c99 -O3
# override LDFLAGS+=#$(shell pkg-config --libs fftw3 glib-2.0) -lm
LDFLAGS :=
SRCS := $(wildcard *.c)
ENCOBJS := lvdoenc.o lvdomain.o
DECOBJS := lvdodec.o lvdomain.o
.PHONY: all clean
all: lvdoenc lvdodec
lvdoenc: $(ENCOBJS)
$(CC) $(LDFLAGS) -o $@ $(ENCOBJS) -L../Lib -lfftw3 -lm
lvdodec: $(DECOBJS)
$(CC) $(LDFLAGS) -o $@ $(DECOBJS) -L../Lib -lfftw3 -lm
%.o:%.c lvdocommon.h
$(CC) -c $(CFLAGS) -c $< -o $@ -I../Include
clean:
rm -f lvdoenc lvdodec lvdomain.o lvdoenc.o lvdodec.o
如果没有 make 输出的副本,当你 运行 它时,我不明白为什么 GCC 应该静默失败,但我可以看到你的 makefile 至少有两个问题:
既然你声明你使用的是MinGW,那么你的目标平台必须是MS-Windows,在这个平台上的可执行文件应该有.exe
扩展名;因此,您的 all: lvdoenc lvdodec
规则格式不正确;它至少应该是 all: lvdoenc.exe lvdodec.exe
[1],(或者更好,为了便携性 all: lvdoenc$(EXEEXT) lvdodec$(EXEEXT)
,您在其中为 Windows 定义 EXEEXT = .exe
,并留下 EXEEXT
未定义,或定义为无,对于不需要扩展的平台)。
你的两个规则lvdoenc.c: lvdocommon.h
和lvdodec.c: lvdocommon.h
显然是不正确的; .c
文件不依赖于 .h
,但它们各自的 .o
文件依赖。因此,这两个规则应该分别是lvdoenc.o: lvdocommon.h
和lvdodec.o: lvdocommon.h
。
[1] 当然,你还需要将这两个"goals"分别正确引用为lvdoenc.exe
和lvdodec.exe
,(或lvdoenc$(EXEEXT)
和lvdodec$(EXEEXT)
), 在整个 makefile 中始终如一。
在您的 makefile 中还有一些其他构造,我认为它们有问题:CC
不应该真正定义为 -I../Include
或 -L..\Lib
,(以及为什么前者不一致/
,而后者\
?两者都应该是/
)。按照惯例,-I ...
属于 CPPFLAGS
,-L ...
属于 LDFLAGS
,CFLAGS
和 CPPFLAGS
都传递给编译器,通常 [= CFLAGS
、CPPFLAGS
和 LDFLAGS
的 56=]all 传递给编译器 driver,当调用链接器时,(尽管正如其他人在评论中指出的那样,-I ...
设置在将 .c
编译为 .o
时是绝对必要的,而 -L ...
设置仅在链接阶段才需要)。
显然,所有的原因都是我卸载了 64 位版本的 MinGW,并试图切换到 32 位版本的 MinGW。不幸的是,有些库无法在 32 位版本中编译,所以我只是使用 MinGW-w 来解决这个问题。事实证明,由于链接器错误,GCC 未启动,但此错误不成比例,直到我尝试从 Windows 终端 运行 才发现。我仍在解决它,当我完全解决问题时会更新此答案。
尝试使用 MSys 的 make 编译我的项目时遇到了同样的问题。意外地解决了问题,在我在 makefile 中为 gcc 输入和输出文件添加引号后。我不知道它是如何工作的,但希望它能帮助别人。
所以在 TS 示例代码中应该是这样的
%.o: %.c
$(CC) -c $(CFLAGS) -o "$@" "$^"
PS:虽然从 ubuntu 终端构建项目没有问题,所以也许这只是一个 msys 问题。
所以我试图重新编译我几周前的一个项目,令我惊讶的是我不断收到一个错误。我最初使用 MinGW 和 Eclipse CDT 编译它。我在 GCC 上启用了 -Wall 标志,所以我假设如果代码有问题,我会得到比抛出 make error 1 更有用的信息。因此,我怀疑问题可能在于我如何格式化 make 文件。幸运的是,我在上次推送提交时确实编译了项目并且二进制文件仍在回购协议中。不过,我会很感激一些帮助,以便我可以继续改进 项目。
编辑:当我执行 -all 时,它只是拒绝编译。
这是生成文件。我希望它像我一样简单,遵循一些不正确的语法:
CC=gcc -I../Include -L..\Lib
override CFLAGS+=-Wall -O3 #$(shell pkg-config --cflags fftw3)
#override LDFLAGS+=#$(shell pkg-config --libs fftw3 glib-2.0) -lm
.PHONY: all clean
all: lvdoenc lvdodec
lvdoenc: lvdoenc.o lvdomain.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -I../Include -L../Lib -lfftw3
lvdodec: lvdodec.o lvdomain.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -I../Include -L../Lib -lfftw3
%.o: %.c
$(CC) -c $(CFLAGS) -o $@ $^
lvdoenc.c: lvdocommon.h
lvdodec.c: lvdocommon.h
clean:
rm -f lvdoenc lvdodec lvdomain.o lvdoenc.o lvdodec.o
这是我的回购 link: https://github.com/Skylion007/LVDOWin
更新:使用一些答案,我已经确认是 GCC 正在退出并出现错误 1,我不知道为什么。
更新 2:它没有向 syserr 打印任何内容。
下面的makefile更符合您项目的需要
但是,它不使用:
#$(shell pkg-config --libs fftw3 glib-2.0)
您需要重新添加。
注意在定义宏时使用':=',这样宏只需要计算一次,而不是每次都被引用。
可能需要针对您的系统修改 SHELL 宏和 CC 宏的路径。
SHELL := /usr/bin/sh
CC := /usr/bin/gcc
#CFLAGS := -c -Wall -Wextra -pedantic -std=c99 -O3 #$(shell pkg-config --cflags fftw3)
CFLAGS := -c -Wall -Wextra -pedantic -std=c99 -O3
# override LDFLAGS+=#$(shell pkg-config --libs fftw3 glib-2.0) -lm
LDFLAGS :=
SRCS := $(wildcard *.c)
ENCOBJS := lvdoenc.o lvdomain.o
DECOBJS := lvdodec.o lvdomain.o
.PHONY: all clean
all: lvdoenc lvdodec
lvdoenc: $(ENCOBJS)
$(CC) $(LDFLAGS) -o $@ $(ENCOBJS) -L../Lib -lfftw3 -lm
lvdodec: $(DECOBJS)
$(CC) $(LDFLAGS) -o $@ $(DECOBJS) -L../Lib -lfftw3 -lm
%.o:%.c lvdocommon.h
$(CC) -c $(CFLAGS) -c $< -o $@ -I../Include
clean:
rm -f lvdoenc lvdodec lvdomain.o lvdoenc.o lvdodec.o
如果没有 make 输出的副本,当你 运行 它时,我不明白为什么 GCC 应该静默失败,但我可以看到你的 makefile 至少有两个问题:
既然你声明你使用的是MinGW,那么你的目标平台必须是MS-Windows,在这个平台上的可执行文件应该有
.exe
扩展名;因此,您的all: lvdoenc lvdodec
规则格式不正确;它至少应该是all: lvdoenc.exe lvdodec.exe
[1],(或者更好,为了便携性all: lvdoenc$(EXEEXT) lvdodec$(EXEEXT)
,您在其中为 Windows 定义EXEEXT = .exe
,并留下EXEEXT
未定义,或定义为无,对于不需要扩展的平台)。你的两个规则
lvdoenc.c: lvdocommon.h
和lvdodec.c: lvdocommon.h
显然是不正确的;.c
文件不依赖于.h
,但它们各自的.o
文件依赖。因此,这两个规则应该分别是lvdoenc.o: lvdocommon.h
和lvdodec.o: lvdocommon.h
。
[1] 当然,你还需要将这两个"goals"分别正确引用为lvdoenc.exe
和lvdodec.exe
,(或lvdoenc$(EXEEXT)
和lvdodec$(EXEEXT)
), 在整个 makefile 中始终如一。
在您的 makefile 中还有一些其他构造,我认为它们有问题:CC
不应该真正定义为 -I../Include
或 -L..\Lib
,(以及为什么前者不一致/
,而后者\
?两者都应该是/
)。按照惯例,-I ...
属于 CPPFLAGS
,-L ...
属于 LDFLAGS
,CFLAGS
和 CPPFLAGS
都传递给编译器,通常 [= CFLAGS
、CPPFLAGS
和 LDFLAGS
的 56=]all 传递给编译器 driver,当调用链接器时,(尽管正如其他人在评论中指出的那样,-I ...
设置在将 .c
编译为 .o
时是绝对必要的,而 -L ...
设置仅在链接阶段才需要)。
显然,所有的原因都是我卸载了 64 位版本的 MinGW,并试图切换到 32 位版本的 MinGW。不幸的是,有些库无法在 32 位版本中编译,所以我只是使用 MinGW-w 来解决这个问题。事实证明,由于链接器错误,GCC 未启动,但此错误不成比例,直到我尝试从 Windows 终端 运行 才发现。我仍在解决它,当我完全解决问题时会更新此答案。
尝试使用 MSys 的 make 编译我的项目时遇到了同样的问题。意外地解决了问题,在我在 makefile 中为 gcc 输入和输出文件添加引号后。我不知道它是如何工作的,但希望它能帮助别人。 所以在 TS 示例代码中应该是这样的
%.o: %.c
$(CC) -c $(CFLAGS) -o "$@" "$^"
PS:虽然从 ubuntu 终端构建项目没有问题,所以也许这只是一个 msys 问题。