How to static link Linux software that uses ./configure?
Categories:
How to Statically Link Linux Software Using ./configure

Learn the intricacies of statically linking software on Linux, especially when dealing with projects that use the ./configure, make, make install build system. This guide covers common challenges and solutions.
Statically linking software means embedding all necessary library code directly into the executable, resulting in a standalone binary that doesn't rely on external shared libraries at runtime. This can be incredibly useful for creating portable applications, deploying to environments with minimal dependencies, or troubleshooting library conflicts. However, achieving a fully static build, especially with projects using the GNU Autotools (./configure, make), can be challenging due to the dynamic nature of most Linux distributions.
Understanding Static vs. Dynamic Linking
Before diving into the how-to, it's crucial to understand the fundamental difference between static and dynamic linking. Dynamic linking (the default on most Linux systems) links against shared libraries (.so files) at runtime. This saves disk space and memory, as multiple programs can share the same library. Static linking, conversely, includes all required library code directly into the executable, making it larger but entirely self-contained.

Comparison of dynamic vs. static linking.
Challenges with Static Linking and ./configure
The ./configure script is designed to detect available libraries and their linking methods (static or dynamic) on your system. By default, it prefers dynamic linking if shared libraries are found. Forcing static linking requires careful manipulation of compiler and linker flags, and ensuring that static versions of all required libraries (.a files) are present on your system.
Strategies for Forcing Static Linking
There are several approaches to encourage or force static linking. The most common involves passing specific flags to the configure script and make command. These flags instruct the compiler and linker to prefer static libraries.
1. Install Static Library Development Packages
Ensure you have the static versions of all necessary libraries. On Debian/Ubuntu, these often end with -dev and include .a files. For example, libssl-dev provides libssl.a.
2. Configure with --enable-static and --disable-shared
Many configure scripts support these flags to explicitly request static linking and disable shared linking. This is the first step to try.
3. Pass LDFLAGS and CFLAGS for Static Linking
If the above flags aren't sufficient, you'll need to explicitly tell the linker to prefer static libraries using LDFLAGS and CFLAGS environment variables. The -static flag for LDFLAGS is crucial, but it often needs to be combined with -Wl,-Bstatic and -Wl,-Bdynamic to control the linking behavior for specific libraries.
4. Specify Library Paths Explicitly
Sometimes, the linker might not find the static versions of libraries. You can use -L/path/to/static/libs in LDFLAGS to point it to the correct directories.
# Example for a generic project
# 1. Install static libs (example for OpenSSL on Debian/Ubuntu)
sudo apt-get install libssl-dev
# 2. Clean previous build attempts
make clean
# 3. Configure with static flags
./configure CFLAGS="-O2 -g" CXXFLAGS="-O2 -g" \
LDFLAGS="-static -Wl,-Bstatic -lssl -lcrypto -Wl,-Bdynamic" \
--enable-static --disable-shared
# 4. Build
make
# 5. Verify (check for 'statically linked' or absence of shared library dependencies)
ldd your_executable
Common command-line sequence for attempting a static build.
ldd command (ldd your_executable) is invaluable for checking if your resulting binary is truly statically linked. A fully static binary will typically output not a dynamic executable or show no shared library dependencies.Dealing with libc and glibc
One of the most significant hurdles in static linking on Linux is glibc (GNU C Library). Statically linking glibc is generally discouraged and often leads to issues, especially with features like DNS resolution, NSS (Name Service Switch), and locale support. Many systems are configured to prevent static linking against glibc by default. If you absolutely need a fully static binary, consider using a different C library like musl-libc or building on a system specifically designed for static compilation (e.g., Alpine Linux).
# Example of a common error when trying to static link glibc
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
# This often indicates that the linker cannot find a static version of glibc,
# or it's intentionally prevented.
Typical error when static linking glibc fails.
OmniOS and Static Linking Considerations
While the principles remain similar, OmniOS (a Solaris derivative) uses a different C library (libc.so.1) and linker (ld.so.1). The flags for static linking might vary slightly, but the core idea of providing static library paths and using linker flags like -Bstatic and -Bdynamic still applies. Always consult the specific compiler and linker documentation for your OmniOS environment.
Successfully statically linking software can be a trial-and-error process, often requiring deep understanding of the project's build system and its dependencies. However, with persistence and the right flags, you can create robust, self-contained executables.