https://github.com/grpc/grpc.git
git checkout release-0_9_1
新建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/