我正在制作基于文本的游戏,使用ICU处理来自3个主要PC平台的UTF-8编码的JSON文件的游戏文本。我能够在引用ICU类型(如UChar,UnicodeString等)的同时使用CMake编译和链接游戏二进制文件,并且一切正常。奇怪的是,有些标题我无法访问任何类型或函数而不会导致“未定义符号”链接器错误。特别是标题“ustdio.h”,我需要从中访问u_fopen(),u_fclose(),u_fgets()等,从我的JSON文件中提取unicode字符串。
架构x86_64的未定义符号: “_u_fclose_57”,引自: libsource.a中的FileReader :: Close()(FileReader.cpp.o) “_u_fgets_57”,引自: libsource.a中的FileReader :: HasNextLine()(FileReader.cpp.o) libsource.a中的FileReader :: NextLine()(FileReader.cpp.o) “_u_fopen_57”,引自: libsource.a中的FileReader :: FileReader(std :: __ 1 :: basic_string,std :: __ 1 :: allocator>)(FileReader.cpp.o)
我正在使用this CMake module file找到.h
和.dylib
个文件。从CMake输出,我知道它链接到/usr/local/lib/libicuuc.dylib
,但在该文件夹中我也看到了很多其他与ICU相关的dylib。另一位程序员指导我检查我正在寻找的符号是否在dylib
中使用nm
进行了真正的定义,我可以在符号列表中看到它们不是。我是否假设这些符号是在其他dylib
文件中定义的?如果是,并且我找到了正确的dylib
,如何修改FindICU.cmake
以链接额外的动态库?该模块对我来说似乎非常迟钝,我不知道我在哪里修改它来解决这个问题。
答案 0 :(得分:1)
我通过搜索每个与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文件的原因。