ICU ld error

23 篇文章 1 订阅

编译icu并链接时可能出现以下错误:

error: undefined reference to "icu_51::UnicodeString::doEquals(icu_51::UnicodeString const&, int) const"





参考:http://stackoverflow.com/questions/14251151/icu-problems-compiling-with-boost-1-50-locale-in-linux?answertab=oldest#tab-top

引用如下:

The version number (used in the linkage) is set by the ICU headers, so it seems you are compiling against 4.8 but trying to link against something else (such as 4.6). uvernum.h (or in older versions, uversion.h) contains the version #.


原因:生成的icu库的版本和你使用icu库时的版本不同,详解如下


首先看一下icu\source\common\unicode\urename.h,摘抄部分代码如下,用红色标记重要内容

/*
*******************************************************************************
*   Copyright (C) 2002-2014, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
*
*   file name:  urename.h
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   <strong><span style="color:#ff6666;">Created by: Perl script tools/genren.pl</span></strong> written by Vladimir Weinstein
*
*  <span style="color:#ff6666;"><strong>Contains data for renaming ICU exports</strong></span>.
*  Gets included by umachine.h
*
*  <span style="color:#ff0000;"><strong>THIS FILE IS MACHINE-GENERATED</strong></span>, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT
*  YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN!
*/

#ifndef URENAME_H
#define URENAME_H

/* U_DISABLE_RENAMING can be defined in the following ways:
 *   - when running configure, e.g.
 *        runConfigureICU Linux --disable-renaming
 *   - by changing the default setting of U_DISABLE_RENAMING in uconfig.h
 */

#include "unicode/uconfig.h"

#if !U_DISABLE_RENAMING

/* We need the U_ICU_ENTRY_POINT_RENAME definition. There's a default one in unicode/uvernum.h we can use, but we will give
   the platform a chance to define it first.
   Normally (if utypes.h or umachine.h was included first) this will not be necessary as it will already be defined.
 */

#ifndef U_ICU_ENTRY_POINT_RENAME
#include "unicode/umachine.h"
#endif

/* If we still don't have U_ICU_ENTRY_POINT_RENAME use the default. */
#ifndef U_ICU_ENTRY_POINT_RENAME
#include "unicode/uvernum.h"
#endif

/* Error out before the following defines cause very strange and unexpected code breakage */
#ifndef U_ICU_ENTRY_POINT_RENAME
#error U_ICU_ENTRY_POINT_RENAME is not defined - cannot continue. Consider defining U_DISABLE_RENAMING if renaming should not be used.
#endif


/* C exports renaming data */

#define T_CString_int64ToString <strong><span style="color:#ff6666;">U_ICU_ENTRY_POINT_RENAME</span></strong>(T_CString_int64ToString)
#define T_CString_integerToString U_ICU_ENTRY_POINT_RENAME(T_CString_integerToString)

两点:

1 . urename.h是由genren.pl自动创建的,作用是rename ICU export,即将ICU export 的API重新命名

2. 用户首先可以再uconfig.h中定义宏U_DISABLE_RENAMING,如果用户没有定义,则继续查找umachine.h和uvernum.h,如果还没有则报错

3. 宏U_ICU_ENTRY_POINT_RENAME将API重新命名


U_ICU_ENTRY_POINT_RENAME在uvernum.h中定义,摘抄部分代码如下

 84 /** Glued version suffix for renamers 
 85  *  This value will change in the subsequent releases of ICU
 86  *  @stable ICU 2.6
 87  */
 88 <strong>#define <span style="color:#3366ff;">U_ICU_VERSION_SUFFIX</span> _51</strong>
 89 
 90 /**
 91  * \def U_DEF2_ICU_ENTRY_POINT_RENAME
 92  * @internal
 93  */
 94 /**
 95  * \def U_DEF_ICU_ENTRY_POINT_RENAME
 96  * @internal
 97  */
 98 /** Glued version suffix function for renamers 
 99  *  This value will change in the subsequent releases of ICU.
100  *  If a custom suffix (such as matching library suffixes) is desired, this can be modified.
101  *  Note that if present, platform.h may contain an earlier definition of this macro.
102  *  \def U_ICU_ENTRY_POINT_RENAME
103  *  @stable ICU 4.2
104  */
105 
106 #ifndef U_ICU_ENTRY_POINT_RENAME
107 #ifdef U_HAVE_LIB_SUFFIX
108 #define U_DEF_ICU_ENTRY_POINT_RENAME(x,y,z) x ## y ##  z
109 #define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y,z) U_DEF_ICU_ENTRY_POINT_RENAME(x,y,z)
110 #define <span style="color:#ff6666;"><strong>U_ICU_ENTRY_POINT_RENAME</strong></span>(x)    U_DEF2_ICU_ENTRY_POINT_RENAME(x,<strong><span style="color:#3366ff;">U_ICU_VERSION_SUFFIX</span></strong>,U_LIB_SUFFIX_C_NAME)
111 #else
112 #define U_DEF_ICU_ENTRY_POINT_RENAME(x,y) x ## y
113 #define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y) U_DEF_ICU_ENTRY_POINT_RENAME(x,y)
114 #define U_ICU_ENTRY_POINT_RENAME(x)    U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_ICU_VERSION_SUFFIX)
115 #endif
116 #endif

可以看到,在头文件uvernum.h中定义了版本号。

头文件uversion.h部分代码

104 #   if U_DISABLE_RENAMING
105 #       define U_ICU_NAMESPACE icu
106         namespace U_ICU_NAMESPACE { }
107 #   else
108 #       <span style="color:#ff0000;"><strong>define U_ICU_NAMESPACE U_ICU_ENTRY_POINT_RENAME(icu)</strong></span>
109         namespace U_ICU_NAMESPACE { }
110         namespace icu = U_ICU_NAMESPACE;
111 #   endif

如果允许rename,命名空间也将改名,这也是最初实例中ld error的原因。

所以解决icu ld error的方法有两种:

1. 保证使用icu的版本和icu库版本相同,即使用icu时的头问题必须和编译icu库时的头文件相同(主要是版本号相同)

2. 预先在uconfig.h中关闭icu的rename,即定义宏U_DISABLE_RENAMING为真





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值