Sign in Join

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

Mailing lists / fpc-pascal / 2013-06

Can someone please explain the linker to me?

5 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Anthony Walter

I am having a lot of problems due to me not understanding why the linker acts the way it does and would appreciate it if someone could explain to me why or how some of the my problem are occurring. I'll provide some examples.

Example on Linux

I am linking to openssl which I assume is already provided on most if not all distros. On 12.04 32 bit I was using "external 'libssl.so'" at the end of all my function imports which worked fine.

On 13.04 this broke and I found there was no libssl.so in /usr/lib but there was a libssl.so.1.0.0 in /lib/x86_64-linux-gnu/libssl.so.1.0.0. I then created a symbolic link to that shared object in my /usr/lib folder named libssl.so and everything worked, or so I thought.

When I tried to use the crypto functions again on 13.04 the linker said it couldn't link "libcrypto", so it would seem that on one distro the crypto function are in libssl while in another they are in libcrypto .... okay I guess that happens.

But the the weird thing is I created a symbolic link from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
to /usr/lib/libcrypto.so.1.0.0 and when I switch my pascal code to use "external 'libcrypto.so.1.0.0'" I still get the linking error stating that libcrypto could not be found. I had to create the symbolic link as /iusr/lib/libcrypto.so and then it worked.

Having a thought I renamed my external to this garbage "external 'libcrypto.so.1.2.asdasd'" and it compiled and everything still works. So it would seem that the linker is is ignoring everything outside the word 'crypto' and requires I specifically name the files 'libcrypto.so' and 'libssl.so'.

So basically ...

const
  libssl = 'libssl.so.1.0.0';
  libcrypto = 'libcrypto.so.1.0.0';
function SSL_library_init: Integer; cdecl; external libssl;
function MD5_Init(out context: TMD5Ctx): LongBool; cdecl; external
libcrypto;

Will not link because the linker wants to find 'libssl' and 'libcrypto'. I have to create those specific symbolic links (a symbolic link or even a copied file named libssl.so.1.0.0 does not link). Why is the linker forcing me to use that specific names and why does free pascal ignore my external name (I can write libssl = 'libssl.so.asdfga'; and it still links so long as libssl.so exists in my /usr/lib directory)?

Ewald
to Anthony Walter

Once upon a time, Anthony Walter said:

Show quoted text 16 lines
On 13.04 this broke and I found there was no libssl.so in /usr/lib but there was a libssl.so.1.0.0 in /lib/x86_64-linux-gnu/libssl.so.1.0.0. I then created a symbolic link to that shared object in my /usr/lib folder named libssl.so and everything worked, or so I thought. When I tried to use the crypto functions again on 13.04 the linker said it couldn't link "libcrypto", so it would seem that on one distro the crypto function are in libssl while in another they are in libcrypto .... okay I guess that happens. But the the weird thing is I created a symbolic link from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 to /usr/lib/libcrypto.so.1.0.0 and when I switch my pascal code to use "external 'libcrypto.so.1.0.0'" I still get the linking error stating that libcrypto could not be found. I had to create the symbolic link as /iusr/lib/libcrypto.so and then it worked.

Perhaps libopenssl references libcrypto, and thus you need both in your library search path. By the way, why son't you just add your `/lib/x86_64-linux-gnu/` directory to the library path? I believe there was an command line option for fpc that did that (or you can maybe pass a similar option to the linker directly). [not tested: try adding `-Fl/lib/x86_64-linux-gnu/` to the fpc command line?]

Show quoted text 6 lines
Having a thought I renamed my external to this garbage "external 'libcrypto.so.1.2.asdasd'" and it compiled and everything still works. So it would seem that the linker is is ignoring everything outside the word 'crypto' and requires I specifically name the files 'libcrypto.so' and 'libssl.so'.

IIRC the part after `.so` is considered a version number (or indication thereof). The behaviour you are seeing is *probably* that the linker could not find `libcrypto.so.1.2.asdasd`, so it decides to use the one it found instead.

Anyway, I don't know that much about `the linker` either, but this would be my guess.

Ewald
Jonas Maebe
to Anthony Walter: I am having a lot of problems due to me not understanding why the linker acts the way it…
Anthony Walter wrote 8 lines
I am linking to openssl which I assume is already provided on most if not all distros. On 12.04 32 bit I was using "external 'libssl.so'" at the end of all my function imports which worked fine. On 13.04 this broke and I found there was no libssl.so in /usr/lib but there was a libssl.so.1.0.0 in /lib/x86_64-linux-gnu/libssl.so.1.0.0. I then created a symbolic link to that shared object in my /usr/lib folder named libssl.so and everything worked, or so I thought.

That is the wrong approach. Delete the .so symlink again, and instead install the libssl-dev package (or similar).

The linker will only look for lib<name>.so, but it will resolve that link to its target in case it's a symlink, so that the symlink is no longer required at run time. It will not look for lib<name>.so.<something>, that one is only used by the programs at run time (since the symlinks at compile/link time pointed to it and the linker will write the name of this symlink target into the binary's list of linked libraries).

Jonas

Anthony Walter
to Jonas Maebe

Ah, so compiling/linking would normally need the libxxx-dev development files. I added libssl-dev and libxml2-dev get commands to my Linux install script. I am trying to avoid situations where compiling projects requires users to set paths or copy files/create sym links manually.

Sven Barth
to Anthony Walter
"Anthony Walter" wrote
Ah, so compiling/linking would normally need the libxxx-dev development

files. I added libssl-dev and libxml2-dev get commands to my Linux install script. I am trying to avoid situations where compiling projects requires users to set paths or copy files/create sym links manually. In the end it will depend on the distribution. E.g. ArchLinux does not use (nor provide) *-dev packages.

Regards,
Sven