之前尝试了交叉编译自己的程序
https://bbs.elecfans.com/jishu_2012330_1_1.html
现在可以开始考虑复杂点的工程了。
darknet是一个基于c/c++编写的深度学习框架,而且本体是没有任何依赖库的,所以很适合进行交叉编译并移植到鸿蒙上。Darknet是一个基于c/c++编写的深度学习框架,而且本体是没有任何依赖库的,所以很适合进行交叉编译并移植到鸿蒙上。
https://pjreddie.com/darknet/
https://github.com/pjreddie/darknet
先尝试交叉编译,成功后等后面肝完大作业T T,然后上板子测试下,最后如果跑通我就将源码更新出来
把darknet源码下载到鸿蒙工程下的third_party内,然后进入darknet工程看看他的Makefile
总的来说,darknet的makefile总共有两个步骤,第一步编译src文件内的文件生成darknet动态库和静态库,第二步引用darknet库编译example内的文件生成darknet可执行文件。因此,我们也需要利用BUILD.gn以及之间的组合实现类似功能。
首先我们实现编译库的功能。
进入darknet工程,在工程的根目录下新建BUILD.gn
写入大概如下内容
ndk_lib提供了个给总的BUILD.gn(前文提到的在//build/lite下的BUILD.gn)一个入口来进入本BUILD.gn,然后deps是:libdarknet表示deps了本BUILD中命名为libdarknet的块(这种说法并不准确,暂时不知道如何形容)
target_type = "staticlibrary"表示编译成静态库,如果是shared_library则是生成动态库
sources就是指定c文件,名字要具体,且不能出错(因为这里文件太多了,一定来认真仔细,我好几个程序漏打了.c而且还没报错,导致最后编译example发现库总是缺胳膊少腿,半天找不到原因。。)
这里的sources要编译哪些文件应该参照Makefile来定,我们这里就针对Makefile只有cpu选项情况下的编译,他还有什么cuda、opencv选项后需要增加的编译内容,我不需要,就没选了。
因为本BUILD.gn位于darknet工程根目录,所以定位include_dirs的时候可以不用绝对路径,直接相对路径就行了。
这样,编译darknet静态库的BUILD.gn就写完了,去到总的BUILD.gn像前文说的一样,只单独编译darknet库
此外,在尝试编译过程中遇到了几个问题(忘了出现的顺序了,到时候就着改吧)
1.fatal error: use of undeclared identifier 'fd_set'
问题出在go.c内
大概上Google查了下,在go.c上加入头文件sys/select.h,该问题解决。
2.源码中使用了c11标准导致出的错误
其实这是因为鸿蒙工程在编译的过程中规定了c99标准
去到鸿蒙工程中的build/lite/config内的BUILD.gn
找到language_c
注释掉并改成-std=c11即可
3.fatal error: shift count >= width of type
这个问题出现在utils.c内,他这部分的代码是针对64位操作系统写的,但是鸿蒙的liteos-a目前是32位,所以这段代码报错,我们只需要把32位以后的操作注释掉即可。
不过也是因为这一点,darknet的源码大概率是针对64位写的,我暂时不清楚这样编译通过放到鸿蒙上是不是会有其他的bug,后面一定要上板测试下。
我们看看编译通过后的结果
编译成功~
接下来就是如何引用的问题了,对于单纯使用clang或者gcc按照要求加入适当参数就行,不过这个时候是用gn来构建了,突然就懵了,花了一段时间去看工程内media例程的BUILD.gn以及自己试错,发现原来这么简单。。。
我们去到examples内新建BUILD.gn然后写入
一些基本的概念跟前面哪个BUILD.gn基本一样,最重要的一点就是,如果要依赖某库进行编译,直接把构建那个库的BUILD.gn文件deps进来即可。
这样,在构建darknetexample的过程中,就会把darknetndk构建,并且引用,编译我们可执行文件darknet,并不需要提前先编译好libdarknet,我们在总的BUILD.gn只需要deps我们这个example就行。
这下,咱们的交叉编译算是正式通过了,库和可执行文件的生成一步到位
[attach]980723[/attach]