On Wed, 3 Mar 2021 at 12:35, Bob via Gcc <gcc@gcc.gnu.org> wrote: > > Hi GCC users mailing list, > > I am currently figuring out a GCC usecase on OpenBSD. This situation > involves some non-superficial understanding of GCC's code, and > therefore I wish to query you here even in the situation that it turns > out not to be needed. > > I describe my problem here: > https://marc.info/?l=openbsd-misc&m=161472828522043&w=2 > > In summary my problem is that on OpenBSD, GCC will prepend to LD's > arguments "-L/usr/lib", which means that "-lz" NEVER will take my > local custom-built libz.so (which is what I want GCC/LD to do), but > instead always will take the OS-bundled libz.so which is in > /usr/lib/ , which is what I don't want. > > In practice this means that I can't make a custom software build in > my home directory, that uses a custom libz (or any other .so whose > name also exists in /usr/lib), and I guess this also disturbs the > ability to do cross-platform builds. What I described now is a veru > normal usecase isn't it? > > > Here is to trig the behavior on OpenBSD: > > $ echo "int main(){}">t.c; gcc -c -o t.o t.c; gcc -o t t.o -LMYDIRTEST -Wl,-v > collect2 version 4.2.1 20070719 (OpenBSD/x86-64 ELF) > /usr/bin/ld --eh-frame-hdr -e __start -Bdynamic -dynamic-linker > /usr/libexec/ld.so \ > -L/usr/lib -o t /usr/lib/crt0.o /usr/lib/crtbegin.o -LMYDIRTEST \ > -L/usr/lib/gcc-lib/amd64-unknown-openbsd6.7/4.2.1 t.o -v -lgcc -lc -lgcc \ > /usr/lib/crtend.o LLD 8.0.1 (compatible with GNU linkers) > > As you see here my "-LMYDIRTEST" comes after -L/usr/lib . > > Normally on any Unix the -L/usr/lib is *appended to the end* of LD's > arguments, is it not - can you please confirm? > > (This question affects why OpenBSD added a custom behavior.) > > > Second, a GCC patching question, your help to figure would be much > appreciated: OpenBSD's patchset to GCC v8 is in the patches > subdirectory here: > > https://cvsweb.openbsd.org/ports/lang/gcc/8/ > > As I get it, GCC's default behavior is to put -L/usr/dir in the > trailing position, so one of these patches must modify GCC to put > it in the leading position instead. Can you tell me which line in which > patch file it is that has this effect?
It's done in several different files, one for each supported arch. You've already found where it's done for x86: https://cvsweb.openbsd.org/ports/lang/gcc/8/patches/patch-gcc_config_i386_openbsdelf_h The latest version has been fixed (as you say below) but the previous version added -L/usr/lib unconditionally. That LINK_SPEC is the first group of options passed to the linker. If -L/usr/lib is added to LINK_SPEC then it comes before any other -L options. In other words, there's no patch to say "put -L/usr/lib first **instead** of last" there's just a patch that puts it first. That's not how other targets do it, which is why -L/usr/lib doesn't come first for other targets, only for OpenBSD. > (This way if I remove that line / file, GCC should behave the same as > on other platforms and my problem would be solved.) > > > Last for completeness a discussion of GCC's "-nostdlib" argument: > > I figure that the since this very recent patch > > https://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/lang/gcc/8/patches/patch-gcc_config_i386_openbsdelf_h.diff?r1=1.3&r2=1.4&f=h > > , the GCC command line argument "-nostdlib" offers partial help, in > the form that adding it causes the *removal* of the leading > -L/usr/lib . However, there is no TRAILING -L/usr/lib so that one needs > to be added manually. Of course. Because when you use -nostdlib ALL libraries and library paths need to be added manually. That's what it means. > And, especially, -nostdlib has a handful > other effects which I don't understand and which are not really > discussed anywhere, as I get it: They're discussed in the manual. > Grepping GCC's code for nostdlib gives me this: > > gcc/cp/g++spec.c: case OPT_nostdlib: > gcc/gcc.c: > %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} \ > gcc/gcc.c:%{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" > LIBASAN_EARLY_SPEC "} \ > gcc/gcc.c:%{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\ > gcc/gcc.c:%{!nostdlib:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start > -u_vtable_map_vars_end}\ > gcc/gcc.c: %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} \ > gcc/gcc.c: %{!nostdlib:%{!nodefaultlibs:%(link_ssp) > %(link_gcc_c_sequence)}}\ > gcc/gcc.c: %{!nostdlib:%{!nostartfiles:%E}} %{T*} \n%(post_link) }}}}}}" > > As you see the nostdlib logics are not in C/C++ code, but in some kind > of special GCC-internal language with its own syntax. Is this called > "GCC spec file" syntax? Yes, documented at https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html > The patch I referenced above, modifies > patches/patch-gcc_config_i386_openbsdelf_h 's line 11 > from " + -L/usr/lib\"" to "%{!nostdlib:-L/usr/lib}\"", again the > same syntax language. That means that -L/usr/lib is only added when -nostdlib is not used. > Someone's discussion on what -nostdlib actually does, would be great > for the purpose of GCC documentation, the current description at > https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html is too brief. I don't see why it's too brief. It's quite accurate. The option means that GCC won't tell the linker to use any of the default libraries and library paths (which you can see by adding -v to the gcc command you use to link). That's accurate. The spec file snippets above are what add the default libraries and default library paths, and those additions are suppressed if -nostdlib is used. Just like the docs say.