我正在制作一个基于文本的游戏,使用ICU处理来自3个主要PC平台的UTF-8编码JSON文件的游戏文本。我能够编译游戏二进制文件并将其与CMake链接,同时引用ICU类型,如UChar、UnicodeString等,一切正常。奇怪的是,在某些标头中,我无法访问任何类型或函数,而不会导致"未定义的符号"链接器错误。特别是标头"ustdio.h",我需要从中访问u_fopen()、u_fclose()和u_fgets()等,以从JSON文件中提取unicode字符串。
体系结构x86_64的未定义符号:"_u_fclose_57",引用自:libsource.a(FileReader.cpp.o)中的FileReader::Close()"_u_fgets_57",引用自:libsource.a(FileReader.cpp.o)中的FileReader::HasNextRine()libsource.a(FileReader.cpp.o)中的FileReader::NextRine()"_u_fopen_57",引用自:libsource.a(FileReader.cpp.o)中的FileReader::FileReader(std::__1::basic_string,std::___1::allocater>)
我正在使用此CMake模块文件来查找.h
和.dylib
文件。从CMake输出中,我知道它与/usr/local/lib/libicuuc.dylib
链接,但在该文件夹中,我也看到了许多其他与ICU相关的dylib。另一位程序员指示我使用nm
检查我要查找的符号是否真的在dylib
中定义,并且我可以在符号列表中看到它们不是。我是否认为这些符号是在其他dylib
文件中定义的?如果是,并且我找到了合适的dylib
,我如何修改FindICU.cmake
以链接到额外的动态库?这个模块对我来说真的很迟钝,我不知道该在哪里修改它来解决这个问题。
我通过搜索每个与ICU相关的dylib文件的符号表找到了它,直到找到丢失的符号(在libicuio.57.1.dylib
中定义)。这让我意识到FindICU.cmake确实没有找到这些符号。然后,我设法解析了足够多的文件来确定问题:有一个变量ICU_FIND_COMPONENTS必须设置为所需组件的列表,才能使模块文件与其他dylib链接。这个变量在任何地方都没有记录,这非常令人沮丧。但我通过在第121行之前将这一行添加到FindICU.cmake
中来解决链接器错误:
set(${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS io)
此外,您还可以通过输出变量ICU_<component>_FOUND
的值来检查是否正在链接所需的组件。在我的案例中,ICU_IO_FOUND
返回false,因为除非明确告知,否则模块不会搜索io dylib。这就是为什么我需要修改FindICU.cmake
,以便链接符号来源的额外dylib文件。