User:Barre/Development/GCC/Static Build

From KitwarePublic
Jump to navigationJump to search

Here is how to build a static release of a given software with GCC.

First you need to build a specific release of the GCC compiler. Let's assume we are going to use GCC 3.4.3 (you mileage may vary, replace 3.4.3 with your favorite version):

 gcc-core-x-y-z.tar.bz2
 gcc-g++-x-y-z.tar.gz
  • Create a distribution directory for GCC:
 mkdir /opt/gcc-3.4.3s
  • Create a src directory inside the distribution directory:
 cd /opt/gcc-3.4.3s
 mkdir src
  • Unpack the GCC packages inside the src directory:
 cd src
 tar xvjf gcc-core-3.4.3.tar.bz2
 tar xvjf gcc-g++-3.4.3.tar.bz2
  • Create the below small configuration script myconfig-gcc-343 inside the src directory (note the --disable-shared option):
 #!/bin/sh
 ../gcc-3.4.3/configure \
   --prefix=/opt/gcc-3.4.3s \
   --enable-languages=c,c++ \
   --disable-shared 
  • Create a build directory inside the src directory:
 mkdir gcc-3.4.3-build
  • At this point, the distribution tree should pretty much look this way:
 /opt/gcc-3.4.3s/
 /opt/gcc-3.4.3s/src/
 /opt/gcc-3.4.3s/src/gcc-3.4.3/
 /opt/gcc-3.4.3s/src/gcc-3.4.3-build/
 /opt/gcc-3.4.3s/src/myconfig-gcc-343
  • Execute the configuration script from the build directory:
 cd gcc-3.4.3-build
 sh ../myconfig-gcc-343
  • Build the compiler from the build directory and install it:
 make
 make install
  • [OPTIONAL] Create some symlinks to this GCC build in /usr/local/bin:
 cd /usr/local/bin
 ln -s /opt/gcc-3.4.3s/bin/gcc gcc-3.4.3s
 ln -s /opt/gcc-3.4.3s/bin/g++ g++-3.4.3s
 ln -s /opt/gcc-3.4.3s/bin/c++ c++-3.4.3s
 ln -s /opt/gcc-3.4.3s/bin/cpp cpp-3.4.3s

Now re-build your software:

  • Whatever tool you were using to build your software (for example, CMake), you need to point this tool to your brand-new GCC compiler. Most of the times, setting the CXX and CC environment variables to the path to the corresponding GCC binaries will do the trick:
 CXX=g++-3.4.3s CC=gcc-3.4.3s cmake
  • Do not forget to pass the -static parameter to your linker. With CMake, set:
 CMAKE_EXE_LINKER_FLAGS=-static

If you plan to distribute your binary, you may want to try shrinking it a little more. To do so, use strip to discard useless symbols from the executable. Once it's done, you may also give a shot to UPX to self-compress the resulting binary and achieve near-gzip compression level:

 $ ls -al dicom2
 -rwxrwxr-x  1 barre barre 4090180 Mar  9 10:48 dicom2*
 $ strip dicom2
 $ ls -al dicom2
 -rwxrwxr-x  1 barre barre 1492828 Mar  9 10:55 dicom2*
 $ upx -9 dicom2
 $ ls -al dicom2
 -rwxrwxr-x  1 barre barre 537136 Mar  9 10:56 dicom2*
 $ gzip dicom2
 $ ls -al dicom2.gz
 -rwxrwxr-x  1 barre barre 528410 Mar  9 10:56 dicom2.gz*

On a side note: UPX (and similar tools) reduce the size of the executable on disk, at the expense of increasing memory usage. For more information check out http://developer.href.com. When Windows loads an EXE, that EXE is mapped into the memory space of the process and loaded on demand by the virtual memory paging system. Multiple processes using the same executable share the loaded pages - the EXE is only loaded ONCE, even if you have multiple copies running. This is not a concern if your executable is reasonably small compared to the amount of memory available, or if it is designed to run a single instance of itself only.