2016-06-04 6 views
3

Я установил новую версию GCC, которая сортирует мою систему linux. Я планирую обрабатывать несколько версий GCC в лучшем виде. Я планирую установить все разные версии в каталоге/opt/tools. И тогда мой проект makefile явно указывает версию для использования. Это включает в себя все бинарные исполняемые файлы, то есть g ++, gcc и т. Д., И файлы заголовков, библиотеки ...Как избежать стандартной стандартной библиотеки C/C++ на Linux?

Преимущество этого подхода ясна. Сборка более воспроизводима. Он не предполагает версию, но выбирает очень конкретную. Переключение между разными версиями компилятора происходит внутри make-файла.

Для этого я использую «-nostdinc» и явно помещаю все включенные пути в свою командную строку компиляции. Мой код включает limits.h и вызывает странную ошибку сборки.

limits.h является частью libc6-dev, установленной в моем debian. Но это не в каталоге gcc include. Некоторые онлайн-материалы говорят, что стандарт C lib является частью ОС. Мой вопрос в том, что практично создавать код, не зависящий от файлов и библиотек системных заголовков? Я сомневаюсь, что в gcc могут отсутствовать другие заголовки. Первоначально я думал, что gcc поставляется со всем. Это не так?

Другими словами, системные библиотеки и заголовки зависят от конкретной версии GCC, которая поставляется с дистрибутивом debian? Я чувствую себя некомфортно, что системные заголовки и библиотеки - это, скажем, GCC 4.7, и я использую GCC 5.3.

+1

вы можете использовать контейнеры/виртуальные машины для установки разных версий компиляторов. посмотрите на https://www.docker.com. вот изображение, которое включает в себя все версии gcc https: // hub.docker.com/_/gcc/ – feech

+0

@feech Использование VM было моей первой мыслью. –

+0

Прочитайте Linux с нуля. –

ответ

3

GCC не отправляет файлы заголовков C. Библиотека GNU C или glibc - это отдельный проект. На самом деле не имеет смысла иметь агностическую компоновку libc, поскольку GCC нуждается в библиотеке C, и она не имеет ничего общего с версией компилятора GCC. Нет, вам не нужна виртуальная машина или «Linux From Scratch», которая плохо подходит, потому что она говорит вам скомпилировать всю инструментальную цепочку из исходного кода. Очень просто установить разные версии GCC на собственный префикс (папка назначения). Он даже позволяет добавлять префиксы к имени исполняемого файла, чтобы упростить задачу.

Я серьезно рекомендую вам погрузиться в Installing GCC. Это написано фактическим сторонником GCC, и это прямо к делу. Не делайте это сложнее, чем есть.

Для компиляции GCC, сделайте следующее:

tar xzf gcc-VERSION.tar.gz 
cd gcc-VERSION 
./contrib/download_prerequisites 
cd .. 
mkdir objdir 
cd objdir 
$PWD/../gcc-VERSION/configure --prefix=$HOME/gcc-VERSION --enable-languages=c,c++ 
make 
make install 

И вариант Я говорил о from the manual:

--program-prefix=prefix - GCC поддерживает некоторые преобразования имен своих программ при их установке. Эта опция добавляет префикс к именам программ для установки в bindir (см. Выше). Например, при определении --program-prefix=foo- будет установлено, что gcc установлено как /usr/local/bin/foo-gcc.

Здесь /usr/local является префиксом по умолчанию для autotools. Я настоятельно не рекомендую вам устанавливать GCC там. Сделайте это для каждой версии, и вы можете получить gcc-4.8, gcc-5.3 и т. Д.

+0

На самом деле ваш ответ не совсем корректен. В частности, gcc поставляется с заголовками, например. 'Varargs.h'. – user3159253

+1

@ user3159253 'varargs.h' не является стандартным C. Это [вещь GCC] (https://stackoverflow.com/questions/37626396/how-to-avoid-system-standard-cc-library-on-linux) в любом случае. –

+0

Ну, 'varargs.h' был плохим примером. Фактически, он содержит только сообщение о том, что файл устарел. Однако 'stdarg.h' и' stddef.h' являются хорошими :) – user3159253

5

В типичной системе Linux/«free unix» имеется несколько уровней, относящихся к компиляции программ.

  1. Kernel.Программы на уровне пользователя редко взаимодействуют с ядром напрямую, хотя могут.
  2. Контейнеры, специфичные для ядра, используемые модулями ядра и привязанные к определенному сборке ядра Linux. В Debian эти заголовки входят в linux-headers-<kernel-version>. Может быть несколько пакетов, предназначенных для соответствующих версий ядра. Они вам не нужны, если ваша программа не является модулем ядра или подобным.
  3. Ядерные детали libc. В системе Debian это входит в пакет linux-libc-dev. Обычно этот пакет не является специфическим для конкретной версии ядра, а скорее «поколением версий» (он медленно развивается и отражает появление новых возможностей на уровне пользователя, констант и т. Д.). You do нужен этот пакет для составления типичной комплексной программы пользовательских земель, поскольку он содержит важные общесистемные константы и типы определения
  4. libc. Эта библиотека предоставляет все обычные функции «C-библиотеки», средства и т. Д., Иногда она обертывает соответствующие ядровые объекты (думаю, open(), send(), brk()), иногда она предоставляет свои собственные функции высокого уровня (например, qsort()). Вам do нужна библиотека для создания практически любой программы. В дебианской системе он поставляется в нескольких пакетах, заголовки находятся в libc6-dev. Там может быть несколькими разными libc экземплярами, работающими поверх одного ядра Linux сразу (например, в chroot s), но поскольку библиотека зависит от определенной иерархии файлов, обычно есть только одна.

  5. Компиляторы. Компиляторы поставляются со своими наборами заголовков, но для C-компилятора гораздо меньше заголовков для компилятора, чем, например, для C++-компилятора, потому что, как правило, компиляторы C++ имеют собственную реализацию STL, которая представляет собой библиотеку заголовков по языковому дизайну. Большинство из этих .h заголовков в компиляторе C отвечают за различные трюки, специфичные для компилятора, такие как обработка varargs (stdarg.h) или Cilk. Например, в gcc-4.7 пакет в Debian 7 там уже только 47 .h файлов, большинство из которых является частью libgcc

На самом деле, в Debian вы можете иметь любое количество трансляторов, установленных и они не будут мешать друг с другом. Например, прямо сейчас в моем Ubuntu-16.04 там уже 4 версии GCC мгновенно доступны для установки: 4.7.4, 4.8.5, 4.9.3, 5.3.1, - и 4 clang версии: 3.5, 3.6, 3.7 и 3.8. Все эти компиляторы разных версий могут быть установлены с apt-get install <package-name>. Я предполагаю, что современный Debian имеет более или менее одинаковый набор. Используя относительно простые правила, вы можете создать пакет для любого данного компилятора и любой данной версии.

Необходимый компилятор C может быть выбран во время компиляции с переменной окружения CC, и для этого не нужно менять Makefile.

Возможно, вам понадобится -nostdinc, только если вы планируете использовать совершенно другую версию libc, что обычно не является случаем. Но иногда это полезно, например. для создания программ для initrd или других этапов загрузки системы, когда нет «полной среды».

+0

Использование другой библиотеки C с GCC [нет тривиального] (http://wiki.osdev.org/Porting_Newlib). Это требует больше, чем просто '-nostdinc'. Хороший ответ. –

Смежные вопросы