前言、写这篇文章的由来

最近在学习韦东山嵌入式培训视频(3期项目实战之USB摄像头监控)时,在对dhcp源代码configure时,报错:cannot check for file existence when cross compiling。虽然按照视频教程给出的办法在“./configure  --host=arm-linux”之后加上“ac_cv_file__dev_random=yes”,解决了问题。但在看到configure文件中那天书一样的文字时,总不免很多疑惑:难道为了写一个dhcp这样的程序,还要写个这么晦涩的configure代码?dhcp的作者,难道如此牛逼么?

经过研究,终于发现,原来这个configure文件并不是直接由人工编写出来的,而是由autoconf这个工具根据autoconf.ac或者autoconf.in自动生成的。而后者才是人工编写出来的。而使用autoconf的目的,是为了使我们写出来的程序(比如这个dhcp)能够方便的移植到多种unix(或类unix)系统上。

结论虽然很简单,但厘清其中的来龙去脉,还是花了不少时间。不过我觉得还是值得的,因为了解了来龙去脉之后,就掌握了套路。以后遇到类似的问题,就可以举一反三,心中有数,而不用再像无头苍蝇那样抓狂了。

一、实验环境

1.1 虚拟机环境

a) Vmware版本:Vmware Workstation 12.5.7

b) Ubuntu版本:9.10

c) 内核版本:2.6.31.14

1.2 开发板环境

1.2.1 硬件

开发板:百问网JZ2440开发板

wifi网卡:RT3070

1.2.2 软件

a) 内核版本: 3.4.2

b) toolchain版本:

arm-linux-gcc 4.3.2

c) dhcp版本:4.2.5-P1

二、交叉编译dhcp,在configure时,报错信息及解决过程简记

1、./configure  --host=arm-linux

报错:configure:error: cannot check for file existence when cross compiling

经查,是configure文件line7695:

if test "${ac_cv_file__dev_random+set}" = set; then

echo $ECHO_N "(cached) $ECHO_C" >&6

else

test "$cross_compiling" = yes &&

{ { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5

echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}

{ (exit 1); exit 1; }; }

解决办法:在./configure  --host=arm-linux 后面加上: ac_cv_file__dev_random=yes

2、make,报错:

configure: error: cannot check for file existence when cross compiling

在configure.log里,找到这行:

configure:22156: error: cannot check for file existence when cross compiling

根据这个提示,在configure:22156,找到了:

if eval \${$as_ac_File+:} false; then :

$as_echo_n "(cached) " >&6

else

test "$cross_compiling" = yes &&

as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5

而$as_ac_File定义在:bind/bind-9.8.4-P2/configure:22149 :

as_ac_File=`$as_echo "ac_cv_file_$devrandom" | $as_tr_sh`

解决办法:修改bind/bind-9.8.4-P2/Makefile:

Line55: ./configure  --host=arm-linux  ac_cv_file__dev_random=yes

三、原理初探

     其实,./configure文件line7695那段天书,是autoconf根据./configure.ac自动生成的:

 Line536:AC_CHECK_FILE(/dev/random,AC_DEFINE([HAVE_DEV_RANDOM], [1],[Define to 1 if you have the /dev/random file.]))

类似的,bind/bind-9.8.4-P2/configure的那段天书,也是autoconf根据bind/bind-9.8.4-P2/configure.in自动生成的:

line1087 :AC_CHECK_FILE($devrandom,AC_DEFINE_UNQUOTED(PATH_RANDOMDEV,"$devrandom"),)

关于AC_CHECK_FILE(file, [action-if-found], [action-if-not-found])的作用,简单说,就是检查$devrandom代表的文件是否存在,若是则执行action-if-found,否则执行action-if-not-found。

该宏的实现代码在/usr/share/autoconf/autoconf/general.m4 ,line 2764

这段代码中间的一大段,是关于cache变量的,目的是为了加速查找结果(详见https://www.gnu.org/software/autoconf/manual/autoconf-2.64/html_node/Cache-Variable-Names.html#Cache-Variable-Names)

注:若要启用cache变量,需要在执行configure命令时传递 -C或者--config-cache选项,此时可在configure同级目录下发现config.cache文件,用于存放所有的cache变量,cache变量在内存中为shell变量,当configure启动时,AC_INIT会调用AC_CACHE_LOAD从config.cache读入到shell变量里。当configure退出时,会调用AC_CHECK_FILE存放到config.cache文件里)。cache变量名必须包含”_cv_”,意即cache value,若缺了它的话,就无法被cache了。

这段宏的大致解释如下(假设调用场景就是bind/bind-9.8.4-P2/configure.in里的line1087:AC_CHECK_FILE(/dev/random, AC_DEFINE_UNQUOTED(PATH_RANDOMDEV,"$devrandom"),):

AC_DEFUN([AC_CHECK_FILE],[AC_DIAGNOSE([cross],[cannot check for file existence when cross compiling])dnl #打印一些信息AS_VAR_PUSHDEF([ac_File], [ac_cv_file_$1])dnl #定义一个临时宏ac_File,其展开结果是ac_cv_file__dev_randomAC_CACHE_CHECK([for $1], [ac_File],  #查找 是否有ac_cv_file__dev_random这个cache变量[test "$cross_compiling" = yes &&    #若无则检查$cross_compiling是否为yesAC_MSG_ERROR([cannot check for file existence when cross compiling]) #是则显示cannot check for...,然后直接退出;if test -r "$1"; then #否则执行test -r"$1" 测试/dev/random是否可读AS_VAR_SET([ac_File], [yes]) #是则设置cache变量ac_cv_file__dev_random=yesElseAS_VAR_SET([ac_File], [no]) #否则设置cache变量ac_cv_file__dev_random=nofi])AS_VAR_IF([ac_File], [yes], [$2], [$3]) #如果cache变量ac_cv_file__dev_random=yes,则执行AS_VAR_POPDEF([ac_File])dnl #取消临时宏ac_File])# AC_CHECK_FILE

那么问题来了:为什么当AC_CHECK_FILE遇到交叉编译的情况,会有这样的行为特征呢?官网的解释是:

Be aware that, like most Autoconf macros, they test a feature of the host machine, and therefore, they die when cross-compiling.

意思是说:AC_CHECK_FILE仅是用于检查宿主机(而不是目标机)上的文件是否存在。所以当遇到交叉编译的情况,它就没辙了!

想来这个解释也有道理,既然configure是运行在宿主机上的,那当然无法去检查目标机上的文件了。但这样一来,又回到了问题的原点:为什么dhcp的configure要检查/dev/random这个文件?我推测应该是由于最终编译出来的程序需要使用到/dev/random?(不然岂不是瞎折腾么?)

如果确实如此的话,那只要目标机上存在/dev/random(通过”ls /dev |grep random”查下来也确实存在),那即使跳过这个检查,应该也没影响。

由此,进一步的问题就是:怎样让configure跳过这个检查?

解决办法是:只要强制把ac_cv_file__dev_random这个cache变量设置为yes即可,具体来说,有两个办法:

办法1)按照视频的做法,修改bind/Makefile:

Line55: ./configure  --host=arm-linux  ac_cv_file__dev_random=yes

办法2)可能通用性稍好一些

既然ac_cv_file__dev_random是cache 变量,而且./configure.ac和bind/bind-9.8.4-P2/configure.in都访问了这个变量,那这两个文件之间是不是能用某种机制来共享这个变量呢?答案是肯定的。在autoconf的官方网站上(https://www.gnu.org/software/autoconf/manual/autoconf-2.64/html_node/Cache-Files.html#Cache-Files)可以查到在 7.4.2 Cache Files里,关于cache files,有这么一段话:

When configure calls configure scripts in subdirectories, it uses the --cache-file argument so that they share the same cache。

也就是说,当父目录中的configure调用子目录中的configure时,前者可以通过传递给后者--cache-file=xxx来使后者共享cache。

由此,对于本文开头所述的configure报错的问题,第2种解决办法是:

Step1)在执行根目录下的configure时,加入-C 选项:

./configure  --host=arm-linux  ac_cv_file__dev_random=yes -C

Step2)修改bind/Makefile:

Line55: ./configure  --host=arm-linux --disable-kqueue --cache-file=../../config.cache

四、后记

关于autoconf,如果要深究的话,又是一个大坑。不过对于本项目来说,只要求能把dhcp移植到开发板上,并且能跑起来即可,并不需要从头开始写一个dhcp。所以,暂时只需要对autoconf了解个大概就行了。本文可当作一个路标,以使在今后前行的路上遇到类似坑时,不至于懵圈。

五、参考资料

1)韦东山 《嵌入式linux视频教程_三期项目实战之USB摄像头监控》

2)GNU autoconf 官网手册(https://www.gnu.org/software/autoconf/manual)

转载于:https://www.cnblogs.com/normalmanzhao2003/p/11517290.html

关于在嵌入式Linux下编译dhcp报错“cannot check for file existence when cross compiling”的初步研究...相关推荐

  1. linux dhcp 4.3编译,关于在嵌入式Linux下编译dhcp报错“cannot check for file existence when cross compiling”的初步研究...

    前言.写这篇文章的由来 最近在学习韦东山嵌入式培训视频(3期项目实战之USB摄像头监控)时,在对dhcp源代码configure时,报错:cannot check for file existence ...

  2. Linux下编译leveldb报错,leveldb ubuntu 11.04下编译失败问题

    我在最新的ubuntu11.04下编译leveldb的时候发现问题,但是在更早前的这个版本很正常: yufeng@yufeng-laptop:/usr/src/leveldb$ make g++ -c ...

  3. linux 卸载 bison,linux下的bison报错,

    linux下的bison报错,求高手指教!急 想用flex+bison写个简单的编译器,生成三地址中间代码.结果bison的编译就一堆警告...大概是说定义的文法没有用之类的. 这个是flex文件 % ...

  4. linux下执行ffmpeg报错无法操作https资源的问题https protocol not found, recompile FFmpeg with openssl, gnutls

    linux下执行ffmpeg报错无法操作https资源的问题https protocol not found, recompile FFmpeg with openssl, gnutls 报错 解决 ...

  5. Linux下Tomcat启动报错:port already in use

    Linux下Tomcat启动报错:port already in use,导致该问题的原因很多,我在这里记录一下我遇到的情况的解决办法. 检查了${TOMCAT_HOME}/conf/server.x ...

  6. 【问题】VS2019在windows10下编译cef报错,导致系统;疑是AMD CPU 超频设置导致

    [问题]VS2019在windows10下编译cef报错,导致系统崩溃:疑是AMD CPU 超频设置导致 编译环境 问题描述 解决? 编译环境 CPU:AMD R5 3600 主板:微星B450 操作 ...

  7. 树莓派重启DHCP报错Warning: The unit file, source configuration file or drop-ins of docker.service changed

    问题 树莓派重启DHCP报错Warning: The unit file, source configuration file or drop-ins of docker.service change ...

  8. CentOS 6.3 下编译cyrus-sasl报错解决

    编译cyrus-sasl报错解决        分类:            Linux2011-12-07 12:501155人阅读评论(0)收藏举报 function 编译cyrus-sasl报错 ...

  9. RK1126从入门到放弃:番外篇(二)Win10 WSL系统下编译buildroot报错不支持SYSV IPC,导致fakeroot无法正常工作

    Win10的Linux子系统是完全可以直接用来进行嵌入式Linux开发操作的,目前已经非常顺畅地编译通过了U-Boot和内核.但是编译Builtroot的最后阶段,需要使用fakeroot来fake文 ...

最新文章

  1. Symantec Backup Exec Remote Agent 2010在Redhat Enterprise 6.6上启动问题
  2. 图解.Net Telerik 控件教程
  3. 手把手教你使用C#操作SQLite数据库,新建数据库,创建表,插入,查询,删除,运算符,like...
  4. Android 图形驱动初始化
  5. python 数字转化excel行列_Python实现excel的列名称转数字、26进制(A-Z)与10进制互相转换...
  6. java ipmitool_ipmitool使用手册
  7. Django 之 Session的简单使用
  8. VS2015 经常不出现智能提示,代码颜色也没有了
  9. php 串行化与json(转)--很不错的文章
  10. Demo(3月28日)
  11. python深度学习图像处理CSV文件分类标签图片到各个文件夹
  12. java简历自我评价_java程序员简历自我评价怎么写
  13. 避障车(L293D电机驱动)
  14. 短视频代运营服务内容
  15. m3u8视频格式转换
  16. 将Ubuntu 用户目录下的中文目录修改为英文
  17. elementUI的input使用扫描枪,回显值后重新刷新页面
  18. Python Matplotlib 3D绘图详解(汇总)
  19. 达梦数据库——模式及状态转换
  20. 机器学习笔记(3.1)

热门文章

  1. 【100个高大尚求职简历】简历模板+修改教程+行业分类简历模板 (涵盖各种行业) (简历模板+编辑指导+修改教程)
  2. Windows python pydub 安装
  3. 《网络营销推广技术、技巧深度解密》文档
  4. 接入微信电子发票java_Android app对接微信电子发票功能
  5. maven依赖管理(依赖配置、依赖传递、依赖冲突、依赖范围)
  6. Java常用类:string 、日期api总结最全
  7. android绘制9宫格图片
  8. KeyError: ‘state_dict‘
  9. 详解u盘怎么重装系统win7,u盘一键安装win7
  10. 计算机在地理科学中的作用,多媒体在地理教学中作用(精).doc