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'   ?

直接注掉该行只是权宜之计。

 

  1. 2.  undefined reference to `__tls_get_addr'  这个错误到底是怎么回事,是不是由于线程库不支持导致的?

 

请有经验的大神赐教一二,感激不尽。