I've got some useful utilities in a .c file that I use for some debugging things. And I'm also writing a plugin that will go into an app I don't control. I also have a test harness that I can load the plugin and do effective debugging. This debugging file has some static variables that it uses to control things, like whether to emit log messages, or do other diagnoses.The problem is, if I include the
usefulStuff.c
in my plugin and my test harness, there are two copies of the static variables, and the test harness can't control the plugin. If I don't includeusefulStuff.c
in the plugin I get link errors. If I don't declare as weak linked the functions I use, I'll get errors when the final program loads the plugin. Sucks to be me.Here's one way of doing it (which is kinda hacky, but after spending a day inside of the ld man page, and other pain, the fact it works is good enough for me for right now).
In the source file for the plugin that uses stuff from usefulStuff:
Declare the function to be weak:
extern void BWDebugLog (int blah, char *blah) __attribute__((weak_import));(you can also do this in your header files. In this case, I didn't want to touch the header)Before you use the function, make sure it's not
NULL
. Note there's no trailing()
after the function name.if (BWDebugLog != NULL) { BWDebugLog (23, "stuff"); }In the Xcode project for the pluginAdd the flags
-flat_namespace
and-undefined dynamic_lookup
to the "Other Linker Flags" (a.k.a.OTHER_LDFLAGS
). The flat namespace lets the symbols be found in the test harness when the plugin is loaded. The undefined dynamic_lookup means to suppress warnings about undefined symbols. This could conceivably mask errors, but it's no worse than ZeroLink.In the Xcode project for the test harness
Add
usefulStuff.c
, and turn on the "Preserve Private External Symbols" checkbox (a.k.a-keep_private_externs
). That turns the symbolBWDebugLog
(and others) into exported symbols that'll be visible to the plugin. Otherwise the plugin will never get past that!= NULL
check earlier.Once all that's done, my plugin loads into the test harness and can get controlled. It can be loaded into the Real App without undefined symbol errors.