# LDFLAGS Central

## taviso

You may or may not be aware that the next versions of portage will probably support $ASFLAGS and $LDFLAGS, options that are usually passed to the assembler and linker during the build process.

There are even patches on gentoo-dev to add this support, although you can still use $LDFLAGS and $ASFLAGS without this patch, just by setting them in /etc/make.conf.

http://marc.theaimsgroup.com/?l=gentoo-dev&m=105793517425320&w=2

$ASFLAGS is not particularly useful, it will probably be supported only for completeness. $LDFLAGS, however, could be useful and  I have been experimenting recently to see what exactly can be done with them.

First of all, you can benchmark dynamic linking using the $LD_DEBUG variable, for example:

```
taviso@insomniac:~$ LD_DEBUG=statistics sh -c true

12937:  

12937:  runtime linker statistics:

12937:    total startup time in dynamic loader: 1108348 clock cycles

12937:              time needed for relocation: 572272 clock cycles (51.6%)

12937:                   number of relocations: 132

12937:        number of relocations from cache: 5

12937:             time needed to load objects: 335136 clock cycles (30.2%)

12937:  

12937:  runtime linker statistics:

12937:             final number of relocations: 204

12937:  final number of relocations from cache: 5
```

as you can see, you can get the dynamic loader to print out lots of interesting stats, mostly measured in clock cycles. 

These are some of the ld options that look interesting:

-O level

If level is a numeric values greater than zero ld optimizes the output.

--sort-common

This is to prevent gaps between symbols due to alignment constraints, presumably increasing efficiency layout.

--no-keep-memory

This option tells ld to optimize for memory usage rather than speed, by rereading the symbol tables as necessary instead of caching it in memory.

-z now

Lazy binding is really clever, rather than loading all shared code into memory at runtime, the dynamic loader locates them, and just keeps track of it, when a reference is made to the shared code, then it is loaded memory. This saves some memory, and speeds up startup. Using -z now disables lazy binding, which means slower startup,  possibly more memory usage, but better runtime performance.

You can test how this will effect a particular application by setting $LD_BIND_NOW, and testing responsiveness or timing some task, for example:

```
taviso@insomniac:~$ LD_BIND_NOW=1 mozilla
```

I Should also point out that when gcc is used to indirectly call ld, it wont always pass the $LDFLAGS to the linker, to force it to you must use the -Wl switch, all spaces in the switch must be substituted with commas. These are my $LDFLAGS, to demonstrate:

```
LDFLAGS="-Wl,-O1 -Wl,--sort-common -s"
```

References I used to collect this information, you can read these for more information:

ld(1) manpage

ld.so(8 ) manpage

http://www.caldera.com/developers/gabi/latest/ch5.dynamic.html

latest ELF draft, Dynamic linking section

http://sources.redhat.com/binutils/docs-2.12/ld.info/Scripts.html#Scripts

linker scripts description

proc(5) manpage

note: this post is 2 years old, i've made a few updates to reflect that.

----------

## aardvark

I don't quite understand your line here. One would not expect a "," between -z and combreloc.

```

LDFLAGS="-Wl,-z,combreloc -Wl,-O,2 -Wl,--relax -Wl,--enable-new-dtags -Wl,--sort-common -s"

```

Furthermore I am pretty sure that at some point in gentoo history , with certain binutils and glibc, " -z combreloc " is enabled by default when U emerge something in portage. (Just default for the compiler)

You can see that it is enabled (this is when it was introduced) by:

```

bash-2.05b$ LD_DEBUG=statistics konqueror

04646:

04646:  runtime linker statistics:

04646:    total startup time in dynamic loader: 1595176706 clock cycles

04646:              time needed for relocation: 1044423406 clock cycles (65.4%)

04646:                   number of relocations: 29638

04646:        number of relocations from cache: 54945

04646:             time needed to load objects: 550219972 clock cycles (34.4%)

mcop warning: user defined signal handler found for SIG_PIPE, overriding

ASSERT: "m_widget" in kaction.cpp (2993)

04646:

04646:  runtime linker statistics:

04646:             final number of relocations: 47460

04646:  final number of relocations from cache: 109400

```

The cached relocations indicate that it is enabled. before combreloc there where no cahced relocation. Do you have some proof that it helps to enable it in your LDFLAGS explicitly?

----------

## taviso

 *aardvark wrote:*   

> I don't quite understand your line here. One would not expect a "," between -z and combreloc.

 

The comma is correct, it is stripped out by gcc when it calls the linker.

 *Quote:*   

> Furthermore I am pretty sure that at some point in gentoo history , with certain binutils and glibc, " -z combreloc " is enabled by default when U emerge something in portage. (Just default for the compiler)

 

Not as far as i am aware.

----------

## aardvark

Ok, but would 

```

LDFLAGS="-z combreloc" 

```

work? 

(I only want combreloc, that I still think I already have anyway  :Smile:  )

----------

## taviso

 *aardvark wrote:*   

> Ok, but would 
> 
> ```
> 
> LDFLAGS="-z combreloc" 
> ...

 

yep, -z xxx is really the exception to the rule, gcc understands that its always a linker invocation option. I only used it with -Wl for consistency. The guide was only a reference, i thought maybe some other people who like to tinker would enjoy it.

 *Quote:*   

> (I only want combreloc, that I still think I already have anyway  )

 

incidentally, combreloc is the default linker script in recent versions of ld.

----------

## aardvark

 *taviso wrote:*   

> [
> 
> incidentally, combreloc is the default linker script in recent versions of [url=http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/ChangeLog?cvsroot
> 
> =src]ld[/url].

 

And that means that it is enabled on my system already?

----------

## deadbeef

I have to rebuild my system tomorrow, I'm going to try this out.

I'll do some benchmarks before+after & post back any results.

-0xdb

----------

## pennedinil

For completeness, should the flags not be

```

LDFLAGS="-Wl,-O1 -Wl,--relax -Wl,--enable-new-dtags -Wl,--sort-common -Wl,-s"

```

----------

## Hackeron

breaks emacs compile! -- everything else so far compiles just fine, but emacs says:

```
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/../../../../i686-pc-linux-gnu/bin/ld: unrecognized option '-Wl,-O1'

/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/../../../../i686-pc-linux-gnu/bin/ld: use the --help option for usage information

collect2: ld returned 1 exit status

make[1]: *** [temacs] Error 1
```

----------

## dalek

This is my ldflags.

```
LDFLAGS="-Wl,-O1"
```

I read that in another thread somewhere on here.  Is that safe?  Does it help any?  Is there a better setting for my rig?  Are they rig specific?  I'm not a guru regardless of what is under my name over there.   :Rolling Eyes:   Hmmm.  Now it says l33t.  Wonder when that changed.   :Embarassed: 

AMD 2500+ CPU and 1GB of ram.  I like speed, I am using Gentoo  :Very Happy: , but I also want stability.  I am almost to 70 days uptime.  Woooo Ooooo.

Thanks.

 :Very Happy:   :Very Happy:   :Very Happy:   :Very Happy: 

----------

## taskara

LDFLAGS are not hardware specific afaik.

So they will work on any system.

The initial post from 2003 suggests

```
LDFLAGS="-Wl,-O1 -Wl,--relax -Wl,--enable-new-dtags -Wl,--sort-common -s"
```

but --relax is only for alpha, and --enable-new-dtags is the default for current binutils, and -s is not neccessary afaik because gentoo strips all packages by default.

so the only other thing you could try is

```
LDFLAGS="-Wl,-O1 -Wl,--sort-common"
```

----------

## wrc1944

After much thought, and a lot of reading, I just put

 LDFLAGS="-Wl,-O1"

 in my make.conf, and started an emerge -e system.  I'm cruising along at 21 out of 103 to go, but am not seeing any LDFLAGS related stuff in the gcc output. 

What output am I supposed to be looking for, and does it even show up in the output, like the CFLAGS do? In other words, how do I know if I'm really compiling with the LDFLAGS I set in .make.conf?

One more thing: I know it's -Wl (letter L, not numeric 1), but can't find anything regarding if -o1 is -o(letter o), or -0(numerical zero).  Since I didn't know which, I pasted what was in the LDFLAGS post, and it seems to be working (shows up in emerge --info), but since I'm not seeing any LDFLAGS output I can identify, I'm still wondering if I have it correct.

Thanks,

wrc1944

----------

## SoTired

The ldflags will only show up during an emerge during linking, which generally is very quick/easy to miss.  If you watch an emerge and it gets to a point where you see a lot of .o files on one line, there should be ldflags there as well.

The 'O' is a capital letter o, just like O for gcc (cflags) they both turn on optimizations.

As reference, an example from my current compilation of gtk+:

 *Quote:*   

> /bin/sh ../libtool --mode=link i586-pc-linux-gnu-gcc  -pipe -Os -march=pentium -
> 
> mieee-fp -momit-leaf-frame-pointer -fforce-addr -freorder-blocks -fomit-frame-po
> 
> inter -fmove-all-movables -fmerge-all-constants -ftracer -finline-functions -fwe
> ...

 

Note the "-Wl,--enable-new-dtags -Wl,--sort-common".

----------

## taipan67

When did '-z combreloc' get edited out of the original post, & why?

I ask because i've just started a very careful rebuild, & had to remove it from my LDFLAGS to get 'glibc' to compile (it's doing so now - i hope it finishes okay...  :Confused:  )

----------

## taipan67

 *taipan67 wrote:*   

> When did '-z combreloc' get edited out of the original post, & why?
> 
> I ask because i've just started a very careful rebuild, & had to remove it from my LDFLAGS to get 'glibc' to compile (it's doing so now - i hope it finishes okay...  )

 

Further to my previous post, because i'm using the 'nptl' USE-flag by itself, & not with the 'nptlonly' one, glibc gets built twice - once without nptl-support, & again with.

By chance, i happened to be watching the text scroll by when the second part of the build started, & noticed that the check for '-z combreloc' returned 'yes', whereas it returned 'no' on the first part (without nptl-support).

I'm not about to do another restart of the entire process to check this out, but i am surmising that an 'nptlonly' system wouldn't spit the '-z combreloc' LDFLAG back in my face. I don't think Gentoo's quite ready to be nptlonly, but i would like any guidance that might be available on whether or not i can put '-z combreloc' back in my LDFLAGS once glibc has finished compiling...  :Question: 

----------

## taviso

 *taipan67 wrote:*   

> i would like any guidance that might be available on whether or not i can put '-z combreloc' back in my LDFLAGS once glibc has finished compiling... 

 

combreloc has been the default linker script for a while now, you dont need it.

----------

## taipan67

 *taviso wrote:*   

> 
> 
> combreloc has been the default linker script for a while now, you dont need it.

 

Thanks for the reassurance - currently ploughing through gcc-3.4.3-compile without '-z combreloc'...  :Very Happy: 

----------

## wrc1944

SoTired,

Thanks for the info.  I got most of the way through emerge -e system, and came back in and my computer was off. Apparently my power supply failed, so I ordered a new 580 watt monster, and presently am back to my old mandrake backup box for a few days, so I can't see how these LDFLAGS work.. Haven't used this older box in about 3 months, and even though it has Mandrake 10.1 on it (just did it today), I'm now reminded of why I went to Gentoo Almost two years ago.

----------

## depontius

Is there a way to get LDFLAGS tailored differently for a specific package, kind of like /etc/portage/package.use?

For most software the suggestions in this thread are good, but XOrg seems to think differently. (IIRC they mentioned security concerns) It will build with these flags, but complains every time and makes suggestions, though at the moment the only one I can remember is "-z now". For that matter, XOrg already strips a bunch of CFLAGS, maybe it a package has feelings that strong, they should strip and rework LDFLAGS, too.

----------

## wrc1944

Update:

I guess sometimes packages do strip LDFLAGS. I've been using the basic

LDFLAGS="-Wl,-O1" 

for about three weeks now. In addition to a few emerge syncs and -upD worlds, I've also done an emerge -e system, and an emerge -e world during this time, with no problems, on two ~x86 systems with gcc-3.4.3-20050110. I've noticed the LDFLAGS showing up in the gcc output of some packages, but not in others.

I've had no issues so far, and no complaints.

----------

## Kyrra

I had the same problem with using LDFLAGS to compile Emacs as listed in a post higher in this thread.  But everything else I've compiled on my system hasn't had a problem with the LDFLAGS yet.

----------

## dalek

I was using this but was getting a error about lazy bindings:  edit, notice that this line is commented out.   :Laughing: 

```
#LDFLAGS="-Wl,-O1"
```

I then changed back to this:

```
LDFLAGS='-Wl,-z,now'
```

I have not had any of those errors that I can see anyway.

Rig in sig if that matters.  New one seems faster but not real sure though.

Later

 :Very Happy:   :Very Happy:   :Very Happy:   :Very Happy: 

----------

## infirit

Another flag that I am looking into lately is -Wl,--as-needed. Some app break horibly but most benefit from it . 

It all started with an editorial on osnews.com and this thread is a result of it.

----------

## makzu

I'm looking around the man page for ld right now, wondering what else we can add into this.  (Yes, I am a ricer, I have to make sure I'm not missing anything)  Anyway, there's a few options that I'm a little curious about now, including: 

 *Quote:*   

>         --strip-debug
> 
>            Omit debugger symbol information (but not  all  symbols)  from  the
> 
>            output file.

 

Debug information really isn't something that we need anyway, is it?

 *Quote:*   

>        --relax
> 
>            An option with machine dependent effects.  This option is only sup-
> 
>            ported on a few targets.
> ...

 

Does this do anything at all on an x86 or amd64 machine?

Also, is --enable-new-dtags useful any more?

----------

## schrepfler

Are there any new tips for the use of LDFLAGS, what are some good configs for the 3.4, 3.4 and 4.0 compilers?

----------

## Hasw

Hm, I'm getting a Segmentation fault:

```

hasw@hasw hasw $ LD_DEBUG=statistics sh -c true

     26096:     

     26096:     runtime linker statistics:

     26096:       total startup time in dynamic loader: 595306 clock cycles

     26096:                 time needed for relocation: 289777 clock cycles (48.6%)

Segmentation fault

hasw@hasw hasw $ 

```

sys-devel/binutils  2.15.92.0.2-r7

sys-libs/glibc         2.3.4.20041102-r1

----------

## Bitspyer

Hmmm I'm asking me, what is the better solution:

LDFLAG or prelink? Or both together???

----------

## Dark_Cloud

 *Bitspyer wrote:*   

> Hmmm I'm asking me, what is the better solution:
> 
> LDFLAG or prelink? Or both together???

 

you can use both. :Very Happy: 

----------

## yardbird

 *Hasw wrote:*   

> Hm, I'm getting a Segmentation fault:
> 
> ```
> 
> hasw@hasw hasw $ LD_DEBUG=statistics sh -c true
> ...

 

Same here... do you have custom LDFLAGS set in make.conf?

----------

## teutzz

```
Teutzz teutzz # LD_DEBUG=statistics sh -c true

     17293:

     17293:     runtime linker statistics:

     17293:       total startup time in dynamic loader: 411310 clock cycles

     17293:                 time needed for relocation: 14399 clock cycles (3.5%)

     17293:                      number of relocations: 0

     17293:           number of relocations from cache: 21

     17293:             number of relative relocations: 0

     17293:                time needed to load objects: 236055 clock cycles (57.3%)

     17293:

     17293:     runtime linker statistics:

     17293:                final number of relocations: 65

     17293:     final number of relocations from cache: 21
```

 and in my make.conf: 

```
Teutzz teutzz # cat /etc/make.conf | grep LDFLAGS

LDFLAGS="-Wl,-O1 -Wl,--enable-new-dtags -Wl,--sort-common -s -Wl,--as-needed"
```

 and the whole system is prelinked

----------

## yardbird

Hmm, I tried upgrading to binutils 2.16 but still the segfault... It's strange since I never had problems with binutils, I'd probably would have never discovered the issue if I had not seen this thread.

@Teutzz: I'm using your same LDFLAGS (apart from -as-needed), so I guess the problem is not there. Does anyone know what commands are executed when executing the LD_DEBUG="..." command?

 :Confused: 

----------

## j-m

 *Kyrra wrote:*   

> I had the same problem with using LDFLAGS to compile Emacs as listed in a post higher in this thread.  But everything else I've compiled on my system hasn't had a problem with the LDFLAGS yet.

 

For emacs, you need only:

```

LDFLAGS="-O1"

```

Probably the only package that does not interpret -Wl as an option passed to the linker.

----------

## wel

Anyone has tried something bigger than -O1? I mean, -O2 or -Os...

----------

## taipan67

 *wel wrote:*   

> Anyone has tried something bigger than -O1? I mean, -O2 or -Os...

 

As i understand other people's posts on the subject, & the 'ld' man-page, the -O optimisation-flag has only two states: zero or not-zero. So setting it to 1, 2, 3, or whatever won't make a blind bit of difference, as long as it's a number greater than zero. It's not the same principle as CFLAGS, so there won't be a size-option, either.

----------

## Zentoo

I've read this thread and i give you back my experience to have play a lot with my LDFLAGS this last year:

I've recompiled a whole system with this: LDFLAGS="-Wl,-O1"

At the first glaze no problem at all... But on the next reboot, system didn't finish to boot up.

It was looking for some libs on some partition that weren't yet mounted at boot.

It seems where is some problem with some library that are on /usr/*/lib and not on /lib that are required at boot.

It was enough a long time ago but i remember to have copy some library on /usr/*/lib without have mounted /usr

so no problem at boot time to look for them but i think it's a dirty hack...

So just be warned if you have a full separated partition scheme as i have about the use of LDFLAGS on a whole system.

Think about gpm libraries for reiserfs binaries was one of theses problems. ( i never understood the need of gpm for reiserfs !)

----------

## j-m

 *Tuttle wrote:*   

> 
> 
> At the first glaze no problem at all... But on the next reboot, system didn't finish to boot up.
> 
> It was looking for some libs on some partition that weren't yet mounted at boot.
> ...

 

WTF?! How does the location where libraries are installed in the system depend on LDFLAGS  :Question:   :Rolling Eyes: 

----------

## MaratIK

ld flag --relax conficts with -r, so they cannot use both.

Package where it occured is glibc-2.3.5.

It is strongly not recommended include -Wl,--relax into LDFLAGS

----------

## MaratIK

 *schrepfler wrote:*   

> Are there any new tips for the use of LDFLAGS, what are some good configs for the 3.4, 3.4 and 4.0 compilers?

 

ld is not the part of gcc, but binutils. Tips the same as is for previous versions of gcc.

----------

## MaratIK

My settings for LDFLAGS:

```
LDFLAGS="-Wl,-O1,--sort-common,--enable-new-dtags,-zdynsort,-Bdirect,-hashvals"
```

Some explanation of last 3 settings can be found here

----------

## vipernicus

 *taviso wrote:*   

> [*]--sort-common
> 
> This is to prevent gaps between symbols due to alignment constraints, presumably increasing efficiency layout.

 

Actually, it seems that it is the other way around.

       -sort-common

              Normally,  when ld places the global common symbols

              in the appropriate output sections, it  sorts  them

              by size.  First come all the one byte symbols, then

              all the two bytes, then all  the  four  bytes,  and

              then  everything else.  This is to prevent gaps be-

              tween symbols due to alignment  constraints.   This

              option disables that sorting.

----------

## luminoso

```

$ LD_DEBUG=statistics sh -c true

     28385:

     28385:     runtime linker statistics:

     28385:       total startup time in dynamic loader: 1578708 clock cycles

     28385:                 time needed for relocation: 29708 clock cycles (1.8%)

     28385:                      number of relocations: 0

     28385:           number of relocations from cache: 29

     28385:             number of relative relocations: 0

     28385:                time needed to load objects: 1107048 clock cycles (70.1%)

     28385:

     28385:     runtime linker statistics:

     28385:                final number of relocations: 0

     28385:     final number of relocations from cache: 29

```

```

grep LDFL /etc/make.conf

LDFLAGS="-Wl,-O1"

```

And no problems at all.

What should i care? time needed to load or time needed for relocation?

----------

## Enlight

 *vipernicus wrote:*   

>  *taviso wrote:*   [*]--sort-common
> 
> This is to prevent gaps between symbols due to alignment constraints, presumably increasing efficiency layout. 
> 
> Actually, it seems that it is the other way around.
> ...

 

erm... no!

 *man binutils-2.17.50.0.6 wrote:*   

> --sort-common
> 
>            This  option  tells  ld  to sort the common symbols by size when it
> 
>            places them in the appropriate output sections

 

other than this, /me still wonders why --enable-new-dtags has been removed from the original post.

edit : @zentoo, definitly not, you probably were using a statical prog and forgot about this.

----------

## Dralnu

Has anyone else messed with LDFLAGS in awhile? I'm going through and sorting out what might be nice and what might not be, and just want to know if there is any new news.

Edit: Um, have LDFLAGS been removed for some odd reason?

----------

## wrc1944

Mine are currently 

```
LDFLAGS="-Wl,-O1 -Wl,--as-needed -Wl,--hash-style=both -Wl,-znow"
```

 on several boxes.

I've been using these with the advanced Gentoo install method and overlay by nesl247 (previously know as Evolution Mission). Works great for me, and the the few packages that have problems with --as-needed or -znow can be taken care of by entries in an /etc/portage/bashrc.nesl247 file, as shown below.

---------------------------------------------------------------------------------------------------

# Packages in this array remove --as-needed.

as_needed_packages=(

${as_needed_packages[*]}

media-video/mjpegtools

kde-base/kdemultimedia

kde-base/kdemultimedia-kioslaves

net-mail/courier-imap

media-sound/cdparanoia

mail-client/evolution

media-libs/imlib

)

LDFLAGS="${LDFLAGS:-$( grep ^LDFLAGS /etc/make.conf | sed 's/LDFLAGS="//' | sed 's/"//')}"

for i in ${as_needed_packages[*]}

do

	case ${CATEGORY}/${PN} in

		${i})

			LDFLAGS="$( echo ${LDFLAGS} | sed 's/-Wl,--as-needed//')"

			break

			;;

	esac

done

# Packages in this array remove -znow.

znow_packages=(

${znow_packages[*]}

dev-python/gst-python

x11-base/xorg-server

x11-drivers/ati-drivers

)

for i in ${znow_packages[*]}

do

	case ${CATEGORY}/${PN} in

		${i})

			LDFLAGS="$( echo ${LDFLAGS} | sed 's/-Wl,-znow//')"

			break

			;;

	esac

done

export LDFLAGS=$( echo ${LDFLAGS} )

----------

## Dralnu

Ran into a problem. its -W, not 1, but a lower case L.

----------

## wrc1944

Correct.  When you copy it from /etc/make.conf and paste it into the forum and add the code tags, the numeral one (1) and a lower case L really look almost identical. You have to look really close to see the numeral one has its top part at a slight downward angle, whereas the lower case L is horizontal.

----------

## webdawg

I had some ldflags that broke gst plugins.  had to comment them out.

----------

## ConiKost

I am using atm this:

```
LDFLAGS="-Wl,-O1 -Wl,-z,now -Wl,--as-needed -Wl,--enable-new-dtags -Wl,--sort-common -s"
```

works fine for me.

----------

## enderandrew

 *ConiKost wrote:*   

> I am using atm this:
> 
> ```
> LDFLAGS="-Wl,-O1 -Wl,-z,now -Wl,--as-needed -Wl,--enable-new-dtags -Wl,--sort-common -s"
> ```
> ...

 

Don't forget --hash-style=both

And I'm working on a toolchain overlay that will add back in support for -Bdirect among many other things!

----------

## gimpel

```
LDFLAGS="-Wl,-O1 -Wl,--hash-style=gnu -Wl,--sort-common"
```

on binutils-2.17.50.0.10 here.

No problems.

----------

## kernelOfTruth

*subscribes*

----------

