Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android compile problem #336

Closed
ouclbc opened this issue Aug 7, 2023 · 20 comments
Closed

Android compile problem #336

ouclbc opened this issue Aug 7, 2023 · 20 comments

Comments

@ouclbc
Copy link

ouclbc commented Aug 7, 2023

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
Copy link
Author

ouclbc commented Aug 7, 2023

指定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
Copy link
Author

ouclbc commented Aug 7, 2023

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

@holmes1412
Copy link
Contributor

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

@ouclbc
Copy link
Author

ouclbc commented Aug 7, 2023

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

@holmes1412
Copy link
Contributor

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

@ouclbc
Copy link
Author

ouclbc commented Aug 8, 2023

目前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
Copy link
Contributor

holmes1412 commented Aug 8, 2023

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

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

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

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

@ouclbc
Copy link
Author

ouclbc commented Aug 8, 2023

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

@holmes1412
Copy link
Contributor

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
Copy link
Author

ouclbc commented Aug 8, 2023

手动指定,如下方式,还是提示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
Copy link
Contributor

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

@ouclbc
Copy link
Author

ouclbc commented Aug 8, 2023

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
Copy link
Contributor

holmes1412 commented Aug 8, 2023

虽然不太了解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
Copy link
Author

ouclbc commented Aug 15, 2023

修改的文件如下:
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 ouclbc closed this as completed Aug 15, 2023
@ouclbc
Copy link
Author

ouclbc commented Aug 15, 2023

另外请教一下,编译出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
Copy link
Contributor

holmes1412 commented Aug 15, 2023

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

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

@ouclbc
Copy link
Author

ouclbc commented Aug 15, 2023

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

@holmes1412
Copy link
Contributor

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

@ouclbc
Copy link
Author

ouclbc commented Nov 15, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants