我试图在我的makefile文件中添加警告作为错误标志。但是我遇到了以下问题。
当我在不添加标志的情况下编译成功。但是,当我在某些“.mk”文件中添加Werror标志时,编译失败并出现一些错误。但是在成功的构建日志中,对于该源文件(“.c”)没有警告,该源文件现在引发错误(Werror)。
我添加他跟随标志。
UN_CDEFS := -Wno-error=%
CDEFS := -Wall -Werror -Wextra
SUB_CDEFS := -Wall -Werror -Wextra
因此,请提出可能的问题。
最佳答案
警告:这不是一个完整的答案,因为我们需要更多信息,但是对于更多的顶级评论(如我已经发布的评论)来说,这太长了。
在您解决问题和/或发布更多数据时,我可以相应地编辑此答案。至少发布实际的makefile可能会有所帮助,以及最终的cc
命令的实际结果以及失败的.c
文件的编译器警告/错误输出[可能有多个,但单个/第一个应该足够]。
根据我对此类问题的经验,以下是一些有关如何调试它的详细说明。
但是,在此之前,我会冒险猜测。我注意到您正在执行以下操作:
CDEFS := -Wall -Werror
[删除注释中提到的
-Wextra
]。如果这样做几乎是makefile中的第一件事,那就很好了。但是,如果它发生在中间,则您要用自己的值替换
CDEFS
。如果makefile中的前一行是(例如):CDEFS = -Dwont_build_cleanly_without_this_option
然后,当您添加行时,可能就是问题所在,因为此行被(有效)删除了。您可以尝试以下方法:
CDEFS += -Wall -Werror
这只是附加到现有符号上,因此将保留所有先前值。
另外,基本makefile可能具有以下内容:
ifndef CDEFS
CDEFS := -Dwont_build_cleanly_without_this_option
endif
通常,
make
将输出其执行以创建目标的命令的全文。对于编译,这是(例如)cc -c foo.c
。一些更高级的编译器将命令包装在(例如)
@doit cc -c foo.c
中,其中doit
打印类似compiling foo.c ...
的消息,并且仅在出现错误时才输出完整命令。 (例如,Linux内核版本会执行此操作,IIRC)。我假设您没有,但是如果这样做,通常会有一个命令行覆盖,例如make VERBOSE=1
因此,在某个地方有一些
.c
文件可以使用常规选项完全构建,但是在添加额外的编译选项时会生成错误。我们将此文件称为badnews.c
我们想要看到的是
make
为badnews.c
打印的编译命令以及两种情况下的警告/错误输出:特别是,将case(1)命令与case(2)命令对照可能会显示
-W
以外的其他选项是不同的。这表明有一个makefile问题,类似于我上面的“猜测”。您已经说过,[相当于](1)情况很干净,没有任何警告,但是,鉴于您遇到的麻烦,再次检查不会有任何伤害。您可以将case(1)
cc
命令剪切并粘贴到Shell脚本中,然后手动添加-W
选项。当心带空格的内容,例如makefile中的-DSTRING="foo bar"
,可能需要在shell脚本中加引号。为了减轻类似于您的冲突,我在自己的makefile文件中将符号分开。
所有
DFLAGS
的-DFOO=1
COPTS
,-g
,-O2
,-Wall
等的-fno-inline-functions
。然后,我要么做:
CFLAGS := $(COPTS) $(DFLAGS)
要么:
%.o: %.c:
cc -c $(COPTS) $(DFLAGS) $<
还有其他方法可以做到这一点。
更新:
I am using following command to build:
emq PRODUCT=ASG >build_log_0508.log
我不熟悉
emq
。除了“JIRA的企业邮件队列”([AFAICT]可能是cPanel
的一部分)之外,我找不到对它的引用。Getting the following error on compilation:
prod/libs/app/app.c:720:5: error: incompatible implicit declaration of built-in function 'free' [-Werror] free(tmp_dn);
这是吸烟枪...
我不知道您使用的是什么编译器,或者什么操作系统/环境,但是默认情况下它似乎没有将其标记为警告/错误。
但是,这是源
app.c
中的错误,需要修复。通过添加-Wall
和-Werror
,已将其正确标记为警告/错误注意:正如我在原始答案中提到的那样,最好使用产生此错误的最终
cc
命令行(以及未标记此文件时的cc
命令)。我创建了一个简单的测试用例:
void
myfree(void *ptr)
{
free(ptr);
}
在
gcc
下,我做了gcc -c test.c
,我得到了:test.c: In function 'myfree':
test.c:5:2: warning: implicit declaration of function 'free' [-Wimplicit-function-declaration]
free(ptr);
^
test.c:5:2: warning: incompatible implicit declaration of built-in function 'free'
test.c:5:2: note: include '<stdlib.h>' or provide a declaration of 'free'
因此,默认情况下
gcc
对此进行标记(即使没有-Wall
或-Werror
)。但是,除非给出-Wall
,否则编译器不会这样做。如果您的编译器是clang
并且您还指定了-std=c89
,则可能会发生这种情况就像我之前暗示的那样,如果只指定
-Wall
而不是-Werror
,则应该得到相同的警告,但它们不会停止构建。在大型构建中,它们很容易在日志中被[人(例如,我:-)忽略]。引用我的原始答案中的建议,假设情况(1)[“良好”]与情况(2)[“不良”]之间的
cc
命令仅因添加了-Wall
而有所不同,正确的解决方法是:编辑app.c
并添加#include <stdlib.h>
作为include的一部分。Is there any problem with "SUB_CDEFS := -Wall -Werror"?
它将具有与
CDEFS
类似的问题/好处。I am adding at the end of the makefiles
这就是使用
+=
而不是:=
的更多原因。如果在某处指定了-std=c89
,则可能会“杀死它”。更新2:
It worked after doing
+=
instead of:=
.
如前所述,使用
:=
删除了一些关键的编译选项,这些选项在makefile中的其他位置指定。但是,再次,源代码有一个错误并且被破坏了。在您触碰它之前,它已经被打破了。通过使用
-Wall -Werror
添加:=
,您发现了此错误,该错误以前没有被正确屏蔽。这是一件好事。通过恢复
+=
丢失的一些构建选项,使用:=
可以再次扫除错误。但是,这些“丢失的”构建选项是错误的。他们允许C代码中的真正缺陷逃脱检测。这不是要使构建正常运行(有解决方法),而是要解决构建问题的根本原因,即修改C源代码。可能还有其他这样的C源代码错误,有些可能更严重。
通过“修复”构建的变通办法,您现在已经拥有了一些无法信任的正确运行的内置软件。它可能会在您的系统上间歇性地失败。或者,产生不正确的结果。或者,如果将系统放置在面向公众的网站上,则允许您的系统被黑客入侵[并可能使您承担法律责任]。
如果您不满意自己进行源代码修改,请向软件的原始作者提交错误报告。源代码应具有
README
文件或BUGS
文件,或应概述该过程的任何文件。Just need one more clarification for what is the difference between
SUB_CDEFS
,UN_CDEFS
, andCDEFS
这是完全任意的。
用
make
构建的软件项目通常可以构建多个程序或库。这些通常放置在子目录中。每个此类子目录通常都有自己的Makefile
。为了避免不必要的重复[和潜在的错误],这些makefile共有的部分放在单个makefile中,通常称为规则文件[但是它只是一个makefile]。各个makefile的行如下:
include ../common/rules.mk
规则文件期望定义了某些符号,以帮助指导它为给定的子目录构建目标。
CDEFS
等等是此类符号的示例。 [应该]选择描述功能的名称。也就是说,CDEFS
[可能]表示“C定义”。实际的符号名称及其功能取决于规则文件。我们可以使用符号SHRONK
代替CDEFS
。这对理解事物没有多大帮助,但是如果所有makefile都经过编辑以将CDEFS
更改为SHRONK
,那么它将起作用。例如,在其他软件中,代替
CDEFS
的类似符号可能被命名为CFLAGS
或COPTS
。这是相当普遍的。旁注:目前还没有定论,但是如果您编辑了问题并按照我的要求发布了输出
cc
命令和您的某些makefile,事情将会变得更加顺利和迅速。您将在几个小时内获得特定答案,而不是一般准则(需要花费几天时间)。因此,如果没有规则文件,就无法分辨。仅根据名称猜测:
CDEFS
-子目录cc
选项SUB_CDEF
-此特定子目录cc
选项UN_CDEFS
-指定-Ufoo
选项您正在构建的特定软件可能在一个文档文件中或一个或多个makefile中的注释中包含有关此文档的文档。
为了大致了解这一点,有许多
make
的在线指南。在Linux下,有“信息”文件。因此,尝试info make
。其他系统有详细的手册页,man make
也有
关于c - 关于添加错误标志的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38773337/