How to static link Linux software that uses ./configure?
Categories:
Static Linking Linux Software with ./configure

Learn how to successfully static link applications on Linux, especially those using the common ./configure && make && make install
build system, to create self-contained executables.
Static linking is a powerful technique that bundles all necessary libraries directly into an executable, creating a self-contained binary that doesn't rely on external shared libraries at runtime. This can be incredibly useful for deployment to environments with minimal or inconsistent library versions, or for creating portable tools. However, achieving a fully static build, especially for software that uses the common GNU Autotools build system (./configure
, make
, make install
), can be challenging. This article will guide you through the process, highlighting common pitfalls and solutions.
Understanding Static vs. Dynamic Linking
Before diving into the how-to, it's crucial to understand the fundamental difference between static and dynamic linking. Most Linux software uses dynamic linking by default, where executables link against shared libraries (e.g., .so
files) at runtime. This saves disk space and memory, as multiple programs can share the same library. Static linking, on the other hand, embeds a copy of all required library code directly into the executable. While this results in larger binaries, it eliminates runtime dependencies on external libraries.

Comparison of Dynamic vs. Static Linking
Prerequisites for Static Linking
To successfully static link, you'll need the static versions of all libraries your software depends on. These are typically identified by a .a
extension (e.g., libz.a
instead of libz.so
). On most Linux distributions, these are provided in development packages, often suffixed with -dev
or -static
. For example, to get the static version of zlib
, you might install zlib1g-dev
or zlib-static
depending on your distribution.
sudo apt-get install build-essential
sudo apt-get install zlib1g-dev libssl-dev libcurl4-openssl-dev # Example for Debian/Ubuntu
sudo yum install zlib-static openssl-static libcurl-static # Example for CentOS/RHEL
Installing common static library development packages
Configuring for Static Linking with ./configure
The ./configure
script is designed to detect your system's capabilities and available libraries. To instruct it to prefer static libraries, you typically use the --enable-static
and --disable-shared
flags. Additionally, you might need to pass specific compiler and linker flags via environment variables like CFLAGS
, LDFLAGS
, and LIBS
.
./configure --enable-static --disable-shared
# More robust approach, forcing GCC to prefer static libraries
# LDFLAGS="-static" ./configure --enable-static --disable-shared
# Even more specific, if you know the exact libraries
# LDFLAGS="-static -L/path/to/static/libs" LIBS="-lstaticlib1 -lstaticlib2" CFLAGS="-static" ./configure --enable-static --disable-shared
Common ./configure
options for static linking
glibc
), are notoriously difficult or impossible to static link completely. You might encounter errors during compilation or linking if a dependency cannot be found in its static form.Dealing with glibc
and ldd
The GNU C Library (glibc
) is a core component of most Linux systems and is almost always dynamically linked. Static linking glibc
is generally discouraged and often leads to issues, as it can break compatibility with other system components and make the resulting binary less portable across different Linux distributions or kernel versions. If your goal is maximum portability, consider using musl-libc
instead of glibc
for a truly static build, or target a specific older glibc
version.
ldd your_executable
Use ldd
to check dynamic library dependencies
After running ldd
on a supposedly static executable, if you still see not a dynamic executable
or no output, it's a good sign. If you see libc.so.6
or other shared libraries, your build is not fully static. For glibc
, you will almost always see it listed unless you've specifically built against musl-libc
or similar alternatives.
Troubleshooting Common Static Linking Issues
Static linking can be finicky. Here are some common issues and their solutions:
1. Missing Static Libraries
Ensure you have installed the -dev
or -static
packages for all dependencies. The linker will complain about undefined references if it can't find the static versions.
2. Order of Libraries
The order of libraries passed to the linker (-l
flags) matters. Dependencies should generally be listed after the libraries that depend on them. For example, if libfoo
depends on libbar
, you'd link with -lfoo -lbar
.
3. Forcing Static Linkage
Sometimes, even with --enable-static
, the build system might still prefer shared libraries. Explicitly setting LDFLAGS="-static"
and CFLAGS="-static"
during ./configure
or make
can help force the issue. Be aware that this might cause issues if some libraries must be dynamic.
4. Position-Independent Code (PIC)
Static libraries often need to be compiled with Position-Independent Code (PIC) if they are to be linked into shared libraries (which is not your goal here) or if the main executable is itself PIC. If you're getting errors related to PIC, try adding -fPIC
to CFLAGS
when compiling the libraries themselves, or ensure your static libraries are built without PIC if they are only for static executables.
5. OmniOS and Solaris-like Systems
On systems like OmniOS (a Solaris derivative), static linking can be even more challenging due to differences in the linker and library conventions. You might need to explicitly specify LIBS
and LDFLAGS
with the full paths to static libraries, and potentially use gcc -static
directly if the build system allows. The ldd
command on these systems might also behave differently.
config.log
file generated by ./configure
. It contains detailed output from the configuration checks and can provide clues about why static libraries weren't found or why certain features were disabled.