0

I have a problem at link between two libraries libA.a (static) and libB.so (dynamic), created from C sources.

In one of the source files used to generate libB.so, I have the following functions :

static uint64_t unassigned_mem_read(void *opaque, hwaddr addr, unsigned size) { ... }
static void unassigned_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { ... }

When I run nm libB.so | grep unassigned_mem I've got:

00000000004662a7 t unassigned_mem_read
0000000000466337 t unassigned_mem_write

And in a source file used for making libA.a, I've got:

extern uint64_t unassigned_mem_read(void *opaque, hwaddr addr, unsigned size);
extern void unassigned_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size);

and a bit further these methods are called.

When I compile, everything is ok. But then at link, I have:

[build] qmg-mmio.c:47: undefined reference to 'unassigned_mem_read'
[build] qmg-mmio.c:84: undefined reference to 'unassigned_mem_write'

When I do nm libA.a | grep unassigned_mem I've got:

U unassigned_mem_read
U unassigned_mem_write

I link in this order: libB.so, libA.a.

As the symbols are the same, what can make them not being resolved?

Moreover when I compile all the sources together, then I have no problem at link. Is there a subtelty when linking a static and a dynamic library altogether that I miss?

8
  • 4
    Remove the static keyword from both functions, ie. export them. Commented Jan 25, 2019 at 19:22
  • Isn't there any other possibility? I would be very pleased not touching the sources of libB.so... =/ Commented Jan 25, 2019 at 19:24
  • 1
    No, there isn't. Commented Jan 25, 2019 at 19:24
  • Damn. Even adding a file? Like a header in project B? Commented Jan 25, 2019 at 19:27
  • 1
    If you really don't want to change libB source [the easiest option], you might be able to use some object editing/linker tools to change libB.so so that you change the linkage from t (static/invisible) to T (global). If you can't find one, you could write your own small utility that uses library API calls (e.g. either libelf.so or libbfd.so) to do the heavy lifting. But, again, if you have the source and control it, you could try building it with -Dstatic=/**/. That may work as well. Commented Jan 25, 2019 at 19:56

1 Answer 1

3

For file-scope identifiers, the static keyword specifies internal linkage. That means that the identifier and any associated definition are essentially private to the translation unit in which they appear. Lest there be any confusion, note well that this is only peripherally related to "static libraries", and especially that functions in static libraries that are intended to be called directly by library users must not be declared static, as that directly and specifically prevents such calls.

Linkage is a property of identifiers, within their scopes, not of the objects or functions they identify, and not necessarily of the same identifier in other scopes. Moreover, the same identifier can be associated with different objects and / or functions in different scopes. In particular, an external declaration of a given identifier is associated with a different function or object than those associated with any internal declarations of the same identifier, so you cannot redefine an internal declaration appearing in one scope as an external one by adding a declaration in some other scope.

Since you seem reluctant to modify the library containing the functions you want to call, I'm supposing that it is provided by a third party. In that case, you should understand that part of the point of declaring those functions static is so that you, the library user, do not call them directly. They are not part of the library's external interface.

Sign up to request clarification or add additional context in comments.

1 Comment

I understand. I have to make a choice about modifying the source or just find another way to do what I want with the exposed API.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.