Sign in Join

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

Mailing lists / fpc-pascal / 2015-01

Linker script doesn't search in /usr/lib32 when cross compiling from x86_64 to i386

9 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

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

leledumbo

I just updated to FPC 29428 and now I can no longer cross compile to i386 (I'm on x86_64). The linking stage always fail with: "/usr/bin/ld: skipping incompatible <libpath here> when searching for -l<libname>"

The weird thing is that the linker only looks at /lib and /usr/lib, but not /usr/lib32, which should be the location of 32-bit libraries on 64-bit system. Using -Cn, I can see that link.res doesn't contain path to /usr/lib32, and manually changing it makes the linking success.

Reply by email

leledumbo
to leledumbo
The weird thing is that the linker only looks at /lib and /usr/lib, but not

/usr/lib32, which should be the location of 32-bit libraries on 64-bit system. Using -Cn, I can see that link.res doesn't contain path to /usr/lib32, and manually changing it makes the linking success.

OK, this one can be solved by explicitly stating /usr/lib32 via -Fl in fpc.cfg (but even then the linker script still adds /lib and /usr/lib to the SEARCH_DIR). The actual problem that makes the linking fail is the two inputs:

/lib/crti.o
/lib/crtn.o

This is because /lib is a symlink to /usr/lib in 64-bit systems. Changing the symlink to /usr/lib32 makes the linking works, but obviously not an elegant solution.

Reply by email

Jonas Maebe
to leledumbo: I just updated to FPC 29428 and now I can no longer cross compile to i386 (I'm on…
leledumbo wrote 5 lines
The weird thing is that the linker only looks at /lib and /usr/lib, but not /usr/lib32, which should be the location of 32-bit libraries on 64-bit system. Using -Cn, I can see that link.res doesn't contain path to /usr/lib32, and manually changing it makes the linking success.

Because we don't use the linker's "-T" option (the one the linker warning refers to), the link.res should be added to the built-in linker script of your system rather than replace it. This built-in linker script should already contain the default library paths. Run "ld -m elf_i386 --verbose" to see this built-in linker script. The default directories are listed via SEARCH_DIR() near the top.

I don't know what could have changed in FPC to cause your observed change. Did you perhaps also regenerate your fpc.cfg configuration file when updating? Maybe something changed in that regard.

Jonas

Reply by email

leledumbo
to Jonas Maebe
Show quoted text 10 lines
Because we don't use the linker's "-T" option (the one the linker warning refers to), the link.res should be added to the built-in linker script of your system rather than replace it. This built-in linker script should already contain the default library paths. Run "ld -m elf_i386 --verbose" to see this built-in linker script. The default directories are listed via SEARCH_DIR() near the top. I don't know what could have changed in FPC to cause your observed change. Did you perhaps also regenerate your fpc.cfg configuration file when updating? Maybe something changed in that regard.

Sorry, I forget to tell you that Marco has given the answer by using -Xd. ld -m elf_i386 --verbose does show the forbidden-for-32-bit-target paths, so it's ld behavior. I now specify correct -Fl surrounded in #ifdef - #endif with target cpu as condition in my fpc.cfg.

Reply by email

Jonas Maebe
to leledumbo
leledumbo wrote 13 lines
> Because we don't use the linker's "-T" option (the one the linker > warning refers to), the link.res should be added to the built-in > linker script of your system rather than replace it. This built-in > linker script should already contain the default library paths. Run > "ld -m elf_i386 --verbose" to see this built-in linker script. The > default directories are listed via SEARCH_DIR() near the top. > > I don't know what could have changed in FPC to cause your observed > change. Did you perhaps also regenerate your fpc.cfg configuration > file when updating? Maybe something changed in that regard. Sorry, I forget to tell you that Marco has given the answer by using -Xd.

That should not be necessary.

ld -m elf_i386 --verbose does show the forbidden-for-32-bit-target paths,

But does it also show the 32 bit ones? If not, you should probably file a bug report against your distribution, and the difference presumably did not come from an update of FPC, but from an update of your system.

Jonas

Reply by email

Marco van de Voort
to Jonas Maebe

In our previous episode, Jonas Maebe said:

Show quoted text 5 lines
> > Sorry, I forget to tell you that Marco has given the answer by using > -Xd. That should not be necessary.

-Xd has nothing to do with linker scripts from ld. It prevents FPC t_linux code from adding default paths to the script.

For target i386 t_linux:133

Which are fine for i386 hosted-and-targeted binaries, but not for i386 targeting binaries on a x86_64 hosted system.

Reply by email

Jonas Maebe
to Marco van de Voort
Marco van de Voort wrote 9 lines
In our previous episode, Jonas Maebe said: >> >> Sorry, I forget to tell you that Marco has given the answer by using >> -Xd. > > That should not be necessary. -Xd has nothing to do with linker scripts from ld. It prevents FPC t_linux code from adding default paths to the script.

I know, and it should not be necessary.

For target i386 t_linux:133 Which are fine for i386 hosted-and-targeted binaries, but not for i386 targeting binaries on a x86_64 hosted system.

The linker will simply skip libraries for incompatible architectures.

Jonas

Reply by email

leledumbo
to Jonas Maebe: That should not be necessary. But does it also show the 32 bit ones? If not, you should…
But does it also show the 32 bit ones?

$ ld -m elf_i386 --verbose
GNU ld (GNU Binutils) 2.25
Supported emulations:
elf_x86_64
elf32_x86_64
elf_i386
i386linux
elf_l1om
elf_k1om
using internal linker script:
================================================== /* Script for -z combreloc: combine and sort reloc sections */ /* Copyright (C) 2014 Free Software Foundation, Inc. Copying and distribution of this script, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. */
OUTPUT_FORMAT("elf32-i386", "elf32-i386",
"elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SEARCH_DIR("/usr/i386-unknown-linux-gnu/lib32");
SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib32"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/usr/i386-unknown-linux-gnu/lib");

I don't see /usr/lib32 here, which is necessary.

Reply by email

Jonas Maebe
to leledumbo
leledumbo wrote 9 lines
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) ENTRY(_start) SEARCH_DIR("/usr/i386-unknown-linux-gnu/lib32"); SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib32"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/usr/i386-unknown-linux-gnu/lib"); I don't see /usr/lib32 here, which is necessary.

Definitely file a bug report with your distro.

Jonas

Reply by email