g++:交叉编译时包含问题

Posted

技术标签:

【中文标题】g++:交叉编译时包含问题【英文标题】:g++ : include problems when cross compiling 【发布时间】:2012-07-19 08:47:45 【问题描述】:

我遇到了一个有点奇怪的问题。 我们有一个项目,我们针对几种不同的架构进行编译,尤其是这 2 个:SH4 和 MIPS。

一段时间以来,我们遇到了一个问题,其中一些代码可以在 SH4 中编译,但不适用于 MIPS,因为缺少包含。我已将问题范围缩小到这个测试文件:

#include <sstream>
// deliberately not including the needed includes

int main()

  const char *toto = "Hello World";
  // using printf and strlen which require <stdio.h> and <string.h>
  printf("Toto has len %d\n", strlen(toto)); 
  return 0;


用这个命令编译成 SH4

$ sh4-linux-g++ -O0 -g -Wall -Werror -Wno-write-strings \
                -fno-rtti -fno-exceptions test.cpp -o test
$ 

-> 完全没问题。文件实际执行正常。


而使用 MIPS

$ mips-linux-gnu-g++ -O0 -g -Wall -Werror -Wno-write-strings \
                     -fno-rtti -fno-exceptions test.cpp -o test 
test.cpp: In function 'int main()':
test.cpp:6: error: 'strlen' was not declared in this scope
$ 

现在,我已经运行了几件事,尤其是 g++ 的依赖生成。我看到的是这样的:

SH4

$ sh4-linux-g++ -O0 -g -Wall -Werror -Wno-write-strings \ 
                -fno-rtti -fno-exceptions test.cpp -M |grep "/string.h"

  /opt/STM/STLinux-2.3/devkit/sh4/target/usr/include/string.h \

-> string.h 自动包含。

MIPS

mips-linux-gnu-g++ -O0 -g -Wall -Werror -Wno-write-strings \
 -fno-rtti -fno-exceptions test.cpp -M |grep "/string.h"

-> 包含中缺少 string.h

有关信息:

SH4 version  = 4.2.4 (2007)  
MIPS version = 4.3.2 (2008)

这里发生了什么?在 SH4 上编译时,&lt;sstream&gt; 包含似乎包含了 strlen() 所需的所有内容,而在 MIPS 上则没有。我怀疑这是因为版本不同,但我不确定。

最后,我真正的问题是,当我在 SH4 上开发时,我想确定如果它编译,它将在所有目标上编译。 有解决办法吗?

【问题讨论】:

不幸的是,我认为唯一的解决方案是在编码时有足够的自律性,以确保所有必需的标头都明确#included,并且永远不要依赖其他#includes 的副作用。在上述情况下,您应该拥有#include &lt;cstdio&gt;#include &lt;cstring&gt;,而不是依赖#include &lt;sstream&gt; 的副作用。 是的,我想这就是解决方案,但上面的这个例子只是我从剥离实际的错误文件中得到的。我们有一个持续集成过程,它会在编译失败时告诉我们。但我想人的错误总会发生:) 【参考方案1】:

这是怎么回事?

您基本上是在问“为什么我的非标准代码使用一个版本的编译器而不是另一个版本编译?”当然是因为版本不同。

查看GCC 4.3 changes 在运行时库 (libstdc++) 部分下的说明:

已简化标题依赖项,减少了不必要的包含和预处理膨胀。

我们也在最近的版本中继续减少标头依赖项,以更加严格并减少命名空间污染(例如,4.6 避免不必要地包含 &lt;cstddef&gt;,4.7 不再包含不必要的 &lt;unistd.h&gt;),所以要回答您的最后一个问题,我建议您尽可能使用最新的 GCC 版本(即使只是检查代码而不是用于生产构建),因为它具有最严格、最干净的标头,并且会发现最多的问题。另一种选择是使用更严格的标准库实现,例如libcomo。

【讨论】:

这实际上是我正在寻找的答案。我不确定标题是否包含从一个版本到另一个版本的不同是正常的。所以,是的,我们必须隔离可以在 x86 上编译的代码,并将这种架构添加到持续集成中。谢谢!

以上是关于g++:交叉编译时包含问题的主要内容,如果未能解决你的问题,请参考以下文章

加载交叉编译的内核模块时出错

如何在交叉编译 Windows 的 vlc 时包含 QtNetwork

为树莓派 pi3 交叉编译 Qt 时出错

与mingw交叉编译时找不到zlib头文件?

每次我尝试使用`clang -Weverything`进行编译时,都会收到警告“包含位置'/usr/local/include'对于交叉编译不安全”

(交叉编译)平台文件是不是需要包含保护?