简体   繁体   中英

g++ without libstdc++ - can it be done? - a very configurable lightweight libstdc++ where I can take stuff out easily would also do the trick

I'm trying something spooky here. I'm trying to write C++ programs, compiled with GNU's g++, but without a dependency on libstdc++ :) but it seems that I need that for even the most basic things need it.

A libstdc++ with a configurable feature set would be acceptable.

The command I use is

g++ -nodefaultlibs -fno-rtti -fno-exceptions -lc

Without libstdc++, I get:

undefined reference to `operator delete(void*)'  
undefined reference to `operator new(unsigned int)'  
undefined reference to `vtable for __cxxabiv1::__class_type_info'  
undefined reference to `vtable for __cxxabiv1::__si_class_type_info'  
undefined reference to `__cxa_pure_virtual'

These aren't in libc, so is there a really light libstdc++ that implements just these things?

My test code which I want to build this way currently looks like this:

#include <stdio.h>

template <class T>
class X
{
    public:
    T a;
};

class A1
{
    public:
        virtual void f() = 0;
        virtual ~A1() {}
};

class A2 : public A1
{
    public:
        virtual void f() {};
        virtual ~A2() {}
};

class Y
{
    public:
        ~Y() {}
};

int main()
{
    X<int> A;
    X<float> B;
    Y *C = new Y;

    A.a = 12;
    B.a = 2.3;

    printf("A: %d; B: %f\n", A.a, B.a);

    A2 *a2 = new A2;
    a2->f();

    return 0;
}

Yes, things like operator new and operator delete are indeed defined in C++, not in C, so it would be absurd to have them in the runtime library for C as opposed to the one for C++ (same for the "pure virtual" used to clearly diagnose wrongful calls to pure virtual methods, and so on). If you link your whole executable without dynamic library access, the linker should (one hopes -- depending on how modularly the C++ runtime library is coded) pick and choose the bare minimum portion of the standard C++ library that you use in your code (and the fewer C++ specific features you use -- such as new implying delete for destructor calls, and so forth -- the greater your chances to avoid pulling in larger chunks of the library, of course;-).

Try linking against libsupc++.a . It is the bare C++ sup port library, without heavyweight iostreams functions or anything.

I'm not sure, but I believe using this instead of libstdc++.a would obtain a "freestanding" C++ implementation, as opposed to "hosted" or complete implementation, as defined in Clause 1 of the Standard.

Here's a good explanation:

http://www.trilithium.com/johan/2005/06/static-libstdc/

The article explains in more detail but one key reason for doing this is the C++ specific libraries tend to be less stable than the base libc stuff. This may help reduce dependency issues.

Maybe this answer is a bit too late, but...

Writing c++ programs without libstdc++ is easy. I'm doing it for decades. Just avoid linking with libstdc++. That's easy: either use gcc for linking instead of g++, or provide a fake libstdc++ with only new, del and a few other functions.

Here's a example how you can replace the basic libstdc++ functionality with a transparent wrapper around malloc:

#include <stdlib.h>

// MSVC uses __cdecl calling convention for new/delete :-O
#ifdef _MSC_VER
#  define NEWDEL_CALL __cdecl
#else
#  define NEWDEL_CALL
#endif

extern "C" void __cxa_pure_virtual ()
{
    abort ();
}

void * NEWDEL_CALL operator new (size_t size)
{
    return malloc (size);
}

void * NEWDEL_CALL operator new [] (size_t size)
{
    return malloc (size);
}

void NEWDEL_CALL operator delete (void *p)
{
    if (p) free (p);
}

void NEWDEL_CALL operator delete [] (void *p)
{
    if (p) free (p);
}

void NEWDEL_CALL operator delete (void *p, size_t)
{
    if (p) free (p);
}

Now put that into a file named, say, libstd--.cpp, and build your own libstdc++.a:

gcc -c -O libstdc--.cpp
ar crs libstdc++.a libstdc--.o

Then you can try a simple test:

class A
{
    int *x;

public:
    A () { x = new int [10]; }
    ~A () { delete [] x; }
};

int main ()
{
    A a;
    return 0;
}

Compile and look what's got linked:

g++ -g test.cpp -o test -L.

# ldd ./test
    linux-vdso.so.1 (0x00007ffed0b8d000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f4d18df0000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f4d18bd9000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f4d18823000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f4d1913b000)

Hey, look, ma, no libstdc++!

As an alternative, you may avoid using a fake libstdc++ by linking with gcc instead of g++ and by providing libstdc--.o on the linker command line so that your code may find the replacement news and deletes.

Another approach could be to "statifie" your program. It means to embed all the libraries in an static executable and that way your code will always use the glibc that was in the machined you used to compile. The only thing you will need is a compatible kernel in the running machine. I know two programs to do that, one is open source:

and the other one is commercial software:

Of course this approach has drawbacks like for instance if you update a dynamic library that your application is using to fix a bug, because in the executable that library is embedded, you are going to have to compile you application again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM