Fedora 21 с лязгом, без gcc

Можете ли вы (разумно) доставить Fedora 21 туда, где есть только llvm/clang/libC++ / libC++abi? (Я обнаружил некоторые вещи, предлагающие нет, но им было всего около 3 лет, и с тех пор llvm / clang прошел большой путь.)

Со свежей установкой я попробовал

yum install gcc gcc-c++
(downloaded, built, installed llvm/cfe(clang)/compiler-rt/libcxx/libcxxabi from svn)
yum remove gcc gcc-c++
added to /etc/profile: export CC=/usr/local/bin/clang \ export CXX=/usr/local/bin/clang++
(in case of hard wiring)
ln -s /usr/local/bin/clang /usr/local/bin/gcc
ln -s /usr/local/bin/clang /usr/local/bin/cc
ln -s /usr/local/bin/clang++ /usr/local/bin/g++
ln -s /usr/local/bin/clang++ /usr/local/bin/c++
ldconfig

Я был все счастлив, затем пошел что-то строить, и я получил:

ld: cannot find crtbegin.o
ld: cannot find -lgcc
ld: cannot find -lgcc_s

Clang -V включает в себя

Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.9.2

ldconfig && ldconfig -p | grep libgcc показывает

libgcc_s.so.1 (libc6,x86-64) => /lib64/libgcc_s.so.1

И /lib64 является символической ссылкой на /usr/lib64. И /usr/lib64/libgcc_s.so.1 является символической ссылкой на /usr/lib64/libgcc_s-4.9.2-20150212.so.1, которая существует как реальный файл (92816 байт.)

Итак, я не понимаю, в чем проблема ld на -lgcc_s. crtbegin нигде не найти, а gcc (без _s) нигде не найти.

yum install libgcc говорит, что он уже установлен и последняя версия, ничего не поделаешь.

Поскольку у меня установлена ​​исходная сборка clang, могу ли я пересобрать clang, на этот раз используя clang, а не gcc, чтобы избавиться от зависимости? (Может быть, тогда "кандидат на установку GCC" исчезнет.)

Могу ли я принудительно установить -stdlib= C++ и -lC++ abi по умолчанию или, по крайней мере, установить libC++ и libC++ abi без gcc?

1 ответ

Потратив некоторое время, пытаясь заставить clang работать с libC++ и libC++ abi без GCC, я обнаружил, что это действительно возможно, даже если это немного проблематично, учитывая текущее состояние LLVM/clang. В дополнение к небольшим тестовым программам я смог собрать CMake и некоторые другие программные пакеты, написанные на C++, без установленного GCC, и получившиеся двоичные файлы были независимы от libstdC++; они зависят только от libC++/libC++ abi в соответствии с выводом ldd. К сожалению, я не смог собрать сам Clang с Clang, который был собран с помощью GCC. Я экспериментировал на разных платформах Linux (32-битная Fedora 21, 64-битная версия Amazon Linux 2015.3 (на основе RPM), 64-битная CentOS 7.1 и 64-битная Ubuntu 14.04).

Несмотря на то, что можно создавать программное обеспечение с использованием clang с использованием libC++/libC++ abi без зависимости от libstdC++ и без присутствия компилятора GCC, типичная установка Linux настолько привязана к libgcc и libstdC++, что избавиться от них нецелесообразно. Попробуйте удалить эти два пакета, и вы увидите, сколько системы зависит от них. Даже во FreeBSD 10.1, где clang является компилятором по умолчанию, а GCC не установлен, libgcc.a, libgcc_s.so и несколько файлов crt*.o используются при сборке программы, как показано в опции -v. Кроме того, в FreeBSD 10.1 результирующие двоичные файлы зависят от libgcc в соответствии с ldd. В Ubuntu, в котором в качестве менеджера пакетов есть dpkg, файлы

   libgcc.a
   libgcc_s.so
   crtbegin.o
   crtbeginT.o
   crtbeginS.o
   crtendS.o
   crtend.o

находятся в пакете libgcc-devel, а в системе на основе RPM, такой как Fedora, они находятся в пакете gcc. Кроме того, вам могут понадобиться эти файлы, даже если они мне не нужны для кода, который я пытался создать:

   crtfastmath.o
   crtprec32.o
   crtprec80.o
   crtprec64.o

Таким образом, можно утверждать, что вышеупомянутые файлы лучше принадлежат libgcc, а не gcc. Насколько я могу судить, перед удалением пакета gcc необходимо выполнить следующие действия в системе на основе RPM:

1) Создайте символическую ссылку

libgcc_s.so -> libgcc_s.so.1

в любом каталоге libgcc_s.so.1 находится.

2) Скопируйте перечисленные выше файлы crt*.o в этот каталог.

3) В той же директории создайте символическую ссылку (libstdC++. So.x уже должен быть там; x - это число):

libstdc++.so -> libstdc++.so.x

Это нужно только в том случае, если вы собираетесь использовать libstdC++; это не нужно, если вы планируете использовать только libC++. В некоторых системах libstdC++. So, который является символической ссылкой на libstdC++. So.x, принадлежащий пакету libstdC++, помещается пакетом libstdC++-devel в каталог библиотеки GCC, поэтому вы можете удалить этот каталог после удаления GCC и просто создать символическая ссылка в том же каталоге, где живет libstdC++.so.x.

Теперь вы должны быть в состоянии сделать следующее:

1) Создайте программу на C:

clang progname.c

2) Создайте программу на C++ с использованием заголовочных файлов / библиотек libstdC++:

clang++ -I<location of headers> progname.cpp

В системах на основе RPM, на которые я смотрел, заголовки libstdC++ являются частью пакета libstdC++-devel, и их расположение можно найти в rpm -ql пакета.

3) Создайте программу на C++, используя заголовки / библиотеки libC++:

clang++ -I/<location of headers> progname.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc -lgcc_s

Расположение заголовков находится там, где они были установлены, когда вы создали LLVM+ Clang и т. Д.

Пожалуйста, смотрите http://libcxx.llvm.org/ для получения дополнительной информации. При построении кода C++ с использованием libC++/libC++ abi вы можете использовать -stdlib=libC++ вместо флага -I, но в моем тестировании, которое работало только с clang, созданным из исходного кода, а не с clang, установленным из репозитория (вы можете установить clang из репозитория и используйте его для сборки libC++/libC++ abi, или вы можете использовать gcc для сборки libC++(abi), затем удалить gcc и использовать библиотеки с предоставленным репо clang).

При настройке программного пакета для его сборки с использованием clang + libC++ может потребоваться установить следующее:

LIBS="-nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc"
CXX=clang++
CXXFLAGS="-stdlib=libc++"
CC=clang

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

#!/bin/bash

MYLFLAGS="-nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc"

# Catch the case when we only want to compile; this helps us avoid some warnings:
if echo "$@" | egrep "(^-c | -c | -c$)" >/dev/null 2>&1; then
MYLFLAGS=""
fi

/usr/local/bin/clang++ -stdlib=libc++ "$@" $MYLFLAGS

Это может быть полезно и для других целей.

Для получения дополнительной информации, пожалуйста, смотрите мою статью на http://www.omniprog.info/clang_no_gcc.html

Другие вопросы по тегам