- Library path in gcc
- Check the configuration
- In compilation
- In linking
- How to add a directory as a library search directory
- Compilation
- Linking
- How to add dynamic library when linking
- Clear environment
- Sign up for more like this.
- Javascript useful code snippets
- My server is scanned with these paths
- How does sql databases and drivers handle Date columns
- Where do executables look for shared objects at runtime?
- 4 Answers 4
- How to print the ld(linker) search path
- 6 Answers 6
- What is the order that Linux’s dynamic linker searches paths in?
- 1 Answer 1
Library path in gcc
There are two steps to build a program with gcc : compilation and linking.
gcc is mostly responsible for the compilation, while when linking, it uses a linker program (e.g., ld ) with some additional flags.
In compilation, gcc only requires header files ( .h files) to ensure that external function calls have correct parameters matched with the definition.
After that, in the linking stage, the linker connects/links all compiled objects and libraries to an executable file.
There are two types of libraries: static library ( .a ) and dynamic library ( .so , .dynlib , dll ). The static libraries are copied and embedded directly to the executable file. In opposite, the dynamic libraries are not. The dynamic libraries are supposed to exist in the system where the executable file is executed.
So, where does gcc look for the header files, and the dynamic libraries?
Check the configuration
In compilation
For c : echo | gcc -x c -E -Wp,-v — >/dev/null
For cpp : echo | gcc -x c++ -E -Wp,-v — >/dev/null
These are the outputs in my PC.
In linking
The output from my PC.
- gcc wraps some flags when calling ld . Therefore, the directories list is different.
The output from my PC.
- My gcc ‘s build information with gcc —verbose .
Note: gcc looks for the libraries’ names from left to right and stop finding when it matches the first library with the searching term.
- You also can show the library search directories list by adding the verbose flag -v when linking.
For example: gcc -v foo.o bar.o -o foo - To figure out which libraries are linked with a program and the libraries’ full path, use ldd . For example, ldd foo . Example output from my PC.
How to add a directory as a library search directory
Customized library paths, which are added to the compilation/linking, by the following method have higher priority than the default library search directories. In other words, if a library is found in a customized directory, it will be selected rather than the library in system default.
Compilation
Method 1: use CPATH (c or c++), C_INCLUDE_PATH (c only), CPLUS_INCLUDE_PATH (c++ only). For example: CPATH=/home/transang/my_libs_headers gcc -c foo.c -o foo.o .
Method 2: use -I to gcc when compiling. For example: gcc -I/home/transang/my_libs_headers -c foo.c -o foo.o .
Linking
Method 1: To add a directory to the library linking search directories list, use LD_LIBRARY_PATH environment variable. For example: LD_LIBRARY_PATH=/home/transang/my_libs gcc foo.o bar.o -o foo
Method 2: add the flag -L to gcc when linking. For example: gcc -L/home/transang/my_libs foo.o bar.o -o foo .
Note 1: LD_LIBRARY_PATH environment variable’s value does not affect the results of ld —verbose and gcc -print-search-dirs commands.
Note 2: LD_LIBRARY_PATH ‘s value affects the result of ldd command. Thus, ldd command is the more reliable way to figure out library path.
Note 3: You also have to provide the LD_LIBRARY_PATH value when running the executable file. For e.g. LD_LIBRARY_PATH=/home/transang/my_libs ./foo .
How to add dynamic library when linking
So far, I have introduced a way to figure out the current configuration and modify it to add more directories for library searching.
To link a library, add -l
For example: with -lfoo , gcc looks for libfoo.so file. With -l:foo.so , gcc looks for foo.so file.
Clear environment
In some cases, you may want a clean build that isolates from the running machine. You can use the following command:
Moreover, the system library header searching path is configured in /etc/ld.so.conf .
By default, /etc/ld.so.conf refers to the content of all files in the directory /etc/ld.so.conf.d . You can look into the directory to control the configuration.
Sign up for more like this.
Javascript useful code snippets
I summarize several useful Javascript/Typescript code snippets. Get the last element from an array. Note: in the future, you can use Array Relative Indexing arr.at(-1) once the proposal is finalized.arr.slice(-1)[0]Optional array element.[ cond && elm, // include elm only when cond is
My server is scanned with these paths
After releasing a website just within 2 weeks, my server is scanned with these URLs. I publish it here for my later reference and also hope that it helps others for a good beforehand protection. From a first server (hosted in AWS). /07-accessing-data/begin/vue-heroes/.env /07-accessing-data/end/vue-heroes/.env
How does sql databases and drivers handle Date columns
I usually get confused when handling date datatype with databases, especially when connecting to the databases via libraries/drivers. In this post, I will summarize the results of their specification after my tests. Environment: Node: v16.0.0.Postgres nodejs driver: pg@8.6.0.Mysqlite nodejs driver: sqlite3@5.
Источник
Where do executables look for shared objects at runtime?
I understand how to define include shared objects at linking/compile time. However, I still wonder how do executables look for the shared object ( *.so libraries) at execution time.
For instance, my app a.out calls functions defined in the lib.so library. After compiling, I move lib.so to a new directory in my $HOME .
How can I tell a.out to go look for it there?
4 Answers 4
The shared library HOWTO explains most of the mechanisms involved, and the dynamic loader manual goes into more detail. Each unix variant has its own way, but most use the same executable format (ELF) and have similar dynamic linkers¹ (derived from Solaris). Below I’ll summarize the common behavior with a focus on Linux; check your system’s manuals for the complete story.
(Terminology note: the part of the system that loads shared libraries is often called “dynamic linker”, but sometimes “dynamic loader” to be more precise. “Dynamic linker” can also mean the tool that generates instructions for the dynamic loader when compiling a program, or the combination of the compile-time tool and the run-time loader. In this answer, “linker” refers to the run-time part.)
In a nutshell, when it’s looking for a dynamic library ( .so file) the linker tries:
- directories listed in the LD_LIBRARY_PATH environment variable ( DYLD_LIBRARY_PATH on OSX);
- directories listed in the executable’s rpath;
- directories on the system search path, which (on Linux at least) consists of the entries in /etc/ld.so.conf plus /lib and /usr/lib .
The rpath is stored in the executable (it’s the DT_RPATH or DT_RUNPATH dynamic attribute). It can contain absolute paths or paths starting with $ORIGIN to indicate a path relative to the location of the executable (e.g. if the executable is in /opt/myapp/bin and its rpath is $ORIGIN/../lib:$ORIGIN/../plugins then the dynamic linker will look in /opt/myapp/lib and /opt/myapp/plugins ). The rpath is normally determined when the executable is compiled, with the -rpath option to ld , but you can change it afterwards with chrpath .
In the scenario you describe, if you’re the developer or packager of the application and intend for it to be installed in a …/bin , …/lib structure, then link with -rpath=’$ORIGIN/../lib’ . If you’re installing a pre-built binary on your system, either put the library in a directory on the search path ( /usr/local/lib if you’re the system administrator, otherwise a directory that you add to $LD_LIBRARY_PATH ), or try chrpath .
Источник
How to print the ld(linker) search path
What is the way to print the search paths that in looked by ld in the order it searches.
6 Answers 6
You can do this by executing the following command:
gcc passes a few extra -L paths to the linker, which you can list with the following command:
The answers suggesting to use ld.so.conf and ldconfig are not correct because they refer to the paths searched by the runtime dynamic linker (i.e. whenever a program is executed), which is not the same as the path searched by ld (i.e. whenever a program is linked).
On Linux, you can use ldconfig , which maintains the ld.so configuration and cache, to print out the directories search by ld.so with
ldconfig -v prints out the directories search by the linker (without a leading tab) and the shared libraries found in those directories (with a leading tab); the grep gets the directories. On my machine, this line prints out
The first paths, without hwcap in the line, are either built-in or read from /etc/ld.so.conf. The linker can then search additional directories under the basic library search path, with names like sse2 corresponding to additional CPU capabilities. These paths, with hwcap in the line, can contain additional libraries tailored for these CPU capabilities.
One final note: using -p instead of -v above searches the ld.so cache instead.
I’m not sure that there is any option for simply printing the full effective search path.
But: the search path consists of directories specified by -L options on the command line, followed by directories added to the search path by SEARCH_DIR(«. «) directives in the linker script(s). So you can work it out if you can see both of those, which you can do as follows:
If you’re invoking ld directly:
- The -L options are whatever you’ve said they are.
- To see the linker script, add the —verbose option. Look for the SEARCH_DIR(«. «) directives, usually near the top of the output. (Note that these are not necessarily the same for every invocation of ld — the linker has a number of different built-in default linker scripts, and chooses between them based on various other linker options.)
If you’re linking via gcc :
- You can pass the -v option to gcc so that it shows you how it invokes the linker. In fact, it normally does not invoke ld directly, but indirectly via a tool called collect2 (which lives in one of its internal directories), which in turn invokes ld . That will show you what -L options are being used.
- You can add -Wl,—verbose to the gcc options to make it pass —verbose through to the linker, to see the linker script as described above.
Источник
What is the order that Linux’s dynamic linker searches paths in?
This is not a duplicate because this is dealing with a peculiarity I noticed when I use /etc/ld.so.conf .
To get the paths that the dynamic linker searches in for libraries, I run the command ldconfig -v | grep -v «^»$’\t’ | sed «s/:$//g» . When /etc/ld.so.conf has no paths listed in it. The output from the previous command is
I figured that it searches /lib first and then /usr/lib . When I add a new path, such as /usr/local/lib , to /etc/ld.so.conf and then remake /etc/ld.so.cache , the output from ldconfig -v | grep -v «^»$’\t’ | sed «s/:$//g» becomes
I find this strange because if I am correct that the order that the listed directories are searched in is from top to bottom, then additional directories are searched before /lib and /usr/lib . That the additional directories are searched before the trusted directories is not strange on its own, but when /lib is searched before /usr/lib , that is strange because /bin & /sbin are searched after /usr/bin & /usr/sbin in PATH .
Even if the paths listed by ldconfig -v | grep -Ev «^»$’\t’ | sed «s/:$//g» were searched from bottom to top, it would still be a skewed ordering because additional directories would be searched after the trusted ones while /lib would be searched after /usr/lib .
So, what is the order that ld.so searches paths for libraries in? Why is /lib searched before /usr/lib ? If it’s not, then why are additional directories searched after /lib ?
1 Answer 1
The order is documented in the manual of the dynamic linker, which is ld.so . It is:
- directories from LD_LIBRARY_PATH ;
- directories from /etc/ld.so.conf ;
- /lib ;
- /usr/lib .
(I’m simplifying a little, see the manual for the full details.)
The order makes sense when you consider that it’s the only way to override a library in a default location with a custom library. LD_LIBRARY_PATH is a user setting, it has to come before the others. /etc/ld.so.conf is a local setting, it comes before the operating system default. So as a user, if I want to run a program with a different version of a library, I can run the program with LD_LIBRARY_PATH containing the location of that different library version. And as an administrator, I can put a different version of the library in /usr/local/lib and list /usr/local/lib in /etc/ld.so.conf .
Trust doesn’t enter into this. Any directory listed on this search path has to be trusted, because any library could end up being loaded from there. In theory, you could list the library names used by all the programs “requiring more trust” on your system and make sure that all these libraries are present in the “most trusted” directories, and then the “less trusted” directories wouldn’t be used if they came after the more trusted directories on the search path, except for the programs “requiring less trust”. But that would be extremely fragile. It would also be pretty pointless: if an attacker can inject a value of LD_LIBRARY_PATH or an element of /etc/ld.so.conf , they surely have a more direct route to executing arbitrary code, such as injecting a value of PATH , of LD_PRELOAD , etc. Trust in the library load path does matter when execution crosses a trust boundary, i.e. when running a program with additional privileges (e.g. setuid/setgid program, or via sudo ). What happens in this case is that LD_LIBRARY_PATH is blanked out.
As for /lib vs /usr/lib , it doesn’t matter much: they’re provided by the same entity (the operating system) and there shouldn’t be a library that’s present in both. It makes sense to list /lib first because it provides a (very tiny) performance advantage: the most-often-used libraries, especially the libraries used by small basic programs (for which load time is a higher fraction of total running time than large, long-running program), are located in /lib .
Источник