冰羚源码编译及通信示例

以 Linux 为例

1 源码编译

以下编译过程为网上搜索结果,也可参考代码仓中 installation.md 文档

1.1. 安装基本依赖

sudo apt install gcc g++ cmake libacl1-dev libncurses5-dev pkg-config

1.2 下载源码

git clone https://github.com/eclipse-iceoryx/iceoryx.git

1.3 cmake版本

要求 cmake 版本不低于 3.16 ,可参照以下博客更新
https://blog.youkuaiyun.com/qq_26226375/article/details/130265617
ps:从 github 拉取 cmake 仓库可能会出现链接不到 github 的情况,如果确认 ssh 等配置OK的情况下,可能是网络问题,重复多试几次后成功(GitHub就这尿性,没有翻墙的情况下全凭运气)

1.4 利用脚本编译

#方式1:编译必要组件
cd iceoryx
cmake -Bbuild -Hiceoryx_meta
cmake --build build
sudo cmake --build build --target install
# 方式2:编译全部组件
cd iceoryx
./tools/iceoryx_build_test.sh build-all

ps1:方式2编译全部组件时若出现文件打开权限问题,请在命令前加上 sudo
ps2:在执行 “cmake -Bbuild -Hiceoryx_meta” 命令时,会自动下载 cpptoml ,可能会链接 github 不成功导致编译失败,多试几次即可

2 通信示例

冰羚代码仓中有具体 examples 可供用户使用:/iceoryx/iceoryx_examples/

2.1 创建Topic

Publisher 和 Subscriber 之间通过 Topic 进行匹配
topic_data.hpp

#ifndef IOX_EXAMPLES_ICEHELLO_TOPIC_DATA_HPP
#define IOX_EXAMPLES_ICEHELLO_TOPIC_DATA_HPP

//! [radar object]
struct RadarObject
{
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;
};
//! [radar object]

#endif // IOX_EXAMPLES_ICEHELLO_TOPIC_DATA_HPP

2.2 创建Publisher

消息发送端:
● 定义 APP_NAME,通过 APP_NAME 初始化 runtime 用于和RouDi进行通信
● 创建 publisher,并绑定 Topic
● 通过 publisher 的 loan 和 数据的 publish() 发送消息
● std::this_thread::sleep_for 设置发送间隔

Radar:服务名称
FrontLeft:代表 Radar 服务的实例的名称
Counter:定义了 FrontLeft 服务实例上的一个事件

//! [include topic]
#include "topic_data.hpp"
//! [include topic]

//! [include sig watcher]
#include "iceoryx_dust/posix_wrapper/signal_watcher.hpp"
//! [include sig watcher]

//! [include]
#include "iceoryx_posh/popo/publisher.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"
//! [include]

#include <iostream>

int main()
{
    //! [initialize runtime]
    constexpr char APP_NAME[] = "iox-cpp-publisher-helloworld";
    iox::runtime::PoshRuntime::initRuntime(APP_NAME);
    //! [initialize runtime]

    //! [create publisher]
    iox::popo::Publisher<RadarObject> publisher({"Radar", "FrontLeft", "Object"});
    //! [create publisher]

    double ct = 0.0;
    //! [wait for term]
    while (!iox::posix::hasTerminationRequested())
    //! [wait for term]
    {
        ++ct;

        // Retrieve a sample from shared memory
        //! [loan]
        auto loanResult = publisher.loan();
        //! [loan]
        //! [publish]
        if (loanResult.has_value())
        {
            auto& sample = loanResult.value();
            // Sample can be held until ready to publish
            sample->x = ct;
            sample->y = ct;
            sample->z = ct;
            sample.publish();
        }
        //! [publish]
        //! [error]
        else
        {
            auto error = loanResult.error();
            // Do something with error
            std::cerr << "Unable to loan sample, error code: " << error << std::endl;
        }
        //! [error]

        //! [msg]
        std::cout << APP_NAME << " sent value: " << ct << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
        //! [msg]
    }

    return 0;
}

2.3 创建Subscriber

消息接收端:
● 定义 APP_NAME,通过 APP_NAME 初始化 runtime
● 创建 subscriber,并绑定 Topic (要与 publisher 的保持一致)
● 通过 subscriber 的 take 接收消息
● std::this_thread::sleep_for 设置接收间隔

//! [include]
#include "topic_data.hpp"

#include "iceoryx_dust/posix_wrapper/signal_watcher.hpp"
#include "iceoryx_posh/popo/subscriber.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"
//! [include]

#include <iostream>

int main()
{
    //! [initialize runtime]
    constexpr char APP_NAME[] = "iox-cpp-subscriber-helloworld";
    iox::runtime::PoshRuntime::initRuntime(APP_NAME);
    //! [initialize runtime]

    //! [initialize subscriber]
    iox::popo::Subscriber<RadarObject> subscriber({"Radar", "FrontLeft", "Object"});
    //! [initialize subscriber]

    // run until interrupted by Ctrl-C
    while (!iox::posix::hasTerminationRequested())
    {
        //! [receive]
        auto takeResult = subscriber.take();
        if (takeResult.has_value())
        {
            std::cout << APP_NAME << " got value: " << takeResult.value()->x << std::endl;
        }
        //! [receive]
        else
        {
            //! [error]
            if (takeResult.error() == iox::popo::ChunkReceiveResult::NO_CHUNK_AVAILABLE)
            {
                std::cout << "No chunk available." << std::endl;
            }
            else
            {
                std::cout << "Error receiving chunk." << std::endl;
            }
            //! [error]
        }

        //! [wait]
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        //! [wait]
    }

    return (EXIT_SUCCESS);
}

2.4 调试运行

代码编译后在build目录下会生成对应应用的 publisher 和 subscriber 的 bin 文件
运行iceoryx程序前,一定要先启动守护进程 iox-roudi

2.4.1 运行步骤:

● 在终端运行:iox-roudi
● 另起终端运行 publisher
● 再起一个终端运行 subscriber

2.4.2 运行结果:

以代码仓中的 icehello 为例
启动 roudi:
在这里插入图片描述
publisher:
在这里插入图片描述

subscriber:
在这里插入图片描述

<think>我们正在为iceoryx库创建Android.bp文件,以便在AOSP中编译iceoryx是一个用C++编写的进程间通信(IPC)中间件,它由多个模块组成,包括核心的posh(平台操作系统抽象层)和utils(工具库)。根据其CMakeLists.txt,我们需要将CMake配置转换为Android.bp。 步骤: 1. 分析iceoryx的模块结构:通常包括iceoryx_utils(基础工具库)和iceoryx_posh(平台抽象和通信核心)。 2. 确定每个模块的源文件、头文件路径、编译标志和依赖。 3. 在AOSP中,我们通常使用`cc_library_static`或`cc_library_shared`来定义库模块。 注意:在AOSP中,我们通常将库编译为静态库,然后链接到共享库或可执行文件。但iceoryx也可以编译为共享库。 根据iceoryx的CMakeLists.txt(以最新版本为例): - iceoryx_utils:包含一些基础工具,如并发数据结构、错误处理等。 - iceoryx_posh:依赖于iceoryx_utils,提供进程间通信的核心功能。 此外,iceoryx还有一些可选模块和示例,但这里我们只关注核心库。 我们需要为iceoryx_utils和iceoryx_posh分别创建模块。 假设iceoryx源码位于AOSP的external/iceoryx目录下。 以下是一个可能的Android.bp文件示例: ```bp // 定义iceoryx_utils静态库 cc_library_static { name: "libiceoryx_utils", srcs: [ "iceoryx_utils/source/*.cpp", "iceoryx_utils/source/concurrent/*.cpp", "iceoryx_utils/source/cxx/*.cpp", "iceoryx_utils/source/error-handling/*.cpp", "iceoryx_utils/source/posix_wrapper/*.cpp", ], // 头文件路径:这些头文件将被导出,以便其他模块使用 export_include_dirs: [ "iceoryx_utils/include", ], local_include_dirs: [ "iceoryx_utils/include", ], cflags: [ "-Wall", "-Wextra", "-Wstrict-aliasing", "-Wconversion", "-Wsign-conversion", "-Werror", "-D_GNU_SOURCE", "-D__STDC_FORMAT_MACROS", "-D__STDC_LIMIT_MACROS", "-D__STDC_CONSTANT_MACROS", "-DICEORYX_PLATFORM_ANDROID", // 标识Android平台 "-fexceptions", // 启用异常 "-frtti", // 启用RTTI ], // 在AOSP中,我们可能需要链接一些系统库 shared_libs: [ "liblog", ], stl: "c++_shared", // 使用共享的C++运行时 // 注意:在AOSP中,我们通常使用c++_shared,但也可以根据需求使用c++_static // 如果需要支持多个ABI,可以指定 compile_multilib: "both", // 目标架构特定设置 target: { android: { cflags: [ "-DIOX_USE_POSIX_PLATFORM", // 使用POSIX平台 ], }, }, } // 定义iceoryx_posh静态库,它依赖于libiceoryx_utils cc_library_static { name: "libiceoryx_posh", srcs: [ "iceoryx_posh/source/*.cpp", "iceoryx_posh/source/iceoryx_posh/*.cpp", "iceoryx_posh/source/mepoo/*.cpp", "iceoryx_posh/source/roudi/*.cpp", "iceoryx_posh/source/runtime/*.cpp", // 根据实际目录结构添加 ], export_include_dirs: [ "iceoryx_posh/include", ], local_include_dirs: [ "iceoryx_posh/include", ], static_libs: [ "libiceoryx_utils", ], shared_libs: [ "liblog", ], cflags: [ "-Wall", "-Wextra", "-Wstrict-aliasing", "-Wconversion", "-Wsign-conversion", "-Werror", "-D_GNU_SOURCE", "-D__STDC_FORMAT_MACROS", "-D__STDC_LIMIT_MACROS", "-D__STDC_CONSTANT_MACROS", "-DICEORYX_PLATFORM_ANDROID", "-fexceptions", "-frtti", ], stl: "c++_shared", compile_multilib: "both", target: { android: { cflags: [ "-DIOX_USE_POSIX_PLATFORM", ], }, }, } // 如果需要,可以定义一个共享库版本,将两个库合并 // 注意:在AOSP中,通常将静态库链接到其他模块,但也可以创建共享库 cc_library_shared { name: "libiceoryx", static_libs: [ "libiceoryx_utils", "libiceoryx_posh", ], shared_libs: [ "liblog", ], stl: "c++_shared", compile_multilib: "both", // 导出头文件路径,这样其他模块可以包含iceoryx的头文件 // 注意:这里需要导出两个库的头文件路径 // 但是,Android.bp不支持直接导出多个路径,因此我们可以创建一个包含路径的变量,或者分别导出 // 但是,由于我们有两个模块,我们可以在各自的模块中导出,然后这里不需要再导出,因为通过静态库的传递性,头文件路径已经包含 // 但是,如果其他模块需要包含iceoryx的头文件,我们需要在这里再次导出 // 或者,更简单的方式是:让使用iceoryx的模块分别依赖这两个静态库,并包含它们的头文件路径 // 因此,这个共享库模块可能不需要导出头文件,除非我们想要一个统一的包含路径 // 我们可以这样导出: export_include_dirs: [ "iceoryx_utils/include", "iceoryx_posh/include", ], // 或者,如果我们不创建这个共享库,那么其他模块可以分别依赖两个静态库 } ``` 注意: 1. 上面的路径可能需要根据iceoryx的实际源码结构进行调整。例如,如果源码目录结构不同,需要修改srcs和include_dirs。 2. 在iceoryx的CMakeLists.txt中,有一些平台特定的代码,我们通过定义`-DICEORYX_PLATFORM_ANDROID`和`-DIOX_USE_POSIX_PLATFORM`来启用Android平台和POSIX接口。 3. 我们启用了异常和RTTI,因为iceoryx可能使用了这些特性。如果不需要,可以去掉`-fexceptions`和`-frtti`,但可能导致编译失败。 4. 我们使用了`cc_library_static`来构建静态库,然后通过`cc_library_shared`将它们合并成一个共享库。也可以不创建共享库,而让其他模块直接链接这两个静态库。 另一种做法是只构建静态库,然后在需要使用iceoryx的模块中链接这两个静态库。 在AOSP中集成步骤: 1. 将iceoryx源码放到external/iceoryx目录下。 2. 在external/iceoryx目录下创建Android.bp文件,内容如上(调整路径)。 3. 在需要链接iceoryx的模块的Android.bp中,添加: static_libs: ["libiceoryx_utils", "libiceoryx_posh"] 或者 shared_libs: ["libiceoryx"] # 如果定义了共享库 4. 编译整个系统或单独编译这些模块。 注意:由于iceoryx可能依赖C++14或更高版本,我们需要确保在AOSP中使用的NDK版本支持。在AOSP中,默认使用最新的C++标准,但我们可以通过`cppflags: ["-std=c++14"]`来指定。不过,在最新的AOSP中,默认可能已经是C++17或更高,所以如果不指定,可能需要确认是否满足要求。 如果遇到标准库问题,可以尝试添加: cppflags: ["-std=c++17"], 另外,iceoryx可能使用了一些C++17特性,因此需要确认AOSP的NDK支持。 最后,由于iceoryx是为实时系统设计的,可能需要一些特定的内核配置(如共享内存支持),在Android设备上通常已经满足。 以上是一个基本的Android.bp配置,实际使用中可能需要根据具体版本和需求进行调整。</think>### 使用 AOSP 编译 iceoryx 开源库的完整指南 #### 一、准备工作 1. **获取 iceoryx 源码**: ```bash git clone https://github.com/eclipse-iceoryx/iceoryx.git ``` 2. **准备 AOSP 环境**: ```bash # 创建 AOSP 工作目录 mkdir aosp && cd aosp repo init -u https://android.googlesource.com/platform/manifest -b master repo sync -j8 # 同步源码[^2] ``` 3. **集成 iceoryx 到 AOSP**: ```bash # 将 iceoryx 放入 external 目录 mv path/to/iceoryx external/ ``` #### 二、创建 Android.bp 文件 在 `external/iceoryx/` 目录下创建 `Android.bp`: ```bp // 基础工具库 cc_library_static { name: "libiceoryx_utils", srcs: [ "iceoryx_utils/source/*.cpp", "iceoryx_utils/source/**/*.cpp", ], export_include_dirs: ["iceoryx_utils/include"], cflags: [ "-DICEORYX_PLATFORM_ANDROID", "-D_GNU_SOURCE", "-fexceptions", "-Wall", "-Wextra", ], shared_libs: ["liblog"], stl: "c++_shared", compile_multilib: "both", } // 核心通信库 cc_library_shared { name: "libiceoryx_posh", srcs: [ "iceoryx_posh/source/*.cpp", "iceoryx_posh/source/**/*.cpp", ], static_libs: ["libiceoryx_utils"], export_include_dirs: ["iceoryx_posh/include"], cflags: [ "-DICEORYX_PLATFORM_ANDROID", "-D_GNU_SOURCE", "-DIOX_USE_POSIX_PLATFORM", "-fexceptions", ], shared_libs: [ "liblog", "libcutils", ], stl: "c++_shared", compile_multilib: "both", target: { android_arm: { cflags: ["-mfloat-abi=softfp"], }, android_arm64: { cflags: ["-D__aarch64__"], }, }, } // 可选:测试模块 cc_test { name: "iceoryx_test", srcs: ["test/**/*.cpp"], static_libs: [ "libiceoryx_utils", "libiceoryx_posh", ], shared_libs: ["liblog"], cflags: ["-DICEORYX_ENABLE_TEST"], gtest: false, } ``` #### 三、关键配置说明 1. **平台标识**: ```bp cflags: ["-DICEORYX_PLATFORM_ANDROID"] ``` 确保 iceoryx 启用 Android 专用代码路径[^3] 2. **POSIX 兼容层**: ```bp cflags: ["-DIOX_USE_POSIX_PLATFORM"] ``` 启用 POSIX API 适配(Android 基于 POSIX) 3. **多架构支持**: ```bp compile_multilib: "both", target: { android_arm: { ... }, android_arm64: { ... } } ``` 同时支持 32/64 位架构 #### 四、编译验证 1. **编译单个模块**: ```bash # 在 AOSP 根目录执行 source build/envsetup.sh lunch aosp_arm64-eng # 选择目标设备 make libiceoryx_posh -j8 ``` 2. **验证输出**: ```bash ls out/target/product/generic_arm64/system/lib/libiceoryx_posh.so ``` 3. **集成到系统镜像**: 在 `device.mk` 中添加: ```makefile PRODUCT_PACKAGES += \ libiceoryx_posh \ libiceoryx_utils ``` #### 五、常见问题解决 1. **头文件找不到**: - 检查 `export_include_dirs` 路径是否正确 - 确保路径大小写匹配(Linux 区分大小写) 2. **链接错误**: ```bash # 查看符号依赖 nm -gC out/.../libiceoryx_posh.so | grep missing_symbol ``` 在对应模块的 `shared_libs` 中添加缺失的库 3. **ABI 不兼容**: ```bp target: { android_arm: { cflags: ["-mfloat-abi=softfp"] } } ``` 显式指定 ARM 浮点 ABI > **提示**:使用 `mmma external/iceoryx` 命令可快速重新编译该模块[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值