Search code examples
objective-cmakefilelinkerclanggnu-make

Clang Linker escape $ for weak symbol


I'm using Theos for a tweak but I'm having trouble with Makefiles and linker flags.

The Linker is complaining about an undefined symbol I'm so trying to pass -Wl,-U, _OBJC_CLASS_$_Hook_HTTestClass for a weakly linked symbol like this,

ARCHS = arm64

TARGET := iphone:clang:latest:7.0
INSTALL_TARGET_PROCESSES = HookTest

include $(THEOS)/makefiles/common.mk

TWEAK_NAME = HookTestTweak

HookTestTweak_FILES = Tweak.m
HookTestTweak_CFLAGS = -fobjc-arc
HookTestTweak_LDFLAGS += -v -Wl,-U,_OBJC_CLASS_$_Hook_HTTestClass

include $(THEOS_MAKE_PATH)/tweak.mk

At first, I thought it was the $, so I tried to escape it.

HookTestTweak_LDFLAGS += -v -Wl,-U,_OBJC_CLASS_$$_Hook_HTTestClass

But the linker just results in this (notice how it says -U _OBJC_CLASS_),

"/home/haow6/.theos/toolchain/linux/iphone/bin/ld" -dynamic -dylib -arch arm64 -dylib_install_name /Library/MobileSubstrate/DynamicLibraries/HookTestTweak.dylib -platform_version ios 7.0.0 14.4 -multiply_defined suppress -syslibroot /home/haow6/.theos/sdks/iPhoneOS14.4.sdk -o /home/haow6/source/HookTest/HookTestTweak/.theos/obj/debug/arm64/HookTestTweak.dylib -L/home/haow6/.theos/lib -L/home/haow6/.theos/vendor/lib -lobjc -framework Foundation -framework CoreFoundation -framework CydiaSubstrate -lc++ -U _OBJC_CLASS_ /home/haow6/source/HookTest/HookTestTweak/.theos/obj/debug/arm64/Tweak.m.bd8afb95.o -lc++ -lSystem -F/home/haow6/.theos/vendor/lib
Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_HTTestClass", referenced from:
      _OBJC_CLASS_$_Hook_HTTestClass in Tweak.m.bd8afb95.o
  "_OBJC_METACLASS_$_HTTestClass", referenced from:
      _OBJC_METACLASS_$_Hook_HTTestClass in Tweak.m.bd8afb95.o
ld: symbol(s) not found for architecture arm64

Next, I tried to encase the symbol name in quotes, and its closer with -U "_OBJC_CLASS_\$_Hook_HTTestClass" but it still doesn't work,

"/home/haow6/.theos/toolchain/linux/iphone/bin/ld" -dynamic -dylib -arch arm64 -dylib_install_name /Library/MobileSubstrate/DynamicLibraries/HookTestTweak.dylib -platform_version ios 7.0.0 14.4 -multiply_defined suppress -syslibroot /home/haow6/.theos/sdks/iPhoneOS14.4.sdk -o /home/haow6/source/HookTest/HookTestTweak/.theos/obj/debug/arm64/HookTestTweak.dylib -L/home/haow6/.theos/lib -L/home/haow6/.theos/vendor/lib -lobjc -framework Foundation -framework CoreFoundation -framework CydiaSubstrate -lc++ -U "_OBJC_CLASS_\$_Hook_HTTestClass" /home/haow6/source/HookTest/HookTestTweak/.theos/obj/debug/arm64/Tweak.m.bd8afb95.o -lc++ -lSystem -F/home/haow6/.theos/vendor/lib
Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_HTTestClass", referenced from:
      _OBJC_CLASS_$_Hook_HTTestClass in Tweak.m.bd8afb95.o
  "_OBJC_METACLASS_$_HTTestClass", referenced from:
      _OBJC_METACLASS_$_Hook_HTTestClass in Tweak.m.bd8afb95.o
ld: symbol(s) not found for architecture arm64

I could use -Wl,-undefined,dynamic_lookup but it complains that it's deprecated.

I hope I'm on the correct track but any help would be greatly appreciated!


Solution

  • The $ character is special to both make and the shell, so you have to escape it twice, once for each.

    For make, you double it via $$ to escape it. For the shell, you include it in single quotes. So try:

    HookTestTweak_LDFLAGS += -v '-Wl,-U,_OBJC_CLASS_$$_Hook_HTTestClass'