This blog post explains how to write a C++ program and compile with GCC (g++
) so that the resulting binary doesn't depend on libstdc++. The reason for avoiding libstdc++ can be purity (don't depend on libraries you don't really need) and statically linking small tools (e.g. for Unix or Win32 console applications with MinGW).
The limitations are:
- The standard C++ STL (e.g.
#include <string>
and#include <vector>
) cannot be used. This functionality has to be reimplemented in the program. - The standard C++ streams (e.g.
#include <iostream>
) cannot be used. The standard C I/O library (e.g.#include <stdio.h>
) is a smaller and faster replacement. A disadvantage: there is no polymorphicoperator<<(ostream&, ...)
method for convenient, type-agnostic output. - Exceptions cannot be used (i.e.
try
,catch
andthrow
are disallowed). - RTTI (run-time type information) cannot be used.
dynamic_cast<...>(...)
cannot be used (because it requires RTTI).
Here is how to do it:
- Add the following C++ code to your program (can be in a separate source file):
#include <stdlib.h> #include <unistd.h> /* for write(), also available on Windows */ extern "C" void* emulate_cc_new(unsigned len) { \ void *p = malloc(len); if (p == 0) { /* Don't use stdio (e.g. fputs), because that may want to allocate more * memory. */ (void)!write(2, "out of memory\n", 14); abort(); } return p; } extern "C" void emulate_cc_delete(void* p) { if (p != 0) free(p); } void* operator new (unsigned len) __attribute__((alias("emulate_cc_new"))); void* operator new[](unsigned len) __attribute__((alias("emulate_cc_new"))); void operator delete (void* p) __attribute__((alias("emulate_cc_delete"))); void operator delete[](void* p) __attribute__((alias("emulate_cc_delete"))); void* __cxa_pure_virtual = 0;
- Compile your program with
g++ -c
to create individual.o
files. Add flags-fno-rtti -fno-exceptions
to get compile errors for disabled features (exceptions and RTTI). - Link your executable with
gcc -o prog code1.o code2.o ...
It's important that you usegcc
here instead ofg++
becauseg++
would link against libstdc++.
This method has been tested and found working with GCC 3.2, GCC 4.2.1 and GCC 4.4.1 (both native Linux compilation and MinGW compilation), and it probably works with other GCC versions as well.
If you need dynamic_cast
, add void* __gxx_personality_v0 = 0;
, don't use -fno-rtti
, and add dyncast.a
to the gcc -o ...
command-line. Here is how to create dyncast.a
(about 55kB) for GCC 4.4.1:
$ ar x /usr/lib/gcc/i486-linux-gnu/4.4/libstdc++.a \ dyncast.o class_type_info.o si_class_type_info.o pointer_type_info.o \ pbase_type_info.o tinfo.o fundamental_type_info.o $ ar crs dyncast.a \ dyncast.o class_type_info.o si_class_type_info.o pointer_type_info.o \ pbase_type_info.o tinfo.o fundamental_type_info.o