Shared library: Difference between revisions
imported>Ninly |
imported>Jamarr81 Removed the article split/cleanup template. The lead and major topics in this page are now sufficiently sourced/verified; the lingering citations needed are only for a few esoteric/specialized claims. |
||
| Line 1: | Line 1: | ||
{{Short description|Software library designed for use in multiple programs}} | {{Short description|Software library designed for use in multiple programs}} | ||
{{redirect|Shared object|the synchronization mechanism|Monitor (synchronization)}} | {{redirect|Shared object|the synchronization mechanism|Monitor (synchronization)}} | ||
| Line 7: | Line 5: | ||
== Library types == | == Library types == | ||
A program | A library can be provided as [[static library|static]], [[dynamic library|dynamic]], or both. A program that uses a static library is [[Static linking|statically linked]] with the library; a program that uses a dynamic library is [[Dynamic linker|dynamically linked]] with the library. Historically, libraries could only be static.<ref>{{Cite web |date=2018-10-25 |title=Difference between Static and Shared libraries |url=https://www.geeksforgeeks.org/difference-between-static-and-shared-libraries/ |access-date=2025-02-02 |website=GeeksforGeeks |language=en-US}}</ref> For static linking, code from the library is embedded into the program's executable file. A dynamically linked library is [[Load time|loaded]] at [[Runtime (program lifecycle phase)|runtime]] from the library file. | ||
A program requires a [[compiler]] and [[Linker (computing)|linker]] step to access a library. In static linking, those references are fully resolved at compile time,<ref>{{Cite web |last=Microsoft |date=2021-10-29 |title=Walkthrough: Create and use a static library (C++) |url=https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-static-library-cpp?view=msvc-170 |access-date=2025-02-01 |website=learn.microsoft.com |language=en-us |quote=Using a static library is a great way to reuse code. Rather than reimplementing the same routines in every app that requires the functionality, you write them one time in a static library and then reference it from the apps. Code linked from a static library becomes part of your app—you don't have to install another file to use the code.}}</ref> whereas in dynamic linking those references are not fully resolved until runtime by the [[operating system]]. | A program requires a [[compiler]] and a [[Linker (computing)|linker]] step to access a library. In static linking, those references are fully resolved at compile time,<ref>{{Cite web |last=Microsoft |date=2021-10-29 |title=Walkthrough: Create and use a static library (C++) |url=https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-static-library-cpp?view=msvc-170 |access-date=2025-02-01 |website=learn.microsoft.com |language=en-us |quote=Using a static library is a great way to reuse code. Rather than reimplementing the same routines in every app that requires the functionality, you write them one time in a static library and then reference it from the apps. Code linked from a static library becomes part of your app—you don't have to install another file to use the code.}}</ref> whereas in dynamic linking, those references are not fully resolved until runtime by the [[operating system]]. | ||
== Formats == | == Formats == | ||
Many modern operating systems | Many modern operating systems use a unified format for their dynamic libraries and executable files. For example: | ||
* [[Microsoft Windows]] uses the [[Portable Executable|Portable Executable (PE)]] format for [[.dll]] files. | * [[Microsoft Windows]] uses the [[Portable Executable|Portable Executable (PE)]] format for [[.dll]] files. | ||
* | * [[Linux]] and [[BSD]], as well as [[Oracle Solaris|Solaris]] and other [[System V Release 4]]-based systems, use the [[Executable and Linkable Format]] (ELF) for [[.so file|.so]] files. | ||
* [[Apple Inc.|Apple's]] [[Darwin (operating system)|Darwin]]-based operating systems, such as [[macOS]] and [[iOS]], use the [[Mach-O]] format for [[.dylib]] files. | * [[Apple Inc.|Apple's]] [[Darwin (operating system)|Darwin]]-based operating systems, such as [[macOS]] and [[iOS]], use the [[Mach-O]] format for [[.dylib]] files. | ||
This offers two main advantages: first, it requires only one loader (building and maintaining a single loader is considered well worth any added complexity). Secondly, it allows an executable file to be used as a shared library (if it has a [[symbol table]]).{{Citation Needed|date=April 2022}} | This offers two main advantages: first, it requires only one loader (building and maintaining a single loader is considered well worth any added complexity). Secondly, it allows an executable file to be used as a shared library (if it has a [[symbol table]]).{{Citation Needed|date=April 2022}} | ||
Significant restrictions were placed on shared library code in some older environments, such as [[16-bit Windows]] or [[HP Multi-Programming Executive|MPE]] for the [[HP 3000]], which only allowed stack-based (local) data.{{Citation Needed|date=April 2022}} | |||
==Memory sharing== | ==Memory sharing== | ||
{{main|Shared memory}} | {{main|Shared memory}} | ||
Library code may be shared in memory by multiple [[Process (computing)|process]]es | Library code may be shared in memory by multiple [[Process (computing)|process]]es and on disk. If virtual memory is used, processes would execute the same physical page of RAM mapped into the processes' different address spaces. This has advantages. For instance, on the [[OpenStep]] system, applications were often only a few hundred kilobytes in size and loaded quickly; most of their code was located in libraries already loaded for other purposes by the operating system.{{Citation needed|date=December 2008}} | ||
Programs can accomplish RAM sharing by using [[position-independent code]], as in [[Unix]], which leads to a complex but flexible architecture, or by using common virtual addresses, as in Windows and [[OS/2]]. These systems ensure | Programs can accomplish RAM sharing by using [[position-independent code]], as in [[Unix]], which leads to a complex but flexible architecture, or by using common virtual addresses, as in Windows and [[OS/2]]. These systems ensure that code has a high probability of being shared by various means, like pre-mapping the address space and reserving slots for each shared library. A third alternative is a [[single-level store]] with a [[single address space operating system|single address space]], as used by the [[IBM System/38]] and its successors. This allows position-dependent code, with programs and libraries assigned a permanent address in that address space. | ||
In some cases, different versions of shared libraries can cause problems, especially when libraries of different versions have the same file name | In some cases, different versions of shared libraries can cause problems, especially when libraries of different versions have the same file name and various applications are installed on a system, each requiring a specific version. This scenario is known as [[DLL hell]], named after the Windows and OS/2 [[DLL file|DLL files]]. Most modern operating systems after 2001 have clean-up methods to eliminate such situations or use application-specific "private" libraries.<ref name="endofdllhell">{{cite web | ||
| url=http://msdn.microsoft.com/library/techart/dlldanger1.htm | | url=http://msdn.microsoft.com/library/techart/dlldanger1.htm | ||
| title=The End of DLL Hell | | title=The End of DLL Hell | ||
| Line 45: | Line 43: | ||
{{main|Dynamic linker}} | {{main|Dynamic linker}} | ||
Dynamic linking or [[late binding]] is linking performed while a program is being loaded ([[load time]]) or executed ([[Runtime (program lifecycle phase)|runtime]]), rather than when the executable file is created. A dynamically linked library ([[dynamic-link library]], or DLL, under [[Microsoft Windows|Windows]] and [[OS/2]]; shareable image under [[OpenVMS]];<ref>{{cite web|url=https://vmssoftware.com/docs/VSI_Linker_Manual.pdf|title=VSI OpenVMS Linker Utility Manual|date=August 2019|access-date=2021-01-31|publisher=VSI}}</ref> dynamic shared object, or DSO, under [[Unix-like]] systems) is a library intended for dynamic linking. Only a minimal amount of work is done by the [[Linker (computing)|linker]] when the executable file is created; it only records what library routines the program needs and the index names or numbers of the routines in the library. | Dynamic linking or [[late binding]] is linking performed while a program is being loaded ([[load time]]) or executed ([[Runtime (program lifecycle phase)|runtime]]), rather than when the executable file is created. A dynamically linked library ([[dynamic-link library]], or DLL, under [[Microsoft Windows|Windows]] and [[OS/2]]; shareable image under [[OpenVMS]];<ref>{{cite web|url=https://vmssoftware.com/docs/VSI_Linker_Manual.pdf|title=VSI OpenVMS Linker Utility Manual|date=August 2019|access-date=2021-01-31|publisher=VSI}}</ref> dynamic shared object, or DSO, under [[Unix-like]] systems) is a library intended for dynamic linking. Only a minimal amount of work is done by the [[Linker (computing)|linker]] when the executable file is created; it only records what library routines the program needs and the index names or numbers of the routines in the library. Most linking work is done when the application is loaded (load time) or during execution (runtime). Usually, the necessary linking program, called a ''dynamic linker'' or ''linking loader'', is part of the underlying [[operating system]]. (However, it is possible, and not exceedingly difficult, to write a program that uses dynamic linking and includes its own dynamic linker, even for an operating system that provides no support for dynamic linking.) | ||
Programmers originally developed dynamic linking in the [[Multics]] operating system, starting in 1964, and the MTS ([[Michigan Terminal System]]), built in the late 1960s.<ref>{{cite journal | title=A History of MTS | journal=Information Technology Digest | volume=5 | issue=5}}</ref> | Programmers originally developed dynamic linking in the [[Multics]] operating system, starting in 1964, and the MTS ([[Michigan Terminal System]]), built in the late 1960s.<ref>{{cite journal | title=A History of MTS | journal=Information Technology Digest | volume=5 | issue=5}}</ref> | ||
==Optimizations== | ==Optimizations== | ||
Since shared libraries on most systems do not change often, systems can compute a likely load address for each shared library on the system before it is needed and store that information in the libraries and executables. If every shared library | Since shared libraries on most systems do not change often, systems can compute a likely load address for each shared library on the system before it is needed and store that information in the libraries and executables. If every loaded shared library has undergone this process, each will load at its predetermined address, which speeds up the dynamic linking process. This optimization is known as [[prebinding|prebinding or prelinking]] on macOS and Linux. IBM [[z/VM]] uses a similar technique, called "Discontinuous Saved Segments" (DCSS).<ref>{{cite book |last1=IBM Corporation |title=Saved Segments Planning and Administration |date=2011 |url=http://publibfp.boulder.ibm.com/epubs/pdf/hcsg4c10.pdf |access-date=Jan 29, 2022}}</ref> Disadvantages of this technique include the time required to precompute these addresses every time the shared libraries change, the inability to use [[address space layout randomization]], and the requirement of sufficient virtual address space for use (a problem that will be alleviated by the adoption of [[64-bit]] architectures, at least for the time being). | ||
==Locating libraries at runtime== | ==Locating libraries at runtime== | ||
Loaders for shared libraries vary widely in functionality. Some depend on the executable storing explicit paths to the libraries. Any change to the library naming or layout of the file system will cause these systems to fail. More commonly, only the name of the library (and not the path) is stored in the executable, with the operating system supplying a method to find the library on disk, based on some algorithm. | Loaders for shared libraries vary widely in functionality. Some depend on the executable storing explicit paths to the libraries. Any change to the library naming or layout of the file system will cause these systems to fail. More commonly, only the name of the library (and not the path) is stored in the executable, with the operating system supplying a method to find the library on disk, based on some algorithm. | ||
If a shared library that an executable depends on is deleted, moved, or renamed, or if an incompatible version of the library is copied to a place | If a shared library that an executable depends on is deleted, moved, or renamed, or if an incompatible version of the library is copied to a place earlier in the search, the executable would fail to load. This is called ''[[dependency hell]]'', existing on many platforms. The (infamous) Windows variant is commonly known as [[DLL hell]]. This problem cannot occur if each library version is uniquely identified and each program references libraries only by their full unique identifiers. The "DLL hell" problems with earlier Windows versions arose from using only the names of libraries, which were not guaranteed to be unique, to resolve dynamic links in programs. (To avoid "DLL hell", later versions of Windows rely primarily on options for programs to install private DLLs—essentially a partial retreat from the use of shared libraries—along with mechanisms to prevent replacement of shared system DLLs with earlier versions.) | ||
===Microsoft Windows=== | ===Microsoft Windows=== | ||
[[Microsoft Windows]] checks the [[Windows registry|registry]] to determine the proper place to load DLLs that implement [[Component Object Model|COM objects]], but for other DLLs it will check the directories in a defined order. First, Windows checks the directory where it loaded the program (''private DLL''<ref name="endofdllhell"/>); any directories set by calling the <code>SetDllDirectory()</code> function; the System32, System, and Windows directories; then the current working directory; and finally the directories specified by the PATH [[environment variable]].<ref>{{cite web | [[Microsoft Windows]] checks the [[Windows registry|registry]] to determine the proper place to load DLLs that implement [[Component Object Model|COM objects]], but for other DLLs, it will check the directories in a defined order. First, Windows checks the directory where it loaded the program (''private DLL''<ref name="endofdllhell"/>); any directories set by calling the <code>SetDllDirectory()</code> function; the System32, System, and Windows directories; then the current working directory; and finally the directories specified by the PATH [[environment variable]].<ref>{{cite web | ||
|url = http://msdn.microsoft.com/en-us/library/ms682586.aspx | |url = http://msdn.microsoft.com/en-us/library/ms682586.aspx | ||
|title = Dynamic-Link Library Search Order | |title = Dynamic-Link Library Search Order | ||
| Line 71: | Line 69: | ||
===OpenStep=== | ===OpenStep=== | ||
[[OpenStep]] used a more flexible system, collecting a list of libraries from | [[OpenStep]] used a more flexible system, collecting a list of libraries from several known locations (similar to the PATH concept) when the system first starts. Moving libraries around causes no problems, although users incur a time cost when first starting the system. | ||
===Unix-like systems=== | ===Unix-like systems=== | ||
Most [[Unix-like]] systems have a "search path" specifying file-system [[Directory (computing)|directories]] | Most [[Unix-like]] systems have a "search path" specifying file-system [[Directory (computing)|directories]] to look for dynamic libraries. Some systems specify the default path in a [[configuration file]], others hard-code it into the dynamic loader. Some [[executable|executable file]] formats can specify additional directories to search for libraries for a particular program. This can usually be overridden with an [[environment variable]], although it is disabled for [[setuid]] and setgid programs, so that a user can't force such a program to run arbitrary code with root permissions. Developers of libraries are encouraged to place their dynamic libraries in places in the default search path. On the downside, this can make installation of new libraries problematic, and these "known" locations quickly become home to an increasing number of library files, making management more complex. | ||
==Dynamic loading== | ==Dynamic loading== | ||
{{Main|Dynamic loading}} | {{Main|Dynamic loading}} | ||
Dynamic loading, a subset of dynamic linking, involves a dynamically linked library loading and unloading at [[Runtime (program lifecycle phase)|runtime]] on request. Such a request may be made implicitly or explicitly. Implicit requests are made when a compiler or static linker adds library references that include file paths or simply file names.{{cn|date=March 2020}} Explicit requests are made when applications | Dynamic loading, a subset of dynamic linking, involves a dynamically linked library loading and unloading at [[Runtime (program lifecycle phase)|runtime]] on request. Such a request may be made implicitly or explicitly. Implicit requests are made when a compiler or static linker adds library references that include file paths or simply file names.{{cn|date=March 2020}} Explicit requests are made when applications directly call an operating system's API. | ||
Most operating systems that support dynamically linked libraries also support dynamically loading such libraries via a [[Runtime (program lifecycle phase)|run-time]] linker [[Application programming interface|API]]. For instance, [[Microsoft Windows]] uses the API functions <code>LoadLibrary</code>, <code>LoadLibraryEx</code>, <code>FreeLibrary</code> and <code>GetProcAddress</code> with [[Microsoft Dynamic Link Library|Microsoft Dynamic Link Libraries]]; [[POSIX]]-based systems, including most UNIX and UNIX-like systems, use <code>dlopen</code>, <code>dlclose</code> and <code>dlsym</code>. Some development systems automate this process. | Most operating systems that support dynamically linked libraries also support dynamically loading such libraries via a [[Runtime (program lifecycle phase)|run-time]] linker [[Application programming interface|API]]. For instance, [[Microsoft Windows]] uses the API functions <code>LoadLibrary</code>, <code>LoadLibraryEx</code>, <code>FreeLibrary</code>, and <code>GetProcAddress</code> with [[Microsoft Dynamic Link Library|Microsoft Dynamic Link Libraries]]; [[POSIX]]-based systems, including most UNIX and UNIX-like systems, use <code>dlopen</code>, <code>dlclose,</code> and <code>dlsym</code>. Some development systems automate this process. | ||
==Notes== | ==Notes== | ||
{{reflist|group=NB}} | {{reflist|group=NB}} | ||
Latest revision as of 15:23, 20 July 2025
Template:Short description Script error: No such module "redirect hatnote".
A shared library is a library that contains executable code designed to be used by multiple computer programs or other libraries at runtime, with only one copy of that code in memory, shared by all programs using the code.[1][2][3]
Library types
A library can be provided as static, dynamic, or both. A program that uses a static library is statically linked with the library; a program that uses a dynamic library is dynamically linked with the library. Historically, libraries could only be static.[4] For static linking, code from the library is embedded into the program's executable file. A dynamically linked library is loaded at runtime from the library file.
A program requires a compiler and a linker step to access a library. In static linking, those references are fully resolved at compile time,[5] whereas in dynamic linking, those references are not fully resolved until runtime by the operating system.
Formats
Many modern operating systems use a unified format for their dynamic libraries and executable files. For example:
- Microsoft Windows uses the Portable Executable (PE) format for .dll files.
- Linux and BSD, as well as Solaris and other System V Release 4-based systems, use the Executable and Linkable Format (ELF) for .so files.
- Apple's Darwin-based operating systems, such as macOS and iOS, use the Mach-O format for .dylib files.
This offers two main advantages: first, it requires only one loader (building and maintaining a single loader is considered well worth any added complexity). Secondly, it allows an executable file to be used as a shared library (if it has a symbol table).Template:Citation Needed
Significant restrictions were placed on shared library code in some older environments, such as 16-bit Windows or MPE for the HP 3000, which only allowed stack-based (local) data.Template:Citation Needed
Memory sharing
Script error: No such module "Labelled list hatnote".
Library code may be shared in memory by multiple processes and on disk. If virtual memory is used, processes would execute the same physical page of RAM mapped into the processes' different address spaces. This has advantages. For instance, on the OpenStep system, applications were often only a few hundred kilobytes in size and loaded quickly; most of their code was located in libraries already loaded for other purposes by the operating system.Script error: No such module "Unsubst".
Programs can accomplish RAM sharing by using position-independent code, as in Unix, which leads to a complex but flexible architecture, or by using common virtual addresses, as in Windows and OS/2. These systems ensure that code has a high probability of being shared by various means, like pre-mapping the address space and reserving slots for each shared library. A third alternative is a single-level store with a single address space, as used by the IBM System/38 and its successors. This allows position-dependent code, with programs and libraries assigned a permanent address in that address space.
In some cases, different versions of shared libraries can cause problems, especially when libraries of different versions have the same file name and various applications are installed on a system, each requiring a specific version. This scenario is known as DLL hell, named after the Windows and OS/2 DLL files. Most modern operating systems after 2001 have clean-up methods to eliminate such situations or use application-specific "private" libraries.[6]
Dynamic linking
Script error: No such module "Labelled list hatnote".
Dynamic linking or late binding is linking performed while a program is being loaded (load time) or executed (runtime), rather than when the executable file is created. A dynamically linked library (dynamic-link library, or DLL, under Windows and OS/2; shareable image under OpenVMS;[7] dynamic shared object, or DSO, under Unix-like systems) is a library intended for dynamic linking. Only a minimal amount of work is done by the linker when the executable file is created; it only records what library routines the program needs and the index names or numbers of the routines in the library. Most linking work is done when the application is loaded (load time) or during execution (runtime). Usually, the necessary linking program, called a dynamic linker or linking loader, is part of the underlying operating system. (However, it is possible, and not exceedingly difficult, to write a program that uses dynamic linking and includes its own dynamic linker, even for an operating system that provides no support for dynamic linking.)
Programmers originally developed dynamic linking in the Multics operating system, starting in 1964, and the MTS (Michigan Terminal System), built in the late 1960s.[8]
Optimizations
Since shared libraries on most systems do not change often, systems can compute a likely load address for each shared library on the system before it is needed and store that information in the libraries and executables. If every loaded shared library has undergone this process, each will load at its predetermined address, which speeds up the dynamic linking process. This optimization is known as prebinding or prelinking on macOS and Linux. IBM z/VM uses a similar technique, called "Discontinuous Saved Segments" (DCSS).[9] Disadvantages of this technique include the time required to precompute these addresses every time the shared libraries change, the inability to use address space layout randomization, and the requirement of sufficient virtual address space for use (a problem that will be alleviated by the adoption of 64-bit architectures, at least for the time being).
Locating libraries at runtime
Loaders for shared libraries vary widely in functionality. Some depend on the executable storing explicit paths to the libraries. Any change to the library naming or layout of the file system will cause these systems to fail. More commonly, only the name of the library (and not the path) is stored in the executable, with the operating system supplying a method to find the library on disk, based on some algorithm.
If a shared library that an executable depends on is deleted, moved, or renamed, or if an incompatible version of the library is copied to a place earlier in the search, the executable would fail to load. This is called dependency hell, existing on many platforms. The (infamous) Windows variant is commonly known as DLL hell. This problem cannot occur if each library version is uniquely identified and each program references libraries only by their full unique identifiers. The "DLL hell" problems with earlier Windows versions arose from using only the names of libraries, which were not guaranteed to be unique, to resolve dynamic links in programs. (To avoid "DLL hell", later versions of Windows rely primarily on options for programs to install private DLLs—essentially a partial retreat from the use of shared libraries—along with mechanisms to prevent replacement of shared system DLLs with earlier versions.)
Microsoft Windows
Microsoft Windows checks the registry to determine the proper place to load DLLs that implement COM objects, but for other DLLs, it will check the directories in a defined order. First, Windows checks the directory where it loaded the program (private DLL[6]); any directories set by calling the SetDllDirectory() function; the System32, System, and Windows directories; then the current working directory; and finally the directories specified by the PATH environment variable.[10] Applications written for the .NET Framework (since 2002), also check the Global Assembly Cache as the primary store of shared dll files to remove the issue of DLL hell.
OpenStep
OpenStep used a more flexible system, collecting a list of libraries from several known locations (similar to the PATH concept) when the system first starts. Moving libraries around causes no problems, although users incur a time cost when first starting the system.
Unix-like systems
Most Unix-like systems have a "search path" specifying file-system directories to look for dynamic libraries. Some systems specify the default path in a configuration file, others hard-code it into the dynamic loader. Some executable file formats can specify additional directories to search for libraries for a particular program. This can usually be overridden with an environment variable, although it is disabled for setuid and setgid programs, so that a user can't force such a program to run arbitrary code with root permissions. Developers of libraries are encouraged to place their dynamic libraries in places in the default search path. On the downside, this can make installation of new libraries problematic, and these "known" locations quickly become home to an increasing number of library files, making management more complex.
Dynamic loading
Script error: No such module "Labelled list hatnote". Dynamic loading, a subset of dynamic linking, involves a dynamically linked library loading and unloading at runtime on request. Such a request may be made implicitly or explicitly. Implicit requests are made when a compiler or static linker adds library references that include file paths or simply file names.Script error: No such module "Unsubst". Explicit requests are made when applications directly call an operating system's API.
Most operating systems that support dynamically linked libraries also support dynamically loading such libraries via a run-time linker API. For instance, Microsoft Windows uses the API functions LoadLibrary, LoadLibraryEx, FreeLibrary, and GetProcAddress with Microsoft Dynamic Link Libraries; POSIX-based systems, including most UNIX and UNIX-like systems, use dlopen, dlclose, and dlsym. Some development systems automate this process.
Notes
See also
References
Sources
- Script error: No such module "citation/CS1".
External links
- How To Write Shared Libraries by Ulrich Drepper
- ↑ Script error: No such module "citation/CS1".
- ↑ Script error: No such module "citation/CS1".
- ↑ Script error: No such module "citation/CS1".
- ↑ Script error: No such module "citation/CS1".
- ↑ Script error: No such module "citation/CS1".
- ↑ a b Script error: No such module "citation/CS1".
- ↑ Script error: No such module "citation/CS1".
- ↑ Script error: No such module "Citation/CS1".
- ↑ Script error: No such module "citation/CS1".
- ↑ Script error: No such module "citation/CS1".