discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Category Unknown ?


From: Andreas Buff
Subject: Re: Category Unknown ?
Date: Mon, 18 Oct 2021 12:38:27 +0200
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.14.0

Hi Andreas,

thanks again for trying to help. I really appreciate it!

Find feedback inlined.

Best,
Andreas

Am 15.10.21 um 17:56 schrieb Andreas Fink:
i have done precompiled libraries for debian10 and 11 and they work fine
for me.
Just to avoid misunderstandings: I do _not_ have a general issue using pre-compiled static libs. Its only about Objective-C Categories that cause issues.

The behaviour is expected when linking a static lib containing Categories without the `-ObjC` linker flag.

From the Apple Docs:
"
# Objective-C

The dynamic nature of Objective-C complicates things slightly. Because the code that implements a method is not determined until the method is actually called, Objective-C does not define linker symbols for methods. Linker symbols are only defined for classes.

For example, if main.m includes the code [[FooClass alloc] initWithBar:nil]; then main.o will contain an undefined symbol for FooClass, but no linker symbols for the -initWithBar: method will be in main.o.

Since categories are a collection of methods, using a category's method does not generate an undefined symbol. This means the linker does not know to load an object file defining the category, if the class itself is already defined. This causes the same "selector not recognized" runtime exception you would see for any unimplemented method.

# The -ObjC Linker Flag

Passing the -ObjC option to the linker causes it to load all members of static libraries that implement any Objective-C class or category. This will pickup any category method implementations. But it can make the resulting executable larger, and may pickup unnecessary objects. For this reason it is not on by default
"
The problem seems to be that the `-ObjC` flag is used by the compiler (who doesn't know and thus ignores it) instead of the linker using the GNUstep make system.

I have created a simple project to reproduce, showing the issue, taking your advice into account.

## HowTo Reproduce

```
# clone
git clone http://pep-security.lu/gitlab/andreas/category-linking-problem-sample.git

# build
cd category-linking-problem-sample
sh build.sh
# note: compiler output "clang: warning: argument unused during compilation: '-ObjC' [-Wunused-command-line-argument]"

# run
./obj/LinkFailSample
```

Expected:

Console output is
```
myDebugPrint
myDebugPrintCategory
```

Actual:
Console output is
```
myDebugPrint
./obj/LinkFailSample: Uncaught exception NSInvalidArgumentException, reason: MyClass(instance) does not recognize myDebugPrintCategory
```

Additional Info:

`nm` shows the Category _is_ contained in the lib:

```
nm static-lib/obj/libmyLib.a | grep myDebugPrint
0000000000000000 t _i_MyClass__myDebugPrint
0000000000000000 V .objc_selector_myDebugPrint_v160:8
0000000000000000 V .objc_sel_name_myDebugPrint
0000000000000000 V .objc_str_myDebugPrint
0000000000000000 t _i_MyClass_Extension_myDebugPrintCategory #HERE
0000000000000000 V .objc_selector_myDebugPrintCategory_v160:8
0000000000000000 V .objc_sel_name_myDebugPrintCategory
0000000000000000 V .objc_str_myDebugPrintCategory
```

`nm` shows it's _not_ in the excecutable:

```
nm obj/LinkFailSample | grep myDebugPrint
0000000000400b40 t _i_MyClass__myDebugPrint
0000000000403220 d .objc_selector_myDebugPrintCategory_v160:8
0000000000403210 d .objc_selector_myDebugPrint_v160:8
0000000000400bf0 r .objc_sel_name_myDebugPrint
0000000000400c10 r .objc_sel_name_myDebugPrintCategory
0000000000403330 d .objc_str_myDebugPrint
```


Attachment: sender_key.asc
Description: application/pgp-keys


reply via email to

[Prev in Thread] Current Thread [Next in Thread]