使用安卓NDK编译VSOMEIP3流程

引子

最近些年车机研发相当火热,而车内通信大多都绕不开vsomeip,这个框架官方对Linux、QNX等系统支持的比较好,但是如果想用NDK去交叉编译它就会踩很多坑,这里就分享一下本人用NDK编译vsomeip3.3.8时的流程,其他版本的vsomeip应该也是大同小异,欢迎有能力的大佬改良我的操作~

环境准备

作者用的是Ubuntu的容器,在docker内首先要下载要用的包:

apt-get update &&
apt-get install zip git curl &&
apt-get install gcc g++ vim less file python3 python3-pip &&
pip3 install --break-system-packages cpplint &&
apt-get install graphviz doxygen asciidoc source-highlight

当然还要下载vsomeip和ndk,安卓交叉编译用到的Boost库以及cmake:

https://github.com/android/ndk/wiki/Unsupported-Downloads
https://github.com/moritz-wundke/Boost-for-Android.git
https://github.com/COVESA/vsomeip
https://github.com/Kitware/CMake/releases/tag/v3.22.1

这里需要注意:要根据Boost for Android库中Readme里Boost版本对NDK的支持性选择下载
eg:作者选择了NDK r25c版本和VSOMEIP3.3.8
再设置几个后面要用到的环境变量:

export ANDROID_NDK=/path/to/your/ndk/root
export CMAKEPATH=/path/to/cmake/bin

这里ndk路径要指向NDK解压后的根目录,eg:~/ndk/ndk-r25c
cmake路径指向其内部的bin目录,eg:~/cmake/cmake-3.22.1/bin
下一步就是根据ndk版本下对应的boost库,这里直接进之前下载的Boost-for-Android自动搞:

cd Boost-for-Android && ./build-android.sh $ANDROID_NDK --boost=1.76.0

这里作者选择了Boost 1.76.0版本,其实1.76.0以上的boost版本都支持了r25c。

魔改vsomeip3

由于vsomeip对安卓的支持性并不好,所以在编译前要自己手动魔改一下:

  1. 现在的安卓ndk已经没有utils/Log.h了 我们去find一下可以发现只有android/log.h,因此我们要修改vsomeip-3.3.8/implementation/logger/src/message.cpp:
#include<android/log.h>  //update from <utils/Log.h>
//update five long **ALOG** define lines to:
#define ALOGE(LOG_TAG, ...) (__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__))
#define ALOGW(LOG_TAG, ...) (__android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__))
#define ALOGI(LOG_TAG, ...) (__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__))
#define ALOGD(LOG_TAG, ...) (__android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__))
#define ALOGV(LOG_TAG, ...) (__android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__))

以及vsomeip-3.3.8/implementation/tracing/src/connector_impl.cpp:

#include<android/log.h>  //update from <utils/Log.h>
//update that long **ALOG** define lines to:
#define ALOGI(LOG_TAG, ...) (__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__))

还有vsomeip-3.3.8/implementation/utility/include/utility.hpp这里可能会在编译时抛出VSOMEIP_BASE_PATH未定义的问题,我们可以在vsomeip的CMakeLists里面加上

target_comepile_definitions(vsomeip3 PRIVATE -DVSOMEIP_BASE_PATH=\"/path/you/want/run/someip\")
  1. 我们继续在CMakeLists里面给安卓交叉编译做一些支持:
    首先找到这一行,我们需要针对安卓做一些针对性的初始化内容而且不要影响到其他OS的:
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")

这一行的上下加完如下:

/* add */ set(OS_LIBS ${SystemD_LIBRARIES})
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
/* add */
if (${CMAKE_SYSTEM_NAME} MATCHES "Android")
    set(OS "ANDROID")
    set(DL_LIBRARY "")
    set(EXPORTSYMBOLS "")
    set(NO_DEPRECATED "")
    set(OPTIMIZE "")
    set(OS_CXX_FLAGS "-DWITHOUT_SYSTEMD")

    find_library(ANDROID_LOG_LIB log)
    set(OS_LIBS ${ANDROID_LOG_LIB})
endif(${CMAKE_SYSTEM_NAME} MATCHES "Android")

同理在我们增加内容的后面几行在OS为FreeBSD的配置里也这么加上:

/* add */ set(OS_LIBS ${ANDROID_LOG_LIB})
endif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")

再继续往下找到文档中 # Directories 块,找到if(MSVC)这一句,修改它的else模块为安卓提供支持:

else()
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OS_CXX_FLAGS} -g ${OPTIMIZE} -std=c++14 ${NO_DEPRECATED} ${EXPORTSYMBOLS}")
    if (${CMAKE_SYSTEM_NAME} MATCHES "Android")
        set(USE_RT "")
    else()
        set(USE_RT "rt")
    endif()
endif()

这里我们将安卓单独拎出来,安卓编译并不依赖librt,ndk也没有它,如果加上它会在LINKING时报错
最后,我们要将我们前面替换的这一句**set(OS_LIBS ${SystemD_LIBRARIES})**为每个编出来的so都进行修改:
具体操作为在CMakeLists中找到# Configuration library , # Base library , # Service Discovery library
, # E2E library , # Compatibility library 这五个部分,找到target_link_libraries这一句,将target_link_libraries(… ${SystemD_LIBRARIES}) 改为 target_link_libraries(… ${OS_LIBS})
3. 现在我们要到Boost库里面去,作者这里用aarch64架构,因此操作流程如下:

cd ~/Boost-for-Android/build/out/arm64-v8a/lib
mv libboost_filesystem-clang-mt-a64-1_76.a libboost_filesystem.a
mv libboost_system-clang-mt-a64-1_76.a libboost_system.a
mv libboost_thread-clang-mt-a64-1_76.a libboost_thread.a

这里改名的原因是cmake对这个库的支持并不好,这样的后缀名它找不到,会在编译时报错。同理的,如果后面你自己的程序需要用到其他库文件,也要都改名。

编译vsomeip3

现在进入vsomeip根目录,然后:

mkdir build && cd build
$CMAKEPATH/cmake .. -DBoost_INCLUDE_DIR=${HOME}/Boost-for-Android/build/out/arm64-v8a/include/boost-1_76 \
 -DBoost_LIBRARY_DIR=${HOME}/Boost-for-Android/build/out/arm64-v8a/lib \
 -DCMAKE_SYSTEM_NAME=Android \
 -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
 -DANDROID_ABI="arm64-v8a" \
 -DANDROID_NDK=$ANDROID_NDK \
 -DANDROID_NATIVE_API_LEVEL=33 \
 -DANDROID_PLATFORM=android-33 \
 -DANDROID_STL=c++_shared \
 -DCMAKE_BUILD_TYPE=${BUILDTYPE} \
 -DBOOST_ROOT=${HOME}/Boost-for-Android/build/out/arm64-v8a \
 -DCMAKE_VERBOSE_MAKEFILE=ON
make -j4
make install

到这里你就应该能够成功编译出vsomeip3了,如果有任何问题可以留言给作者,或者如果有大佬有更好的操作也可以一起讨论~

参考资料

https://www.cnblogs.com/BruceWayne09/p/16716973.html
https://github.com/nkh-lab/vsomeip/blob/ndk/CMakeLists.txt

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值