一、 介绍
三方库指其他公司或者组织提供的服务或者模块,例如常见的开源 OpenCV 库,能持续繁荣 OpenAtom OpenHarmony(简称“OpenHarmony”)的生态建设。本文介绍如何在 RK3568 开发板上成功移植 OpenJPEG 开源库。OpenJPEG 是一个用 C 语言编写的开源 jpeg 2000 编解码器,可以对图片进行深度压缩和解压等。下面以 OpenJPEG 为例,总结移植三方库到 OpenHarmony 的经验。二、开发步骤
三方库主要是基于标准 Linux 系统的 c/c++ 开源库,所以三方库的移植工作,首先是在标准 Linux 系统搭建环境、编译与验证,然后将三方库的编译加入到 OpenHarmony 工程的构建中。
三方库移植的主要开发步骤如下:
1.在标准Linux系统下载三方库源码,搭建开发环境,编译整个源码工程;
2.分析在标准Linux系统的编译过程文件,提取编译需要的源文件、编译依赖等信息;
3.根据上一步分析结果,编写gn文件,将三方库加入到OpenHarmony的编译体系;
4.验证编译结果,在OpenHarmony的out目录是否生成目标库;
5.测试demo/测试单元用例执行。
注:标准系统编译构方法可参考 标准系统编译构建指导
https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/subsys-build-standard-large.md
三、开源库的下载与编译
下面以 OpenJPEG 开源库为例,详细的介绍开发流程。
1.搜索OpenJPEG开源库
本示例的代码库链接地址:https://github.com/uclouvain/openjpeg
2.下载代码
在 OpenHarmony/third_party 目录下,输入以下命令克隆 OpenJPEG 的源代码:
git clone git@github.com:uclouvain/openjpeg.git
然后切换到 openjpeg-2.1 分支:
git checkout -b openjp-2.1
3. 执行编译
代码仓库的 INSTALL.md 中详细介绍了使用 CMake 编译 OpenJPEG 库的步骤。本文参考该文档编译了 OpenJPEG 库。若在移植过程中对该库的编译选项有疑惑的地方,可参考该文档。INSTALL 文档中详细的介绍了编译步骤,如下图:
可以按以上信息,根据如下步骤编译 openjpeg 工程,具体如下:
在 openjpeg 的目录下,按以下步骤编译:
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
4. 编译过程
整个编译过程如下:
water@ubuntu:~/openjpeg/openjpeg/build$ make
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/thread.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/bio.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/cio.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/dwt.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/event.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/ht_dec.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/image.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/invert.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/j2k.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/jp2.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/mct.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/mqc.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/openjpeg.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/opj_clock.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/pi.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/t1.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/t2.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/tcd.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/tgt.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/function_list.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/opj_malloc.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2_static.dir/sparse_array.c.o ] Building C
[static library ../../../bin/libopenjp2.a ] Linking C
[ ] Built target openjp2_static
[object src/lib/openjp2/CMakeFiles/openjp2.dir/thread.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/bio.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/cio.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/dwt.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/event.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/ht_dec.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/image.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/invert.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/j2k.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/jp2.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/mct.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/mqc.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/openjpeg.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/opj_clock.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/pi.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/t1.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/t2.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/tcd.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/tgt.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/function_list.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/opj_malloc.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/sparse_array.c.o ] Building C
[ ] Linking C shared library ../../../bin/libopenjp2.so
[ ] Built target openjp2
[object src/bin/jp2/CMakeFiles/opj_dump.dir/opj_dump.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_dump.dir/convert.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_dump.dir/convertbmp.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_dump.dir/index.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_dump.dir/__/common/color.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_dump.dir/__/common/opj_getopt.c.o ] Building C
[ ] Linking C executable ../../../bin/opj_dump
[ ] Built target opj_dump
[object src/bin/jp2/CMakeFiles/opj_compress.dir/opj_compress.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_compress.dir/convert.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_compress.dir/convertbmp.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_compress.dir/index.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_compress.dir/__/common/color.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_compress.dir/__/common/opj_getopt.c.o ] Building C
[ ] Linking C executable ../../../bin/opj_compress
[ ] Built target opj_compress
[object src/bin/jp2/CMakeFiles/opj_decompress.dir/opj_decompress.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_decompress.dir/convert.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_decompress.dir/convertbmp.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_decompress.dir/index.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_decompress.dir/__/common/color.c.o ] Building C
[object src/bin/jp2/CMakeFiles/opj_decompress.dir/__/common/opj_getopt.c.o ] Building C
[ ] Linking C executable ../../../bin/opj_decompress
[ ] Built target opj_decompress
依据上述信息中生成 openjp2 库(libopenjp2.so)的过程可以知道编译库需要的 C 源文件,具体内如下所示:
[object src/lib/openjp2/CMakeFiles/openjp2.dir/thread.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/bio.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/cio.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/dwt.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/event.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/ht_dec.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/image.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/invert.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/j2k.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/jp2.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/mct.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/mqc.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/openjpeg.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/opj_clock.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/pi.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/t1.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/t2.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/tcd.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/tgt.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/function_list.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/opj_malloc.c.o ] Building C
[object src/lib/openjp2/CMakeFiles/openjp2.dir/sparse_array.c.o ] Building C
[ ] Linking C shared library ../../../bin/libopenjp2.so
[ ] Built target openjp2
有了以上信息我们可以在后续分析的编译文件中对比验证,编译库需要的源文件。
5. 查看结果
整个的 build 目录结构如下:
water@ubuntu:~/openjpeg/openjpeg/build$ tree -L 2
.
├── bin
│ ├── libopenjp2.a
│ ├── libopenjp2.so -> libopenjp2.so.7
│ ├── libopenjp2.so.2.5.0
│ ├── libopenjp2.so.7 -> libopenjp2.so.2.5.0
│ ├── opj_compress
│ ├── opj_decompress
│ └── opj_dump
├── CMakeCache.txt
├── CMakeFiles
│ ├── 3.16.3
│ ├── CheckIncludeFiles
│ ├── CheckTypeSize
│ ├── cmake.check_cache
│ ├── CMakeDirectoryInformation.cmake
│ ├── CMakeError.log
│ ├── CMakeOutput.log
│ ├── CMakeTmp
│ ├── Export
│ ├── Makefile2
│ ├── Makefile.cmake
│ ├── progress.marks
│ ├── TargetDirectories.txt
│ ├── TestEndianess.bin
│ └── TestLargeFiles.c
├── cmake_install.cmake
├── CPackConfig.cmake
├── CPackSourceConfig.cmake
├── CTestCustom.cmake
├── libopenjp2.pc
├── LICENSE.txt
├── Makefile
├── OpenJPEGConfig.cmake
├── src
│ ├── bin
│ └── lib
├── thirdparty
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ └── Makefile
└── wrapping
├── CMakeFiles
├── cmake_install.cmake
└── Makefile
四、 分析编译过程
1. 查看生成的库
首先在 openjpeg/build/bin 目录可以看出我们需要编译生成的目标文件,分别为 libopenjp2.a、libopenjp2.so.2.5.0、opj_compress、opj_decompress、opj_dump,还有一些链接符号,经过阅读代码发现 opj_compress、opj_decompress 和 opj_dump 为一些测试相关的文件,因此可以不加入到代码工程。
2. 分析生成过程
从 build 目录下的 Makefile 开始分析生成 libopenjp2.so 所依赖的 C 源文件、cflag 标志、需要包含的头文件和需要链接的库等信息。
在 openjpeg/build/Makefile 中,可以找到如下信息:
#=============================================================================
# Target rules for targets named openjp2
# Build rule for target.
openjp2: cmake_check_build_system
$(MAKE) -f CMakeFiles/Makefile2 openjp2
.PHONY : openjp2
# fast build rule for target.
openjp2/fast:
$(MAKE) -f src/lib/openjp2/CMakeFiles/openjp2.dir/build.make src/lib/openjp2/CMakeFiles/openjp2.dir/build
.PHONY : openjp2/fast
由上述信息可以发现生成 openjp2 目标是依赖 CMakeFiles/Makefile2 文件。
因此再分析 openjpeg/build/CMakeFiles/Makefile2 这个文件,具体内如下:
src/lib/openjp2/CMakeFiles/openjp2.dir/all:
$(MAKE) -f src/lib/openjp2/CMakeFiles/openjp2.dir/build.make src/lib/openjp2/CMakeFiles/openjp2.dir/depend
$(MAKE) -f src/lib/openjp2/CMakeFiles/openjp2.dir/build.make src/lib/openjp2/CMakeFiles/openjp2.dir/build
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --progress-dir=/home/water/openjpeg/openjpeg/build/CMakeFiles --progress-num=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 "Built target openjp2"
.PHONY : src/lib/openjp2/CMakeFiles/openjp2.dir/all
src/lib/openjp2/CMakeFiles/openjp2.dir/rule: cmake_check_build_system
$(CMAKE_COMMAND) -E cmake_progress_start /home/water/openjpeg/openjpeg/build/CMakeFiles 23
$(MAKE) -f CMakeFiles/Makefile2 src/lib/openjp2/CMakeFiles/openjp2.dir/all
$(CMAKE_COMMAND) -E cmake_progress_start /home/water/openjpeg/openjpeg/build/CMakeFiles 0
.PHONY : src/lib/openjp2/CMakeFiles/openjp2.dir/rule
openjp2: src/lib/openjp2/CMakeFiles/openjp2.dir/rule
.PHONY : openjp2
src/lib/openjp2/CMakeFiles/openjp2.dir/clean:
$(MAKE) -f src/lib/openjp2/CMakeFiles/openjp2.dir/build.make src/lib/openjp2/CMakeFiles/openjp2.dir/clean
.PHONY : src/lib/openjp2/CMakeFiles/openjp2.dir/clean
由以上内容可以发现最终是根据 src/lib/openjp2/CMakeFiles/openjp2.dir/build.make 来编译生成 openjp2 库。
因此需要再分析 openjpeg/build/src/lib/openjp2/CMakeFiles/openjp2.dir/build.mak。
build.make 文件节选:
//包含depend.make文件
include src/lib/openjp2/CMakeFiles/openjp2.dir/depend.make
//包含flags.make文件,C_FLAG相关信息
include src/lib/openjp2/CMakeFiles/openjp2.dir/flags.make
//依赖link.txt,链接相关信息
cd /home/water/openharmony/third_party/openjpeg/build/src/lib/openjp2 && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/openjp2.dir/link.txt --verbose=$(VERBOSE)
cd /home/water/openharmony/third_party/openjpeg/build/src/lib/openjp2 && $(CMAKE_COMMAND) -E cmake_symlink_library ../../../bin/libopenjp2.so.2.5.0 ../../../bin/libopenjp2.so.7 ../../../bin/libopenjp2.so
//编译依赖的C
openjp2_OBJECTS =
"CMakeFiles/openjp2.dir/thread.c.o"
"CMakeFiles/openjp2.dir/bio.c.o"
"CMakeFiles/openjp2.dir/cio.c.o"
"CMakeFiles/openjp2.dir/dwt.c.o"
"CMakeFiles/openjp2.dir/event.c.o"
"CMakeFiles/openjp2.dir/ht_dec.c.o"
"CMakeFiles/openjp2.dir/image.c.o"
"CMakeFiles/openjp2.dir/invert.c.o"
"CMakeFiles/openjp2.dir/j2k.c.o"
"CMakeFiles/openjp2.dir/jp2.c.o"
"CMakeFiles/openjp2.dir/mct.c.o"
"CMakeFiles/openjp2.dir/mqc.c.o"
"CMakeFiles/openjp2.dir/openjpeg.c.o"
"CMakeFiles/openjp2.dir/opj_clock.c.o"
"CMakeFiles/openjp2.dir/pi.c.o"
"CMakeFiles/openjp2.dir/t1.c.o"
"CMakeFiles/openjp2.dir/t2.c.o"
"CMakeFiles/openjp2.dir/tcd.c.o"
"CMakeFiles/openjp2.dir/tgt.c.o"
"CMakeFiles/openjp2.dir/function_list.c.o"
"CMakeFiles/openjp2.dir/opj_malloc.c.o"
"CMakeFiles/openjp2.dir/sparse_array.c.o"
通过分析 build.make 文件发现需要依赖 depend.make、flags.make 和 link.txt,由以上内容可以分析出如下信息:
下面看下 flags.make 和 link.txt 文件的具体内容。
link.txt 的内容如下:
/usr/bin/cc -fPIC -O3 -DNDEBUG -shared -Wl,-soname,libopenjp2.so.7 -o ../../../bin/libopenjp2.so.2.5.0 CMakeFiles/openjp2.dir/thread.c.o CMakeFiles/openjp2.dir/bio.c.o CMakeFiles/openjp2.dir/cio.c.o CMakeFiles/openjp2.dir/dwt.c.o CMakeFiles/openjp2.dir/event.c.o CMakeFiles/openjp2.dir/ht_dec.c.o CMakeFiles/openjp2.dir/image.c.o CMakeFiles/openjp2.dir/invert.c.o CMakeFiles/openjp2.dir/j2k.c.o CMakeFiles/openjp2.dir/jp2.c.o CMakeFiles/openjp2.dir/mct.c.o CMakeFiles/openjp2.dir/mqc.c.o CMakeFiles/openjp2.dir/openjpeg.c.o CMakeFiles/openjp2.dir/opj_clock.c.o CMakeFiles/openjp2.dir/pi.c.o CMakeFiles/openjp2.dir/t1.c.o CMakeFiles/openjp2.dir/t2.c.o CMakeFiles/openjp2.dir/tcd.c.o CMakeFiles/openjp2.dir/tgt.c.o CMakeFiles/openjp2.dir/function_list.c.o CMakeFiles/openjp2.dir/opj_malloc.c.o CMakeFiles/openjp2.dir/sparse_array.c.o -lm -lpthread
从以上内容可以发现需要链接 -lm、-lpthread 这两个库。
flags.make 中的内容如下:
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.16
# compile C with /usr/bin/cc
C_FLAGS = -fPIC -Wall -Wextra -Wconversion -Wunused-parameter -Wdeclaration-after-statement -Werror=declaration-after-statement
C_DEFINES = -DMUTEX_pthread -Dopenjp2_EXPORTS
C_INCLUDES = -I/home/water/openjpeg/openjpeg/build/src/lib/openjp2
从以上内容可以发现编译需要的 C_FLAGS 信息。
3.提取有效信息
从上述分析可以提取以下信息:
需要包含的源文件:
openjpeg/src/lib/openjp2/bio.c
openjpeg/src/lib/openjp2/cio.c
openjpeg/src/lib/openjp2/dwt.c
openjpeg/src/lib/openjp2/event.c
openjpeg/src/lib/openjp2/function_list.c
openjpeg/src/lib/openjp2/ht_dec.c
openjpeg/src/lib/openjp2/image.c
openjpeg/src/lib/openjp2/invert.c
openjpeg/src/lib/openjp2/j2k.c
openjpeg/src/lib/openjp2/jp2.c
openjpeg/src/lib/openjp2/mct.c
openjpeg/src/lib/openjp2/mqc.c
openjpeg/src/lib/openjp2/openjpeg.c
openjpeg/src/lib/openjp2/opj_clock.c
openjpeg/src/lib/openjp2/opj_malloc.c
openjpeg/src/lib/openjp2/pi.c
openjpeg/src/lib/openjp2/sparse_array.c
openjpeg/src/lib/openjp2/t1.c
openjpeg/src/lib/openjp2/t2.c
openjpeg/src/lib/openjp2/tcd.c
openjpeg/src/lib/openjp2/tgt.c
openjpeg/src/lib/openjp2/thread.c
需要包含的头文件:
src/lib/openjp2
需要链接的库:
-lm -lpthread
编译器需要添加的C_FLAGS标记:
C_FLAGS = -O3 -DNDEBUG -fPIC -ffast-math -Wall -Wextra -Wconversion -Wunused-parameter -Wdeclaration-after-statement -Werror=declaration-after-statement
从上述内容中我们可以获取到编译 libopenjp2.so 所需的源文件、头文件、链接库、C_FLAGS 等信息。接下来就可以根据这些信息在 OpenHarmony 的三方库文件夹下的 openjpeg 目录下编写 BUILD.gn 脚本,把 openjpeg 加入到 OpenHarmony 的编译体系中。
五、将三方库加入OpenHarmony的编译体系
接下来演示一下如何把 OpenJPEG 开源库通过 BUILD.gn 脚本添加到 OpenHarmony 工程中
表1:添加到工程后的目录结构
1.OpenHarmony/build/subsystem_config.json 中添加 subsystem 节点。
"openjpeg": {
"path": "third_party/openjpeg",
"name": "openjpeg"
}
2.OpenHarmony/productdefine/common/products/rk3568.json 文件里面加入如下内容,添加板级相关的信息:
{
"product_name": "rk3568",
"product_company": "hihope",
"product_device": "rk3568",
"version": "2.0",
"type": "standard",
"product_build_path": "device/hihope/build",
"parts":{
"openjpeg:openjpeg_lib":{} #新增openjpeg_lib
}
}
3.third_partyopenjpeg ests 下添加 ohos.build 文件,以便系统可以编译 tests 目录下的测试文件:
third_partyopenjpeg ests下添加ohos.build文件:
{
"subsystem": "openjpeg",
"parts": {
"openjpeg_lib": {
"module_list":[
"//third_party/openjpeg/tests:test_tile_decoder", #新增测试文件test_tile_decoder
"//third_party/openjpeg/tests:test_tile_encoder", #新增测试文件test_tile_encoder
...........
]
}
}
}
4.OpenHarmony//third_party/openjpeg/ 目录添加 BUILD.gn 文件,根据不同的系统生成静态或者动态库,如下:
if (defined(ohos_lite)) {
import("//build/lite/config/component/lite_component.gni")
} else {
import("//build/ohos.gni")
}
#编译CFLAG标记和需要链接的库
config("openjpeg_cflag_config") {
cflags = [
"-O3" ,
"-DNDEBUG",
"-fPIC",
"-ffast-math",
"-Wall",
"-Wextra",
"-Wconversion",
"-Wunused-parameter",
"-Wdeclaration-after-statement",
"-Werror=declaration-after-statement",
]
ldflags = [
"-lm",
"-lpthread",
]
}
#需要包含的头文件
config("openjpeg_config") {
include_dirs = [
"//third_party/openjpeg/src/lib/openjp2"
]
}
#需要包含的源文件
ohos_source_set("libopenjpeg_source") {
sources = [
"//third_party/openjpeg/src/lib/openjp2/thread.c",
"//third_party/openjpeg/src/lib/openjp2/bio.c",
"//third_party/openjpeg/src/lib/openjp2/cio.c",
"//third_party/openjpeg/src/lib/openjp2/dwt.c",
"//third_party/openjpeg/src/lib/openjp2/event.c",
"//third_party/openjpeg/src/lib/openjp2/ht_dec.c",
"//third_party/openjpeg/src/lib/openjp2/image.c",
"//third_party/openjpeg/src/lib/openjp2/invert.c",
"//third_party/openjpeg/src/lib/openjp2/j2k.c",
"//third_party/openjpeg/src/lib/openjp2/jp2.c",
"//third_party/openjpeg/src/lib/openjp2/mct.c",
"//third_party/openjpeg/src/lib/openjp2/mqc.c",
"//third_party/openjpeg/src/lib/openjp2/openjpeg.c",
"//third_party/openjpeg/src/lib/openjp2/opj_clock.c",
"//third_party/openjpeg/src/lib/openjp2/pi.c",
"//third_party/openjpeg/src/lib/openjp2/t1.c",
"//third_party/openjpeg/src/lib/openjp2/t2.c",
"//third_party/openjpeg/src/lib/openjp2/tcd.c",
"//third_party/openjpeg/src/lib/openjp2/tgt.c",
"//third_party/openjpeg/src/lib/openjp2/function_list.c",
"//third_party/linu/src/lib/openjp2/opj_malloc.c",
"//third_party/openjpeg/src/lib/openjp2/sparse_array.c",
]
}
#根据不同系统编译不同类型的库lite类型的设备可以编程静态库,也可编成动态库
if (defined(ohos_lite)) {
lite_library("libjpeg") {
if (ohos_kernel_type == "liteos_m") {
target_type = "static_library" #编译成静态库libopenjpeg.a
} else {
target_type = "shared_library" #编成动态库libopenjpeg.z.so
}
sources = libopenjpeg_source #依赖的源文件
public_configs = [ ":openjpeg_config" ] #依赖的头文件
configs = [ ":openjpeg_cflag_config" ] #依赖的CFLAGS配置信息
}
} else {
#标准系统编成动态库,libopenjpeg.z.so
ohos_shared_library("openjpeg") {
deps = [ ":libopenjpeg_source" ] #依赖的源文件
public_configs = [ ":openjpeg_config" ] #依赖的头文件配置信息
configs = [ ":openjpeg_cflag_config" ] #依赖的CFLAGS配置信息
part_name = "openjpeg_lib"
}
}
5.third_party/openjpeg/tests/ 目录添加 BUILD.gn 文件,编译测试文件,由于测试文件会依赖 OpenJPEG 库,根据依赖关系(如下图中的 deps)会链接到 thirdparty/openjpeg 下面的 BUILD.gn(即步骤 4 中的 BUILD.gn),最终此文件会编译生成 libopenjpeg 库。
third_party/openjpeg/tests/BUILD.gn 的内容如下:
以上几个文件的具体调用关系如下图所示:
通过 git status --ignored 命令可以查看我们修改什么内容,具体内如下:
通过以上操作以后,就可以在 OpenHarmony 编译源码了,编译命令如下:
./build.sh --product-name rk3568 --ccache
编译完成以后可以在 /out/rk3568/packages/phone/system/lib 目录下看到编译生成的 libopenjpeg.z.so 文件。
water@ubuntu:~/OpenHarmony/out/rk3568/packages/phone/system/lib$ ls -l libopenjpeg.z.so
-rwxr-xr-x 1 root root 286148 Mar 23 18:59 libopenjpeg.z.so
同时,还可以在 out/rk3568/packages/phone/system/bin 目录下看到我们编译的测试文件 test_tile_encoder,如下所示:
water@ubuntu:~/openharmony/out/rk3568/packages/phone/system/bin$ ls -l test_
test_decode_area test_tile_decoder test_tile_encoder
把编译完成的镜像文件烧录到 RK3568 开发板中,运行测试文件验证整个库的移植情况。
六、测试验证
在开源库的 tests 目录下有很多测试用例,在 test 目录下的 CMakeLists.txt 文件会生成一些测试文件来进行验证,其中会给出一些测试方法,具体如下:
代码工程编译完成后,将镜像文件烧录到 RK3568 开发板中,在开发板 /system/bin 文件夹下可以发现,有编译 tests 目录后生成的测试文件,如下所示:
# ls -l test_*
test_decode_area test_open_jpeg.sh test_tile_decoder test_tile_encoder
在 data 目录下创建 test 目录:
pwd
/data
test mkdir
把测试用例文件从 /bin 目录下拷贝到 data/test 目录下:
pwd
/data
cp /bin/test_* ./
添加可执行权限:
chmod +x test_tile_decoder
输入如下命令:
./test_tile_encoder 3 2000 2000 1000 1000 8 1 tte1.j2k 64 64 4 1 1 1 256 256
运行 test_tile_encoder,测试结果如下:
至此,整个 OpenJPEG 开源库在 OpenHarmony 上的移植就完毕,感兴趣的开发者可以动手移植自己的三方库了。
附录
开发过程中遇到的问题:
In file included from ../../third_party/openjpeg/src/lib/openjp2/thread.c:431:
../../third_party/openjpeg/src/lib/openjp2/opj_includes.h:40:10: fatal error: 'opj_config_private.h' file not found
#include "opj_config_private.h"
由于 opj_config_private.h 是由 cmake 生成的,因此需要在 Linux 下编译整个 OpenJPEG 源码,然后把生成的 opj_config_private.h 拷贝到相应的目录下:cp ./build/src/lib/openjp2/opj_config_private.h /src/lib/./build/src/bin/common/opj_apps_config.h/
cp ./build/src/lib/openjp2/opj_config.h /src/lib/openjp2/
cp ./build/src/bin/common/opj_apps_config.h ./src/bin/common/
遇到重定义问题,在 third_party/openjpeg/tests/pdf2jp2.c 文件中把这行定义注释掉:
../../third_party/openjpeg/tests/pdf2jp2.c:45:9: error: '_GNU_SOURCE' macro redefined [-Werror,-Wmacro-redefined]
RK3568 开发板相关的操作可以参考如下文档:
RK3568 开发板标准设备上手-HelloWorld
https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/docs/rk3568_helloworld
审核编辑 :李倩
全部0条评论
快来发表一下你的评论吧 !