Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2005-01

Is it possible to link to SO libraries that have filename ending like '.so.0'

6 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Michalis Kamburelis

Hi

This problem arised with recent change to JEDI-SDL, but it seems a general problem with linking to libraries under UNIXes.

Before the change, JEDI-SDL headers linked to libraries named like 'libSDL.so', using constructs that looked like (after removing preproc $ifdefs and resolving constants)

   procedure SDL_Quit; cdecl; external 'libSDL.so';

and it worked OK. Of course, libSDL.so was on all systems only a symlink to an actual so file, e.g. to 'libSDL-1.2.so.0.7.0' on my system.

However, recently we're trying to link to 'libSDL-1.2.so.0', to make sure that at compilation time we're linking to proper SDL version (since JEDI-SDL headers were always supposed to work only with "rather new" SDL version, not with "every possible SDL version". As is the case with most header units.) But the problem is that doing

   procedure SDL_Quit; cdecl; external 'libSDL-1.2.so.0';

fails at linking with

   /usr/bin/ld: cannot find -lSDL-1.2
   link_so_filename.dpr(4,1) Error: Error while linking

So it seems that fpc passes to ld -lSDL-1.2, and ld looks for 'libSDL-1.2.so' (without '.0' suffix). Honestly, I don't know what one should pass to ld to tell it to link to 'libSDL-1.2.so.0'.

Question: Can this be somehow fixed in FPC ? Or is it just impossible for FPC to say such thing to ld (so we have another problem that can't be solved because FPC uses external linker) ?

In another words, should this be considered something that must be fixed in JEDI-SDL (by changing lib name back to 'libSDL.so') or can this be fixed in newer FPC versions ? Or maybe it's all already working, but I have to pass some command-line parameter to FPC or use some {$...} preprocessor directive to make it work ?

Regards,

Michalis
Peter Vreman
to Michalis Kamburelis
Show quoted text 40 lines
Hi This problem arised with recent change to JEDI-SDL, but it seems a general problem with linking to libraries under UNIXes. Before the change, JEDI-SDL headers linked to libraries named like 'libSDL.so', using constructs that looked like (after removing preproc $ifdefs and resolving constants) procedure SDL_Quit; cdecl; external 'libSDL.so'; and it worked OK. Of course, libSDL.so was on all systems only a symlink to an actual so file, e.g. to 'libSDL-1.2.so.0.7.0' on my system. However, recently we're trying to link to 'libSDL-1.2.so.0', to make sure that at compilation time we're linking to proper SDL version (since JEDI-SDL headers were always supposed to work only with "rather new" SDL version, not with "every possible SDL version". As is the case with most header units.) But the problem is that doing procedure SDL_Quit; cdecl; external 'libSDL-1.2.so.0'; fails at linking with /usr/bin/ld: cannot find -lSDL-1.2 link_so_filename.dpr(4,1) Error: Error while linking So it seems that fpc passes to ld -lSDL-1.2, and ld looks for 'libSDL-1.2.so' (without '.0' suffix). Honestly, I don't know what one should pass to ld to tell it to link to 'libSDL-1.2.so.0'. Question: Can this be somehow fixed in FPC ? Or is it just impossible for FPC to say such thing to ld (so we have another problem that can't be solved because FPC uses external linker) ? In another words, should this be considered something that must be fixed in JEDI-SDL (by changing lib name back to 'libSDL.so') or can this be fixed in newer FPC versions ? Or maybe it's all already working, but I have to pass some command-line parameter to FPC or use some {$...} preprocessor directive to make it work ?

It is not possible for the compiler to detect if you want to link to a specific version or to the generic .so file. If you specify a complete filename then you must also pass the correct path where the file is located (In most cases /usr/lib) otherwise the linker can't find it. That means that the compiler needs to search for the file. This is not implemented.

Michalis Kamburelis
to Peter Vreman
Peter Vreman wrote 52 lines
>Hi > >This problem arised with recent change to JEDI-SDL, but it seems a >general problem with linking to libraries under UNIXes. > >Before the change, JEDI-SDL headers linked to libraries named like >'libSDL.so', using constructs that looked like (after removing preproc >$ifdefs and resolving constants) > > procedure SDL_Quit; cdecl; external 'libSDL.so'; > >and it worked OK. Of course, libSDL.so was on all systems only a symlink >to an actual so file, e.g. to 'libSDL-1.2.so.0.7.0' on my system. > >However, recently we're trying to link to 'libSDL-1.2.so.0', to make >sure that at compilation time we're linking to proper SDL version (since >JEDI-SDL headers were always supposed to work only with "rather new" SDL >version, not with "every possible SDL version". As is the case with most >header units.) But the problem is that doing > > procedure SDL_Quit; cdecl; external 'libSDL-1.2.so.0'; > >fails at linking with > > /usr/bin/ld: cannot find -lSDL-1.2 > link_so_filename.dpr(4,1) Error: Error while linking > >So it seems that fpc passes to ld -lSDL-1.2, and ld looks for >'libSDL-1.2.so' (without '.0' suffix). Honestly, I don't know what one >should pass to ld to tell it to link to 'libSDL-1.2.so.0'. > >Question: Can this be somehow fixed in FPC ? Or is it just impossible >for FPC to say such thing to ld (so we have another problem that can't >be solved because FPC uses external linker) ? > >In another words, should this be considered something that must be fixed >in JEDI-SDL (by changing lib name back to 'libSDL.so') or can this be >fixed in newer FPC versions ? Or maybe it's all already working, but I >have to pass some command-line parameter to FPC or use some {$...} >preprocessor directive to make it work ? It is not possible for the compiler to detect if you want to link to a specific version or to the generic .so file. If you specify a complete filename then you must also pass the correct path where the file is located (In most cases /usr/lib) otherwise the linker can't find it. That means that the compiler needs to search for the file. This is not implemented.

You mean that

   procedure SDL_Quit; cdecl; external '/usr/lib/libSDL-1.2.so.0';

should work ? But it does not, fails with the same error as before. And I see that link.res sill contains lines

INPUT(
-lSDL-1.2
)

Or do you mean by "This is not implemented" that for now compiler always strips path and extensions from specified library name, so even doing "external '/usr/lib/libSDL-1.2.so.0'" is not supposed to work now ?

Michalis
Marco van de Voort
to Peter Vreman: It is not possible for the compiler to detect if you want to link to a specific version…
Show quoted text 10 lines
> fixed in newer FPC versions ? Or maybe it's all already working, but I > have to pass some command-line parameter to FPC or use some {$...} > preprocessor directive to make it work ? It is not possible for the compiler to detect if you want to link to a specific version or to the generic .so file. If you specify a complete filename then you must also pass the correct path where the file is located (In most cases /usr/lib) otherwise the linker can't find it. That means that the compiler needs to search for the file. This is not implemented.

I wouldn't advise this anyway (to put this in the compiler. Better use an installer (script or bin) to search stuff like this, and make the symlink if necessary.

There are simply too many naming conventions, directories etc to do this right, and upfront in a FPC release that must be good for at least a year.

Moreover it makes shipping binary libraries near impossible. (which is why the generic one must exist always anyway)

Pedro Lopez-Cabanillas
to Michalis Kamburelis: Hi This problem arised with recent change to JEDI-SDL, but it seems a general problem…

Hi,

Michalis Kamburelis wrote 13 lines
So it seems that fpc passes to ld -lSDL-1.2, and ld looks for 'libSDL-1.2.so' (without '.0' suffix). Honestly, I don't know what one should pass to ld to tell it to link to 'libSDL-1.2.so.0'. Question: Can this be somehow fixed in FPC ? Or is it just impossible for FPC to say such thing to ld (so we have another problem that can't be solved because FPC uses external linker) ? In another words, should this be considered something that must be fixed in JEDI-SDL (by changing lib name back to 'libSDL.so') or can this be fixed in newer FPC versions ? Or maybe it's all already working, but I have to pass some command-line parameter to FPC or use some {$...} preprocessor directive to make it work ?

IMHO, FPC behaves right and matches with other UNIX's compilers, like GCC. In fact it is the "ld" linker behavior, not the compiler.

You should tell to the linker to bind your program against a generic library 'libSDL.so', and then it will find the real "soname", that will be extracted from the real library and stored into your program, so the dynamic loader (ld-loader) will be able to find the right library at run time. I mean:

You can have two versions of some library in your system, say: /usr/lib/libFOO.so.1.0.0 and /usr/lib/libFOO.so.2.0.0; but only one symlink /usr/lib/libFOO.so pointing to any of them. You only need this symlink to compile programs, not to execute them. This means that even if you have several versions, you only develop programs for one version at a time. The liker extracts from the real library file the "soname" symbol, that is usually something like "libFOO.so.2", including the major version name. This symbol is included in your program, and will be used to find the real library that should be can test the sonames for a program with the "ldd" utility.

Compare with GCC:
http://ww.telent.net/linux/GCC-HOWTO-6.html#index.73

Regards,
Pedro

Michalis Kamburelis
to Pedro Lopez-Cabanillas
Pedro Lopez-Cabanillas wrote 44 lines
Hi, On Wednesday 05 January 2005 16:49, Michalis Kamburelis wrote: >So it seems that fpc passes to ld -lSDL-1.2, and ld looks for >'libSDL-1.2.so' (without '.0' suffix). Honestly, I don't know what one >should pass to ld to tell it to link to 'libSDL-1.2.so.0'. > >Question: Can this be somehow fixed in FPC ? Or is it just impossible >for FPC to say such thing to ld (so we have another problem that can't >be solved because FPC uses external linker) ? > >In another words, should this be considered something that must be fixed >in JEDI-SDL (by changing lib name back to 'libSDL.so') or can this be >fixed in newer FPC versions ? Or maybe it's all already working, but I >have to pass some command-line parameter to FPC or use some {$...} >preprocessor directive to make it work ? IMHO, FPC behaves right and matches with other UNIX's compilers, like GCC. In fact it is the "ld" linker behavior, not the compiler. You should tell to the linker to bind your program against a generic library 'libSDL.so', and then it will find the real "soname", that will be extracted from the real library and stored into your program, so the dynamic loader (ld-loader) will be able to find the right library at run time. I mean: You can have two versions of some library in your system, say: /usr/lib/libFOO.so.1.0.0 and /usr/lib/libFOO.so.2.0.0; but only one symlink /usr/lib/libFOO.so pointing to any of them. You only need this symlink to compile programs, not to execute them. This means that even if you have several versions, you only develop programs for one version at a time. The liker extracts from the real library file the "soname" symbol, that is usually something like "libFOO.so.2", including the major version name. This symbol is included in your program, and will be used to find the real library that should be can test the sonames for a program with the "ldd" utility. Compare with GCC: http://ww.telent.net/linux/GCC-HOWTO-6.html#index.73 Regards, Pedro

Thanks for answer, although I knew that ld does such thing, and I know that it's standard UNIX behaviour of linking under UNIXes. But I think that in some cases such behaviour is not perfect, as you can't precisely specify in source code of your program to what version of the library you want to link.

Two examples:
- Consider for example JEDI-SDL sources: you have 'libSDL.so' written in source code but compiled executable is actually linked to something more specific. Everything seems fine (as I have what I wanted, compiled binary is actually linked to 'libSDL-1.2.so.0'). But the problem is that it means that the same source code compiled on different systems may produce different executable code.

- Example from my own programs: I use libpng. And I use only a limited subset of libpng API, and this subset is supported by both libpng.so.2 and libpng.so.3. So I thought that I'll be OK if I will link to 'libpng.so', and check at runtime using png_access_version_number whether I work with supported version of libpng.

However, this failed as my compiled program was actually linked to 'libpng.so.3', not 'libpng.so' (because at the time of compilation libpng.so was on my system a symlink to libpng.so.3).

Of course, simple workaround exists: don't link using "external" clauses but instead do explicit dlopen/dlsym/dlclose calls. But this complicates code (a little).

Anyway, I understand that this issue is not related to FPC but to UNIX linker behaviour. Thanks for all answers.

Michalis