Ubuntu16.04编译sdk遇到的问题和解决方法

在Ubuntu16.04下开发遇到的问题和解决方法

最近在项目开发中需要用到服务器编译代码,服务器使用的ubuntu版本是1604的;
因为原来一直是在虚拟机上编的,虚拟机装的是ubuntu1204版本,代码在1204下编译打包固件都没问题,当放到1604下编译的时候就出现各种问题了,这也在我的意料之中了,毕竟版本差异还是有点点,主要是一些系统工具版本,脚本命令格式等等差异带来的。

下面直接进入正题,程序员讲究的是效率!效率!效率!

一、首先,拿到代码后先看一下开发文档是需要的,知道怎么编译,打包固件这些基本命令。

从文档知道顶层makefile在target目录下,cd到target目录下执行以下命令:
(目录结构仅限我手上的sdk,不具通用参考性,不过顶层makefile的位置一般比较容易找的)
1、 在target目录下执行config.sh脚本,主要是做一些选择板型的工作。
2、 make all编译整个代码。

二、ubuntu1604编译结果

1、make all出现以下错误,编kernel出错了,然后make kernel看下具体错误
Makefile:130: recipe for target ‘sub-make’ failed
make[1]: * [sub-make] Error 2
make[1]: Leaving directory ‘/home/itman/a9/a90629/kernel’
Makefile:50: recipe for target ‘kernel’ failed
make: * [kernel] Error 2

2、make kernel出现以下错误
Can’t use ‘defined(@array)’ (Maybe you should just omit the defined()?) at /home/itman/a9/a90629/kernel/kernel/timeconst.pl line 373.
其实,提示的错误信息已经明确告诉你了,你应该省略defined().
这里,我们打开 kernel/timeconst.pl
@val = @{canned_values{$hz}};  
if (!defined(@val)) {  
@val = compute_values($hz);  
}  
output(
canned_values{$hz}};  if (!defined(@val)) {  @val = compute_values($hz);  }  output(
hz, @val);
将if (!defined(@val)) 改为if (!(@val))
然后再次编译。。。good 通过了

查了一下更新,发现其中有一项是perl版本升级到了 v5.22.1,然后查了perl官方文档,发现官网因为一个bug,该版本将defined(@array)去掉了。可以直接使用数组判断非空。

3、继续make all……出现以下错误
/home/itman/a9/a90629/rootfs/external/busybox/busybox-1.14.3/Makefile:422: * mixed implicit and normal rules: deprecated syntax
/home/itman/a9/a90629/rootfs/external/busybox/busybox-1.14.3/Makefile:1271: * mixed implicit and normal rules: deprecated syntax
make[6]: * No rule to make target ‘silentoldconfig’。 停止。
意思是“把隐含的和通用的规则混合一起使用了”,那就分开分别写就ok了。

遇到问题先在网上搜一下,有人遇到过这样的问题,说是编译系统(ubuntu1604)的make版本比代码makefile(ubuntu1204)的版本新,make版本兼容问题。于是根据错误信息找到这个makefile,定位到422和1271行看个究竟
修改如下:
makefile 422行:
config %config: scripts_basic outputmakefile FORCE 
改为
config: scripts_basic outputmakefile FORCE
%config: scripts_basic outputmakefile FORCE

makefile 1271行:/ %/: prepare scripts FORCE 
改为 
/: prepare scripts FORCE
%/: prepare scripts FORCE

此时单独编译busybox,通过了。

4、继续make all到最后打包固件的时候失败了
提示unsupport ubuntu version
应该是工具的问题
找到打包固件用的脚本看到有如下命令,上面的打印unsupport ubuntu version就是这里打印出来的,修改一下,增加对16.04版本的支持。
# 枚举环境, 以创建link
ubuntu_ver=”10”
case cat /etc/issue in
[Uu]buntu\ 10.*) ubuntu_ver=”10” ;;
[Uu]buntu\ 11.*) ubuntu_ver=”11” ;;
[Uu]buntu\ 12.*) ubuntu_ver=”12” ;;
[Uu]buntu\ 16.*) ubuntu_ver=”16” ;;
* ) { echo “unsupport ubuntu version” ; exit 1; } ;;
esac

上面case里的cat /etc/issue在ubuntu16.04上运行的结果是这样的
xxx@xxxx:~/xxx/a90629/target$ cat /etc/issue
Ubuntu 16.04.4 LTS \n \l

脚本里还有个case里的uname -m在ubuntu16.04上运行的结果是这样的
xxx@xxxx:~/xxx/a90629/target$ uname -m
x86_64
以上两个命令主要是拿来判断当前系统版本和系统是32位还是64位的。

5、继续make all完成最后的工作,这次整个编译过程没有出错,固件打包也正常了。
给自己赞一个~!~

然后继续折腾吧,看看其他流程有没有问题,比如make clean。
~
看到这里应该就知道这篇文章远没有那么快收尾。
make clean出~错~了~~~

6、make clean执行到json目录下出错了
make[3]: Entering directory ‘/home/itman/a9/a9_sdk_0629/rootfs/external/json-c’
if [ -f ./json-c-json-c-0.12-20140410/Makefile ];then\
cd ./json-c-json-c-0.12-20140410 && make distclean;\
fi;
make[4]: Entering directory ‘/home/itman/a9/a9_sdk_0629/rootfs/external/json-c/json-c-json-c-0.12-20140410’
Making distclean in .
make[5]: Entering directory ‘/home/itman/a9/a9_sdk_0629/rootfs/external/json-c/json-c-json-c-0.12-20140410’
test -z “libjson-c.la ” || rm -f libjson-c.la
rm -f ./so_locations
rm -rf .libs _libs
rm -f *.o
rm -f *.lo
rm -f *.tab.c
test -z “json-c.pc json-c-uninstalled.pc” || rm -f json-c.pc json-c-uninstalled.pc
test . = “.” || test -z “” || rm -f
rm -f config.h stamp-h1 json_config.h stamp-h2
rm -f libtool config.lt
rm -rf
rm -rf config.h.in~ Makefile.in aclocal.m4 autom4te.cache/ config.guess config.sub depcomp install-sh ltmain.sh missing
rm -f INSTALL test-driver tests/Makefile.in compile
rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
rm -f cscope.out cscope.in.out cscope.po.out cscope.files
make[5]: Leaving directory ‘/home/itman/a9/a9_sdk_0629/rootfs/external/json-c/json-c-json-c-0.12-20140410’
Making distclean in tests
make[5]: Entering directory ‘/home/itman/a9/a9_sdk_0629/rootfs/external/json-c/json-c-json-c-0.12-20140410/tests’
cd .. && make am–refresh
make[6]: Entering directory ‘/home/itman/a9/a9_sdk_0629/rootfs/external/json-c/json-c-json-c-0.12-20140410’
CDPATH=”${ZSH_VERSION+.}:” && cd . && /bin/sh /home/itman/a9/a9_sdk_0629/rootfs/external/json-c/json-c-json-c-0.12-20140410/missing aclocal-1.15
/bin/sh: /home/itman/a9/a9_sdk_0629/rootfs/external/json-c/json-c-json-c-0.12-20140410/missing: 没有那个文件或目录

6.1 跟1204系统下make clean的结果不一样
对比configure文件得出Autoconf的版本不一样,1604是Autoconf 2.69,1204是Autoconf 2.68,导致产生的configure文件不同。

6.2 分析在1604和1204系统下make clean的执行顺序
发现不同的地方是,按照脚本1204会先cd到子目录tests执行clean命令后返回主目录json-c-json-c-0.12-20140410继续完成主目录的clean工作,在1604下的执行顺序有点不同,它先在主目录下执行clean工作然后再到tests目录下clean,进入到tests目录时马上又返回主目录了,从运行输出打印可以看到这样的打印
Making distclean in tests
make[5]: Entering directory ‘/home/itman/a9/a9_sdk_0629/rootfs/external/json-c/json-c-json-c-0.12-20140410/tests’
cd .. && make am–refresh ##这里又返回了,并且紧接着执行了make am–refresh,也就是在主目录再make一次;

由于刚刚已经把主目录下autotool(automake autoconf autohead)生成的文件删除了包括missing,所以make的时候用到missing脚本就提示找不到文件。

解决方法:
在网上找了各种资料,看了关于GNU构建系统的流程、autotools是怎么工作的;

又看了一天json-c-json-c-0.12-20140410的makefile;

跟1204下的各种跟make相关的文件对比;

最终只是发现了1204和1604的差别是autotools版本上的不同,这貌似是已知的事实啊……

最终还是无果……不得不说autotools产生的makefile真不是一般难懂。。。。。

突然,灵光一闪,在快下班的时候灵感来了………………
——程序员不想加班的信念让我有了发现灵感的源动力~

是不是改一下目录顺序就好了?!
既然1204执行clean的时候先clean了子目录然后再到主目录,1604是先主目录再子目录,我反一下不就得了?!——机智如我,必须给自己加个鸡腿~~~~
于是在大脑中快速地search各种片段,我曾经见到过定义目录的东东,于是找到makefile.am,这个文件是开发人员可以改的,找到SUBDIRS变量。
原来是这样定义的SUBDIRS = . tests
把它改成这样SUBDIRS = tests .
然后make没问题
再然后make clean……
成功了,运行结果和在1204下make clean结果一样
程序人生的小确幸
……
……
……
……

原来就这么简单,幸福来得太突然。。。。。。
……
……
……
……
……
好了,可以收拾收拾下班,回家做饭去了
……
……
……
……
……
7、本来还准备了第7点继续解BUG的,现在没有7了,怎么办?强迫症犯了,写了开头要写结尾啊,要有个完美的ending~
希望这篇博客有帮助到大家解决实际问题,谢谢!
乐于分享,支持原创
写BUG我是天生的,解BUG我是认真的

喜欢的点个赞呗

Ubuntu16.04编译sdk遇到的问题和解决方法_第1张图片

这个ENDING怎么样,有没有闪到各位的老腰啊,哈哈哈~

你可能感兴趣的:(linux,ubuntu1604,笔记)