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