我正在尝试在makefile中添加警告作为错误标志。但是我遇到了以下问题。
当我在没有添加标志的情况下进行编译时,它是成功的。但是当我在一些“.mk”文件中添加Werror标志时,编译失败并出现一些错误。但是在成功的构建日志警告不存在那个现在抛出错误的源文件(“。c”)(Werror)。
我正在添加以下标志。
UN_CDEFS := -Wno-error=%
CDEFS := -Wall -Werror -Wextra
SUB_CDEFS := -Wall -Werror -Wextra
所以请建议可能出现的问题。
答案 0 :(得分:1)
警告:这不是完整的答案,因为我们需要更多信息,但对于我已经发布的更多热门评论来说,它会变得太长。< / p>
在您优化问题和/或发布更多数据时,我可以相应地编辑此答案。至少,发布实际的makefile可能会有所帮助,以及实际的最终cc
命令和失败的.c
文件的编译器警告/错误输出[可能有多个,但单个/第一个应该足够了。
以下是有关如何根据自己对此类问题的经验进行调试的详细说明。
但是,在我做到这一点之前,我会冒险猜测。我注意到你在做:
CDEFS := -Wall -Werror
[正如您在评论中提到的那样离开-Wextra
。
如果这是[几乎] makefile中的第一件事,那很好。但是,如果它出现在中间,则用您自己的值替换 CDEFS
。 如果生成文件中的先前行(例如):
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(2)命令检查case(1)命令可能会显示其他的选项不同于-W
。这表示makefile问题,类似于我的&#34; guess&#34;以上。你已经说过[你的等同于]案例(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) $<
还有其他方法可以做到这一点。
<强>更新强>
我正在使用以下命令来构建:
emq PRODUCT=ASG >build_log_0508.log
我不熟悉emq
。我无法找到对它的引用,除了#34; JIRA&#34;的企业邮件队列,[AFAICT] 可能是cPanel
的一部分?
在编译时遇到以下错误:
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)[&#34;好&#34;]和案例(2)[&#34;坏&#34;之间的cc
命令] 仅因添加-Wall
而有所不同,解决此问题的正确方法是编辑app.c
并添加#include <stdlib.h>
作为包含的一部分。
&#34; SUB_CDEFS:= -Wall -Werror&#34;是否有问题?
与CDEFS
一样,它会有类似的问题/好处。
我在makefile的末尾添加
这是使用+=
代替:=
的更多理由。你可能会&#34;杀掉&#34;如果在某处指定了-std=c89
。
更新#2:
在执行
+=
而不是:=
后,它有效。
正如我所提到的,使用:=
删除了一些在makefile中其他地方指定的关键编译选项。
但是,再一次,源代码有 bug 并且已损坏。 之前你曾经碰过它。通过使用-Wall -Werror
添加:=
,您发现了此错误,之前被错误地掩盖了 。这是好的事情。
使用+=
通过恢复:=
丢失的一些构建选项,只需再次扫描地毯下的错误。但是,这些&#34;失去了&#34;构建选项错误。他们允许C代码中的真正缺陷逃脱检测。
这是不关于使构建工作[使用解决方法],而是修复构建问题的根本原因,即修改C源代码。可能还有其他类似的C源代码错误,有些可能更严重。
使用解决方法来修复&#34;在构建中,您现在已经拥有了一块可以不可以正确运行运行的构建软件。它可能会在您的系统上以间歇方式失败。或者,产生不正确的结果。或者,如果您将此系统置于面向公众的网站上,则允许您的系统被黑客攻击[并可能使您承担法律责任]。
如果您不习惯自己进行源代码修改,请向该软件的原作者提交错误报告。源代码应该有一个README
文件或BUGS
文件,或任何应该概述这样做的程序。
只需要再澄清
之间的区别SUB_CDEFS
,UN_CDEFS
和CDEFS
这完全是武断的。
使用make
构建的软件项目通常可以构建多个程序或库。这些通常放在子目录中。每个这样的子目录通常都有自己的Makefile
。
为避免不必要的重复[和潜在错误],这些makefile常见的部分放在单 makefile中,通常称为规则文件[但是它只是一个makefile]。然后,各个makefile会有一行:include ../common/rules.mk
规则文件需要定义某些符号,以帮助指导它为给定的子目录构建目标。
CDEFS
et。人。是这种符号的一个例子。 [应该]选择描述功能的名称。也就是说,CDEFS
[可能]意味着&#34; C定义&#34;。实际的符号名称及其功能取决于规则文件。我们可以使用符号SHRONK
代替CDEFS
。这对理解事物没有多大帮助,但是如果编辑了所有的文件以将CDEFS
更改为SHRONK
,那么它就可以工作。
例如,在其他软件中,代替CDEFS
,类似的符号可能会被命名为CFLAGS
或COPTS
。这很常见。
旁注:此时此刻没有意义,但如果您编辑了问题并发布了输出cc
命令,事情就会变得更加顺畅和快速和我的一些makefile一样,按照我的要求。您可能会在几个小时内获得特定的答案,而不是一般的指导方针[需要几天时间]。
因此,如果没有规则文件,就无法分辨。只根据名称猜:
CDEFS
- 子目录的全局cc
选项SUB_CDEF
- 此特定子目录的cc
个选项UN_CDEFS
- 指定-Ufoo
个选项您正在构建的特定软件可能在文档文件中或在一个或多个makefile中的注释中包含此文档。
为了理解这一点,有很多make
的在线指南。在Linux下,有&#34; info&#34;文件。所以,试试info make
。其他系统有详细的联机帮助页,man make