Why LD_LIBRARY_PATH did not work but LDFLAGS did?

Hello, a few moments ago, I tried to compile lynx. It complained about the lack of ncurses . I downloaded it, compiled it and then installed it to non standard directory.

Going back to the lynx, I expected to pass ncurses location to it through a .pc file and PKG_CONFIG_PATH . However the version of ncurses that I installed does not have . pc file.

Then I passed the location of ncurses "lib" dir to LD_LIBRARY_PATH and exported it. It did not work, lynx configure was not able to find it. Then I decided to use LDFLAGS=-L'..../ncurses/lib/'. And it did work! The question is.......why?
'
What LDFLAGS d oes that LD_LIBRARY_PATH does not? Thanks for your time

1 Like

Bash on Linux ?

Obviously the environment variables LDFLAGS and LD_LIBRARY_PATH serve similar but different purposes. The way you used them both tell some (part of the) system to look in a certain list of directories to find something the respective part of the system looks for. So far, they are similar and hence work similarly. But the parts of the system they address are different and this is why the one "worked" and the other "didn't" - both actually worked, but you needed the part of the system addressed by the one and therefore the other had no effect.

LD_LIBRARY_PATH tells the runtime environment where to look for (dynamically linked) libraries. When you compile a (C) program it will consist of a main() function and many other functions. Each of these are first compiled into "object code". This is what the compiler does. Then these objects are picked up by the linker (more precisely "linkage editor") and are bound together to the final executable. This can be done by either putting all the objects together statically ("static linking") which will make the executable independent of external libraries but will make the functions available only within the executable. The executable can also be linked "dynamically" which means that some functions may still be included within the executable but some may be put into a separate library instead or they may even be provided from such a library so that there is no source code (and no object code) within the programs source to begin with. The advantage is that you can (re-)use already available functions without having to write them and other programs can use these functions too but it also makes the executable dependent on the availability of these external libraries from which the functions are being loaded at runtime.

Where these libraries exactly are (typically /usr/lib , /usr/local/lib , etc.) will be determined by the environment variable LD_LIBRARY_PATH (the Linux variant, the "LD" actually stands for "dynamic loader") or LIBPATH (the UNIX variant) and from a practical POV it is sensible to set both variables and set them to the same value. If either one is required it will work.

After this, now for the LDFLAGS variable: the LDFLAGS variable is used by the cmake utility to set the flags for the linker. So, basically what you did by:

LDFLAGS=-L'..../ncurses/lib/'

was to tell cmake that whenever the linker was called during the make process it should add -L'..../ncurses/lib/' to the commandline in addition to all the things already placed there by various other means. The role of LDFLAGS in this regard is similar to that of CFLAGS which sets additional flags for every call of the compiler. Note that both LDFLAGS as well as CFLAGS can put any other flag onto the commandline of their respective utility, not just the location of libraries.

I suggest to read the man pages of make (i.e. the cmake variant), the C-compiler of your choice (probably gcc, but then there are others too), the linkage editor you use, etc., for a list of available flags.

Also notice that there are similar variables (also called "macros") for other tools:

CFLAGS          C compiler
CPPFLAGS        Preprocessor
CXXFLAGS        C++-compiler
LDFLAGS         linker

I hope this helps.

bakunin

4 Likes

In short, LDFLAGS only works at compile-time, while LD_LIBRARY_PATH only works at run-time. You were compiling, hence LDFLAGS.

2 Likes

Thanks for the answers.

Another doubt. Once during a compilation, I passed the location of the Glib .pc file to the program I was compiling through PKG_CONFIG_PATH, however, configure complained about the existence of another version of Glib, that already was installed in my system. However, when I adjusted LD_LIBRARY_PATH to the lib dir of my compiled Glib, it ignored the system default Glib, allowing the configuration process to execute until its end. If LD_LIBRARY_PATH is to be used during runtime, how it did work in this case? Shouldn't have been LDFLAGS ?

Yes, LD_LIBRARY_PATH is for runtime, but when you run configure this is its runtime. Therefore it noticed that you are compiling against one glibc but woud have been running (once you would have tried to run the compiled program) against another glibc . This was why it complained. Most probably this was not an error but a warning, right?

Once you changed your runtime environment configure saw that your compile-time environment and your runtime-environment would be the same and found nothing to complain about any more.

I hope this helps.

bakunin

1 Like