windows下使用ndk编译grpc

下载grpc

https://github.com/grpc/grpc.git
git checkout release-0_9_1

使用nodejs由build.json生成Android.mk

新建gen-ndk.js,内容如下

var fs = require("fs");
var build = JSON.parse(fs.readFileSync("build.json", "utf8"));

var libs = build.libs;

process.stdout.write('LOCAL_PATH := $(call my-dir)  \n');
process.stdout.write('SRC_PATH := ..\n')

function getGroup(name)
{
    for (var i = 0; i < build.filegroups.length; i++)
        if (build.filegroups[i].name == name)
            return build.filegroups[i];

}

for (var i = 0; i < libs.length; i++) {
    if (libs[i].build == 'all' && libs[i].secure == 'no') {
        process.stdout.write('\n\ninclude $(CLEAR_VARS)\n')
        process.stdout.write('LOCAL_MODULE_TAGS:= optional\n');
        process.stdout.write('LOCAL_MODULE:= ' + libs[i].name + '\n')
        var headers = {};
        headers['include'] = 'include';

        if (libs[i].headers != undefined) {
            for (var j = 0; j < libs[i].headers.length; j++) {
                var path = libs[i].headers[j];
                var last = path.lastIndexOf('/');
                path = path.substr(0, last);
                headers[path] = path;
            }
        }


        if (libs[i].deps !== undefined) {
            process.stdout.write('LOCAL_SHARED_LIBRARIES:=')
            for (var j = 0; j < libs[i].deps.length; j++) {
               process.stdout.write(libs[i].deps[j] + ' ');
            }
            process.stdout.write('\n');
        }

        process.stdout.write('LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog -lz\n');



        process.stdout.write('LOCAL_SRC_FILES:= \\\n');
        if (libs[i].src !== undefined) {
            for (var j = 0; j < libs[i].src.length; j++) {
               process.stdout.write('\t$(SRC_PATH)/' + libs[i].src[j] + ' \\\n');
            }            
        }

        if (libs[i].filegroups !== undefined) {
            for (var j = 0; j < libs[i].filegroups.length; j++) {
                var group = getGroup(libs[i].filegroups[j]);
                for (var k = 0; k < group.src.length; k++)
                    process.stdout.write('\t$(SRC_PATH)/' + group.src[k] + ' \\\n');

                if (group.headers != undefined) {
                    for (var k = 0; k < group.headers.length; k++) {
                        var path = group.headers[k];
                        var last = path.lastIndexOf('/');
                        path = path.substr(0, last);
                        headers[path] = path;
                    }
                }
            }       
        }


        process.stdout.write('\nLOCAL_C_INCLUDES:= \\\n')
        process.stdout.write('\t$(LOCAL_PATH)/../include \\\n');
        process.stdout.write('\t$(LOCAL_PATH)/../ \\\n');
        process.stdout.write('\t$(LOCAL_PATH)/../../protobuf/src \\\n');


        process.stdout.write('\ninclude $(BUILD_SHARED_LIBRARY)\n');


    }
}

生成的Android.mk内容如下

LOCAL_PATH := $(call my-dir)  
SRC_PATH := ..


include $(CLEAR_VARS)
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= gpr
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog -lz
LOCAL_SRC_FILES:= \
    $(SRC_PATH)/src/core/support/alloc.c \
    $(SRC_PATH)/src/core/support/cancellable.c \
    $(SRC_PATH)/src/core/support/cmdline.c \
    $(SRC_PATH)/src/core/support/cpu_iphone.c \
    $(SRC_PATH)/src/core/support/cpu_linux.c \
    $(SRC_PATH)/src/core/support/cpu_posix.c \
    $(SRC_PATH)/src/core/support/cpu_windows.c \
    $(SRC_PATH)/src/core/support/env_linux.c \
    $(SRC_PATH)/src/core/support/env_posix.c \
    $(SRC_PATH)/src/core/support/env_win32.c \
    $(SRC_PATH)/src/core/support/file.c \
    $(SRC_PATH)/src/core/support/file_posix.c \
    $(SRC_PATH)/src/core/support/file_win32.c \
    $(SRC_PATH)/src/core/support/histogram.c \
    $(SRC_PATH)/src/core/support/host_port.c \
    $(SRC_PATH)/src/core/support/log.c \
    $(SRC_PATH)/src/core/support/log_android.c \
    $(SRC_PATH)/src/core/support/log_linux.c \
    $(SRC_PATH)/src/core/support/log_posix.c \
    $(SRC_PATH)/src/core/support/log_win32.c \
    $(SRC_PATH)/src/core/support/murmur_hash.c \
    $(SRC_PATH)/src/core/support/slice.c \
    $(SRC_PATH)/src/core/support/slice_buffer.c \
    $(SRC_PATH)/src/core/support/string.c \
    $(SRC_PATH)/src/core/support/string_posix.c \
    $(SRC_PATH)/src/core/support/string_win32.c \
    $(SRC_PATH)/src/core/support/subprocess_posix.c \
    $(SRC_PATH)/src/core/support/sync.c \
    $(SRC_PATH)/src/core/support/sync_posix.c \
    $(SRC_PATH)/src/core/support/sync_win32.c \
    $(SRC_PATH)/src/core/support/thd.c \
    $(SRC_PATH)/src/core/support/thd_posix.c \
    $(SRC_PATH)/src/core/support/thd_win32.c \
    $(SRC_PATH)/src/core/support/time.c \
    $(SRC_PATH)/src/core/support/time_posix.c \
    $(SRC_PATH)/src/core/support/time_win32.c \
    $(SRC_PATH)/src/core/support/tls_pthread.c \

LOCAL_C_INCLUDES:= \
    $(LOCAL_PATH)/../include \
    $(LOCAL_PATH)/../ \

include $(BUILD_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= grpc_unsecure
LOCAL_SHARED_LIBRARIES:=gpr 
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog -lz
LOCAL_SRC_FILES:= \
    $(SRC_PATH)/src/core/surface/init_unsecure.c \
    $(SRC_PATH)/src/core/channel/census_filter.c \
    $(SRC_PATH)/src/core/channel/channel_args.c \
    $(SRC_PATH)/src/core/channel/channel_stack.c \
    $(SRC_PATH)/src/core/channel/child_channel.c \
    $(SRC_PATH)/src/core/channel/client_channel.c \
    $(SRC_PATH)/src/core/channel/client_setup.c \
    $(SRC_PATH)/src/core/channel/connected_channel.c \
    $(SRC_PATH)/src/core/channel/http_client_filter.c \
    $(SRC_PATH)/src/core/channel/http_server_filter.c \
    $(SRC_PATH)/src/core/channel/noop_filter.c \
    $(SRC_PATH)/src/core/compression/algorithm.c \
    $(SRC_PATH)/src/core/compression/message_compress.c \
    $(SRC_PATH)/src/core/debug/trace.c \
    $(SRC_PATH)/src/core/iomgr/alarm.c \
    $(SRC_PATH)/src/core/iomgr/alarm_heap.c \
    $(SRC_PATH)/src/core/iomgr/endpoint.c \
    $(SRC_PATH)/src/core/iomgr/endpoint_pair_posix.c \
    $(SRC_PATH)/src/core/iomgr/endpoint_pair_windows.c \
    $(SRC_PATH)/src/core/iomgr/fd_posix.c \
    $(SRC_PATH)/src/core/iomgr/iocp_windows.c \
    $(SRC_PATH)/src/core/iomgr/iomgr.c \
    $(SRC_PATH)/src/core/iomgr/iomgr_posix.c \
    $(SRC_PATH)/src/core/iomgr/iomgr_windows.c \
    $(SRC_PATH)/src/core/iomgr/pollset_kick.c \
    $(SRC_PATH)/src/core/iomgr/pollset_multipoller_with_epoll.c \
    $(SRC_PATH)/src/core/iomgr/pollset_multipoller_with_poll_posix.c \
    $(SRC_PATH)/src/core/iomgr/pollset_posix.c \
    $(SRC_PATH)/src/core/iomgr/pollset_windows.c \
    $(SRC_PATH)/src/core/iomgr/resolve_address_posix.c \
    $(SRC_PATH)/src/core/iomgr/resolve_address_windows.c \
    $(SRC_PATH)/src/core/iomgr/sockaddr_utils.c \
    $(SRC_PATH)/src/core/iomgr/socket_utils_common_posix.c \
    $(SRC_PATH)/src/core/iomgr/socket_utils_linux.c \
    $(SRC_PATH)/src/core/iomgr/socket_utils_posix.c \
    $(SRC_PATH)/src/core/iomgr/socket_windows.c \
    $(SRC_PATH)/src/core/iomgr/tcp_client_posix.c \
    $(SRC_PATH)/src/core/iomgr/tcp_client_windows.c \
    $(SRC_PATH)/src/core/iomgr/tcp_posix.c \
    $(SRC_PATH)/src/core/iomgr/tcp_server_posix.c \
    $(SRC_PATH)/src/core/iomgr/tcp_server_windows.c \
    $(SRC_PATH)/src/core/iomgr/tcp_windows.c \
    $(SRC_PATH)/src/core/iomgr/time_averaged_stats.c \
    $(SRC_PATH)/src/core/iomgr/wakeup_fd_eventfd.c \
    $(SRC_PATH)/src/core/iomgr/wakeup_fd_nospecial.c \
    $(SRC_PATH)/src/core/iomgr/wakeup_fd_pipe.c \
    $(SRC_PATH)/src/core/iomgr/wakeup_fd_posix.c \
    $(SRC_PATH)/src/core/json/json.c \
    $(SRC_PATH)/src/core/json/json_reader.c \
    $(SRC_PATH)/src/core/json/json_string.c \
    $(SRC_PATH)/src/core/json/json_writer.c \
    $(SRC_PATH)/src/core/profiling/basic_timers.c \
    $(SRC_PATH)/src/core/profiling/stap_timers.c \
    $(SRC_PATH)/src/core/statistics/census_init.c \
    $(SRC_PATH)/src/core/statistics/census_log.c \
    $(SRC_PATH)/src/core/statistics/census_rpc_stats.c \
    $(SRC_PATH)/src/core/statistics/census_tracing.c \
    $(SRC_PATH)/src/core/statistics/hash_table.c \
    $(SRC_PATH)/src/core/statistics/window_stats.c \
    $(SRC_PATH)/src/core/surface/byte_buffer.c \
    $(SRC_PATH)/src/core/surface/byte_buffer_queue.c \
    $(SRC_PATH)/src/core/surface/byte_buffer_reader.c \
    $(SRC_PATH)/src/core/surface/call.c \
    $(SRC_PATH)/src/core/surface/call_details.c \
    $(SRC_PATH)/src/core/surface/call_log_batch.c \
    $(SRC_PATH)/src/core/surface/channel.c \
    $(SRC_PATH)/src/core/surface/channel_create.c \
    $(SRC_PATH)/src/core/surface/client.c \
    $(SRC_PATH)/src/core/surface/completion_queue.c \
    $(SRC_PATH)/src/core/surface/event_string.c \
    $(SRC_PATH)/src/core/surface/init.c \
    $(SRC_PATH)/src/core/surface/lame_client.c \
    $(SRC_PATH)/src/core/surface/metadata_array.c \
    $(SRC_PATH)/src/core/surface/server.c \
    $(SRC_PATH)/src/core/surface/server_chttp2.c \
    $(SRC_PATH)/src/core/surface/server_create.c \
    $(SRC_PATH)/src/core/surface/surface_trace.c \
    $(SRC_PATH)/src/core/transport/chttp2/alpn.c \
    $(SRC_PATH)/src/core/transport/chttp2/bin_encoder.c \
    $(SRC_PATH)/src/core/transport/chttp2/frame_data.c \
    $(SRC_PATH)/src/core/transport/chttp2/frame_goaway.c \
    $(SRC_PATH)/src/core/transport/chttp2/frame_ping.c \
    $(SRC_PATH)/src/core/transport/chttp2/frame_rst_stream.c \
    $(SRC_PATH)/src/core/transport/chttp2/frame_settings.c \
    $(SRC_PATH)/src/core/transport/chttp2/frame_window_update.c \
    $(SRC_PATH)/src/core/transport/chttp2/hpack_parser.c \
    $(SRC_PATH)/src/core/transport/chttp2/hpack_table.c \
    $(SRC_PATH)/src/core/transport/chttp2/huffsyms.c \
    $(SRC_PATH)/src/core/transport/chttp2/status_conversion.c \
    $(SRC_PATH)/src/core/transport/chttp2/stream_encoder.c \
    $(SRC_PATH)/src/core/transport/chttp2/stream_map.c \
    $(SRC_PATH)/src/core/transport/chttp2/timeout_encoding.c \
    $(SRC_PATH)/src/core/transport/chttp2/varint.c \
    $(SRC_PATH)/src/core/transport/chttp2_transport.c \
    $(SRC_PATH)/src/core/transport/metadata.c \
    $(SRC_PATH)/src/core/transport/stream_op.c \
    $(SRC_PATH)/src/core/transport/transport.c \
    $(SRC_PATH)/src/core/transport/transport_op_string.c \

LOCAL_C_INCLUDES:= \
    $(LOCAL_PATH)/../include \
    $(LOCAL_PATH)/../ \

include $(BUILD_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE := libprotobuf
LOCAL_SRC_FILES := $(SRC_PATH)/libprotobuf.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= grpc++_unsecure
LOCAL_SHARED_LIBRARIES:=gpr grpc_unsecure libprotobuf
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog -lz
LOCAL_SRC_FILES:= \
    $(SRC_PATH)/src/cpp/client/channel.cc \
    $(SRC_PATH)/src/cpp/client/channel_arguments.cc \
    $(SRC_PATH)/src/cpp/client/client_context.cc \
    $(SRC_PATH)/src/cpp/client/client_unary_call.cc \
    $(SRC_PATH)/src/cpp/client/create_channel.cc \
    $(SRC_PATH)/src/cpp/client/credentials.cc \
    $(SRC_PATH)/src/cpp/client/generic_stub.cc \
    $(SRC_PATH)/src/cpp/client/insecure_credentials.cc \
    $(SRC_PATH)/src/cpp/client/internal_stub.cc \
    $(SRC_PATH)/src/cpp/common/call.cc \
    $(SRC_PATH)/src/cpp/common/completion_queue.cc \
    $(SRC_PATH)/src/cpp/common/rpc_method.cc \
    $(SRC_PATH)/src/cpp/proto/proto_utils.cc \
    $(SRC_PATH)/src/cpp/server/async_generic_service.cc \
    $(SRC_PATH)/src/cpp/server/insecure_server_credentials.cc \
    $(SRC_PATH)/src/cpp/server/server.cc \
    $(SRC_PATH)/src/cpp/server/server_builder.cc \
    $(SRC_PATH)/src/cpp/server/server_context.cc \
    $(SRC_PATH)/src/cpp/server/server_credentials.cc \
    $(SRC_PATH)/src/cpp/server/thread_pool.cc \
    $(SRC_PATH)/src/cpp/util/byte_buffer.cc \
    $(SRC_PATH)/src/cpp/util/slice.cc \
    $(SRC_PATH)/src/cpp/util/status.cc \
    $(SRC_PATH)/src/cpp/util/time.cc \

LOCAL_C_INCLUDES:= \
    $(LOCAL_PATH)/../include \
    $(LOCAL_PATH)/../ \
    $(LOCAL_PATH)/../../protobuf/src

include $(BUILD_SHARED_LIBRARY)

建立Application.mk,内容如下

APP_MODULES      := gpr grpc_unsecure grpc++_unsecure
APP_PLATFORM     := android-9
APP_ABI          := armeabi-v7a
APP_STL          := gnustl_static
APP_OPTIM        := release
NDK_TOOLCHAIN_VERSION := clang

APP_CPPFLAGS     := -fexceptions -frtti -std=c++11

编译后得到gpr grpc_unsecure grpc++_unsecure,就是我们所需要的。

遇到的问题:
默认使用grpc库链接得到的程序,运行的时候会提示下面错误,

CANNOT LINK EXECUTABLE: could not load library "libgrpc_unsecure.so" needed by "xxx"; caused by cannot locate symbol "__tls_get_addr" referenced by "libgrpc_unsecure.so"...

做下面的修改就可以了,使用android libthread自己的tls

diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h
index a695acf..f36ac63 100644
--- a/include/grpc/support/port_platform.h
+++ b/include/grpc/support/port_platform.h
@@ -67,7 +67,8 @@
 #define GPR_ARCH_32 1
 #define GPR_CPU_LINUX 1
 #define GPR_GCC_SYNC 1
-#define GPR_GCC_TLS 1
+//#define GPR_GCC_TLS 1
+#define GPR_PTHREAD_TLS 1
 #define GPR_POSIX_MULTIPOLL_WITH_POLL 1
 #define GPR_POSIX_WAKEUP_FD 1
 #define GPR_LINUX_EVENTFD 1

来源:http://transing.xyz/2015/07/23/build-grpc-with-ndk-under-windows/

你可能感兴趣的:(android)