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 平台编译 #773

Open
BDZNH opened this issue Feb 26, 2022 · 6 comments
Open

为 Android 平台编译 #773

BDZNH opened this issue Feb 26, 2022 · 6 comments
Labels
documentation Improvements or additions to documentation

Comments

@BDZNH
Copy link
Contributor

BDZNH commented Feb 26, 2022

使用 NDK 编译

安卓NDK是不自带 openssl 的,需要我们手动编译好提供。
国内可以直接访问安卓的开发者网站 https://developer.android.google.cn/ndk/downloads/ 来下载到 NDK 。
可以参考下面的懒人脚本
p.s: 安卓常用的平台: arm/arm64/x86/x86_64 ,想要编译不同平台的库,修改脚本内的 ANDROID_ABI_ARCHANDROID_ABI

#!/bin/bash
set -e

# 用于编译 workflow 安卓版
# 下载本仓库,并将 NDK_HOME 传入,例如 ANDROID_NDK_HOME=/home/user/android-ndk-r21e ./build_android.sh
# 需要自行下载 NDK
# 脚本内默认编译出来 x86 的,如果你需要其他版本的请修改下面的 ANDROID_ABI_ARCH 和 ANDROID_ABI 的值

#  arch        abi
# arm64 <--> arm64-v8a
# arm   <--> armeabi-v7a
# x86   <--> x86
# x86_64   <--> x86_64
ANDROID_ABI_ARCH=x86
ANDROID_ABI=x86
ANDROID_API_LEVEL=26
OPEN_SSL_VERSION=1.1.1l
OPEN_SSL_DIR=

WORKFLOW_DIR=$(realpath $(dirname $0))
DEFAULT_BUILD_DIR=build.cmake

echo WORKFLOW_DIR ${WORKFLOW_DIR}
echo ANDROID_NDK_HOME ${ANDROID_NDK_HOME}
echo ANDROID_ABI_ARCH ${ANDROID_ABI_ARCH}
echo ANDROID_ABI ${ANDROID_ABI}
echo ANDROID_API_LEVEL ${ANDROID_API_LEVEL}

if [ ! -n ${ANDROID_NDK_HOME} ]; then
    echo "you must specific Android ndk direcotry"
    exit 1
fi

function check_ndk_valid()
{
    if [ ! -d ${ANDROID_NDK_HOME} ]; then
        echo -e "no such a directory: ${ANDROID_NDK_HOME}"
        exit 1
    fi
}

function build_openssl()
{
    if [ ! -f openssl-${OPEN_SSL_VERSION}.tar.gz ]; then
        wget https://www.openssl.org/source/openssl-${OPEN_SSL_VERSION}.tar.gz
        tar -xf openssl-${OPEN_SSL_VERSION}.tar.gz -C .
    fi

    if [ -d openssl-${OPEN_SSL_VERSION} ]; then
	rm -rf openssl-${OPEN_SSL_VERSION}
        tar -xf openssl-${OPEN_SSL_VERSION}.tar.gz -C .
    fi

    OPEN_SSL_DIR=`realpath openssl-${OPEN_SSL_VERSION}`
    echo OPEN_SSL_DIR ${OPEN_SSL_DIR}
    rm -rf ${OPEN_SSL_DIR}
    tar -xvf openssl-${OPEN_SSL_VERSION}.tar.gz -C .
    echo "ready to build openssl "

    pushd openssl-${OPEN_SSL_VERSION}
    PATH=${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin:${ANDROID_NDK_HOME}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH
    ./Configure android-${ANDROID_ABI_ARCH} -D__ANDROID_API__=${ANDROID_API_LEVEL}
    make -j$(nproc)
    popd
}

function build_workflow()
{
    echo "ready to build workflow"
    
    rm -rvf ${DEFAULT_BUILD_DIR}
    cmake -B${DEFAULT_BUILD_DIR} -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} ${WORKFLOW_DIR}
    echo -e "proc num: ${nproc}"
    make clean -C ${DEFAULT_BUILD_DIR}
    make -j$(nproc) -C ${DEFAULT_BUILD_DIR}

    pushd tutorial
    rm -vrf ${DEFAULT_BUILD_DIR}
    cmake -B${DEFAULT_BUILD_DIR} -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} -Dworkflow_DIR=${WORKFLOW_DIR} .
    make -j$(nproc) -C ${DEFAULT_BUILD_DIR}
    popd
}

check_ndk_valid
build_openssl
build_workflow

在 AOSP 源码内编译

AOSP 源码内提供的 ssl 和 crypto 是 boringssl ,Android 8.0 及以上,可以参考以下 Android.bp

cc_defaults{
    name: "libworkflow_common_c_defaults",
    srcs: [
        "src/kernel/mpoller.c",
        "src/kernel/msgqueue.c",
        "src/kernel/poller.c",
        "src/kernel/rbtree.c",
        "src/kernel/thrdpool.c",
        "src/util/crc32c.c",
    ],
    local_include_dirs:[
        "src/kernel",
        "src/util",
    ],
}
cc_defaults{
    name: "libworkflow_common_defaults",
    srcs: [
        "src/algorithm/DnsRoutine.cc",
        "src/client/WFDnsClient.cc",
        "src/factory/DnsTaskImpl.cc",
        "src/factory/FileTaskImpl.cc",
        "src/factory/WFGraphTask.cc",
        "src/factory/WFResourcePool.cc",
        "src/factory/WFTaskFactory.cc",
        "src/factory/Workflow.cc",
        "src/manager/DnsCache.cc",
        "src/manager/RouteManager.cc",
        "src/manager/WFGlobal.cc",
        "src/nameservice/WFDnsResolver.cc",
        "src/nameservice/WFNameService.cc",
        "src/protocol/DnsMessage.cc",
        "src/protocol/DnsUtil.cc",
        "src/protocol/SSLWrapper.cc",
        "src/protocol/dns_parser.c",
        "src/server/WFServer.cc",
        "src/kernel/CommRequest.cc",
        "src/kernel/CommScheduler.cc",
        "src/kernel/Communicator.cc",
        "src/kernel/Executor.cc",
        "src/kernel/IOService_linux.cc",
        "src/kernel/SubTask.cc",
        "src/util/EncodeStream.cc",
        "src/util/MD5Util.cc",
        "src/util/StringUtil.cc",
        "src/util/URIParser.cc",
    ],
    local_include_dirs: [
        "src/algorithm",
        "src/client",
        "src/factory",
        "src/kernel",
        "src/manager",
        "src/nameservice",
        "src/protocol",
        "src/server",
        "src/util",
    ]
}

cc_defaults{
    name: "libworkflow_http_defaults",
    srcs: [
        "src/factory/HttpTaskImpl.cc",
        "src/protocol/HttpMessage.cc",
        "src/protocol/HttpUtil.cc",
        "src/protocol/http_parser.c",
    ],
    local_include_dirs: [
        "src/protocol",
        "src/server",
    ]
}

cc_defaults{
    name: "libworkflow_redis_defaults",
    srcs: [
        "src/factory/RedisTaskImpl.cc",
        "src/protocol/RedisMessage.cc",
        "src/protocol/redis_parser.c",
    ],
    local_include_dirs: [
        "src/protocol",
        "src/server",
    ],
}

cc_defaults{
    name: "libworkflow_mysql_defaults",
    srcs: [
        "src/client/WFMySQLConnection.cc",
        "src/factory/MySQLTaskImpl.cc",
        "src/protocol/MySQLMessage.cc",
        "src/protocol/MySQLResult.cc",
        "src/protocol/mysql_byteorder.c",
        "src/protocol/mysql_parser.c",
        "src/protocol/mysql_stream.c",
    ],
    local_include_dirs: [
        "src/protocol",
        "src/client",
        "src/server",
    ],
}

cc_defaults{
    name: "libworkflow_upstream_defaults",
    srcs: [
        "src/manager/UpstreamManager.cc",
        "src/nameservice/UpstreamPolicies.cc",
        "src/nameservice/WFServiceGovernance.cc",
    ],
    local_include_dirs:[
        "src/manager",
        "src/nameservice",
    ],
}

cc_defaults{
    name: "libwfkafka_defaults",
    srcs: [
        "src/client/WFKafkaClient.cc",
        "src/util/crc32c.c",
        "src/protocol/kafka_parser.c",
        "src/protocol/KafkaMessage.cc",
        "src/protocol/KafkaDataTypes.cc",
        "src/protocol/KafkaResult.cc",
        "src/factory/KafkaTaskImpl.cc",
    ],
    local_include_dirs: [
		"src/client",
		"src/factory",
		"src/protocol",
    ],
    defaults: [
        "libworkflow_common_defaults",
    ]
}

cc_defaults{
    name: "libworkflow_defaults",
    defaults: [
        "libworkflow_common_c_defaults",
        "libworkflow_common_defaults",
        "libworkflow_http_defaults",
        "libworkflow_redis_defaults",
        "libworkflow_mysql_defaults",
        "libworkflow_upstream_defaults",
    ],
    cflags: [
        "-Wno-unused-parameter",
        "-Wno-unused-function",
        "-Wno-implicit-fallthrough",
    ],
    rtti: true,
}

cc_library{
    name: "libworkflow",
    vendor_available: true,
    static_libs: [
        "libssl", 
        "libcrypto"
    ],
    export_include_dirs: [
        "src/include",
    ],
    defaults: ["libworkflow_defaults"],
}

cc_defaults{
    name: "libworkflow_link_defaults",
    vendor: true,
    static_libs: [
        "libworkflow",
        "libssl", 
        "libcrypto"
    ],
    cflags: [
        "-Wno-unused-parameter",
        "-Wno-unused-function",
        "-Wno-implicit-fallthrough",
        "-Wall",
        "-fPIC",
        "-pipe",
        "-std=c++11",
        "-fno-exceptions",
    ],
    rtti: true,
}

cc_binary{
    name: "helloworld",
    srcs: [
        "tutorial/tutorial-00-helloworld.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "wget",
    srcs: [
        "tutorial/tutorial-01-wget.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "redis_cli",
    srcs: [
        "tutorial/tutorial-02-redis_cli.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "wget_to_redis",
    srcs: [
        "tutorial/tutorial-03-wget_to_redis.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "http_echo_server",
    srcs: [
        "tutorial/tutorial-04-http_echo_server.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "http_proxy",
    srcs: [
        "tutorial/tutorial-05-http_proxy.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "parallel_wget",
    srcs: [
        "tutorial/tutorial-06-parallel_wget.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "sort_task",
    srcs: [
        "tutorial/tutorial-07-sort_task.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "matrix_multiply",
    srcs: [
        "tutorial/tutorial-08-matrix_multiply.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "http_file_server",
    srcs: [
        "tutorial/tutorial-09-http_file_server.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "wfserver",
    srcs: [
        "tutorial/tutorial-10-user_defined_protocol/server.cc",
        "tutorial/tutorial-10-user_defined_protocol/message.cc",
    ],
    local_include_dirs:[
        "tutorial/tutorial-10-user_defined_protocol",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "wfclient",
    srcs: [
        "tutorial/tutorial-10-user_defined_protocol/client.cc",
        "tutorial/tutorial-10-user_defined_protocol/message.cc",
    ],
    local_include_dirs:[
        "tutorial/tutorial-10-user_defined_protocol",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "graph_task",
    srcs: [
        "tutorial/tutorial-11-graph_task.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}

cc_binary{
    name: "mysql_cli",
    srcs: [
        "tutorial/tutorial-12-mysql_cli.cc",
    ],
    defaults: [
        "libworkflow_link_defaults",
    ],
}
@ouclbc
Copy link

ouclbc commented Aug 7, 2023

用上面的脚本提示错误:make: *** build.cmake: No such file or directory. Stop.

@holmes1412
Copy link
Contributor

用上面的脚本提示错误:make: *** build.cmake: No such file or directory. Stop.

我看上面的脚本是在``build_workflow()这个函数里调用的cmake -B“build.cmake” 创建目录的,是不是没有调到这个函数呀?

function build_workflow()
{
    rm -rvf ${DEFAULT_BUILD_DIR}
    cmake -B${DEFAULT_BUILD_DIR} -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} ${WORKFLOW_DIR}
    ...
}

@ouclbc
Copy link

ouclbc commented Aug 7, 2023

在调用build_workflow()里面的cmake执行后并没有生成build.cmake目录。
cmake版本cmake version 3.10.2

@holmes1412
Copy link
Contributor

holmes1412 commented Aug 7, 2023

这个脚本里面没有创建build.cmake这个目录,所以提示不存在。

image 这里需要调用一下**build_workflow()**这个函数,里边会创建build.cmake这个目录。上面有写**DEFAULT_BUILD_DIR=build.cmake**

@ouclbc
Copy link

ouclbc commented Aug 7, 2023

脚本我是从这里下载的,放到workflow目录,然后把openssl-1.1.1l.tar.gz放到workflow根目录,然后执行脚本,是这个流程吧。我执行好几遍了,都是提示make: *** build.cmake: No such file or directory.
错误是执行在这句上:
cmake -B${DEFAULT_BUILD_DIR} -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} ${WORKFLOW_DIR}
我export变量手动执行也是没有创建build.cmake目录,不知道为啥
改了后面的两句
make clean -C ${DEFAULT_BUILD_DIR}
make -j$(nproc) -C ${DEFAULT_BUILD_DIR}
改为如下,可以编译过workflow
make clean
make -j$(nproc)
不知道是否和cmake版本有关系还是其他。

@holmes1412
Copy link
Contributor

看起来cmake -B${DEFAULT_BUILD_DIR} 并没有默认帮你创建需要的目录,查了一下cmake 3.0以上就可以支持这个功能了。
有没有可能是cmake执行权限导致创建失败呢。

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

No branches or pull requests

4 participants