因此,使用这段人为设计的代码-使用clang编译可以很好地工作,但是当使用ccache时,会出现额外的警告/错误-我认为ccache应该透明地传递这些信息。这是来自epel repo的CentOS 6上的ccache 3.1.6-不能选择升级,因为这是生产环境。
#include <byteswap.h>
int main()
{
int i = 42;
auto j = bswap_32(i);
(void)j;
return 0;
}
因此,示例1中未使用的包含路径不会给出任何错误:
clang++ -Wno-c++98-compat -Wall -Werror -std=c++17 -I/usr/local/include -c ccache.cpp
但是用ccache我得到:
ccache clang++ -Wno-c++98-compat -Wall -Werror -std=c++17 -I/usr/include/xmlib -c ccache.cpp
clang-5.0: error: argument unused during compilation: '-I /usr/include/xmlib' [-Werror,-Wunused-command-line-argument]
没有额外包含的示例2可以正常工作:
clang++ -Wno-c++98-compat -Wall -Werror -std=c++17 -c ccache.cpp
并与ccache
cache clang++ -Wno-c++98-compat -Wall -Werror -std=c++17 -c ccache.cpp
ccache.cpp:6:32: error: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
auto j = (__extension__ ({ register unsigned int __v, __x = (i); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) << 24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v; }));
^~~~~~~~~
ccache.cpp:6:32: error: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
auto j = (__extension__ ({ register unsigned int __v, __x = (i); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) << 24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v; }));
^~~~~~~~~
2 errors generated.
为什么使用ccache会改变结果?
最佳答案
基本问题是,默认情况下,ccache
将对文件进行预处理(在其上运行C预处理器),以获得单个预处理的翻译单元,该翻译单元用于检查其缓存。然后,为了提高效率,如果它在缓存中“丢失”并不得不编译文件,则它将经过预处理的文件直接传递给clang
,告诉clang
不要运行预处理器,而仅运行编译器(例如,通过它是.i
扩展名)。
由于它未运行预处理器,因此固有会忽略-I
参数,而这正是clang
所提示的。 gcc
对此没有那么挑剔,因此在那儿不构成问题。
在ccache
3.2中,已进行了修复,根据我的本地测试,此问题消失了。
如果您坚持使用3.1,则可以在您的环境中使用export CCACHE_CPP2=yes
,它告诉ccache
不必进行上述优化,只需将原始C或C++文件传递到clang
中即可。此成本要多少性能取决于预处理与编译的成本。
我在TravisCI(具有3.1版的ccache
的旧版本)上遇到了此问题,并为我解决了此问题。
您的编译错误可能源于相同的原因:clang
可能会忽略某些或所有系统 header (例如<byteswap.h>
)中的错误,但不会忽略“用户代码”中的错误。由于ccache
向它传递了一个很大的预处理blob,因此所有内容看起来都像是对叮叮当当的用户代码。
该three part blog series更详细地说明了此问题,并包含指向相关ccache
错误和讨论的链接。
关于clang++ - 将ccache与clang 5一起使用会导致与clang5不同的结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49927317/