g ++ без libstdc ++ - это можно сделать?- очень легко настраиваемый облегченный libstdc ++, где я могу легко что-то вынести - PullRequest
11 голосов
/ 15 сентября 2010

Я пытаюсь что-то жуткое здесь. Я пытаюсь писать программы на C ++, скомпилированные с GNU g ++, но без зависимости от libstdc ++ :), но мне кажется, что это нужно даже для самых простых вещей.

Будет приемлемым libstdc ++ с настраиваемым набором функций.

Используемая мной команда:

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

Без libstdc ++ я получаю:

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'

Это не в libc, так есть ли действительно легкая libstdc ++, которая реализует только эти вещи?

Мой тестовый код, который я хочу построить таким образом, в настоящее время выглядит следующим образом:

#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;
}

Ответы [ 5 ]

5 голосов
/ 15 сентября 2010

Да, такие вещи, как operator new и operator delete действительно определены в C ++, , а не в C, поэтому было бы абсурдно иметь их в библиотеке времени выполнения для C, в отличие от библиотеки для C ++ (то же самое для «чистого виртуального», используемого для четкой диагностики неправильных вызовов чисто виртуальных методов и т. Д.). Если вы связываете весь исполняемый файл без динамического доступа к библиотеке, компоновщик должен (можно надеяться - в зависимости от того, как модульно закодирована библиотека времени выполнения C ++) выбрать и выбрать минимальную часть стандартной библиотеки C ++, которую вы используете в своем коде (и чем меньше используемых вами специфических функций C ++ - таких как new, подразумевающих delete для вызовов деструкторов и т. д. - тем больше у вас шансов избежать использования больших кусков библиотеки, разумеется; -).

2 голосов
/ 15 сентября 2010

Попробуйте связать с libsupc++.a. Это голая библиотека портов C ++ sup, без тяжелых функций iostreams или чего-либо еще.

Я не уверен, но я полагаю, что использование этого вместо libstdc++.a даст «автономную» реализацию C ++, в отличие от «размещенной» или полной реализации, как определено в пункте 1 стандарта.

1 голос
/ 03 ноября 2018

Может быть, этот ответ слишком поздно, но ...

Написание программ на c ++ без libstdc ++ - это просто.Я делаю это десятилетиями.Просто избегайте ссылок на libstdc ++.Это просто: либо используйте gcc для компоновки вместо g ++, либо предоставьте поддельный libstdc ++ только с новыми, del и несколькими другими функциями.

Вот пример того, как вы можете заменить базовую функциональность libstdc ++ прозрачной оболочкой вокруг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);
}

Теперь поместите это в файл с именем, скажем, libstd -. cpp, и создайте свой собственный libstdc ++. a:

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

Затем вы можете попробовать простойtest:

class A
{
    int *x;

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

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

Скомпилируйте и посмотрите, что связано:

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)

Эй, смотри, ма, no libstdc ++!

В качестве альтернативы вы можете избежать использования поддельного libstdc ++, связываясь с gcc вместо g ++ и предоставляя libstdc -. o в командной строке компоновщика, чтобы ваш код мог найти новости о замене.и удаляет.

1 голос
/ 15 сентября 2010

Вот хорошее объяснение:

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

Статья объясняет более подробно, но одна из ключевых причин для этого Это специфичные для C ++ библиотеки, как правило, менее стабильные, чем базовые библиотеки libc. Это может помочь уменьшить проблемы с зависимостями.

0 голосов
/ 16 сентября 2010

Другим подходом может быть «утвердить» вашу программу.Это означает встраивание всех библиотек в статический исполняемый файл, и ваш код всегда будет использовать glibc, который был в механической обработке, которую вы использовали для компиляции.Единственное, что вам нужно, это совместимое ядро ​​на работающей машине.Я знаю две программы для этого, одна с открытым исходным кодом:

, а другая - коммерческое программное обеспечение:

Конечно, у этого подхода есть недостатки, например, если вы обновляете динамическую библиотеку, которую ваше приложение использует для исправления ошибки, потому что ввыполняя эту библиотеку, вы должны будете снова скомпилировать ваше приложение.

...