sogou / srpc

RPC framework based on C++ Workflow. Supports SRPC, Baidu bRPC, Tencent tRPC, thrift protocols.
Apache License 2.0
1.95k stars 386 forks source link

Android compile problem #336

Closed ouclbc closed 1 year ago

ouclbc commented 1 year ago

when I config android cross compile,and build srpc, I met the following error workflow/_include/workflow/Communicator.h:28:10: fatal error: 'openssl/ssl.h' file not found since android ndk has no openssl,How can I config this? I try to do this:https://segmentfault.com/a/1190000004522943 but seems I build 64 bit so.

ouclbc commented 1 year ago

指定openssl include和so路径后,报错如下: /home/Android/srpc/workflow/src/manager/WFGlobal.cc:566:16: error: use of undeclared identifier 'getline'; did you mean 'std::getline'? while ((ret = getline(&line, &bufsize, fp)) > 0) ^~~ std::getline /home/Android/android-ndk-r21e/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/string:4244:1: note: 'std::getline' declared here getline(basic_istream<_CharT, _Traits>& __is, ^ /home/Android/srpc/workflow/src/manager/WFGlobal.cc:566:16: error: no matching function for call to 'getline' while ((ret = getline(&line, &bufsize, fp)) > 0) ^~~ /home/barton/Android/android-ndk-r21e/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/string:4244:1: note: candidate template ignored: could not match 'basic_istream<type-parameter-0-0, type-parameter-0-1>' against 'char **' getline(basic_istream<_CharT, _Traits>& __is, ^ 2 errors generated.

ouclbc commented 1 year ago

改成std::getline提示参数不匹配。只有2个参数,实际传了三个。

holmes1412 commented 1 year ago

我们看看先前能在Android上编译过的版本对比一下,看看是不是后来加的、是否需要替换掉这个函数。

ouclbc commented 1 year ago

thank you very much,想问一下你们之前在Android上面编译有文档么?

holmes1412 commented 1 year ago

https://github.com/sogou/workflow/issues/773 原先有一个人在Android上编译过Workflow,写了个很详细的总结,可以看看这个~ 另外确认了下commit log,当时已经是这样使用的getline了,但是他没有遇到这样的问题。你如果还没有解决,可以到这个issue下圈他问问。

ouclbc commented 1 year ago

目前workflow android可以编译通过,srpc还不行。 参考workflow的cmakelist修改了一下srpc/src/目录下的cmakelist。 if(ANDROID) include_directories(${OPENSSL_INCLUDE_DIR}) link_directories(${OPENSSL_LINK_DIR}) else() find_package(OpenSSL REQUIRED) endif () set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "") if (WIN32) find_package(Protobuf REQUIRED CONFIG) else () if(ANDROID) set(PROTOBUF_DIR /home/barton/Android/protobuf-3.14.0/cmake) include_directories(${PROTOBUF_DIR}) link_directories(${PROTOBUF_DIR}) else() find_package(Protobuf 3.5.0 REQUIRED) endif() endif () 但是还是有报错,应该是系统本身的protoc没有加入环境变量: CMake Error at src/module/CMakeLists.txt:13 (protobuf_generate_cpp): Unknown CMake command "protobuf_generate_cpp".

holmes1412 commented 1 year ago

感觉这个是OPENSSL_CRYPTO_LIBRARY缺少了,你尝试一下手动指定一下?比如

set(OPENSSL_CRYPTO_LIBRARY /path/to/openssl/lib/libcrypto.a)

一般来说通过OPENSSL_ROOT_DIR的路径应该就可以找到crypto了,所以在一般环境下,这个在CMakeCache.txt里可以找到这个变量。

不过这个crypto包workflow也需要,感觉crypto本身不应该有区别才是~

ouclbc commented 1 year ago

再请教一下protobuf_generate_cpp这个是调用本机的protoc的么,而非host的,目前我指定的protobuf dir是host主机的,不知道这块怎么设置

holmes1412 commented 1 year ago

protobuf_generate_cpp会由CMake 自动查找 protoc 工具的路径。CMake 会首先查找系统路径,如果找不到,则会查找 PROTOBUF_PROTOC_EXECUTABLE 变量指定的路径。如果 PROTOBUF_PROTOC_EXECUTABLE 变量未设置,则会使用默认路径 /usr/bin/protoc。

这个得看你find_package(protobuf)用的是哪个路径,需要libprotobuf.so和protoc版本对应。如果这里不确定,要不你手动指定一下set (PROTOBUF_PROTOC_EXECUTABLE /xxx/xxx/protoc) 让它们对应起来试试看?

ouclbc commented 1 year ago

https://blog.csdn.net/gcs_20210916/article/details/123919119这个链接有说明,不过目前试了效果还是提示package找不到,我再看看

ouclbc commented 1 year ago

手动指定,如下方式,还是提示unknown command protobuf_generate_cpp set (PROTOBUF_PROTOC_EXECUTABLE /home/barton/work/protobuf-3.14.0/src) protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_LIST}) 参考这个文章,https://blog.csdn.net/gcs_20210916/article/details/123919119 也不太行。 目前看就是找不到protoc的路径。

holmes1412 commented 1 year ago

试试set (PROTOBUF_PROTOC_EXECUTABLE /home/barton/work/protobuf-3.14.0/src/protoc) ?

ouclbc commented 1 year ago

set (PROTOBUF_PROTOC_EXECUTABLE /home/barton/work/protobuf-3.14.0/src/protoc)这个设置之后还是会提示unknown command protobuf_generate_cpp 参考这个https://blog.csdn.net/lnwaycool/article/details/102685354 可以编译过去一部分 SET(Protobuf_INCLUDE_DIR /home/barton/Android/protobuf-3.14.0/src) SET(Protobuf_LIBRARY /home/barton/Android/protobuf-3.14.0/cmake) include_directories(${Protobuf_INCLUDE_DIR}) link_directories(${Protobuf_LIBRARY}) 在module的cmakelists.txt里面添加 if(ANDROID) find_package(Protobuf REQUIRED) else() find_package(Protobuf 3.5.0 REQUIRED) endif() module编译正常,但是在message里面添加还是提示找不到protobuf /home/barton/Android/protobuf-3.14.0/src/google/protobuf/arena.h:658: error: undefined reference to 'google::protobuf::Arena 我android编译的proto在Android/protobuf-3.14.0/,本地编译的在work/protobuf-3.14.0/,感觉还是proto的配置有问题

holmes1412 commented 1 year ago

虽然不太了解Android下的依赖应该怎么写,但是看了下当时workflow支持Android的时候,cmake文件里都进行了如下改动:

参考文件:https://github.com/sogou/workflow/blob/master/src/CMakeLists.txt

1、编译时,依赖库通过交叉编译指定的路径:

if(ANDROID)
    include_directories(${OPENSSL_INCLUDE_DIR})
    link_directories(${OPENSSL_LINK_DIR})
else()
    find_package(OpenSSL REQUIRED)
endif ()

2、链接时,依赖库需要明确指定一下:

if(ANDROID)
    target_link_libraries(${SHARED_LIB_NAME} ssl crypto c)
else()
    target_link_libraries(${SHARED_LIB_NAME} OpenSSL::SSL OpenSSL::Crypto pthread)
endif ()

要不你试试把这里:https://github.com/sogou/srpc/blob/master/src/CMakeLists.txt#L154 模仿Workflow里的写法?比如(但不一定正确,需要你在环境里调一下)

if (APPLE)
    target_link_libraries(${SHARED_LIB_NAME} OpenSSL::SSL  OpenSSL::Crypto pthread protobuf workflow z ${SNAPPY_LIB} ${LZ4_LIB})
if (ANDROID) # 写法不一定正确,大概这么个想法?
    target_link_libraries(${SHARED_LIB_NAME} ssl crypto c protobuf workflow z snappy)
else ()
    target_link_libraries(${SHARED_LIB_NAME})
endif ()

如果确认了src/CMakeLists.txt和tutorial/CMakeLists.txt的正确改法,可以给srpc提一个PR,感谢~

ouclbc commented 1 year ago

修改的文件如下: srpc下面的gnumakefile: elseif(ANDROID) ANDROID_NDK_HOME :=ndk的绝对路径 ANDROID_ABI_ARCH :=arm64 ANDROID_ABI :=arm64-v8a ANDROID_API_LEVEL :=29 OPEN_SSL_DIR :=编译的openssl绝对路径 cd $(BUILD_DIR) && $(CMAKE3) -DANDROID_ABI=${ANDROID_ABI} -DANDROID_PLATFORM=android-${ANDROID_API_LEVEL} -DANDROID_NDK=${ANDROID_NDK_HOME} -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake -DOPENSSL_INCLUDE_DIR=${OPEN_SSL_DIR}/include -DOPENSSL_LINK_DIR=${OPEN_SSL_DIR} $(ROOT_DIR) workflow也是上面类似修改 2.srpc里面的cmakelist修改如下

set(CMAKE_CROSSCOMPILING TRUE)

if(ANDROID) include_directories(${OPENSSL_INCLUDE_DIR}) link_directories(${OPENSSL_LINK_DIR}) else() find_package(OpenSSL REQUIRED) endif ()

set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "") if (WIN32) find_package(Protobuf REQUIRED CONFIG) else () if(ANDROID) SET(Protobuf_INCLUDE_DIR /home/XX/Android/protobuf-3.14.0/src) SET(Protobuf_LIBRARY /home/XX/Android/protobuf-3.14.0/cmake) SET(Protobuf_LIB_DIR /home/XX/Android/protobuf-3.14.0/cmake) else() find_package(Protobuf 3.5.0 REQUIRED) endif() endif ()

elseif(ANDROID) target_link_libraries(${SHARED_LIB_NAME} ssl crypto protobuf workflow z) 另外srpc里面的message和module模块也需要修改 if(ANDROID) SET(Protobuf_INCLUDE_DIR /home/XX/Android/protobuf-3.14.0/src) SET(Protobuf_LIBRARY /home/XX/Android/protobuf-3.14.0/cmake) find_package(Protobuf REQUIRED) endif()

ouclbc commented 1 year ago

另外请教一下,编译出so后,在编译sample的时候出现如下错误: vendor/androidsrpcsample/include/srpc/rpc_message.h:30:7: error: 'srpc::RPCRequest' has virtual functions but non-virtual destructor [-Werror,-Wnon-virtual-dtor] class RPCRequest ^ vendor/androidsrpcsample/include/srpc/rpc_message.h:45:35: warning: unused parameter 'seqid' [-Wunused-parameter] virtual void set_seqid(long long seqid) {} ^ vendor/androidsrpcsample/include/srpc/rpc_message.h:48:7: error: 'srpc::RPCResponse' has virtual functions but non-virtual destructor [-Werror,-Wnon-virtual-dtor] class RPCResponse ^ vendor/androidsrpcsample/include/srpc/rpc_message.h:61:33: warning: unused parameter 'code' [-Wunused-parameter] virtual bool set_http_code(int code) { return false; } ^ vendor/androidsrpcsample/include/srpc/rpc_message.h:64:7: error: 'srpc::RPCMessage' has virtual functions but non-virtual destructor [-Werror,-Wnon-virtual-dtor] class RPCMessage 这个虚函数应该是在其他模块里面实现的。

holmes1412 commented 1 year ago
  1. 感谢你的建议!方便的话可以把你的修改提一个PR给我们,这样在你的环境上 run过的比较能保证正确性。 不过像ANDROID_XXX这种设置是否可以跟workflow那边的小伙伴那样单独放到一个脚本里呢?就是只对CMakeList做每个环境必要的、通用的修改,把其他系统的package信息提出到各个具体环境下独立使用。

  2. 这个确实应该把基类的虚析构加上的(其他环境下竟然没有报这个错误,可能和默认flag有关Q_Q)。我提个PR,review并merge了之后给你说,谢谢~

ouclbc commented 1 year ago

改动的东西比较零散,等我有空看看能不能整合成一个脚本

holmes1412 commented 1 year ago

好的,感谢,不急。 上面的编译错误已经改好merge了,麻烦拉一下代码再试试~

ouclbc commented 11 months ago

目前看srpc依赖的libcrypto和libssl以及libprotobuf和Android系统的有冲突,目前只能应用到apk里面。服务里面不可以。