草庐IT

[触觉智能RK3568]OpenHarmony NDK工具(上)

离北况归 2023-03-28 原文

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

在OpenHarmony应用开发中选择Native C ++开发方式需要使用OpenHarmony NDK工具,或者想移植一个C/C ++的三方库到OpenHarmony中也可以使用NDK。NDK使用到的编译工具是cmake,也就是CMakeLists.txt那一套。Native C ++应用开发方式可以做直接编译三方库的so库再利用NAPI框架实现能力的调用(只需要在三方库原生的CMakeLists.txt中修改小部分的内容就可以实现)。

一、OpenHarmony NDK

  • NDK (原生开发套件) 是一套工具,使开发者能够在 OpenHarmony hap应用中使用 C/C++ 代码。
  • NDK提供了一系列的工具可以帮助开发者快速的开发C/C++的动态库、静态库和可执行文件。
  • OpenHarmony 应用开发的​​Native C++​​​开发方式就要依赖NDK。NDK被包含在OpenHarmony SDK中。可以在​​DevEco Studio​​​使用 NDK 将 C/C ++ 代码编译到so库中,然后使用 DevEco Studio 的构建插件​​hvigor-ohos-plugin​​​将so库打包到 Hap 中。ArkTS代码随后可以通过​​NAPI框架​​调用SO库中的函数。

二、获取NDK的方式

1、从每日构建中获取

每日构建地址: http://ci.openharmony.cn/dailys/dailybuilds。

组件形态选择ohos-sdk,版本选择最新版本的sdk一般是没有问题的(但是笔者之前遇到下载的ndk中的clang工具找不到libatomic.so无法工作的情况的情况)。

下载解压后可以得到如下文件,根据linux或者windows端解压不同文件得到sdk。

2、编译源码得到SDK中的NDK

安装依赖
./build/build_scripts/env_setup.sh

执行完上述命令后记得执行source ~/.bashrc或者重启终端
source ~/.bashrc

安装编译SDK需要的依赖包(编译镜像的时候是不依赖这些包的)
sudo apt-get install libxcursor-dev libxrandr-dev libxinerama-dev

./build.sh --product-name ohos-sdk --ccache --build-target ohos_ndk
写文章提的issue https://gitee.com/openharmony/build/issues/I6H8IO?from=project-issue

  • 在对应的目录底下找到编译成功的NDK,相关路径out/sdk/packages/ohos-sdk/linux/native,根据linux或者windows端解压不同文件得到sdk

二、NDK目录

native
├── NOTICE.txt 声明文件
├── build
└── cmake
├── ohos.toolchain.cmake ---->编译的工具链
└── sdk_native_platforms.cmake ---->编译的工具链(在DevEco Studio中编译打包so要用到)
├── build-tools ---->cmake编译工具所在目录(NDK提供的编译工具)
├── llvm ---->编译器所在目录(NDK提供的编译工具)
├── sysroot ---->编译器的 sysroot 目录,存放 SDK 内部的已经包含的库和对应的头文件
├── ndk_system_capability.json ---->NDK自带so库能力描述文件
├── nativeapi_syscap_config.json ---->调用NDK自带so库能力相关头文件
├── docs ---->调用NDK自带so库能力相关文档
└── oh-uni-package.json ---->SDK 信息描述
  • llvm中bin目录下的编译器有。
FileCheck clang-format ld64.lld lldb-vscode llvm-cxxfilt llvm-objdump llvm-strip yaml2obj
clang clang-tidy lld llvm-addr2line llvm-dis llvm-profdata llvm-symbolizer
clang++ clangd lld-link llvm-ar llvm-lib llvm-ranlib not
clang-12 count lldb llvm-as llvm-link llvm-readelf sancov
clang-check dsymutil lldb-argdumper llvm-cfi-verify llvm-modextract llvm-readobj sanstats
clang-cl git-clang-format lldb-mi llvm-config llvm-nm llvm-size scan-build
clang-cpp ld.lld lldb-server llvm-cov llvm-objcopy llvm-strings scan-view

三、linux下使用NDK编译库文件和可执行文件

1、使用NDK编译一个简单demo

shared-library
├── CMakeLists.txt 外部CMakeLists.txt
├── include 头文件目录
└── shared
└── Hello.h
└── src 源文件目录
├── CMakeLists.txt 内部CMakeLists.txt
├── Hello.cpp
└── main.cpp
  • 外部CMakeLists.txt
#cmake的版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.16)
#工程名称
PROJECT(HELLO_LIBRARY)
#添加一个子目录并构建该子目录
ADD_SUBDIRECTORY(src)
cmake的内置命令是不区分大小写的,因此add_subdirectory与ADD_SUBDIRECTORY作用一致。但是cmake的所有变量都是区分大小写的

  • 内部CMakeLists.txt
#设置可执行文件输出路径
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/output)
# 设置so库文件输出路径
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/output)

############################################################
# Create a library
############################################################

#SHARED表示生成的是动态库,动态库的名字是hello_shared_library。生成动态库的源文件是Hello.cpp
ADD_LIBRARY(hello_shared_library SHARED
Hello.cpp
)
#为生成的动态库添加一个别名,后续hello::library可使用来替代hello_shared_library
ADD_LIBRARY(hello::library ALIAS hello_shared_library)

#为指定目标hello_shared_library添加头文件搜索路径(这个指定目标决不能是alias target,也就是指定的别名hello::library)
TARGET_INCLUDE_DIRECTORIES(hello_shared_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)

############################################################
# Create an executable
############################################################

# 使用指定的源文件main.cpp创建出一个可执行文件hello_shared_binary
ADD_EXECUTABLE(hello_shared_binary
main.cpp
)

#TARGET_LINK_LIBRARIES指令的作用为将目标文件与库文件进行链接
#将可执行文件hello_shared_binary与库文件hello::library进行链接
TARGET_LINK_LIBRARIES( hello_shared_binary
PRIVATE
hello::library
)

3、进行cmake编译

(1)NDK自带的cmake编译工具添加到环境变量

1、第一种方法:

#将其临时加入环境变量中(适用于临时想用用NDK)
export PATH=$PATH:/ohos-sdk/linux/native/build-tools/cmake/bin(你自己解压的NDK目录)
2、第二种方法:

#将其永远加入环境变量中
#打开.bashrc文件
vim ~/.bashrc
#在文件最后添加cmake路径,该路径是自己的放置文件的路径,之后保存退出
export PATH=/ohos-sdk/linux/native/build-tools/cmake/bin:$PATH
#在命令行执行source ~/.bashrc使环境变量生效
source ~/.bashrc
3、查看环境变量添加是否成功。

cmake -version

可知cmake的版本是3.16.5 ,所以编写CMakeLists.txt可参考的链接为 https://cmake.org/cmake/help/v3.16/guide/tutorial/

(2)安装make

如果没有安装make会出现以下报错,则执行sudo apt-get install make。(如果已经安装make,请忽略)。

(3)cmake的几个参数

1、OHOS_STL参数,其类型可以是c++_shared和c++_static,默认是c++_shared。

2、OHOS_ARCH参数(设置应用程序二进制接口ABI),其类型是armeabi-v7a、x86_64 ,默认值是arm64-v8a。每一种ABI定义了相应的二进制文件。

  • armeabi-v7a (选择这个是编译32位的二进制文件)。
  • arm64-v8a (选择这个是编译64位的二进制文件)。
  • x86_64 (现在不使用,OpenHarmony现在在适配x86的芯片)。
3、OHOS_PLATFORM参数,其类型为OHOS(只能选择OHOS平台)。

4、 CMAKE_TOOLCHAIN_FILE参数指向的是工具链文件所在的位置,就是ohos.toolchain.cmake的路径(对于编译不同平台二进制文件是很重要的)。

  • build目录中的工具链文件ohos.toolchain.cmake,cmake编译时需要读取该文件中的默认值,比如编译器的选择、编译平台,例如ohos.toolchain.cmake文件中,
# Common default settings
39:if(NOT DEFINED OHOS_PLATFORM_LEVEL)
set(OHOS_PLATFORM_LEVEL 1)
endif()
43:if(NOT DEFINED OHOS_TOOLCHAIN)
set(OHOS_TOOLCHAIN clang)
endif()
47:if(NOT DEFINED OHOS_STL)
set(OHOS_STL c++_shared)
endif()
51:if(NOT DEFINED OHOS_PIE)
set(OHOS_PIE TRUE)
endif()
55:if(NOT DEFINED OHOS_ARM_NEON)
set(OHOS_ARM_NEON thumb)
endif()
60:if(NOT DEFINED OHOS_ARCH)
set(OHOS_ARCH arm64-v8a)
endif()
  • 在编译时需要指出该文件的所在路径,以便于cmake在编译时定位到该文件。在编译的时候需要为cmake指定参数来控制编译目标的属性。

(4)使用CMake进行构建,并传递工具链文件及cmake参数

# dmeo目录下创建build目录,用来放置cmake构建时产生的中间文件。
mkdir build && cd build

# 传递OHOS_STL(可选,默认就是c++_shared)、OHOS_ARCH、OHOS_PLATFORM、工具链文件
# CMAKE_TOOLCHAIN_FILE是ohos.toolchain.cmake具体放置的路径
# 这一步会检查CMakeLists.txt是否有语法错误
# 不要忘记在ohos.toolchain.cmake路径后面加上 ..
cmake -D OHOS_STL=c++_shared -D OHOS_ARCH=armeabi-v7a -D OHOS_PLATFORM=OHOS -D CMAKE_TOOLCHAIN_FILE=/xxx/build/cmake/ohos.toolchain.cmake ..

cmake --build .
1、执行如下过程如下:

2、可以注意到执行cmake --build .时会有warning: -Wunused-command-line-argument,通过在内部的CMakeLists.txt中添加如下语句消除warning。

set(CMAKE_CXX_FLAGS "-Wno-unused-command-line-argument")

  • 注意:.c文件时是使用CMAKE_C_FLAGS,.cpp文件时是使用CMAKE_CXX_FLAGS。
3、编译结果如下:

生成可执行文件和动态库。

4、要编译静态库及其可执行文件,内部的CMakeLists.txt中添加如下语句

############################################################
# Create a library
############################################################

#Generate the static library from the library sources
ADD_LIBRARY(hello_static_library STATIC
Hello.cpp
)

TARGET_INCLUDE_DIRECTORIES(hello_static_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)

############################################################
# Create an executable
############################################################

# Add an executable with the above sources
ADD_EXECUTABLE(hello_static_binary
main.cpp
)

# link the new hello_library target with the hello_binary target
TARGET_LINK_LIBRARIES( hello_static_binary
PRIVATE
hello_static_library
)
编译结果如下,生成静态库及其可执行文件。

5、编译64位的库文件和可执行文件,OHOS_ARCH参数选择arm64-v8a或者编译时不传递该参数。

(5)使用CMake进行构建,选择ninja生成器并生成编译流程图

1、执行cmake -G查看linux环境下的生成器,ndk中自带的生成器是Ninja。

2、使用CMake进行构建时添加上-G “Ninja”。

第一步:mkdir build && cd build

第二步:cmake -G "Ninja" -D OHOS_STL=c++_shared -D OHOS_ARCH=armeabi-v7a -D OHOS_PLATFORM=OHOS -D CMAKE_TOOLCHAIN_FILE=/xxx/build/cmake/ohos.toolchain.cmake ..

第三步:cmake --build .或者ninja -f build.ninja
执行完第二步后,build目录下会生成build.ninja,有了build.ninja可以使用ninja生成程序的编译流程图。

3、使用ninja工具生成库文件和可执行文件的编译流程图。

# 将libhello_shared_library.so动态库的编译流程转为dot
ninja -t graph libhello_shared_library.so > xxx.dot

# 将dot格式转化为png格式的流程图
dot -T png xxx.dot -o libhello_shared_library.so.png
# 将dot格式转化为svg格式的流程图
dot -T svg xxx.dot -o libhello_shared_library.so.svg

如果生成图片格式太小的话,可以生成svg格式到浏览器打开,这一点很重要,请参考该 issue

(6)使用NDK中的cmake-gui进行图形化操作编译

1、native/build-tools/cmake/bin目录有cmake-gui,可以用它图形化传入编译参数进行编译。

2、首先点击Where is source code行的Browser Source,加载工程所在目录。再点击Where to build the binarys行的Browser Source,加载点击“Where is source code”行的Browser Source,加载源码所在目录。点击“Where to build the binarys行的Browser Source,加载工程所在目录下的build目录(没有就创建一个)。

3、点击Add Entry传入cmake 参数。勾选把旁边的Grouped选项。

4、点击Configure选择Current Generator生成器为Unix Makefiles。

5、最后打开Where to build the binarys加载构建目录终端,执行make -j 8命令。

make -j n含义是 让make最多允许n个编译命令同时执行,这样可以更有效的利用CPU资源。假设系统cpu是12核,在不影响其他工作的情况下,我们可以make -j 12将cpu资源充分利用起来,一般来说,最大并行任务数为cpu_num * 2。

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

有关[触觉智能RK3568]OpenHarmony NDK工具(上)的更多相关文章

  1. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  2. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  3. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  4. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  5. ruby - 使用 Ruby 开发工具包将文件上传到 Amazon S3 - 2

    我正在尝试上传文件。一个简单的hello.txt。我正在关注文档,但无法将其上传到我的存储桶。#STARTAWSCLIENTs3=Aws::S3::Resource.newbucket=s3.bucket(BUCKET_NAME)begins3.buckets[BUCKET_NAME].objects[KEY].write(:file=>FILE_NAME)puts"Uploadingfile#{FILE_NAME}tobucket#{BUCKET_NAME}."bucket.objects.eachdo|obj|puts"#{obj.key}=>#{obj.etag}"endresc

  6. ruby - 在 StockChart (highchart) 中以编程方式显示柱形图的工具提示 - 2

    我有一个Highstock图表(带有标记和阴影的线条),并且想以编程方式显示一个highstock工具提示,例如,当我选择某个表上的一行(包含图表数据)我想显示相应的highstock工具提示。这可能吗? 最佳答案 股票图表thissolution不起作用:在thisexample你必须更换这个:chart.tooltip.refresh(chart.series[0].data[i]);为此:chart.tooltip.refresh([chart.series[0].points[i]]);解决方案可用here.

  7. 玩以太坊链上项目的必备技能(初识智能合约语言-Solidity之旅一) - 2

    前面一篇关于智能合约翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用程序语言去编写智能合约了。而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂智能合约代码,或找出其中的漏洞,那么,学习Solidity这门高级的智能合约语言是有必要的,当然,这都得在公链``````以太坊上,毕竟国内的联盟链有些是不兼容Solidity。Solidity是一种面向对象的高级语言,用于实现智能合约。智能合约是管理以太坊状态下的账户行为的程序。Solidity是运行在以太坊(Ethereum)虚拟机(EVM)上,其语法受到了c++、python、javascript影响。Solidity是静态类型

  8. ABB-IRB-1200运动学分析MATLAB RVC工具分析+Simulink-Adams联合仿真 - 2

    一、机器人介绍        此处是基于MATLABRVC工具箱,对ABB-IRB-1200型号的微型机械臂进行正逆向运动学分析,并利Simulink工具实现对机械臂进行具有动力学参数的末端轨迹规划仿真,最后根据机械模型设计Simulink-Adams联合仿真。 图1.ABBIRB 1200尺寸参数示意图ABBIRB 1200提供的两种型号广泛适用于各作业,且两者间零部件通用,两种型号的工作范围分别为700 mm 和 900 mm,大有效负载分别为 7 kg 和5 kg。 IRB 1200 能够在狭小空间内能发挥其工作范围与性能优势,具有全新的设计、小型化的体积、高效的性能、易于集成、便捷的接

  9. 智能客服 | 浅谈人工智能聊天机器人ChatGPT - 2

    2022年底,OpenAI的预训练模型ChatGPT给人工智能领域的爱好者和研究人员留下了深刻的印象和启发,他展现的惊人能力将人工智能的研究和应用热度推向高潮,网上也充斥着和ChatGPT的各种聊天,他可以作诗、写小说、写代码、讨论疫情问题等。下面就是一些他的神回复:人命关天的坑: 写歌,留给词作者的机会不多了。。。 回答人类怎么样面对人工智能: 什么是ChatGPT?借用网上的一段介绍,ChatGPT是由人工智能研究实验室OpenAI在2022年11月30日发布的全新聊天机器人模型,一款人工智能技术驱动的自然语言处理工具。它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动

  10. Ruby & Syslog & 自定义工具 - 2

    我是syslog的新手。我们决定使用系统日志来跟踪Rails应用程序中的一些特殊事件。问题是我不想使用默认的/var/log/system.log文件,而是使用自定义文件,例如/var/log/myapp_events.log.我看到我必须像这样在/etc/syslog.conf中定义我自己的设施:myapp_events.*/var/log/myapp_events.log重新启动syslogd后,我发现我可以直接在bash控制台中使用它:syslog-s-kFacilitymyapp_eventsMessage"thisismymessage"该消息按预期出现在/var/log/m

随机推荐