linuxshared-librariescompile-timeunresolved-external

How to compile-time verify that all symbols are completely defined in a linux shared object library


Recently, I realized that linux shared object libraries won't fail to compile if you try to reference an undefined function/variable. The symbols do need to be declared but not defined. I'm more familiar with Windows DLLs than I am Linux shared object libraries, and on Windows DLLs such undefined references aren't allowed. I'm not suggesting one is better than the other but it caught me by surprise.

Here's a decently short example of what I'm talking about.

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#define TRY_COMPILE_UNDEFINED_FUNC

#ifdef TRY_COMPILE_UNDEFINED_FUNC
extern int undefined_variable;
void undefined_function();
#endif // TRY_COMPILE_UNDEFINED_FUNC

void SharedLibTest_TestFunc()
{
    printf("%s executed.\n", __FUNCTION__);

    // The below ifdef block compiles just fine as a linux shared object binary.
    // It does *NOT* compile as a windows DLL.
#ifdef TRY_COMPILE_UNDEFINED_FUNC
    undefined_variable += 1;
    undefined_function();
#endif // TRY_COMPILE_UNDEFINED_FUNC
}

#ifdef __cplusplus
}
#endif // __cplusplus

I'm wondering if there's some minimally hacky way to replicate that "fail to compile" behavior from Windows DLLs with linux shared object libraries. Without getting too in the weeds, the shared object library I'm building is being used in a context where it's delay loaded and not compiled against so right now it seems the only way to catch these issues is at runtime which is prone to error.

Two ideas I've had that haven't quite panned out:

  1. adding an unused executable to the build which compiles against the shared library. this is non-ideal since it's error-prone and relies on my updating the executable to actually link against all of the different parts of the shared library (e.g. by calling exported functions and whatnot)
  2. using the nm utility to dump all unresolved symbols but that also includes unresolved symbols from things like libc

Solution

  • @user17732522 shared the answer "-Wl,--no-allow-shlib-undefined and/or -Wl,--no-undefined"