LINUX.ORG.RU

Clang vs Gcc: две компиляторные системы в одном дистрибутиве

 , , ,


0

4

По моим представлениям длительное время clang/llvm использовал

  • binutils
  • glibc/libstdc++

из компилятора gcc (на стадии dragonegg еще и фронтенд языка C/C++). Но при этом разработчики clang/llvm последовательно двигаются к достижению полной замкнутости. Похоже они достигли независимости по binutils, libc++. Активно пилят свою версию libc. Что касается взгляда со стороны, то между разработчиками gcc и clang нет стремления к поддержанию совместимости своих систем (стандарт C/C++ не гарантирует совместимости бинарников библиотек и/или хедеров). Соответственно возникает вопрос, а что будет с linux/unix-дистрибутивами после достижения полной независимости в clang/llvm от gcc (glibc по сути последний мостик)?

Уточню суть вопроса. Пусть есть дистрибутив (Ubuntu/Mint/…), который собран gcc. Можно закачивать пакеты, собранные разработчиками дистрибутива. Допустим есть приложение X, которое собирается с помощью clang. Приложение X зависит от библиотеки Y (и еще большего количества других библиотек). Все требуемые библиотеки уже установлены в дистрибутиве, но собраны с помощью gcc. При сборке X clang соберет ее с хедерами и слинкует ее с libc/libstdc++. Если X будет слинкована с установленной Y, то при запуске X, получается, что X должна использовать func (какую-нибудь fopen или std::vector()) из libc/libstdc++, а Y должна использовать func из glibc/libstdc++. Но по текущим правилам линковки глобальный символ func будет взят из одной библиотеки. Но независимо развиваемые библиотеки не будут совместимы и взаимозаменяемыми. Более сложная ситуация, когда хедеры Y будут просто по-разному скомпилированы clang и gcc, в том числе из-за разных хедеров libc++ и libstdc++.

Тогда получается, что для компиляции X нужна Y также собранная с помощью clang? В отдельных случаях можно заморочиться и собрать Y в ручную. Но собрать все такие библиотеки - это по сути сделать кусочек дистрибутива, собранного clang’ом (а у некоторых проектов системы сборки могут быть сложными). Поэтому хотелось бы точно также скачать пакет с собранной версией Y. Значит ли это, что дистрибутив должен теперь быть собран в двух экземплярах - каждый пакет с помощью gcc и каждый пакет с помощью clang?

Уже давно около 70% пакетов в дебиане собраны шлангом. Есть дистр позиционирующий свою модность. Они там заявляют, что программы быстрее работают если их шлангом компилять. В Gentoo можно собирать любым компилятором. И если что-то дает лучший эффект то и используется. Но некоторые программы требуют всю цепочку собрать одним компилятором и смешивание отдельный вопрос и самостоятельно можо указать в файлике какие пакеты чем собраны.

anonymous ()

Ради интереса пробовал пилить сборку Linux на базе llvm / llc / lld, compiler-rt, musl - всё вполне прекрасно работает

gcc + glibc иногда криво, либо жирно собирают статически линкованные бинарники

Щас с приходом докера интерес к статической линковке возрос

menangen ★★★★★ ()

Что касается взгляда со стороны, то между разработчиками gcc и clang нет стремления к поддержанию совместимости своих систем (стандарт C/C++ не гарантирует совместимости бинарников библиотек и/или хедеров).

Как это нет? Оба компилятора реализуют Intel Itanium ABI и динамическая библиотека на C++, собранная одним компилятором, должна работать в программе, собранной другим компилятором. У gcc и clang по большей части совместимы флаги командной строки так что они взаимозаменяемы. Например в Haiku (там значительная часть API на C++), собранной с помощью clang/lld, работают бинарники, собранные с помощью gcc.

X512 ★★★ ()
Ответ на: комментарий от anonymous

я видел как программы от него работают медленнее

тем более в дебиане вечно пропихивают всякое говно, вроде как когда-то libav вместо ffmpeg

anonymous ()
Ответ на: комментарий от anonymous

А можно тему со смешиванием раскрыть подробнее? О каком файлике идет речь? Есть ли штатный способ одновременно держать две библиотеки, собранные gcc и clang? Как переход clang на libc (а значит перерубание последнего каната, связывающих их с gcc) может повлиять на экосистему дистрибутивов? Про 70% не знал - это точно?

sidtver ()
Ответ на: комментарий от X512

Как это нет? Оба компилятора реализуют Intel Itanium ABI

В основу реализации EH действительно взята идея ZeroCost от Itanium’а, но кто-то внес свои «расширения», а другие - свои и вот библиотеки libc++ и libstdc++ из-за пары «всего лишь» каких-то деталей стали не совместимы

динамическая библиотека на C++, собранная одним компилятором, должна работать в программе, собранной другим компилятором.

А с чего это вдруг? Стандартные библиотеки могут иметь различные хедеры. В итоге библиотека собрана с одними стандартными хедерами, приложение - с другими. А при запуске по правилам линковки одна стандартная библиотека «заборет» другую. В итоге либо приложение, либо динамическая библиотека будут работать не с той стандартной библиотекой, с которой компилировались. А там еще какой-нибудь std::vector по разному реализован и пошло поехало и вот уже хедера самой динамической библиотеки по-разному компилируются.

У gcc и clang по большей части совместимы флаги командной строки так что они взаимозаменяемы.

Есть много флагов, которые есть только у gcc, и наоборот. Но речь не по флаги. Речь по то, что получается на выходе из компиляторов, и насколько совместимы результаты, а не про то, что проекты можно (целиком) компилировать gcc или (целиком) clang.

Например, несколько лет назад разработчики gcc взяли и просто так поменяли алгоритм манглирования. У разработчиков clang на полгода перестал работать компилятор. Вряд ли они этому обрадовались, но делать нечего из-за технологической зависимости пришлось опять подстраиваться под gcc. А при полной независимости ни под кого они подстраиваются уже не будут.

С другой стороны llvm создает ассемблер, который в общем случае gas не может ассемблировать (если не использовать gas для asm-файлов из под llvm, то и ничего страшного, но это к вопросу о стремлении к совместимости, которая не на входе, а на выходе).

Например в Haiku (там значительная часть API на C++), собранной с помощью clang/lld, работают бинарники, собранные с помощью gcc.

Ну сейчас свезло, а что будет, когда clang полностью перейдет на libc/libc++? Про это собственно и речь.

sidtver ()
Ответ на: комментарий от sidtver

А при запуске по правилам линковки одна стандартная библиотека «заборет» другую.

Есть symbol versioning который позволяет в том числе импортировать символ из конкретной библиотеки даже если символ с таким же именем есть в другой загруженной библиотеке.

Например, несколько лет назад разработчики gcc взяли и просто так поменяли алгоритм манглирования.

Вы про переход GCC 3 со своего манглирования на Itanium ABI или что-то другое? Если про это, что это было давно (2001 год) и вряд ли что либо серьёзно поменяется.

а что будет, когда clang полностью перейдет на libc/libc++

Ничего не будет. В Haiku std::vector, string и т.п. в публичных API не используются, их можно использовать только во внутренней реализации.

X512 ★★★ ()
Последнее исправление: X512 (всего исправлений: 2)

По моим представлениям длительное время clang/llvm использовал binutils glibc/libstdc++ из компилятора gcc

Шта? binutils это отдельный проект, а glibc даже не плюсовая библиотека.

Тогда получается, что для компиляции X нужна Y также собранная с помощью clang?

Главное - не компилятор, а плюсовый рантайм. Конечно же код собранный с libstdc++ и libc++ несовместим.

Значит ли это, что дистрибутив должен теперь быть собран в двух экземплярах - каждый пакет с помощью gcc и каждый пакет с помощью clang?

Нет, это значит что X которая собирается только clang’ом не будет опакечена в этом дистрибутиве.

slovazap ★★★★★ ()
Ответ на: комментарий от X512

и динамическая библиотека на C++, собранная одним компилятором, должна работать в программе, собранной другим компилятором

Даладна?

Новая программа управления fb2-библиотекой (комментарий)

mord0d ★★★★★ ()
Ответ на: комментарий от sidtver

В Gentoo это реализовано и в make.conf указывается переменная что есть си, что такое с++ и вместо gcc и g++ указать clang. Часто clang ускоряет, но не так прям много. Если не использовать флаги вроде -O3 или еще более опасные, то нет смысла особого. Экосистема остается в норме. Из плюсов это не будет нужды собирать GCC. На не слишком быстрой машине это очень даже плюс. Так как если какая-нибудь Mesa требует Clang, то его все равно ставить придется.

https://packages.gentoo.org/packages/media-libs/mesa/dependencies

anonymous ()