gcc -shared Option

The -shared option in gcc creates shared libraries (.so files) that can be dynamically linked at runtime. This allows multiple programs to share the same library code, reducing memory usage and enabling library updates without recompiling programs.

Syntax

gcc -shared -fPIC -o libname.so source.c

-shared Option Details

  • Purpose: Create shared libraries (.so files)
  • Requires: Usually combined with -fPIC for position-independent code
  • Output: Shared object file with .so extension
  • Loading: Libraries loaded at runtime by dynamic linker
  • Naming: Follow libname.so.version convention

Description

The -shared option creates dynamic libraries that are loaded at runtime rather than being embedded into executables. This provides flexibility and efficiency in software distribution and memory usage.

Key characteristics:

  • Code shared between multiple programs
  • Smaller executable sizes
  • Runtime library loading and linking
  • Ability to update libraries independently
  • Reduced memory footprint when multiple programs use same library

Shared Library Creation Process

  1. Write Code: Create library functions in source files
  2. Compile with -fPIC: Generate position-independent code
  3. Create Library: Use -shared to create .so file
  4. Install: Place library in system or custom directory
  5. Link Programs: Use -l flag to link with library
  6. Runtime Loading: Dynamic linker loads library when program runs

Shared vs Static Libraries

Aspect Shared Libraries (.so) Static Libraries (.a)
File Size Smaller executables Larger executables
Memory Usage Shared between programs Duplicated per program
Loading Time Runtime loading No runtime loading
Updates Update library independently Must recompile programs
Dependencies Requires library at runtime Self-contained executable

✅ Advantages of Shared Libraries

  • Memory Efficiency: Single copy shared by multiple programs
  • Smaller Executables: Reduced disk space usage
  • Easy Updates: Update library without recompiling programs
  • Plugin Architecture: Dynamic loading of optional components
  • System Libraries: Standard system functionality

⚠️ Considerations

  • Runtime Dependencies: Library must be available at runtime
  • Version Conflicts: "DLL Hell" - incompatible library versions
  • Startup Time: Slight delay for dynamic linking
  • Distribution: Must ensure library availability on target systems
  • Debugging: More complex debugging across library boundaries

Detailed Examples

Basic shared library creation

# Create library source
gcc -fPIC -c mathlib.c -o mathlib.o
gcc -shared -o libmath.so mathlib.o

# Use library in program
gcc main.c -L. -lmath -o program
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./program

Creates a shared library and links it with a program

One-step library creation

gcc -shared -fPIC -o libutils.so utils.c helper.c

Compiles and creates shared library in one command

Library with version information

# Create versioned library
gcc -shared -fPIC -Wl,-soname,libmath.so.1 -o libmath.so.1.0 mathlib.c

# Create symbolic links
ln -sf libmath.so.1.0 libmath.so.1
ln -sf libmath.so.1 libmath.so

Creates versioned shared library with proper naming convention

Complex library with dependencies

# Create library that depends on other libraries
gcc -shared -fPIC -o libcomplex.so complex.c -lm -lpthread

# Link program with complex library
gcc main.c -L. -lcomplex -o program

Creates shared library with external dependencies

Installing system-wide

# Create and install library
gcc -shared -fPIC -o libmylib.so mylib.c
sudo cp libmylib.so /usr/local/lib/
sudo ldconfig

# Now can link without -L flag
gcc main.c -lmylib -o program

Installs shared library system-wide for easy access

Complete Example

Library source (mathlib.c)

#include "mathlib.h"

int add(int a, int b) {
    return a + b;
}

int multiply(int a, int b) {
    return a * b;
}

Header file (mathlib.h)

#ifndef MATHLIB_H
#define MATHLIB_H

int add(int a, int b);
int multiply(int a, int b);

#endif

Build and use

# Create shared library
gcc -shared -fPIC -o libmath.so mathlib.c

# Create main program
gcc main.c -L. -lmath -o calculator

# Run program
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./calculator

Best Practices

  • Use -fPIC: Always compile with position-independent code
  • Version Libraries: Use semantic versioning for library names
  • Export Control: Use visibility attributes to control symbol exports
  • ABI Stability: Maintain binary compatibility across versions
  • Documentation: Provide clear API documentation and examples
  • Testing: Test library with different programs and scenarios

See also