linux dhcp 4.3编译,关于在嵌入式Linux下编译dhcp报错“cannot check for file existence when cross compiling”的初步研究...
前言、写这篇文章的由来
最近在学习韦东山嵌入式培训视频(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变量,需要在执行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_random
AC_CACHE_CHECK([for $1], [ac_File], #查找 是否有ac_cv_file__dev_random这个cache变量
[test "$cross_compiling" = yes && #若无则检查$cross_compiling是否为yes
AC_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=yes
Else
AS_VAR_SET([ac_File], [no]) #否则设置cache变量ac_cv_file__dev_random=no
fi])
AS_VAR_IF([ac_File], [yes], [$2], [$3]) #如果cache变量ac_cv_file__dev_random=yes,则执行AC_DEFINE_UNQUOTED(PATH_RANDOMDEV,"$devrandom")
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摄像头监控》
linux dhcp 4.3编译,关于在嵌入式Linux下编译dhcp报错“cannot check for file existence when cross compiling”的初步研究...相关推荐
- 关于在嵌入式Linux下编译dhcp报错“cannot check for file existence when cross compiling”的初步研究...
前言.写这篇文章的由来 最近在学习韦东山嵌入式培训视频(3期项目实战之USB摄像头监控)时,在对dhcp源代码configure时,报错:cannot check for file existence ...
- 嵌入式linux零基础培训,零基础精通嵌入式linux系统有那么容易吗
嵌入式linux系统让你从入门到精通,新手必备学习技术你要不要来试试.对于新手来说,嵌入式linux系统应该如何更快更好的学习,首先可以告诉你:你要有C语言基础,看你走哪方面,看是底层系统还是应用层开 ...
- linux课程_【课程完结】嵌入式Linux应用/驱动开发基础知识两大篇章已全部录制完毕 共72集...
完结撒花 <第四篇嵌入式Linux应用开发基础知识> <第五篇嵌入式Linux驱动开发基础知识> 两大篇章已全部录制完毕 共计 72 集 01 嵌入式Linux应用开发基础知识 ...
- 【致敬嵌入式攻城狮第2期活动预热征文】解决瑞萨RA2E1开发板在RT-Thread的版本中编译报错 error: ‘board_cfg.h‘ file not found
解决瑞萨RA2E1开发板在RT-Thread的版本中编译报错 error: 'board_cfg.h' file not found 继上上周在RA2E1开发板上跑通了RT-Thread最新版本的代码 ...
- 嵌入式Linux开发,Ubuntu22下交叉编译内核报错: multiple definition of `yylloc‘; scripts/dtc/dtc-lexer.lex.o:(.bss+0x0
一.问题描述 嵌入式Linux开发,Ubuntu22下交叉编译内核报错: /usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss+0x10): multiple ...
- linux 卸载 bison,linux下的bison报错,
linux下的bison报错,求高手指教!急 想用flex+bison写个简单的编译器,生成三地址中间代码.结果bison的编译就一堆警告...大概是说定义的文法没有用之类的. 这个是flex文件 % ...
- linux下执行ffmpeg报错无法操作https资源的问题https protocol not found, recompile FFmpeg with openssl, gnutls
linux下执行ffmpeg报错无法操作https资源的问题https protocol not found, recompile FFmpeg with openssl, gnutls 报错 解决 ...
- linux 安装包 在此作用域中尚未声明_Linux运行go项目报错:copy_file_range: bad file descriptor...
这两天在 Linux 环境部署一个 Go 项目遇到一个报错:copy_file_range: bad file descriptor.网上查找各种方法,花了两天的时间,经过一番折腾后才解决,觉得非常有 ...
- Keil编译报错:Cannot open include file: 'stdbool.h': No such file or directory问题解决
Keil编译出现报错:Cannot open include file: 'stdbool.h': No such file or directory,或者出现Error: L6411E: No co ...
最新文章
- 002_支持并发的内部类饿汉单例
- tns03505 无法解析名称_SpringBootWeb源码解析SpringMVC自动配置
- PL\SQL 打开时出现动态执行表不可访问,本会话的自动统计被禁止
- python任意代码都可以缩进去_我发现了个 Python 黑魔法,执行任意代码都会自动念上一段 『平安经』...
- [国家集训队]middle
- torch的DataLoader 浅析
- druid 多数据源_Spring Boot2 系列教程(二十二)整合 MyBatis 多数据源
- LDAP密码认证例子
- C/C++经典项目开发:教你破解Windows系统密码,手把手教你做解密项目
- 全球最顶级的十大创新公司
- 2019阿里秋招一道笔试题(关于火柴拼出最大数字) - Android开发岗
- Excel忽略0值求平均分,将某一列分类后求平均值
- ·使用Xtext/Xtend 实现域专用语言DSL(1)
- 北大学子求职经历与建议(IT类)
- 在html table 标签的中background和bgcolor两个属性有什么关系?
- 如何查找IBM P5、6的HMC管理地址
- 计算机网络中m的含义,宽带中的“M(兆)”是什么意思?
- Visual Stdio C/C++的汇编代码的输出
- vue中怎么根据不同的(分屏模式)调整【自定义不同视频布局】?
- SAP ABAP屏幕(Dialog)开发中,获取文本框的内容并且存到数据库中。
热门文章
- 计算机应用基础第2版刘念祖答案,大学数学与计算机公共基础课程的教学研究-刘念祖主编.pdf...
- C#,哈夫曼编码(Huffman Code)压缩(Compress )与解压缩(Decompress)算法与源代码
- 【笑话】金庸笔下的武侠如何杀苍蝇
- 操作系统学习笔记:操作系统的硬件环境
- CSDN博客同步更新至简书
- Python发QQ邮件(来自菜鸟教程)
- python计算复杂公式_复杂指标计算公式
- 山东理工大学计算机考研资料汇总
- Tips系列:西门子HMI之历史曲线的自动刷新
- 蓝桥杯 真题 2021 4、路径