Kafka C库源代码:https://github.com/edenhill/librdkafka
参考:http://grokbase.com/t/kafka/users/133wrjj8cb/c-c-client
交叉工具链:arm-xxx_v7a-linux-uclibcgnueabi-gcc
步骤一:修改Makefile
修改工具链:
CC=gcc改为:
CC=arm-xxx_v7a-linux-uclibcgnueabi-gcc
AR=arm-xxx_v7a-linux-uclibcgnueabi-ar
修改目标文件:
libs: $(LIBNAME).so $(LIBNAME).a 改为: libs: $(LIBNAME).a
步骤二: make all
提示:
[root@localhost librdkafka-master]# make all
arm-xxx_v7a-linux-uclibcgnueabi-gcc -MD -MP -O2 -Wall -Werror -Wfloat-equal -Wpointer-arith -fPIC -I. -g -c rdkafka.c
rdkafka.c:57:18: error: zlib.h: No such file or directory
In file included from rd.h:44,
from rdkafka.h:38,
from rdkafka.c:60:
rdtypes.h:42: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rd_rwlock_t'
make: *** [rdkafka.o] Error 1
交叉编译时没有找到zlib.h(直接用gcc应该会有的),zlib.h是libz.a的头文件,应该是缺少libz.a压缩库。从网上找到zlib-1.2.8,按照上一篇的步骤生成libz.a。将libz.a、zlib.h、zconf.h拷贝到kafka目录下。修改Makefile:
LDFLAGS+=-shared -g -fPIC -lpthread -lrt -lz –lc
改为:
LDFLAGS+=-shared -g -fPIC -lpthread -lrt ../libz.a –lc
步骤三: 继续make all
提示:
arm-xxx_v7a-linux-uclibcgnueabi-gcc -MD -MP -O2 -Wall -Werror -Wfloat-equal -Wpointer-arith -fPIC -I. -g -c rdkafka.c
In file included from rd.h:44,
from rdkafka.h:38,
from rdkafka.c:60:
rdtypes.h:42: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rd_rwlock_t'
make: *** [rdkafka.o] Error 1
打开rdtypes.h查看错误原因: vim rdtypes.h
#pragma once
#include <inttypes.h>
/*
* Fundamental types
*/
typedef pthread_mutex_t rd_mutex_t;
typedef pthread_rwlock_t rd_rwlock_t;
typedef pthread_cond_t rd_cond_t;
/* Timestamp (microseconds) */
typedef uint64_t rd_ts_t;
没看明白是哪错了,但是查找整个工程,都没有用到rd_rwlock_t,故将这一行注释掉。
步骤四:再make all,搞定,生成librdkafka.a
下面进入example测试一下:
步骤一:同样先修改Makefile
CC ?= cc
CXX ?= g++ 改为:
CC = arm-xxx_v7a-linux-uclibcgnueabi-gcc
CXX = arm-xxx_v7a-linux-uclibcgnueabi-g++
LDFLAGS += -lpthread -lrt –lz 改为:
LDFLAGS += -lpthread -lrt ../libz.a
步骤二: make rdkafka_example
提示:
[root@localhost examples]# make rdkafka_example
../librdkafka.a(rdkafka.o): In function `rd_tsprintf':
/mnt/hgfs/D/work/opensrc/librdkafka-master/rdkafka.c:140: undefined reference to `__tls_get_addr'
../librdkafka.a(rdkafka.o): In function `rd_kafka_topicpart_serialize':
/mnt/hgfs/D/work/opensrc/librdkafka-master/rdkafka.c:506: undefined reference to `__tls_get_addr'
../librdkafka.a(rdaddr.o): In function `rd_addrinfo_prepare':
/mnt/hgfs/D/work/opensrc/librdkafka-master/rdaddr.c:97: undefined reference to `__tls_get_addr'
/mnt/hgfs/D/work/opensrc/librdkafka-master/rdaddr.c:127: undefined reference to `__tls_get_addr'
/mnt/hgfs/D/work/opensrc/librdkafka-master/rdaddr.c:131: undefined reference to `__tls_get_addr'
../librdkafka.a(rdaddr.o):/mnt/hgfs/D/work/opensrc/librdkafka-master/rdaddr.c:119: more undefined references to `__tls_get_addr' follow
collect2: ld returned 1 exit status
make: *** [rdkafka_example] Error 1
打开报错文件,发现都有类似static __thread char ret[27];
static __thread union这种带有__thread的定义。
百度、谷歌一下,原来这是一种叫 线程局部存储(TLS)的东西(有可能是线程库的问题,没有尝试这个方向的修改)。折腾了半天,没有任何作用。最后查看整个工程,出现__thread的地方也就那么几处,与其花时间折腾,不如直接想办法实现TLS好了。具体内容请看下篇。
本篇遗留问题:
1. rdtypes.h中typedef pthread_rwlock_t rd_rwlock_t;为什么会报
rdtypes.h:42: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rd_rwlock_t' ?
直接注掉该行只是权宜之计。
- 2. undefined reference to `__tls_get_addr' 这个错误到底是怎么回事,是不是由于线程库不支持导致的?
请有经验的大神赐教一二,感激不尽。