Executables and SO files in linux

In Linux, there isn't a direct equivalent to Windows' .exe file extension, as Linux doesn't rely on file extensions to determine whether a file is executable. Instead, the "executable" status of a file is determined by its file permissions and format. Here's an explanation:


What is an Executable in Linux?

An executable in Linux is any file that has:

  1. Executable Permissions: A file is executable if it has the execute (x) permission set for the user, group, or others. You can check a file's permissions using:

    ls -l filename

    Example output:

    -rwxr-xr-x 1 user group size date filename

    The x indicates that the file is executable.

  2. Proper Format: The file must be a valid binary or script that the operating system can execute. Common formats include:

    • ELF (Executable and Linkable Format): Standard for compiled programs in Linux.

    • Shell Scripts (e.g., Bash): Executable text files starting with a shebang (#!) specifying the interpreter (e.g., #!/bin/bash).


Examples of Executable Types in Linux

  1. Compiled Binary Executables:

    • Compiled programs (e.g., gcc output) are stored in the ELF format.

    • Example: ls, bash, vim are all binary executables.

    You can check if a file is in ELF format using:

    file filename

    Example output:

    filename: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux
  2. Scripts:

    • Text files that contain commands interpreted by a specific program (e.g., Bash, Python).

    • They must start with a shebang (e.g., #!/bin/bash or #!/usr/bin/python3).

    • Example:

      #!/bin/bash
      echo "Hello, World!"

      Save as script.sh and make it executable:

      chmod +x script.sh
      ./script.sh
  3. Dynamic Libraries and Loaders:

    • Sometimes, executables dynamically link to shared libraries (.so files).


Key Points About Linux Executables

  1. No File Extension Required:

    • Unlike .exe in Windows, Linux executables don't require specific extensions.

    • Example: my_program can be an executable without .exe or .sh.

  2. How to Run an Executable:

    • For a binary or script located in the current directory:

    • If the executable is in a directory listed in the PATH variable (e.g., /usr/bin), you can run it directly:

  3. Permission Management:

    • Use chmod to make a file executable:


Windows .exe vs. Linux Executables

Feature

Windows .exe

Linux Executable

File Extension

.exe (mandatory)

No specific extension required

File Format

PE (Portable Executable)

ELF (Executable and Linkable Format)

Dependency System

Dynamic-link libraries (.dll)

Shared libraries (.so)

Execution Control

Based on file extension

Based on permissions and file format


Common Linux Executable Locations

  • System-Wide Binaries:

    • /bin, /sbin, /usr/bin, /usr/sbin

    • Examples: ls, cp, mkdir

  • User-Specific Binaries:

    • Located in directories like ~/bin or custom paths.

  • Custom Programs:

    • Often placed in /opt or manually installed in a user directory.


How to Identify an Executable in Linux

  1. Check permissions:

  2. Verify format:

  3. Test execution:


What Are Shared Libraries (.so Files) in Ubuntu?

Shared libraries are files with the extension .so (short for shared object) in Linux-based systems like Ubuntu. They are collections of compiled functions or code that can be used by multiple programs or executables. Shared libraries are analogous to .dll (Dynamic Link Library) files in Windows.

Shared libraries enable code reusability and modularity, making programs smaller and more efficient by avoiding redundant inclusion of the same code in multiple binaries.


Characteristics of Shared Libraries

  1. Dynamic Loading:

    • Shared libraries are loaded into memory when a program starts or during runtime (if needed).

    • This is in contrast to static libraries, which are linked directly into the program at compile time.

  2. File Format:

    • Typically in the ELF (Executable and Linkable Format).

    • They have the .so extension followed by a version number, e.g., libexample.so.1.2.3.

  3. Storage Locations:

    • Shared libraries are usually stored in standard system directories:

      • /lib or /lib64: Essential libraries.

      • /usr/lib or /usr/lib64: User-installed libraries.

      • /usr/local/lib: Libraries installed from source.

    • The LD_LIBRARY_PATH environment variable can also specify additional locations.

  4. Versioning:

    • Shared libraries often have multiple versions for compatibility, e.g.:

      • libexample.so (generic link)

      • libexample.so.1 (major version)

      • libexample.so.1.2.3 (specific version)


Use Cases of Shared Libraries

1. Code Reusability Across Applications

  • Common functionality (e.g., mathematical operations, networking, or graphical rendering) is implemented once in a shared library.

  • Multiple applications link to the library instead of duplicating the code.

Example:

  • libm.so: Shared library for mathematical functions (e.g., sin, cos, sqrt).

  • Both gcc and python can dynamically link to libm.so instead of embedding the math code.

2. Reduced Disk and Memory Usage

  • Applications do not need to bundle the library code within their binaries, reducing their size.

  • At runtime, a single copy of the shared library is loaded into memory and shared among processes.

Example:

  • Graphical applications often use shared libraries like libGL.so for OpenGL rendering.

3. Modular Software Development

  • Libraries allow software components to be developed and updated independently.

  • Programs that depend on the library automatically benefit from updates or bug fixes.

Example:

  • Web browsers use shared libraries for rendering engines like libwebkitgtk.so.

4. Simplified Updates

  • Updating a shared library benefits all applications that use it without requiring re-compilation.

  • Example:

    • A security patch for libssl.so (OpenSSL) secures all programs using it.

5. Runtime Plugins

  • Programs can load shared libraries as plugins during runtime to extend functionality dynamically.

Example:

  • libvstplugin.so is loaded by audio software to enable Virtual Studio Technology (VST) plugins.

6. Compatibility Layers

  • Shared libraries facilitate cross-platform development by abstracting platform-specific details.

Example:

  • libc.so (GNU C Library) provides a standard interface for Linux applications, abstracting low-level OS differences.

7. Device Drivers

  • Shared libraries are often used in proprietary drivers (e.g., graphics or printer drivers).

Example:

  • NVIDIA provides libnvidia-glcore.so for its GPU driver functionality.


How Shared Libraries Work

  1. Compilation:

    • Programs are compiled to reference shared libraries rather than include their code:

      Here, -lm tells the compiler to link to libm.so.

  2. Linking:

    • Dynamic Linking: At runtime, the program dynamically resolves references to the shared library.

    • This is done by the dynamic linker (e.g., ld.so).

  3. Loading:

    • The shared library is loaded into memory when the program is executed.

    • The linker ensures all symbols (functions or variables) are resolved.


Managing Shared Libraries

Finding Shared Libraries

  • To see what shared libraries a program uses:

    Example:

    Output:

Setting Library Paths

  • Use LD_LIBRARY_PATH to specify additional directories for shared libraries:

Updating Library Cache

  • After adding or updating shared libraries, update the library cache:

Loading Libraries at Runtime

  • Programs can load shared libraries explicitly using functions like dlopen() in C.


Common Shared Libraries in Ubuntu

  1. Standard C Library (libc.so):

    • Provides core system functions (file I/O, memory allocation).

    • Location: /lib/x86_64-linux-gnu/libc.so.6.

  2. Mathematical Library (libm.so):

    • Implements advanced math functions.

    • Location: /lib/x86_64-linux-gnu/libm.so.

  3. PThread Library (libpthread.so):

    • Provides threading support.

    • Location: /lib/x86_64-linux-gnu/libpthread.so.

  4. SSL/TLS Library (libssl.so):

    • Used for encryption and secure communications.

    • Location: /usr/lib/x86_64-linux-gnu/libssl.so.

  5. Graphics Library (libGL.so):

    • Provides OpenGL support for rendering graphics.


Static Libraries vs. Shared Libraries

Feature

Shared Libraries (.so)

Static Libraries (.a)

Linking Time

Dynamically linked at runtime.

Statically linked at compile time.

File Size

Smaller binaries (library code excluded).

Larger binaries (library code included).

Memory Usage

Shared across processes.

Each program includes its own copy.

Updates

Library updates affect all programs.

Programs need to be recompiled.

Dependency Management

Requires runtime resolution.

No runtime dependencies.


Conclusion

Shared libraries are a powerful mechanism for reusing code across applications, reducing memory usage, and simplifying software development. They are integral to many aspects of Ubuntu, from system utilities to application development.

Would you like a practical example of creating and using a shared library in C, or help with managing shared libraries on your system?

Last updated