linker not using make.conf
Mark Millard
marklmi at yahoo.com
Wed Sep 4 20:38:18 UTC 2019
On 2019-Sep-4, at 11:35, Sid <sid at bsdmail.com> wrote:
> When the base linker is not available, the link needs to be from /usr/bin/ld rather than from /usr/local/*/ to /usr/local/bin/ld.lld80 or variant of that. Also, programs being compiled do look for /usr/bin/ld or maybe another ld under /usr/local/*. There were about two locations that could be used for each version of the compiler and its toolchain, one like you described, because another also had a soft link.
>
> Mine works, since I have a soft link from /usr/bin/ld to the needed one in /usr/local/bin/*
>
> If I remember correctly, installing xtoolchain-llvm didn't do much, except for give hints on what to put as XLD. From trial an error, I found that, LD covers everything, including what XLD covers, except when XLD is used, it overrides LD only for ports. In other words, LD in make.conf covered building the kernel, base, and ports. When XLD was set, it overrode LD's settings only for ports. At least the X version (XCC, XCXX, compared to CC, CXX) of the other make.conf setting.
>
> The point is, I wonder how much confusion is being caused for developers, when LD and XLD are not working as they are supposed to. When one gets fixed, but ends up with the same problem, because the base linker is used, rather than the one make.conf is intended to make work. I wonder if this has to do with why some ports require llvm80, and others llvm60, when the assumption is on the wrong needed update, when it's not using the linkers from those. I also guess that, this is causing difficulties for when trying to make clang's utils work for different architectures. A problem like this doesn't help, and it likely slows down development, that a new release must be waited for before significant improvements can be made. The LD setting in make.conf not working properly is a fundamental problem, that can cause other problems, and false assumptions.
>
> It's more difficult to see the problem, if the base ld is available.
>
>
>> Sent: Wednesday, September 04, 2019 at 10:18 AM
>> From: <brooks at freebsd.org>
>> Cc: freebsd-toolchain at freebsd.org
>> Subject: Re: linker not using make.conf
>
>> The LD variable only effects the very few cases where the linker is called
>> directly. The linker is almost always run via clang. If you install the
>> xtoolchain-llvm80 port it will install a link from
>> /usr/local/llvm80/bin/ld.lld to /usr/local/llvm80/bin/ld which I think will
>> be sufficient for your use case.
>>
>> On Tue, Sep 03, 2019 at 11:04:08PM +0200, Sid wrote:
>>> In /etc/make.conf, I have
>>> LD= /usr/local/bin/ld.lld80
>>>
>>> This is not used for ports. It may be used for building the kernel and world.
>>>
>>> clang-8: error: unable to execute command: Executable "ld" doesn't exist!
>>> clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
>>> *** Error code 1
>>>
>>> XLD= /usr/local/bin/ld.lld80 being set as well also provides the same error. XD sets it for all, but XLD is only applicable if a different compiler is used for ports than kernel and the base. When LD is set, XLD only applies when it is set as well, but this suggests that XLD is not working correctly either.
>>>
>>> I have to manually link /usr/bin/ld to /usr/local/bin/ld.lld80 for ports to build correctly. This is with both make, and with portmaster.
>>>
>>> I built my computer without ld in the base system, and this has worked well. make.conf should reference the chosen linker without having to manually link it. Otherwise, LD in make.conf is not working correctly, and gives the impression that one linker is used, when it's not. This can cause faulty conclusions and confusion for developers as well, who think one linker is set, when it's not.
May be what brooks was referring to is not familiar.
So I show examples for system-clang++, llvm90's
clang++90, and g++9.
Here is an example of building and linking a program:
# c++ -std=c++17 -pedantic -O3 -pthread -c cpp_thousandslocale.cpp
# c++ -std=c++17 -pedantic -O3 -pthread -c cpp_clockinfo.cpp
# c++ -std=c++17 -pedantic -O3 -pthread cpp_thousandslocale.o cpp_clockinfo.o -o cpp_clockinfo_main cpp_clockinfo_main.cpp
That last runs a linker aa part of its activity.
It make s no use of makefile macros or environment variables LD or XLD.
This would be true even if if comamnds were in a makefile.
Use of the -### option for the last of those commands shows the link
command that clang used ("/usr/bin/ld"):
FBSDFHUGE# c++ -### -std=c++17 -pedantic -O3 -pthread cpp_thousandslocale.o cpp_clockinfo.o -o cpp_clockinfo_main cpp_clockinfo_main.cpp
FreeBSD clang version 8.0.1 (tags/RELEASE_801/final 366581) (based on LLVM 8.0.1)
Target: x86_64-unknown-freebsd13.0
Thread model: posix
InstalledDir: /usr/bin
"/usr/bin/c++" "-cc1" "-triple" "x86_64-unknown-freebsd13.0" "-emit-obj" "-disable-free" "-main-file-name" "cpp_clockinfo_main.cpp" "-mrelocation-model" "static" "-mthread-model" "posix" "-mdisable-fp-elim" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-fuse-init-array" "-target-cpu" "x86-64" "-dwarf-column-info" "-debugger-tuning=gdb" "-resource-dir" "/usr/lib/clang/8.0.1" "-internal-isystem" "/usr/include/c++/v1" "-O3" "-pedantic" "-std=c++17" "-fdeprecated-macro" "-fdebug-compilation-dir" "/root/c_tests" "-ferror-limit" "19" "-fmessage-length" "200" "-pthread" "-fobjc-runtime=gnustep" "-fcxx-exceptions" "-fexceptions" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-vectorize-loops" "-vectorize-slp" "-o" "/tmp/cpp_clockinfo_main-bf9d80.o" "-x" "c++" "cpp_clockinfo_main.cpp" "-faddrsig"
"/usr/bin/ld" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld-elf.so.1" "--hash-style=both" "--enable-new-dtags" "-o" "cpp_clockinfo_main" "/usr/lib/crt1.o" "/usr/lib/crti.o" "/usr/lib/crtbegin.o" "-L/usr/lib" "cpp_thousandslocale.o" "cpp_clockinfo.o" "/tmp/cpp_clockinfo_main-bf9d80.o" "-lc++" "-lm" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lpthread" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "/usr/lib/crtend.o" "/usr/lib/crtn.o"
Systenm-clang makes no use of ${LD} or ${XLD} but directly tries to use /usr/bin/ld
instead.
Similarly for devel/llvm90 : its clang++90 uses
"/usr/local/llvm90/bin/ld" directly:
# clang++90 -std=c++17 -pedantic -O3 -pthread -c cpp_thousandslocale.cpp
# clang++90 -std=c++17 -pedantic -O3 -pthread -c cpp_clockinfo.cpp
# clang++90 -std=c++17 -pedantic -O3 -pthread cpp_thousandslocale.o cpp_clockinfo.o -o cpp_clockinfo_main cpp_clockinfo_main.cpp
Again using -### :
# clang++90 -### -std=c++17 -pedantic -O3 -pthread cpp_thousandslocale.o cpp_clockinfo.o -o cpp_clockinfo_main cpp_clockinfo_main.cpp
clang version 9.0.0 (tags/RELEASE_900/rc2)
Target: x86_64-portbld-freebsd13.0
Thread model: posix
InstalledDir: /usr/local/llvm90/bin
"/usr/local/llvm90/bin/clang-9" "-cc1" "-triple" "x86_64-portbld-freebsd13.0" "-emit-obj" "-disable-free" "-disable-llvm-verifier" "-discard-value-names" "-main-file-name" "cpp_clockinfo_main.cpp" "-mrelocation-model" "static" "-mthread-model" "posix" "-mdisable-fp-elim" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-fuse-init-array" "-target-cpu" "x86-64" "-dwarf-column-info" "-debugger-tuning=gdb" "-resource-dir" "/usr/local/llvm90/lib/clang/9.0.0" "-internal-isystem" "/usr/include/c++/v1" "-O3" "-pedantic" "-std=c++17" "-fdeprecated-macro" "-fdebug-compilation-dir" "/root/c_tests" "-ferror-limit" "19" "-fmessage-length" "200" "-pthread" "-fobjc-runtime=gnustep" "-fcxx-exceptions" "-fexceptions" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-vectorize-loops" "-vectorize-slp" "-faddrsig" "-o" "/tmp/cpp_clockinfo_main-bb1750.o" "-x" "c++" "cpp_clockinfo_main.cpp"
"/usr/local/llvm90/bin/ld" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld-elf.so.1" "--hash-style=both" "--enable-new-dtags" "-o" "cpp_clockinfo_main" "/usr/lib/crt1.o" "/usr/lib/crti.o" "/usr/lib/crtbegin.o" "-L/usr/lib" "cpp_thousandslocale.o" "cpp_clockinfo.o" "/tmp/cpp_clockinfo_main-bb1750.o" "-lc++" "-lm" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lpthread" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "/usr/lib/crtend.o" "/usr/lib/crtn.o"
Similarly for g++9 which uses "/usr/local/bin/ld" directly:
# g++9 -std=c++17 -pedantic -O3 -pthread -c cpp_thousandslocale.cpp
# g++9 -std=c++17 -pedantic -O3 -pthread -c cpp_clockinfo.cpp
# g++9 -std=c++17 -pedantic -O3 -pthread cpp_thousandslocale.o cpp_clockinfo.o -o cpp_clockinfo_main cpp_clockinfo_main.cpp
Again using -### :
# g++9 -### -std=c++17 -pedantic -O3 -pthread cpp_thousandslocale.o cpp_clockinfo.o -o cpp_clockinfo_main cpp_clockinfo_main.cpp
Using built-in specs.
COLLECT_GCC=g++9
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/lto-wrapper
Target: x86_64-portbld-freebsd13.0
Configured with: /wrkdirs/usr/ports/lang/gcc9/work/gcc-9.2.0/configure --enable-multilib --with-build-config=bootstrap-debug --disable-nls --enable-gnu-indirect-function --libdir=/usr/local/lib/gcc9 --libexecdir=/usr/local/libexec/gcc9 --program-suffix=9 --with-as=/usr/local/bin/as --with-gmp=/usr/local --with-gxx-include-dir=/usr/local/lib/gcc9/include/c++/ --with-ld=/usr/local/bin/ld --with-pkgversion='FreeBSD Ports Collection' --with-system-zlib --enable-languages=c,c++,objc,fortran --prefix=/usr/local --localstatedir=/var --mandir=/usr/local/man --infodir=/usr/local/share/info/gcc9 --build=x86_64-portbld-freebsd13.0
Thread model: posix
gcc version 9.2.0 (FreeBSD Ports Collection)
COLLECT_GCC_OPTIONS='-std=c++17' '-Wpedantic' '-O3' '-pthread' '-o' 'cpp_clockinfo_main' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/local/libexec/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/cc1plus -quiet cpp_clockinfo_main.cpp -quiet -dumpbase cpp_clockinfo_main.cpp "-mtune=generic" "-march=x86-64" -auxbase cpp_clockinfo_main -O3 -Wpedantic "-std=c++17" -o /tmp//ccqXOrjE.s
COLLECT_GCC_OPTIONS='-std=c++17' '-Wpedantic' '-O3' '-pthread' '-o' 'cpp_clockinfo_main' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/local/bin/as -o /tmp//ccxktS2W.o /tmp//ccqXOrjE.s
COMPILER_PATH=/usr/local/libexec/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/:/usr/local/libexec/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/:/usr/local/libexec/gcc9/gcc/x86_64-portbld-freebsd13.0/:/usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/:/usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/:/usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/../../../../../x86_64-portbld-freebsd13.0/bin/
LIBRARY_PATH=/usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/:/usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/../../../../../x86_64-portbld-freebsd13.0/lib/:/usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-std=c++17' '-Wpedantic' '-O3' '-pthread' '-o' 'cpp_clockinfo_main' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/local/libexec/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/collect2 -plugin /usr/local/libexec/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/liblto_plugin.so "-plugin-opt=/usr/local/libexec/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/lto-wrapper" "-plugin-opt=-fresolution=/tmp//ccA61h1w.res" "-plugin-opt=-pass-through=-lgcc_s" "-plugin-opt=-pass-through=-lgcc" "-plugin-opt=-pass-through=-lpthread" "-plugin-opt=-pass-through=-lc" "-plugin-opt=-pass-through=-lgcc_s" "-plugin-opt=-pass-through=-lgcc" --eh-frame-hdr -m elf_x86_64_fbsd -dynamic-linker /libexec/ld-elf.so.1 -o cpp_clockinfo_main /usr/lib/crt1.o /usr/lib/crti.o /usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/crtbegin.o -L/usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0 -L/usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/../../../../../x86_64-portbld-freebsd13.0/lib -L/usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/../../.. cpp_thousandslocale.o cpp_clockinfo.o /tmp//ccxktS2W.o "-lstdc++" -lm -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc /usr/local/lib/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/crtend.o /usr/lib/crtn.o
COLLECT_GCC_OPTIONS='-std=c++17' '-Wpedantic' '-O3' '-pthread' '-o' 'cpp_clockinfo_main' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
Although here it is less obvious what:
/usr/local/libexec/gcc9/gcc/x86_64-portbld-freebsd13.0/9.2.0/collect2
ends up using. So using truss produced the evidence:
3472: execve("/usr/local/bin/ld",0x800b35180,0x7fffffffd380) EJUSTRETURN
Again: no use of ${LD} or ${XLD} .
Builds that want to control which linker is used need to avoid
using such commands and instead use ${LD} or ${XLD} or such
explicitly. Many do not do this.
===
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)
More information about the freebsd-toolchain
mailing list