- 22.2 Installation
- 22.2.1 Installing Linux Runtime Libraries
- 22.2.1.1 Installing Using the linux_base Port
- 22.2.1.2 Installing Libraries Manually
- 22.2.1.3 How to Install Additional Shared Libraries
- 22.2.2 Installing Linux ELF Binaries
- 22.2.3 Configuring the Hostname Resolver
- Install the .NET SDK or the .NET Runtime manually
- .NET releases
- Dependencies
- RPM dependencies
- DEB dependencies
- Common dependencies
- Scripted install
- Manual install
- Static, Shared Dynamic and Loadable Linux Libraries
- Library naming conventions:
- ar: list object files in archive library
- nm: list symbols: object files, archive library and shared library
- readelf: list symbols in shared library
22.2 Installation
Linux binary compatibility is not turned on by default. The easiest way to enable this functionality is to load the linux KLD object («Kernel LoaDable object»). You can load this module by simply typing linux at the command prompt.
If you would like Linux compatibility to always be enabled, then you should add the following line to /etc/rc.conf:
This, in turn, triggers the following action in /etc/rc.i386:
The kldstat (8) command can be used to verify that the KLD is loaded:
If for some reason you do not want to or cannot load the KLD, then you may statically link Linux binary compatibility into the kernel by adding options LINUX to your kernel configuration file. Then install your new kernel as described in Chapter 9.
22.2.1 Installing Linux Runtime Libraries
This can be done one of two ways, either by using the linux_base port, or by installing them manually.
22.2.1.1 Installing Using the linux_base Port
This is by far the easiest method to use when installing the runtime libraries. It is just like installing any other port from the ports collection. Simply do the following:
You should now have working Linux binary compatibility. Some programs may complain about incorrect minor versions of the system libraries. In general, however, this does not seem to be a problem.
22.2.1.2 Installing Libraries Manually
If you do not have the «ports» collection installed, you can install the libraries by hand instead. You will need the Linux shared libraries that the program depends on and the runtime linker. Also, you will need to create a «shadow root» directory, /compat/linux, for Linux libraries on your FreeBSD system. Any shared libraries opened by Linux programs run under FreeBSD will look in this tree first. So, if a Linux program loads, for example, /lib/libc.so, FreeBSD will first try to open /compat/linux/lib/libc.so, and if that does not exist, it will then try /lib/libc.so. Shared libraries should be installed in the shadow tree /compat/linux/lib rather than the paths that the Linux ld.so reports.
Generally, you will need to look for the shared libraries that Linux binaries depend on only the first few times that you install a Linux program on your FreeBSD system. After a while, you will have a sufficient set of Linux shared libraries on your system to be able to run newly imported Linux binaries without any extra work.
22.2.1.3 How to Install Additional Shared Libraries
What if you install the linux_base port and your application still complains about missing shared libraries? How do you know which shared libraries Linux binaries need, and where to get them? Basically, there are 2 possibilities (when following these instructions you will need to be root on your FreeBSD system).
If you have access to a Linux system, see what shared libraries the application needs, and copy them to your FreeBSD system. Look at the following example:
Let us assume you used FTP to get the Linux binary of Doom, and put it on a Linux system you have access to. You then can check which shared libraries it needs by running ldd linuxdoom, like so:
You would need to get all the files from the last column, and put them under /compat/linux, with the names in the first column as symbolic links pointing to them. This means you eventually have these files on your FreeBSD system:
Note: Note that if you already have a Linux shared library with a matching major revision number to the first column of the ldd output, you will not need to copy the file named in the last column to your system, the one you already have should work. It is advisable to copy the shared library anyway if it is a newer version, though. You can remove the old one, as long as you make the symbolic link point to the new one. So, if you have these libraries on your system:
and you find a new binary that claims to require a later version according to the output of ldd:
If it is only one or two versions out of date in the in the trailing digit then do not worry about copying /lib/libc.so.4.6.29 too, because the program should work fine with the slightly older version. However, if you like, you can decide to replace the libc.so anyway, and that should leave you with:
Note: The symbolic link mechanism is only needed for Linux binaries. The FreeBSD runtime linker takes care of looking for matching major revision numbers itself and you do not need to worry about it.
22.2.2 Installing Linux ELF Binaries
ELF binaries sometimes require an extra step of «branding». If you attempt to run an unbranded ELF binary, you will get an error message like the following:
To help the FreeBSD kernel distinguish between a FreeBSD ELF binary from a Linux binary, use the brandelf (1) utility.
The GNU toolchain now places the appropriate branding information into ELF binaries automatically, so you this step should become increasingly more rare in the future.
22.2.3 Configuring the Hostname Resolver
If DNS does not work or you get this message:
You will need to configure a /compat/linux/etc/host.conf file containing:
The order here specifies that /etc/hosts is searched first and DNS is searched second. When /compat/linux/etc/host.conf is not installed, Linux applications find FreeBSD’s /etc/host.conf and complain about the incompatible FreeBSD syntax. You should remove bind if you have not configured a name server using the /etc/resolv.conf file.
Prev | Home | Next |
Linux Binary Compatibility | Up | Installing Mathematica |
For questions about FreeBSD, read the documentation before contacting .
For questions about this documentation, e-mail .
Источник
Install the .NET SDK or the .NET Runtime manually
.NET is supported on Linux and this article describes how to install .NET on Linux using the install script or by extracting the binaries. For a list of distributions that support the built-in package manager, see Install .NET on Linux.
You can also install .NET with snap. For more information, see Install the .NET SDK or the .NET Runtime with Snap.
Install the SDK (which includes the runtime) if you want to develop .NET apps. Or, if you only need to run apps, install the Runtime. If you’re installing the Runtime, we suggest you install the ASP.NET Core Runtime as it includes both .NET and ASP.NET Core runtimes.
If you’ve already installed the SDK or Runtime, use the dotnet —list-sdks and dotnet —list-runtimes commands to see which versions are installed. For more information, see How to check that .NET is already installed.
.NET releases
The following table lists the .NET (and .NET Core) releases:
вњ”пёЏ Supported | вќЊ Unsupported |
---|---|
5.0 | 3.0 |
3.1 (LTS) | 2.2 |
2.1 (LTS) | 2.0 |
1.1 | |
1.0 |
For more information about the life cycle of .NET releases, see .NET Core and .NET 5 Support Policy.
Dependencies
It’s possible that when you install .NET, specific dependencies may not be installed, such as when manually installing. The following list details Linux distributions that are supported by Microsoft and have dependencies you may need to install. Check the distribution page for more information:
For generic information about the dependencies, see Self-contained Linux apps.
RPM dependencies
If your distribution wasn’t previously listed, and is RPM-based, you may need the following dependencies:
If the target runtime environment’s OpenSSL version is 1.1 or newer, you’ll need to install compat-openssl10.
DEB dependencies
If your distribution wasn’t previously listed, and is debian-based, you may need the following dependencies:
Common dependencies
For .NET apps that use the System.Drawing.Common assembly, you’ll also need the following dependency:
You can install a recent version of libgdiplus by adding the Mono repository to your system. For more information, see https://www.mono-project.com/download/stable/.
Scripted install
The dotnet-install scripts are used for automation and non-admin installs of the SDK and Runtime. You can download the script from https://dot.net/v1/dotnet-install.sh.
![IMPORTANT] Bash is required to run the script.
The script defaults to installing the latest SDK long term support (LTS) version, which is .NET Core 3.1. To install the current release, which may not be an (LTS) version, use the -c Current parameter.
To install .NET Runtime instead of the SDK, use the —runtime parameter.
You can install a specific version by altering the -c parameter to indicate the specific version. The following command installs .NET SDK 5.0.
Manual install
As an alternative to the package managers, you can download and manually install the SDK and runtime. Manual installation is commonly used as part of continuous integration testing or on an unsupported Linux distribution. For a developer or user, it’s better to use a package manager.
First, download a binary release for either the SDK or the runtime from one of the following sites. If you install the .NET SDK, you will not need to install the corresponding runtime:
Next, extract the downloaded file and use the export command to set DOTNET_ROOT to the extracted folder’s location and then ensure .NET is in PATH. This should make the .NET CLI commands available at the terminal.
Alternatively, after downloading the .NET binary, the following commands may be run from the directory where the file is saved to extract the runtime. This will also make the .NET CLI commands available at the terminal and set the required environment variables. Remember to change the DOTNET_FILE value to the name of the downloaded binary:
The preceding export commands only make the .NET CLI commands available for the terminal session in which it was run.
You can edit your shell profile to permanently add the commands. There are a number of different shells available for Linux and each has a different profile. For example:
- Bash Shell:
/.bashrc
Korn Shell:
/.kshrc or .profile
Z Shell:
Edit the appropriate source file for your shell and add :$HOME/dotnet to the end of the existing PATH statement. If no PATH statement is included, add a new line with export PATH=$PATH:$HOME/dotnet .
Also, add export DOTNET_ROOT=$HOME/dotnet to the end of the file.
This approach lets you install different versions into separate locations and choose explicitly which one to use by which application.
Источник
Static, Shared Dynamic and Loadable Linux Libraries
This tutorial discusses the philosophy behind libraries and the creation and use of C/C++ library «shared components» and «plug-ins». The various technologies and methodologies used and insight to their appropriate application, is also discussed. In this tutorial, all libraries are created using the GNU Linux compiler.
Related YoLinux Tutorials:
Libraries employ a software design also known as «shared components» or «archive libraries», which groups together multiple compiled object code files into a single file known as a library. Typically C functions/C++ classes and methods which can be shared by more than one application are broken out of the application’s source code, compiled and bundled into a library. The C standard libraries and C++ STL are examples of shared components which can be linked with your code. The benefit is that each and every object file need not be stated when linking because the developer can reference the library collective. This simplifies the multiple use and sharing of software components between applications. It also allows application vendors a way to simply release an API to interface with an application. Components which are large can be created for dynamic use, thus the library can remain separate from the executable reducing it’s size and thus less disk space is used for the application. The library components are then called by various applications for use when needed.
Benefits include:
- Component reuse: update one library, shared resource takes up less disk space.
- Version management: Linux libraries can cohabitate old and new versions on a single system.
- Component Specialization: niche and specialized developers can focus on their core competency on a single library. Simplifies testing and verification.
There are two Linux C/C++ library types which can be created:
- Static libraries (.a): Library of object code which is linked with, and becomes part of the application.
- Dynamically linked shared object libraries (.so): There is only one form of this library but it can be used in two ways.
- Dynamically linked at run time. The libraries must be available during compile/link phase. The shared objects are not included into the executable component but are tied to the execution.
- Dynamically loaded/unloaded and linked during execution (i.e. browser plug-in) using the dynamic linking loader system functions.
Library naming conventions:
Consider the following compile and link command: gcc src-file.c -lm -lpthread
The libraries referenced in this example for inclusion during linking are the math library («m») and the thread library («pthread»). They are found in /usr/lib/libm.a and /usr/lib/libpthread.a.
Note: The GNU compiler now has the command line option «-pthread» while older versions of the compiler specify the pthread library explicitly with «-lpthread». Thus now you are more likely to see gcc src-file.c -lm -pthread
How to generate a static library (object code archive file):
- Compile: cc -Wall -c ctest1.c ctest2.c
Compiler options:- -Wall: include warnings. See man page for warnings specified.
- Create library «libctest.a»: ar -cvq libctest.a ctest1.o ctest2.o
- List files in library: ar -t libctest.a
- Linking with the library:
- cc -o executable-name prog.c libctest.a
- cc -o executable-name prog.c -L/path/to/library-directory -lctest
- Example files:
- ctest1.c
- ctest2.c
- prog.c
Historical note: After creating the library it was once necessary to run the command: ranlib ctest.a. This created a symbol table within the archive. Ranlib is now embedded into the «ar» command.
Note for MS/Windows developers: The Linux/Unix «.a» library is conceptually the same as the Visual C++ static «.lib» libraries.
How to generate a shared object: (Dynamically linked object library file.) Note that this is a two step process.
- Create object code
- Create library
- Optional: create default version using a symbolic link.
Library creation example: This creates the library libctest.so.1.0 and symbolic links to it.
It is also valid to cascade the linkage: If you look at the libraries in /lib/ and /usr/lib/ you will find both methodologies present. Linux developers are not consistent. What is important is that the symbolic links eventually point to an actual library.
- -Wall: include warnings. See man page for warnings specified.
- -fPIC: Compiler directive to output position independent code, a characteristic required by shared libraries. Also see «-fpic».
- -shared: Produce a shared object which can then be linked with other objects to form an executable.
- -Wl,options: Pass options to linker.
In this example the options to be passed on to the linker are: «-soname libctest.so.1«. The name passed with the «-o» option is passed to gcc. - Option -o: Output of operation. In this case the name of the shared object to be output will be «libctest.so.1.0«
- The link to /opt/lib/libctest.so allows the naming convention for the compile flag -lctest to work.
- The link to /opt/lib/libctest.so.1 allows the run time binding to work. See dependency below.
Compile main program and link with shared object library:
Compiling for run-time linking with a dynamically linked libctest.so.1.0: Use: Where the name of the library is libctest.so. (This is why you must create the symbolic links or you will get the error «/usr/bin/ld: cannot find -lctest».)
The libraries will NOT be included in the executable but will be dynamically linked during run-time execution.
The shared library dependencies of the executable can be listed with the command: ldd name-of-executable
Example: ldd prog [Potential Pitfall] : Unresolved errors within a shared library may cause an error when the library is loaded. Example:
Error message at run-time:
The first three libraries show that there is a path resolution. The last two are problematic.
The fix is to resolve dependencies of the last two libraries when linking the library libname-of-lib.so:
- Add the unresolved library path in /etc/ld.so.conf.d/name-of-lib-x86_64.conf and/or /etc/ld.so.conf.d/name-of-lib-i686.conf
Reload the library cache (/etc/ld.so.cache) with the command: sudo ldconfig
or - Add library and path explicitly to the compiler/linker command: -lname-of-lib -L/path/to/lib
or - Add the library path to the environment variable to fix run-time dependency:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/lib
- Set path: export LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH
- Run: prog
Example with code:
Using the example code above for ctest1.c, ctest2.c and prog.c
- Compile the library functions: gcc -Wall -fPIC -c ctest1.c ctest2.c
- Generate the shared library: gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 ctest1.o ctest2.o
This generates the library libctest.so.1.0 - Move to lib/ directory:
- sudo mv libctest.so.1.0 /opt/lib
- sudo ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1
- sudo ln -sf /opt/lib/libctest.so.1 /opt/lib/libctest.so
Compile program for use with a shared library: gcc -Wall -L/opt/lib prog.c -lctest -o prog
[Potential Pitfall] : If the symbolic links are not created (above), you will get the following error: The reference to the library name -lctest refers to /opt/lib/libctest.so - Configure the library path (see below and choose one of three mechanisms).
In this example we set the environment variable: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/lib - Run the program: ./prog
[Potential Pitfall] : You get the following error if the library path is not set:
- gcc — GNU C compiler
- ld — The GNU Linker
- ldd — List library dependencies
- ldconfig — configure dynamic linker run time bindings (update cache /etc/ld.so.cache)
In order for an executable to find the required libraries to link with during run time, one must configure the system so that the libraries can be found. Methods available: (Do at least one of the following)
- Add library directories to be included during dynamic linking to the file /etc/ld.so.conf
Add the library path to this file and then execute the command (as root) ldconfig to configure the linker run-time bindings.
You can use the «-f file-name» flag to reference another configuration file if you are developing for different environments.
See man page for command ldconfig.
Add specified directory to library cache: (as root)
ldconfig -n /opt/lib
Where /opt/lib is the directory containing your library libctest.so
(When developing and just adding your current directory: ldconfig -n . Link with -L.)
This will NOT permanently configure the system to include this directory. The information will be lost upon system reboot.
Specify the environment variable LD_LIBRARY_PATH to point to the directory paths containing the shared object library. This will specify to the run time loader that the library paths will be used during execution to resolve dependencies.
(Linux/Solaris: LD_LIBRARY_PATH, SGI: LD_LIBRARYN32_PATH, AIX: LIBPATH, Mac OS X: DYLD_LIBRARY_PATH, HP-UX: SHLIB_PATH)
Example (bash shell): export LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH or add to your
This instructs the run time loader to look in the path described by the environment variable LD_LIBRARY_PATH, to resolve shared libraries. This will include the path /opt/lib.
Library paths used should conform to the «Linux Standard Base» directory structure.
ar: list object files in archive library
This will list all of the object files held in the archive library: Also see: Man page for ar
nm: list symbols: object files, archive library and shared library
The command «nm» lists symbols contained in object files:
The command «nm» lists symbols contained in the archive library:
Object symbols in static archive libraries are categorized using the source and object file hierarchy of the library:
The command «nm» lists symbols contained in the object file or shared library.
Use the command nm -D libctest.so.1.0
(or nm --dynamic libctest.so.1.0)
Note that other platforms (Cygwin) may not respond to «-D». Try nm -gC libctest.so.1.0
Also see: Man page for nm
Symbol Type | Description |
---|---|
A | The symbol’s value is absolute, and will not be changed by further linking. |
B | Un-initialized data section |
D | Initialized data section |
T | Normal code section |
U | Undefined symbol used but not defined. Dependency on another library. |
W | Doubly defined symbol. If found, allow definition in another library to resolve dependency. |
Also see: objdump man page
readelf: list symbols in shared library
The command «readelf» command to list symbols contained in a shared library:
Use the command readelf -s /usr/lib64/libjpeg.so
Also see: readelf man page
Library versions should be specified for shared objects if the function interfaces are expected to change (C++ public/protected class definitions), more or fewer functions are included in the library, the function prototype changes (return data type (int, const int, . ) or argument list changes) or data type changes (object definitions: class data members, inheritance, virtual functions, . ).
The library version can be specified when the shared object library is created. If the library is expected to be updated, then a library version should be specified. This is especially important for shared object libraries which are dynamically linked. This also avoids the Microsoft «DLL hell» problem of conflicting libraries where a system upgrade which changes a standard library breaks an older application expecting an older version of the the shared object function.
Versioning occurs with the GNU C/C++ libraries as well. This often make binaries compiled with one version of the GNU tools incompatible with binaries compiled with other versions unless those versions also reside on the system. Multiple versions of the same library can reside on the same system due to versioning. The version of the library is included in the symbol name so the linker knows which version to link with.
One can look at the symbol version used: nm csub1.o
No version is specified in object code by default.
There is one GNU C/C++ compiler flag that explicitly deals with symbol versioning. Specify the version script to use at compile time with the flag: --version-script=your-version-script-file
Note: This is only useful when creating shared libraries. It is assumed that the programmer knows which libraries to link with when static linking. Run-time linking allows opportunity for library incompatibility.
GNU/Linux, see examples of version scripts here: sysdeps/unix/sysv/linux/Versions
Some symbols may also get version strings from assembler code which appears in glibc headers files. Look at include/libc-symbols.h.
Example: nm /lib/libc.so.6 | more
Note the use of a version script.
Library referencing a versioned library: nm /lib/libutil-2.2.5.so
These libraries are dynamically loaded / unloaded and linked during execution. Useful for creating a «plug-in» architecture.
Prototype include file for the library: ctest.h
Load and unload the library libctest.so (created above), dynamically:
gcc -rdynamic -o progdl progdl.c -ldl
- dlopen("/opt/lib/libctest.so", RTLD_LAZY);
Open shared library named «libctest.so«.
The second argument indicates the binding. See include file dlfcn.h.
Returns NULL if it fails.
Options:- RTLD_LAZY: If specified, Linux is not concerned about unresolved symbols until they are referenced.
- RTLD_NOW: All unresolved symbols resolved when dlopen() is called.
- RTLD_GLOBAL: Make symbol libraries visible.
- dlsym(lib_handle, "ctest1");
Returns address to the function which has been loaded with the shared library..
Returns NULL if it fails.
Note: When using C++ functions, first use nm to find the «mangled» symbol name or use the extern "C" construct to avoid name mangling.
i.e. extern "C" void function-name();
Object code location: Object code archive libraries can be located with either the executable or the loadable library. Object code routines used by both should not be duplicated in each. This is especially true for code which use static variables such as singleton classes. A static variable is global and thus can only be represented once. Including it twice will provide unexpected results. The programmer can specify that specific object code be linked with the executable by using linker commands which are passed on by the compiler.
Use the «-Wl» gcc/g++ compiler flag to pass command line arguments on to the GNU «ld» linker.
Example makefile statement: g++ -rdynamic -o appexe $(OBJ) $(LINKFLAGS) -Wl,--whole-archive -L
- —whole-archive: This linker directive specifies that the libraries listed following this directive (in this case AA_libs) shall be included in the resulting output even though there may not be any calls requiring its presence. This option is used to specify libraries which the loadable libraries will require at run time.
- -no-whole-archive: This needs to be specified whether you list additional object files or not. The gcc/g++ compiler will add its own list of archive libraries and you would not want all the object code in the archive library linked in if not needed. It toggles the behavior back to normal for the rest of the archive libraries.
- dlopen() — gain access to an executable object file
- dclose() — close a dlopen object
- dlsym() — obtain the address of a symbol from a dlopen object
- dlvsym() — Programming interface to dynamic linking loader.
- dlerror() — get diagnostic information
C++ and name mangling:
When running the above «C» examples with the «C++» compiler one will quickly find that «C++» function names get mangled and thus will not work unless the function definitions are protected with extern "C"<>.
Note that the following are not equivalent:
The following are equivalent:
Dynamic loading of C++ classes:
The dynamic library loading routines enable the programmer to load «C» functions. In C++ we would like to load class member functions. In fact the entire class may be in the library and we may want to load and have access to the entire object and all of its member functions. Do this by passing a «C» class factory function which instantiates the class.
The class «.h» file:
The class «.cpp» file:
Main executable which calls the loadable libraries:
Pitfalls:
- The new/delete of the C++ class should both be provided by the executable or the library but not split. This is so that there is no surprise if one overloads new/delete in one or the other.
The Microsoft Windows equivalent to the Linux / Unix shared object («.so») is the «.dll». The Microsoft Windows DLL file usually has the extension «.dll», but may also use the extension «.ocx». On the old 16 bit windows, the dynamically linked libraries were also named with the «.exe» suffix. «Executing» the DLL will load it into memory.
The Visual C++ .NET IDE wizard will create a DLL framework through the GUI, and generates a «.def» file. This «module definition file» lists the functions to be exported. When exporting C++ functions, the C++ mangled names are used. Using the Visual C++ compiler to generate a «.map» file will allow you to discover the C++ mangled name to use in the «.def» file. The «SECTIONS» label in the «.def» file will define the portions which are «shared». Unfortunately the generation of DLLs are tightly coupled to the Microsoft IDE, so much so that I would not recommend trying to create one without it.
The Microsoft Windows C++ equivalent functions to libdl are the following functions:
- ::LoadLibrary() — dlopen()
- ::GetProcAddress() — dlsym()
- ::FreeLibrary() — dlclose()
[Potential Pitfall] : Microsoft Visual C++ .NET compilers do not allow the linking control that the GNU linker «ld» allows (i.e. —whole-archive, -no-whole-archive). All symbols need to be resolved by the VC++ compiler for both the loadable library and the application executable individually and thus it can cause duplication of libraries when the library is loaded. This is especially bad when using static variables (i.e. used in singleton patterns) as you will get two memory locations for the static variable, one used by the loadable library and the other used by the program executable. This breaks the whole static variable concept and the singleton pattern. Thus you can not use a static variable which is referenced by by both the loadable library and the application executable as they will be unique and different. To use a unique static variable, you must pass a pointer to that static variable to the other module so that each module (main executable and DLL library) can use the same instantiation. On MS/Windows you can use shared memory or a memory mapped file so that the main executable and DLL library can share a pointer to an address they both will use.
Cross platform (Linux and MS/Windows) C++ code snippet:
Источник