Creating Static Executables on Linux
It is difficult to create distributable executables for Linux because of issues like incompatible C libraries and C++ standard libraries. Creating static executables avoids some of the dependencies, although it may not necessarily help with portability. Static builds are useful for other problems, as discussed in future posts. ITK Git master recently added support for building static executables. In this post, we will describe how to build static executables against ITK.
When configuring ITK, use the following options:
cmake \ -DBUILD_SHARED_LIBS=OFF \ -DITK_DYNAMIC_LOADING=OFF \ ~/src/ITK
The BUILD_SHARED_LIBS option tells CMake to build static libraries instead of shared libraries, which can be linked into the static executable. Also, the ITK_DYNAMIC_LOADING option disables ITK’s ability to load libraries at runtime into its object factory — this requires dynamic loading.
When building executables against ITK, use the following configuration,
cmake \ -DITK_DIR=/path/to/static/ITK \ -DCMAKE_EXE_LINKER_FLAGS="-static" \ -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" \ ~/src/BuildAHelloWorldProgram
The -static flag is passed to the linker so it will create a static executable instead of a dynamically linked executable. The CMAKE_FIND_LIBRARY_SUFFIXES variable will ensure that CMake only finds static libraries, which end it .a. In this case, it is not strictly necessary since we only built ITK with static libraries.
When we examine the executable created from a dynamic build:
$ file BuildAHelloWorldProgram BuildAHelloWorldProgram: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.12.0, not stripped $ du -sh BuildAHelloWorldProgram 124K BuildAHelloWorldProgram
we see that it is dynamically linked and uses an interpreter, i.e. the dynamic loader, /lib64/ld-linux-x86-64.so.2. The file size is 124 kilobytes.
And the executable created from a static build:
$ file BuildAHelloWorldProgram BuildAHelloWorldProgram: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.12.0, not stripped $ du -sh BuildAHelloWorldProgram 6.0M BuildAHelloWorldProgram
In this case, the executable is statically linked. The disadvantage to statically linked executables is their size — 6.0 megabytes versus 124 kilobytes. There are other important disadvantages to consider when statically linking in glibc into executables, especially when creating executables for distribution.
Enjoy ITK!
is it a disadvantage? considering that all libraries in your system use much more space than 6Mb, but statically linked executable can run in the same environment without need of a whole bunch of libraries in your system
Eh? static linking is nice if you have only one or two application to run eg: docker containers. However, in case of complete systems dynamic linking can help avoid duplication of libraries.
2020 (ITK 5.0.1) update: please remove DCMAKE_EXE_LINKER_FLAGS=”-static” from the above example. It creates problems at runtime. See discourse discussion in https://discourse.itk.org/t/static-compiled-example-exits-with-segfault/2744/2
This flag can still be used as described in the above post. However, as noted in the Discourse discussion, if the goal is to create distributable Linux executables, dockbuild is a great new tool:
https://github.com/dockbuild/dockbuild