对 `icu_56::UnicodeString::UnicodeString(signed char, unsigned short const*, int)' 的未定义引用

9

我正在使用Ubuntu操作系统,可以构建ICU。

我已经包含了以下内容:

#include <unistr.h>
using namespace icu;

这是我为ICU编写的构建方法:
CPPFLAGS="-DU_USING_ICU_NAMESPACE=0" 
CPPFLAGS="-DU_CHARSET_IS_UTF8=1"

export CFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_GNUC_UTF16_STRING=1 -DU_STATIC_IMPLEMENTATION"
export CXXFLAGS="-DU_USING_ICU_NAMESPACE=0 -std=gnu++0x -DU_CHARSET_IS_UTF8=1 -DU_GNUC_UTF16_STRING=1 -DU_HAVE_CHAR16_T=1 -DUCHAR_TYPE=char16_t -Wall --std=c++0x -DU_STATIC_IMPLEMENTATION"
export CPPFLAGS="-DU_USING_ICU_NAMESPACE=0 -DU_CHARSET_IS_UTF8=1 -DU_STATIC_IMPLEMENTATION"
export LDFLAGS="-std=gnu++0x"

./runConfigureICU Linux --enable-static --disable-shared --disable-renaming

make check 
sudo make install

我随后链接到

/usr/local/lib/libicuuc.a

并尝试编译

icu::UnicodeString s1=UNICODE_STRING("such characters are safe 123 %-.", 32);

但是出现了错误。
undefined reference to `icu_56::UnicodeString::UnicodeString(signed char, unsigned short const*, int)'

我在SO上找到了另一篇关于相同问题的帖子,但是当我按照提供的步骤进行操作时,它并不能解决我的问题,可能是不同版本造成的。
编辑:这是构建项目时IDE的输出。
Cleaning Solution: myProject (Debug)

Cleaning: myProject (Debug)
Removing output files...
Clean complete

Building Solution: myProject (Debug)

Building: myProject (Debug)
Performing main compilation...

Precompiling headers

    Compiling source to object files
    g++  -MMD "/home/user/myProject/myProject/main.cpp" -g -O0 -std=c++11 -DDEBUG -I"/home/user/myProject/myProject/include" -I"/home/user/myProject/icu/unicode" -I"/home/user/myProject/myProject/.prec/Debug"  -c -o "/home/user/myProject/myProject/bin/Debug/main.o"

    Generating binary "myProject" from object files
    g++ -o "/home/user/myProject/myProject/bin/Debug/myProject" "/home/user/myProject/myProject/bin/Debug/main.o"
"/home/user/myProject/icu/libicuuc.a" 
    /home/user/myProject/myProject/bin/Debug/main.o: In function `icuTest':
    /home/user/myProject/myProject/icuTest.hpp:3: undefined reference to `icu_56::StringPiece::StringPiece(char const*)'
    /home/user/myProject/myProject/icuTest.hpp:3: undefined reference to `icu_56::UnicodeString::fromUTF8(icu_56::StringPiece const&)'
    /home/user/myProject/myProject/icuTest.hpp:3: undefined reference to `icu_56::UnicodeString::~UnicodeString()'
    /home/user/myProject/myProject/icuTest.hpp:3: undefined reference to `icu_56::UnicodeString::~UnicodeString()'
    collect2: error: ld returned 1 exit status
    Build complete -- 4 errors, 0 warnings

    ---------------------- Done ----------------------

    Build: 4 errors, 0 warnings

啊,我应该提醒要包含-C来还原C++符号。 - dlmeetei
libicuuc.a 包含了 U icu::UnicodeString::~UnicodeString()。 - Chris
@Chris:你说 'libicuuc.a 包含 U icu::UnicodeString::UnicodeString()' - 但是你的问题表明链接器正在寻找 'icu_56::UnicodeString::UnicodeString()'。命名空间不匹配是你问题的原因吗? - Jeremy
我尝试使用命名空间icu和icu_56,但都无法工作。 - Chris
@Chris - 你的意思是你尝试过在配置库时同时使用--disable-renaming和不使用此开关吗?还是你编译了U_DISABLE_RENAMING设置为1和未设置的main.cpp?或者是四种组合都尝试了?请注意,你的问题显示库被配置为使用--disable-renaming(因此使用icu_56),但是你的main.cpp被编译时没有定义U_DISABLE_RENAMING(因此使用icu)。 - Jeremy
显示剩余10条评论
4个回答

4

当你运行:

./runConfigureICU Linux --enable-static --disable-shared --disable-renaming

你是否注意到了这个警告?
*** WARNING: You must set the following flags before code compiled against this ICU will function properly:

    -DU_DISABLE_RENAMING=1

The recommended way to do this is to prepend the following lines to source/common/unicode/uconfig.h or #include them near the top of that file.

 /* -DU_DISABLE_RENAMING=1 */
#define U_DISABLE_RENAMING 1

如果还没有这样做,请现在开始操作。 接下来,在任何其他内容之前修改你的测试程序为#include <unicode/uconfig.h>,例如:

main.cpp

#include <unicode/uconfig.h>
#include <unicode/platform.h>
#include <unicode/unistr.h>

int main()
{
    icu::UnicodeString s1=UNICODE_STRING("such characters are safe 123 %-.", 32);
    (void)s1;
    return 0;
}

这段代码将编译并链接到libicuuc.a库。

如果您希望在编译之前自动包含类似unicode/uconfig.hunicode/platform.h这样的样板头文件,可以使用预包含头文件,例如:

icu_preinc.h

// pre-include header for icu
#include <unicode/uconfig.h>
#include <unicode/platform.h>

你需要将以下选项传递给GCC或clang:

-include /path/to/icu_preinc.h

如果您使用基于make的构建系统,可以将此选项放入CPPFLAGS中。

对于上面的玩具程序,只需在命令行中定义U_DISABLE_RENAMING=1即可,无需包含<unicode/uconfig.h>

g++ -DU_DISABLE_RENAMING=1 -o prog main.cpp -L/your/libicuuc/search/path -licuuc

在uconfig.h中的#define U_DISABLE_RENAMING 1解决了问题。谢谢。 - Huy Pham

3

我注意到你的g++命令行没有指向你安装icu的/usr/local/lib/libicuuc.a路径。显然它可以编译头文件,但是你使用的路径中是否存在静态库("/home/user/myProject/icu/libicuuc.a")呢?


我应该指出我从同一个地方获取了它,并且我刚刚检查了文件哈希值,它是相同的,只是为了证明给自己。无论如何,谢谢。 - Chris

1

我认为问题在于g++语法:

g++ -o "/home/user/myProject/myProject/bin/Debug/myProject" "/home/user/myProject/myProject/bin/Debug/main.o" "/home/user/myProject/icu/libicuuc.a" 

您说要使用对象文件main.o和静态库libicuuc.a来构建myProject。然而,后者不是一个对象文件,它是一个静态库。我认为您应该修改g++命令行为:
g++ /home/user/myProject/myProject/bin/Debug/main.o -L/home/user/myProject/icu/ -licuuc -o /home/user/myProject/myProject/bin/Debug/myProject

-L/home/user/myProject/icu/ 告诉链接器在 /home/user/myProject/icu/ 文件夹中查找库文件,而 -licuuc 则告诉它链接名为 libicuuc.a 或 libicuuc.so 的库文件。


我在想我是否正确构建了ICU,因为我已经按照您的建议完全操作了,但仍然出现“undefined reference to icu_56::StringPiece::StringPiece(char const*)'”,“undefined reference to icu_56::UnicodeString::fromUTF8(icu_56::StringPiece const&)'”和“undefined reference to `icu_56::UnicodeString::~UnicodeString()'”。 - Chris
那么我会跟进Jeremy的评论。你声称正在使用的命名空间是icu,但实际上在头文件中它确实是icu_56,这就是链接器抱怨的原因。你有带有icu_56的头文件,但库却有icu命名空间。因此,也许你真的错误地重建了ICU。 - Jakub Zaverka
我尝试使用命名空间icu和icu_56,但都无法工作,出现相同的错误。 - Chris
它甚至无法将其与非静态的.so库配合使用。 - Chris
"UNICODE_STRING" 扩展成什么?它看起来像一个宏。 - Jakub Zaverka

1
注意:对于 ICU 67,应该使用 using namespace icu_67

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接