Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #151250 > unrolled thread
| Started by | Frederick Gotham <cauldwell.thomas@gmail.com> |
|---|---|
| First post | 2020-04-09 05:49 -0700 |
| Last post | 2020-04-10 09:09 -0500 |
| Articles | 16 — 9 participants |
Back to article view | Back to comp.lang.c
Linker error I've never seen before Frederick Gotham <cauldwell.thomas@gmail.com> - 2020-04-09 05:49 -0700
Re: Linker error I've never seen before Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-04-09 05:59 -0700
Re: Linker error I've never seen before Frederick Gotham <cauldwell.thomas@gmail.com> - 2020-04-09 06:06 -0700
Re: Linker error I've never seen before Richard Damon <Richard@Damon-Family.org> - 2020-04-09 09:24 -0400
Re: Linker error I've never seen before Frederick Gotham <cauldwell.thomas@gmail.com> - 2020-04-09 06:40 -0700
Re: Linker error I've never seen before felix@palmen-it.de (Felix Palmen) - 2020-04-09 16:46 +0200
Re: Linker error I've never seen before BGB <cr88192@gmail.com> - 2020-04-09 13:17 -0500
Re: Linker error I've never seen before Frederick Gotham <cauldwell.thomas@gmail.com> - 2020-04-09 06:22 -0700
Re: Linker error I've never seen before gazelle@shell.xmission.com (Kenny McCormack) - 2020-04-09 13:47 +0000
Re: Linker error I've never seen before scott@slp53.sl.home (Scott Lurndal) - 2020-04-09 14:57 +0000
Re: Linker error I've never seen before Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-04-09 13:08 -0700
Re: Linker error I've never seen before jacobnavia <jacob@jacob.remcomp.fr> - 2020-04-09 19:40 +0200
Re: Linker error I've never seen before BGB <cr88192@gmail.com> - 2020-04-09 13:10 -0500
Re: Linker error I've never seen before felix@palmen-it.de (Felix Palmen) - 2020-04-10 09:16 +0200
Re: Linker error I've never seen before BGB <cr88192@gmail.com> - 2020-04-10 08:54 -0500
Re: Linker error I've never seen before BGB <cr88192@gmail.com> - 2020-04-10 09:09 -0500
| From | Frederick Gotham <cauldwell.thomas@gmail.com> |
|---|---|
| Date | 2020-04-09 05:49 -0700 |
| Subject | Linker error I've never seen before |
| Message-ID | <2aab30ec-f3e7-4b46-9be5-bbc5ddd01f91@googlegroups.com> |
About ten years ago I thought that I'd seen every kind of compiler and linker error.
Today I'm stumped. It's a linker error that has me stumped.
Let's say I have already compiled a dynamic shared library, and my library is called 'Monkey'. So on MS-Windows, I have "libMonkey.dll", and on Linux and Mac, I have "libMonkey.so".
So then I write a program that makes use of my Monkey library, and I compile it like so:
gcc -o new_program new_program.c -lMonkey
This compilation of "new_program" is failing, and the linker is saying that there are undefined references in the Monkey library. I've never seen this before. My Monkey library has already been successfully compiled. I can't see how "new_program" would fail to link. I've never known a linker to complain that a dynamic shared library, which has already been compiled, contains undefined references. I'm only trying to link with a library that's already been compiled.
I'm working on ARM 32-Bit embedded Linux, and so I build in two steps like this:
arm-linux-gnueabihf-gcc -o frederick.o -c frederick.c
arm-linux-gnueabihf-gcc -o frederick frederick.o -lMonkey
The first command succeeds and creates the object file.
The second command fails with this output:
libMonkey.so: undefined reference to `log_debug'
libMonkey.so: undefined reference to `log_error'
libMonkey.so: undefined reference to `log_trace'
libMonkey.so: undefined reference to `log_info'
collect2: error: ld returned 1 exit status
I've never seen a linker do this before.
Any got a clue what's going on?
[toc] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2020-04-09 05:59 -0700 |
| Message-ID | <677f2dca-afc7-4ec7-bb3f-9fe3b31b72af@googlegroups.com> |
| In reply to | #151250 |
On Thursday, 9 April 2020 13:49:55 UTC+1, Frederick Gotham wrote: > About ten years ago I thought that I'd seen every kind of compiler and linker error. > > Today I'm stumped. It's a linker error that has me stumped. > > Let's say I have already compiled a dynamic shared library, and my library is called 'Monkey'. So on MS-Windows, I have "libMonkey.dll", and on Linux and Mac, I have "libMonkey.so". > > So then I write a program that makes use of my Monkey library, and I compile it like so: > > gcc -o new_program new_program.c -lMonkey > > This compilation of "new_program" is failing, and the linker is saying that there are undefined references in the Monkey library. I've never seen this before. My Monkey library has already been successfully compiled. I can't see how "new_program" would fail to link. I've never known a linker to complain that a dynamic shared library, which has already been compiled, contains undefined references. I'm only trying to link with a library that's already been compiled. > > I'm working on ARM 32-Bit embedded Linux, and so I build in two steps like this: > > arm-linux-gnueabihf-gcc -o frederick.o -c frederick.c > > arm-linux-gnueabihf-gcc -o frederick frederick.o -lMonkey > > The first command succeeds and creates the object file. > > The second command fails with this output: > > libMonkey.so: undefined reference to `log_debug' > libMonkey.so: undefined reference to `log_error' > libMonkey.so: undefined reference to `log_trace' > libMonkey.so: undefined reference to `log_info' > collect2: error: ld returned 1 exit status > > I've never seen a linker do this before. > > Any got a clue what's going on? > I'd guess that the lib Monkey people haven't been following comp.lang.c and dont separate out their IO. So the library still has an external dependency (though only for logging and error handling). YOu need to find out where log_error and the linke are defined, and link them. Or supply your own stubs. Which means finding out the functions' signatures.
[toc] | [prev] | [next] | [standalone]
| From | Frederick Gotham <cauldwell.thomas@gmail.com> |
|---|---|
| Date | 2020-04-09 06:06 -0700 |
| Message-ID | <b20e89cc-9db7-453a-be3a-81cb621f4d74@googlegroups.com> |
| In reply to | #151251 |
On Thursday, April 9, 2020 at 1:59:54 PM UTC+1, Malcolm McLean wrote:
> I'd guess that the lib Monkey people haven't been following comp.lang.c
> and dont separate out their IO. So the library still has an external
> dependency (though only for logging and error handling).
I would expect my own program, "new_program", to compile successfully. Then if I go to run my program, I would understand if it can't find certain dynamic shared libraries.
But that's not what's happening. My program is failing to link even though libMonkey has already been successfully compiled to a binary.
> YOu need to find out where log_error and the linke are defined, and
> link them. Or supply your own stubs. Which means finding out the
> functions' signatures.
I've searched through the entire repository for any library exporting those functions, and I haven't found any. I searched like this:
find -iname "*.so" | xargs -n1 readelf -d | grep -i "log_trace"
find -iname "*.a" | xargs -n1 nm | grep -i "log_trace"
For the time being I will make a dummy library with stubs. I have the function signatures.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2020-04-09 09:24 -0400 |
| Message-ID | <LmFjG.824878$Zw7.259473@fx34.iad> |
| In reply to | #151252 |
On 4/9/20 9:06 AM, Frederick Gotham wrote: > On Thursday, April 9, 2020 at 1:59:54 PM UTC+1, Malcolm McLean wrote: > >> I'd guess that the lib Monkey people haven't been following comp.lang.c >> and dont separate out their IO. So the library still has an external >> dependency (though only for logging and error handling). > > > I would expect my own program, "new_program", to compile successfully. Then if I go to run my program, I would understand if it can't find certain dynamic shared libraries. > > But that's not what's happening. My program is failing to link even though libMonkey has already been successfully compiled to a binary. > A library does not need to satisfy all its own requirements, it may well need another library, or even for the calling program to define functions for it to call back to. A library is different in that respect than a final executable. > >> YOu need to find out where log_error and the linke are defined, and >> link them. Or supply your own stubs. Which means finding out the >> functions' signatures. > > > I've searched through the entire repository for any library exporting those functions, and I haven't found any. I searched like this: > > find -iname "*.so" | xargs -n1 readelf -d | grep -i "log_trace" > find -iname "*.a" | xargs -n1 nm | grep -i "log_trace" > > For the time being I will make a dummy library with stubs. I have the function signatures. > Read the documentation for libMonkey, they likely define these functions as call backs to the application to allow you to adjust its logging behavior. You need not just the signatures, but what they are supposed to do. It may be that a basically nil stub would work, but it also might not.
[toc] | [prev] | [next] | [standalone]
| From | Frederick Gotham <cauldwell.thomas@gmail.com> |
|---|---|
| Date | 2020-04-09 06:40 -0700 |
| Message-ID | <9a46faa7-5850-45a6-91d6-2f417d7f688f@googlegroups.com> |
| In reply to | #151254 |
On Thursday, April 9, 2020 at 2:25:08 PM UTC+1, Richard Damon wrote:
> Read the documentation for libMonkey, they likely define these functions
> as call backs to the application to allow you to adjust its logging
> behavior. You need not just the signatures, but what they are supposed
> to do. It may be that a basically nil stub would work, but it also might
> not.
I figured it out. Here's what I did in my C++ program:
extern "C" {
#if 0
int log_error(const char* func, const char *format, ...) __attribute__((visibility("default")));
int log_info(const char* func, const char *format, ...) __attribute__((visibility("default")));
int log_debug(const char* func, const char *format, ...) __attribute__((visibility("default")));
int log_trace(const char* func, const char *format, ...) __attribute__((visibility("default")));
#endif
int log_error(const char* func, const char *format, ...)
{
return 0;
}
int log_info(const char* func, const char *format, ...)
{
return 0;
}
int log_debug(const char* func, const char *format, ...)
{
return 0;
}
int log_trace(const char* func, const char *format, ...)
{
return 0;
}
}
int main(void)
{
}
Now it compiles just fine without having to pass any special options to the linker.
[toc] | [prev] | [next] | [standalone]
| From | felix@palmen-it.de (Felix Palmen) |
|---|---|
| Date | 2020-04-09 16:46 +0200 |
| Message-ID | <a2p3mg-1cc2.ln1@mail.home.palmen-it.de> |
| In reply to | #151255 |
* Frederick Gotham <cauldwell.thomas@gmail.com>:
> I figured it out. Here's what I did in my C++ program:
What's that '#if 0' block good for? :o
Anyways, if that's how the library is meant to be used, an obvious
feature request would be to provide a "null logger" by default. If the
application is interested in the log messages, it could actively set
callbacks...
--
Dipl.-Inform. Felix Palmen <felix@palmen-it.de> ,.//..........
{web} http://palmen-it.de {jabber} [see email] ,//palmen-it.de
{pgp public key} http://palmen-it.de/pub.txt // """""""""""
{pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A
[toc] | [prev] | [next] | [standalone]
| From | BGB <cr88192@gmail.com> |
|---|---|
| Date | 2020-04-09 13:17 -0500 |
| Message-ID | <r6nos8$1ae$1@dont-email.me> |
| In reply to | #151262 |
On 4/9/2020 9:46 AM, Felix Palmen wrote: > * Frederick Gotham <cauldwell.thomas@gmail.com>: >> I figured it out. Here's what I did in my C++ program: > > What's that '#if 0' block good for? :o > > Anyways, if that's how the library is meant to be used, an obvious > feature request would be to provide a "null logger" by default. If the > application is interested in the log messages, it could actively set > callbacks... > (Hmm, seems I should have read the full thread first) But, yeah, I agree. The library doing logging in this way is both non-portable and annoying, and the use of explicit callback registration or similar would have been preferable.
[toc] | [prev] | [next] | [standalone]
| From | Frederick Gotham <cauldwell.thomas@gmail.com> |
|---|---|
| Date | 2020-04-09 06:22 -0700 |
| Message-ID | <3085aa51-dee1-466f-8800-0978c2f0afef@googlegroups.com> |
| In reply to | #151250 |
I got it to compile with this option passed to the linker:
-Wl,--allow-shlib-undefined
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2020-04-09 13:47 +0000 |
| Message-ID | <r6n90u$fis$1@news.xmission.com> |
| In reply to | #151253 |
In article <3085aa51-dee1-466f-8800-0978c2f0afef@googlegroups.com>, Frederick Gotham <cauldwell.thomas@gmail.com> wrote: >I got it to compile with this option passed to the linker: > > -Wl,--allow-shlib-undefined Yes, but you're just delaying the problem to runtime. The program won't run (at least when it tries to call those functions). Actually, it has been a while since I've tested this - On Linux, does it fail immediately, or does it only fail when it tries to call the function? -- Marshall: 10/22/51 Jessica: 4/4/79
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2020-04-09 14:57 +0000 |
| Message-ID | <4JGjG.1048869$K87.276783@fx46.iad> |
| In reply to | #151256 |
gazelle@shell.xmission.com (Kenny McCormack) writes: >In article <3085aa51-dee1-466f-8800-0978c2f0afef@googlegroups.com>, >Frederick Gotham <cauldwell.thomas@gmail.com> wrote: >>I got it to compile with this option passed to the linker: >> >> -Wl,--allow-shlib-undefined > >Yes, but you're just delaying the problem to runtime. > >The program won't run (at least when it tries to call those functions). > >Actually, it has been a while since I've tested this - On Linux, does it >fail immediately, or does it only fail when it tries to call the function? That entirely depends on the environment or the caller of dlopen; Lazy binding is the default, but options (to dlopen and via environment variables) exist to bind at load.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2020-04-09 13:08 -0700 |
| Message-ID | <87y2r4juce.fsf@nosuchdomain.example.com> |
| In reply to | #151253 |
Frederick Gotham <cauldwell.thomas@gmail.com> writes:
> I got it to compile with this option passed to the linker:
>
> -Wl,--allow-shlib-undefined
No, you got it to *link* with that option. It was already compiling
(or you wouldn't have gotten to the point of a linker error in the
first place).
I hadn't known about the "--allow-shlib-undefined" option before,
but it looks like it just inhibits error messages. I wouldn't be
surprised if the resulting program failed at run time.
I see you've fixed the problem by defining your own log_error et
al functions. I don't know whether you posted the above before or
afte that post.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | jacobnavia <jacob@jacob.remcomp.fr> |
|---|---|
| Date | 2020-04-09 19:40 +0200 |
| Message-ID | <r6nmmn$fns$1@dont-email.me> |
| In reply to | #151250 |
Le 09/04/2020 à 14:49, Frederick Gotham a écrit : > > About ten years ago I thought that I'd seen every kind of compiler and linker error. > > Today I'm stumped. It's a linker error that has me stumped. > > Let's say I have already compiled a dynamic shared library, and my library is called 'Monkey'. So on MS-Windows, I have "libMonkey.dll", and on Linux and Mac, I have "libMonkey.so". > > So then I write a program that makes use of my Monkey library, and I compile it like so: > > gcc -o new_program new_program.c -lMonkey > > This compilation of "new_program" is failing, and the linker is saying that there are undefined references in the Monkey library. I've never seen this before. My Monkey library has already been successfully compiled. I can't see how "new_program" would fail to link. I've never known a linker to complain that a dynamic shared library, which has already been compiled, contains undefined references. I'm only trying to link with a library that's already been compiled. > > I'm working on ARM 32-Bit embedded Linux, and so I build in two steps like this: > > arm-linux-gnueabihf-gcc -o frederick.o -c frederick.c > > arm-linux-gnueabihf-gcc -o frederick frederick.o -lMonkey > > The first command succeeds and creates the object file. > > The second command fails with this output: > > libMonkey.so: undefined reference to `log_debug' > libMonkey.so: undefined reference to `log_error' > libMonkey.so: undefined reference to `log_trace' > libMonkey.so: undefined reference to `log_info' > collect2: error: ld returned 1 exit status > > I've never seen a linker do this before. > > Any got a clue what's going on? > > Yes, just include the icu libraries for instance. /icu/icu4c-57_1-src/icu/source/tools/ctestfw/unicode/ctest.h 195 T_CTEST_API void T_CTEST_EXPORT2 196 log_info(const char* pattern, ...);
[toc] | [prev] | [next] | [standalone]
| From | BGB <cr88192@gmail.com> |
|---|---|
| Date | 2020-04-09 13:10 -0500 |
| Message-ID | <r6nof2$u1u$1@dont-email.me> |
| In reply to | #151250 |
On 4/9/2020 7:49 AM, Frederick Gotham wrote: > > About ten years ago I thought that I'd seen every kind of compiler and linker error. > > Today I'm stumped. It's a linker error that has me stumped. > > Let's say I have already compiled a dynamic shared library, and my library is called 'Monkey'. So on MS-Windows, I have "libMonkey.dll", and on Linux and Mac, I have "libMonkey.so". > > So then I write a program that makes use of my Monkey library, and I compile it like so: > > gcc -o new_program new_program.c -lMonkey > > This compilation of "new_program" is failing, and the linker is saying that there are undefined references in the Monkey library. I've never seen this before. My Monkey library has already been successfully compiled. I can't see how "new_program" would fail to link. I've never known a linker to complain that a dynamic shared library, which has already been compiled, contains undefined references. I'm only trying to link with a library that's already been compiled. > > I'm working on ARM 32-Bit embedded Linux, and so I build in two steps like this: > > arm-linux-gnueabihf-gcc -o frederick.o -c frederick.c > > arm-linux-gnueabihf-gcc -o frederick frederick.o -lMonkey > > The first command succeeds and creates the object file. > > The second command fails with this output: > > libMonkey.so: undefined reference to `log_debug' > libMonkey.so: undefined reference to `log_error' > libMonkey.so: undefined reference to `log_trace' > libMonkey.so: undefined reference to `log_info' > collect2: error: ld returned 1 exit status > > I've never seen a linker do this before. > > Any got a clue what's going on? > Linux generally treats SO's more like object files in this regard, so it is necessary when linking against an SO to supply *all* of the dependencies both for the current program as well as anything the SO's make use of (unlike Windows and DLL's, where each DLL remembers its own set of dependencies). Linking an SO is essentially combining all of the smaller object files into a bigger object file, which is linked at runtime (unlike static libs which puts a collection of object files into an 'ar' archive, and directly links everything into the main binary). When loading, the "ld.so" binary effectively gets invoked in the background to load and link together all of the ELF objects into a combined image (via a mechanism not too different from how "#!" works for shell scripts), taking the list of libraries to from the main binary, and producing a combined image (effectively, the kernel only needs to understand statically linked binaries in this case, and how to invoke ELF's "interpreter" in other cases). The linker, however, will try to helpfully check that all of the symbols are accounted for (rather than having it fail at runtime), but since the SO in this case may not remember what it was linked against, the linker is unable to satisfy additional dependencies (hence the unresolved symbols). The mechanism for PE/COFF and DLL's is a little different, as it is basically a recursive graph walk in this case, with the loader loading each DLL in series, and then loading any depended-on DLLs (via the import tables), ... until everything is loaded. DLL's are otherwise pretty much already linked beforehand, with the loader basically applying a list of relocations (to fixup the load address), and then fills in a table of "imports" keyed to the corresponding "exports" table of each target DLL. Side note: This is also part of why DLL's need imports and exports to be given explicitly (and implicitly forms a directed acyclic graph); unlike Linux where all this is implicit and a linked SO will use any symbol with a given name regardless of where it came from (and also allows for things like casually sharing global variables and similar between libraries, ...), more like how things work with normal object files. Or such...
[toc] | [prev] | [next] | [standalone]
| From | felix@palmen-it.de (Felix Palmen) |
|---|---|
| Date | 2020-04-10 09:16 +0200 |
| Message-ID | <54j5mg-rjv2.ln1@mail.home.palmen-it.de> |
| In reply to | #151274 |
* BGB <cr88192@gmail.com>:
> Linux generally treats SO's more like object files in this regard, so it
> is necessary when linking against an SO to supply *all* of the
> dependencies both for the current program as well as anything the SO's
> make use of (unlike Windows and DLL's, where each DLL remembers its own
> set of dependencies).
Sorry, but that's wrong. An ELF shared object has DT_NEEDED entries, no
matter whether it's a library or an executable. When linking ELF shared
objects, you only supply the /direct/ dependencies to the linker
(unlike when linking static libraries, which are indeed just archives of
plain object files).
> The mechanism for PE/COFF and DLL's is a little different, as it is
> basically a recursive graph walk in this case, with the loader loading
> each DLL in series, and then loading any depended-on DLLs (via the
> import tables), ... until everything is loaded. DLL's are otherwise
> pretty much already linked beforehand, with the loader basically
> applying a list of relocations (to fixup the load address), and then
> fills in a table of "imports" keyed to the corresponding "exports" table
> of each target DLL.
PE DLLs have an extra indirection; for needed libraries, you
(statically) link an "import library" that requires a specific DLL and
symbols from /that/ DLL. Yes, this is a difference, but not to the
extent you describe here ;)
> where all this is implicit and a linked SO will use any symbol with a
> given name regardless of where it came from
This last part is actually true. An ELF shared object has a list of
needed libraries and a list of imported symbols, but it doesn't specify
which symbol to use from which library, while a PE DLL will specify
that.
Therefore, the solution from later in this thread would never work on
Windows. That's something you'll learn once you try to implement e.g.
"plugins" for Windows. If your DLL needs symbols from your main binary,
you need to create an import library of your main binary and link that
with the DLL, or communicate the interface of your main binary to the
plugin at runtime, e.g. by calling a function in the plugin that takes a
struct full of function pointers. Just exporting symbols from your main
binary won't do.
Another reason why the library discussed here seems a bit "fishy".
--
Dipl.-Inform. Felix Palmen <felix@palmen-it.de> ,.//..........
{web} http://palmen-it.de {jabber} [see email] ,//palmen-it.de
{pgp public key} http://palmen-it.de/pub.txt // """""""""""
{pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A
[toc] | [prev] | [next] | [standalone]
| From | BGB <cr88192@gmail.com> |
|---|---|
| Date | 2020-04-10 08:54 -0500 |
| Message-ID | <r6ptqo$djc$1@dont-email.me> |
| In reply to | #151284 |
On 4/10/2020 2:16 AM, Felix Palmen wrote: > * BGB <cr88192@gmail.com>: >> Linux generally treats SO's more like object files in this regard, so it >> is necessary when linking against an SO to supply *all* of the >> dependencies both for the current program as well as anything the SO's >> make use of (unlike Windows and DLL's, where each DLL remembers its own >> set of dependencies). > > Sorry, but that's wrong. An ELF shared object has DT_NEEDED entries, no > matter whether it's a library or an executable. When linking ELF shared > objects, you only supply the /direct/ dependencies to the linker > (unlike when linking static libraries, which are indeed just archives of > plain object files). > This doesn't entirely match my observations though, where sometimes a full dependency list is needed for things to link correctly. Could be wrong, could be missremembering some things... Not gone and compared, eg, how desktop Linux compares with WSL, Raspbian, and Android+Termux, or GCC vs Clang behavior, ..., which I was generally lumping all together as "Linux". Admittedly, I have also tended to mostly avoid 3rd partly libraries (most things not needing much more than libc, libm, and sometimes libdl or similar). >> The mechanism for PE/COFF and DLL's is a little different, as it is >> basically a recursive graph walk in this case, with the loader loading >> each DLL in series, and then loading any depended-on DLLs (via the >> import tables), ... until everything is loaded. DLL's are otherwise >> pretty much already linked beforehand, with the loader basically >> applying a list of relocations (to fixup the load address), and then >> fills in a table of "imports" keyed to the corresponding "exports" table >> of each target DLL. > > PE DLLs have an extra indirection; for needed libraries, you > (statically) link an "import library" that requires a specific DLL and > symbols from /that/ DLL. Yes, this is a difference, but not to the > extent you describe here ;) > More or less, import libraries are one solution. Some linkers allow linking directly against the DLL, which then serves a similar role to the import library. IIRC, the import library more serves to tell the linker what symbols a given DLL exports, rather than containing much in the way of code. >> where all this is implicit and a linked SO will use any symbol with a >> given name regardless of where it came from > > This last part is actually true. An ELF shared object has a list of > needed libraries and a list of imported symbols, but it doesn't specify > which symbol to use from which library, while a PE DLL will specify > that. > > Therefore, the solution from later in this thread would never work on > Windows. That's something you'll learn once you try to implement e.g. > "plugins" for Windows. If your DLL needs symbols from your main binary, > you need to create an import library of your main binary and link that > with the DLL, or communicate the interface of your main binary to the > plugin at runtime, e.g. by calling a function in the plugin that takes a > struct full of function pointers. Just exporting symbols from your main > binary won't do. > Yeah, as noted, there is a difference. Using tables of function pointers, or using some sort of "FooGetProcAddress" style interface (get a function to get functions by name, then fetch each function by name), is something I am pretty familiar with. As can be noted, I tend to write a lot more code on Windows than I do on Linux. Also, my own projects generally use COFF and PE/COFF, so I am a little more familiar with how it works. Though, on my CPU/ISA project is using a slightly modified version of PE/COFF, which splits the ".data/.bss" sections off into their own region, and optionally LZ4 compresses the binary to save space and to speed up loading from an SDcard. Also a few (target related) tweaks to the ".reloc" data, and effectively replaces the "resource section" data with an embedded "WAD" file, ... > Another reason why the library discussed here seems a bit "fishy". > Yep.
[toc] | [prev] | [next] | [standalone]
| From | BGB <cr88192@gmail.com> |
|---|---|
| Date | 2020-04-10 09:09 -0500 |
| Message-ID | <r6punb$k5a$1@dont-email.me> |
| In reply to | #151288 |
On 4/10/2020 8:54 AM, BGB wrote: > On 4/10/2020 2:16 AM, Felix Palmen wrote: >> * BGB <cr88192@gmail.com>: >>> Linux generally treats SO's more like object files in this regard, so it >>> is necessary when linking against an SO to supply *all* of the >>> dependencies both for the current program as well as anything the SO's >>> make use of (unlike Windows and DLL's, where each DLL remembers its own >>> set of dependencies). >> >> Sorry, but that's wrong. An ELF shared object has DT_NEEDED entries, no >> matter whether it's a library or an executable. When linking ELF shared >> objects, you only supply the /direct/ dependencies to the linker >> (unlike when linking static libraries, which are indeed just archives of >> plain object files). >> > > This doesn't entirely match my observations though, where sometimes a > full dependency list is needed for things to link correctly. Could be > wrong, could be missremembering some things... > > Not gone and compared, eg, how desktop Linux compares with WSL, > Raspbian, and Android+Termux, or GCC vs Clang behavior, ..., which I was > generally lumping all together as "Linux". > > Admittedly, I have also tended to mostly avoid 3rd partly libraries > (most things not needing much more than libc, libm, and sometimes libdl > or similar). > Then just remembers... Yeah, I am at the moment (on WSL) running a program which is linked against SDL (-lSDL) without also (manually) linking against X and similar, which also works on Termux without changing anything, ... Errm, yeah, this was a bit of an oversight on my part... Not sure how I missed this...
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web