静态库中的类别在运行时未重新识别

Categories in static lib not regocnized at runtime

我正在 Linux 上构建一个可执行文件(“工具”)。使用 include $(GNUSTEP_MAKEFILES)/tool.make.

它链接到一个静态库,该库也是使用 GNUstep 构建的。库
包含类别。

可执行文件构建良好,但在运行时出现错误无法识别
静态库类别中定义的方法:

Uncaught exception NSInvalidArgumentException, reason:  
ClassNameOfClassTheCategoryExtends(instance) does not recognize  
nameOfMethodInCategory

我试图通过将 -ObjC 传递给链接器标志来解决这个问题(还有
在可执行文件的 GNUmakefile 中尝试 -all_load):

ADDITIONAL_LDFLAGS = -ObjC -all_load

但这似乎被 clang 忽略了。这是
的相关输出 make install messages=yes debug=yes

clang: warning: argument unused during compilation: '-ObjC'  
[-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-all_load'  
[-Wunused-command-line-argument]

看起来 ADDITIONAL_LDFLAGS 使用的是编译,而不是链接。

使用这个会导致相同的结果:

LDFLAGS := $(LDFLAGS) -ObjC

可执行文件GNUmakefile包括以下内容:

include $(GNUSTEP_MAKEFILES)/common.make
# My make 
include $(GNUSTEP_MAKEFILES)/tool.make

生成的命令行输出为:

$ make install messages=yes debug=yes
This is gnustep-make 2.9.0. Type 'gmake print-gnustep-make-help' for help.
Running in gnustep-make version 2 strict mode.
Making all for tool NameOfExcecutable...
clang -ObjC     -fuse-ld=/usr/bin/ld.gold  -pthread -fexceptions -rdynamic -fobjc-runtime=gnustep-2.0 -fblocks  -o obj/NameOfExcecutable \
./obj/NameOfExcecutable.obj/main.m.o ./obj/NameOfExcecutable.obj/MyClass.m.o ./obj/NameOfExcecutable.obj/StreamRunLoop.m.o ./obj/NameOfExcecutable.obj/Connector.m.o ./obj/NameOfExcecutable.obj/HTTPClient.m.o \
     -L/home/user/GNUstep/Library/Libraries -L/usr/GNUstep/Local/Library/Libraries -L/usr/GNUstep/System/Library/Libraries     -lgnustep-base -ldispatch -l/path/to/libOwnLib1.a -l/path/to/libOwnLib2.a -l/path/to/libOwnHavingTheCategories.a -l/path/to/libOwnLib4.a -l/path/to/libOwnLib5.a -luuid -lz -lpthread -ldl   -lpthread -lobjc   -lm

clang: warning: argument unused during compilation: '-ObjC' [-Wunused-command-line-argument]

问题:

我做错了什么

我该如何解决这个问题?

在深入了解链接器不知道 -ObjC 标志(我们习惯在 Xcode 中使用)的问题后,它看起来像:

  • 只有 ld.ld64 知道这个标志
  • ld.ld64 是一个(过于笼统的命名)“macOS 链接器”(来自 LLDB.org
  • 因此不适用于 Linux 链接器

为了解决这个问题,我们首先停止使用 GNUstep makefile 来
禁用所有 GNUstep 魔法了解正在发生的事情并编写我们自己的 makefile。

强制 link/load 所有 .o 文件的实际修复是明确地将 --whole-archive 传递给链接器:

-Wl,-whole-archive path/to/static/lib/containing/categories/libOwnLib1.a -Wl,-no-whole-archive