5

I have the header files of a shared library but not the shared library nor its source code.

Can I still compile some code against this library?

If not, what information does the shared library contain which is not in the headers?

Georg Schölly
  • 124,188
  • 49
  • 220
  • 267
  • 1
    It is possible in AIX: when linking, you can use an _export-file_ instead of the actual library. I don't know if something like that is possible in GNU/Linux – Zsigmond Lőrinczy Jul 11 '17 at 04:18
  • See also: [c++ - Do shared libraries (.so) files need to present (or specified) at link time? - Stack Overflow](https://stackoverflow.com/questions/42017681/do-shared-libraries-so-files-need-to-present-or-specified-at-link-time) – user202729 Nov 18 '22 at 20:17

3 Answers3

5

Can I still compile some code against this library?

Compile: yes. Link: maybe.

You can create a dummy library to link against. E.g. if the header contains:

int library_func(void*);

then:

// dummy_lib.c
int library_func(void *p) { return 0; }

gcc -fPIC -shared -o libfoo.so dummy_lib.c

# Now you can use libfoo.so to link your program.

There are some gotcha's:

  1. The real library may have SONAME of something other than libfoo.so (e.g. libfoo.so.2). There is no way for you to know without access to the real libfoo.
  2. The real library could use versioned symbols. If you link your program against the dummy library, it will use default version of all referenced symbols, which is likely to be correct now, but is likely to break in the future (if/when the real library is updated with a new and incompatible implementation of any symbols you call).
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • 3
    I found a simpler although less robust solution: Create an empty library using clang: `echo "" | clang++ -shared -fPIC -x c++ - -o libfoo.so` and tell `clang / ld` to ignore the unresolved symbols when linking: `-Wl,--unresolved-symbols=ignore-in-object-files`. – Georg Schölly Jul 11 '17 at 11:51
3

Yes. You can declare pointers-to-functions for them, and then call dlopen and dlsym, and off you go. However, trying to concoct somehow an executable or shared library which acts as if you've linked to the library is risky; see Employed Russian's answer for details.

You will need this libraries themselves to run the code, of course.

However, note that not all 'shared libs' are just shared libs. In some cases, there is a .a file that is used at link time to supply some statically linked code in addition to the .so at runtime. This is not common.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
  • "The linker does not change anything based on the contents of the libraries." -- this is very much false when one considers versioned symbols. – Employed Russian Jul 10 '17 at 23:37
  • I don't think that versioned symbols have curious effects of this form when you are going to use dlopen and dlsym. I will clarify. – bmargulies Jul 11 '17 at 04:05
  • `dlsym` and versioned symbols interact in even more confusing (arguably broken) ways. https://sourceware.org/bugzilla/show_bug.cgi?id=14932 – Employed Russian Jul 11 '17 at 13:49
1

For those who just want it done, aside from using a dummy lib, there is another (probably even less robust) option: patchelf

Execute the following command after linking complete

patchelf --add-needed missinglib.so mylib.so

For CMake users, this can be done automatically by adding

add_custom_command(
    TARGET mylib POST_BUILD
    COMMAND patchelf --add-needed missinglib.so "$<TARGET_FILE:mylib>")
Huazuo Gao
  • 1,603
  • 14
  • 20