Clang

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Clang

Непрочитанное сообщение Olej » 24 мар 2013, 02:23

Clang идёт весьма серьёзно на замену GCC.
Он уже представлен практически во всех репозитариях пакетных систем Linux, а в FreeBSD объявлен заменой GCC.

Код: Выделить всё

bash-4.2$ yum list clang*
...
Доступные пакеты
clang.i686                                       3.0-14.fc17                             updates
clang-analyzer.i686                              3.0-14.fc17                             updates
clang-devel.i686                                 3.0-14.fc17                             updates
clang-doc.noarch                                 3.0-14.fc17                             updates
Поэтому самое время собрать информацию о Clang, а заодно прогнать ним примеры кода C/C++, ранее собранные GCC, чтоб посмотреть что оно и с чем...

Clang. Материал из Википедии — свободной энциклопедии.
Clang является фронтендом для языков программирования C, C++, Objective-C и Objective-C++ (англ.), использующим для оптимизации и кодогенерации фреймворк LLVM.
Целью проекта является создание замены GNU Compiler Collection (GCC). Разработка ведется согласно концепции open source; в проект вовлечены несколько крупнейших в разработке ПО корпораций, включая Google и Apple. Исходный код доступен на условиях BSD-подобной лицензии.
clang: a C language family frontend for LLVM - официальная страница проекта.

Clang API. Начало

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Clang

Непрочитанное сообщение Olej » 24 мар 2013, 02:34

Код: Выделить всё

bash-4.2$ sudo yum install clang*
...
Объем загрузки: 41 M
Продолжить? [y/N]: y
...
Установлено:
  clang.i686 0:3.0-14.fc17   clang-analyzer.i686 0:3.0-14.fc17   clang-devel.i686 0:3.0-14.fc17   clang-doc.noarch 0:3.0-14.fc17

Установлены зависимости:
  llvm.i686 0:3.0-14.fc17

Обновлены зависимости:
  cpp.i686 0:4.7.2-2.fc17       gcc.i686 0:4.7.2-2.fc17        gcc-c++.i686 0:4.7.2-2.fc17          libgcc.i686 0:4.7.2-2.fc17
  libgomp.i686 0:4.7.2-2.fc17   libstdc++.i686 0:4.7.2-2.fc17  libstdc++-devel.i686 0:4.7.2-2.fc17  libtool.i686 0:2.4.2-3.1.fc17
  llvm-libs.i686 0:3.0-14.fc17

Выполнено!
New leaves:
  clang-analyzer.i686
  clang-devel.i686
  clang-doc.noarch

Код: Выделить всё

bash-4.2$ which clang
/usr/bin/clang

bash-4.2$ ls -l /usr/bin/clang*
-rwxr-xr-x 1 root root 13726864 сент. 24 17:39 /usr/bin/clang
lrwxrwxrwx 1 root root        5 марта 24 01:27 /usr/bin/clang++ -> clang
-rwxr-xr-x 1 root root   780752 сент. 24 17:39 /usr/bin/clang-tblgen

Код: Выделить всё

bash-4.2$ clang --help
OVERVIEW: clang "gcc-compatible" driver

USAGE: clang [options] <inputs>

OPTIONS:
  -###                    Print the commands to run for this compilation
  --analyze               Run the static analyzer
  --help                  Display available options
  --relocatable-pch       Build a relocatable precompiled header
  -E                      Only run the preprocessor
...

Код: Выделить всё

bash-4.2$ man clang
CLANG(1)                                  Clang Tools Documentation                                     CLANG(1)

NAME
       clang - the Clang C, C++, and Objective-C compiler

SYNOPSIS
       clang [-c|-S|-E] -std=standard -g
         [-O0|-O1|-O2|-Os|-Oz|-O3|-O4]
         -Wwarnings... -pedantic
         -Idir... -Ldir...
         -Dmacro[=defn]
         -ffeature-option...
         -mmachine-option...
         -o output-file
         -stdlib=library
         input-filenames
...

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Clang

Непрочитанное сообщение Olej » 24 мар 2013, 11:58

Несколько интересных публикаций относительно LLVM (Low Level Virtual Machine), на чём базируется Clang, и о самом Clang ... это, может и избыточно, но пробежать бегло стоит - многие вещи проясняет:

Создание действующего компилятора с помощью инфраструктуры LLVM. Часть 1
LLVM (Low Level Virtual Machine) — это весьма мощная инфраструктура компилятора, предназначенная для оптимизации программ, написанных на предпочтительном для разработчика языке программирования, на этапах компиляции, связывания и исполнения. Инфраструктура LLVM работает на нескольких разных платформах. Ее основное достоинство — генерация кода, который исполняется с высокой скоростью.
Создание действующего компилятора с помощью инфраструктуры LLVM. Часть 2

Много проясняет во "внутренней кухне" GCC & Clang :
GCC был написан на C, использует собственный промежуточный язык GIMPLE для геренации кода, развивается фанатами оптимизирующих компиляторов; Apple была отстранена от участия в этом проекте трудами Р.М.С. в 2008-м году. Clang пишется на C++, использует LLVM для генерации кода и некоторых других вещей (кстати, LLVM также используют в графических драйверах в Mac OS X и Linux, а также в компиляторе CUDA от NVIDIA и компиляторах OpenCL). В clang никого не отстраняют от разработки, и многие контрибьюторы проекта на самом деле интересуются не компиляцией в стиле GCC, а другими вещами: интеграцией в среды разработки (XCode, QtCreator, плагин для vim), анализом невероятно огромной базы исходников (Google), компиляцией для GPU или DSP (тут перечислять слишком долго), автоматическим поиском ошибок (Apple, Google, Qualcomm и другие).

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Clang

Непрочитанное сообщение Olej » 24 мар 2013, 12:11

Первая попытка компиляции простейшего приложения:

Код: Выделить всё

#include <cstdlib>
#include <iostream>

using namespace std;

int main ( int argc, char **argv ) {
   std::cout << "Hello Clang!" << endl;
   exit( EXIT_SUCCESS );
}
Завершается с серьёзной ошибкой компиляции:

Код: Выделить всё

bash-4.2$ make
clang++ -xc++ hello.cc -o hellocc
In file included from hello.cc:1:
In file included from /usr/bin/../lib/gcc/i686-redhat-linux/4.7.2/../../../../include/c++/4.7.2/ostream:39:
In file included from /usr/bin/../lib/gcc/i686-redhat-linux/4.7.2/../../../../include/c++/4.7.2/ios:42:
In file included from /usr/bin/../lib/gcc/i686-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/ios_base.h:40:
/usr/bin/../lib/gcc/i686-redhat-linux/4.7.2/../../../../include/c++/4.7.2/ext/atomicity.h:48:45: error: use of undeclared
      identifier '__ATOMIC_ACQ_REL'
  { return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
                                            ^
/usr/bin/../lib/gcc/i686-redhat-linux/4.7.2/../../../../include/c++/4.7.2/ext/atomicity.h:52:38: error: use of undeclared
      identifier '__ATOMIC_ACQ_REL'
  { __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }


1. Понятно, что это где-то в заголовочных файлах CGG C++ (которые используются для сборки).

2. Происходит это в инсталляции Fedora 17 (из репозитария), с набором инструментов (и определений, библиотек):

Код: Выделить всё

bash-4.2$ clang --version
clang version 3.0 (tags/RELEASE_30/final)
Target: i386-redhat-linux-gnu
Thread model: posix

Код: Выделить всё

bash-4.2$ gcc --version
gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)
Copyright (C) 2012 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая 
коммерческую ценность и применимость для каких-либо целей.
3. Такая же ошибка неоднократно цитируется в Интернет (находится, главным образом, в англоязычной части, в сообщениях типа "караул" ;-) ).

Это явно накладка версий ... Смотрим в atomicity.h ... Исправляется определением в своих .cc файлах:

Код: Выделить всё

#include <cstdlib>
#undef _GLIBCXX_ATOMIC_BUILTINS
#include <iostream>
Почему это так я не знаю ... но это работает!
(вот так просто ларчик открывался ... но крови он попил ;-) )

Прилагается простейший проект, содержащий сборку "приложений" а). на классическом C, б). на C++.

Код: Выделить всё

bash-4.2$ make
clang -xc  hello.c -o helloc
clang++ -xc++  hello.cc -o hellocc

bash-4.2$ ./helloc
Hello Clang!

bash-4.2$ ./hellocc
Hello Clang!
Вложения
clang.tgz
(839 байт) 544 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Clang

Непрочитанное сообщение Olej » 24 мар 2013, 15:03

Olej писал(а):простейшего приложения:
Компиляция существенно более сложного проекта:
- более-менее реального ... сделанного недавно здесь в соседней теме: исполнение промышленных проектов под Wine;
- использующего пакет Boost ...
- использующего Boost не только в заголовочных определениях (#include ...), но и в бинарных Boost-библиотеках (libboost_system.so, libboost_timer.so и др.)

Всё та же история в *.cc:

Код: Выделить всё

#include <ctime>
#undef _GLIBCXX_ATOMIC_BUILTINS
#include <iostream>
#include <fstream>
(причём, если передвинуть #include <ctime> после #include <iostream>, то он опять начнёт орать ... я не разбирался)

Всё таки, пока Clang очень капризный к опциям запуска ... или это кажется с непривычки?
Вот сравнительные Makefile для сборки в GCC и Clang (в отличающейся части):

Makefile.clang :

Код: Выделить всё

CC = clang++ -xc++
LDOPT += -l boost_system -l boost_timer -l boost_chrono -l rt

PROGLIST = randwr
all:    $(PROGLIST)

randwr: randwr.cpp
        $(CC) $(COPT) $(LDOPT) randwr.cpp -o randwr.clang
Makefile.gcc :

Код: Выделить всё

CC = c++
COPT += -Wall
LDOPT += -L /usr/lib -l boost_timer -l boost_system -l boost_chrono -l rt

PROGLIST = randwr
all:    $(PROGLIST)

randwr: randwr.cpp
        $(CC) $(COPT) $(LDOPT) randwr.cpp -o randwr.gcc
Поехали... ;-)

Код: Выделить всё

bash-4.2$ make -f Makefile.clang
clang++ -xc++  -l boost_system -l boost_timer -l boost_chrono -l rt randwr.cpp -o randwr.clang

bash-4.2$ make -f Makefile.gcc
c++ -Wall -L /usr/lib -l boost_timer -l boost_system -l boost_chrono -l rt randwr.cpp -o randwr.gcc

bash-4.2$ ls -l randwr.*
-rwxrwxr-x 1 olej olej 24809 марта 24 13:40 randwr.clang
-rw-r--r-- 1 olej olej  4036 марта 24 13:33 randwr.cpp
-rw-r--r-- 1 olej olej 37888 марта 22 20:08 randwr.exe
-rwxrwxr-x 1 olej olej 23618 марта 24 13:41 randwr.gcc
-rw-rw-r-- 1 olej olej 25098 марта 23 01:15 randwr.hist
Отличия минимальные ... так же как и на выполнении (с выполнением всё ОК):

Код: Выделить всё

bash-4.2$ ./randwr.clang data 10000 1K
длина файла 2097152, блоков в файле 2048
продолжительность выполнения случайной записи:
 0.084923s wall, 0.000000s user + 0.040000s system = 0.040000s CPU (47.1%)
в случайные позиции файла записано 10000 блоков длиной 1024 байт каждый
из 2048 блоков файла модифицировано 2029 блоков
длина файла после записи: 2097152

Код: Выделить всё

bash-4.2$ ./randwr.gcc data 10000 1K
длина файла 2097152, блоков в файле 2048
продолжительность выполнения случайной записи:
 0.064438s wall, 0.000000s user + 0.030000s system = 0.030000s CPU (46.6%)
в случайные позиции файла записано 10000 блоков длиной 1024 байт каждый
из 2048 блоков файла модифицировано 2040 блоков
длина файла после записи: 2097152
Вложения
randwr.tgz
(39.16 КБ) 527 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Clang

Непрочитанное сообщение Olej » 26 мар 2013, 16:35

Olej писал(а): clang: a C language family frontend for LLVM - официальная страница проекта.
Исчерпывающее, большого объёма, описание: CLANG COMPILER USER’S MANUAL

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Clang

Непрочитанное сообщение Olej » 26 мар 2013, 19:25

Olej писал(а):Clang API. Начало
Хотя, если вы попытаетесь скомпилировать оттуда примеры, то получите сразу же отлуп:

Код: Выделить всё

bash-4.2$ make
clang++ -xc++  clang-api.cc -o clang-api
In file included from clang-api.cc:9:
In file included from /usr/include/clang/Frontend/DiagnosticOptions.h:13:
In file included from /usr/include/clang/Basic/Diagnostic.h:17:
/usr/include/clang/Basic/DiagnosticIDs.h:17:10: fatal error: 'llvm/ADT/IntrusiveRefCntPtr.h' file not found
#include "llvm/ADT/IntrusiveRefCntPtr.h"
         ^
1 error generated.
make: *** [clang-api] Ошибка 1
1. Если установка Clang шла из пакетной системы (не из исходников на сайте проекта), то такой установки мало.
Добавляем:

Код: Выделить всё

bash-4.2$ yum list *llvm*
...
Установленные пакеты
llvm.i686                                             3.0-14.fc17                                      @updates
llvm-libs.i686                                        3.0-14.fc17                                      @updates
Доступные пакеты
holland-mysqllvm.noarch                               1.0.6-5.fc17                                     fedora
llvm-devel.i686                                       3.0-14.fc17                                      updates
llvm-doc.noarch                                       3.0-14.fc17                                      updates
llvm-ocaml.i686                                       3.0-14.fc17                                      updates
llvm-ocaml-devel.i686                                 3.0-14.fc17                                      updates
llvm-ocaml-doc.noarch                                 3.0-14.fc17                                      updates

Код: Выделить всё

bash-4.2$ sudo yum install llvm-devel llvm-doc
...
Объем загрузки: 15 M
Объем изменений: 72 M
Продолжить? [y/N]: y
...
Выполнено!
New leaves:
  llvm-devel.i686
  llvm-doc.noarch
То же самое примерно будет в любой другой пакетной системе (Debian и др.).
После этого всё становится лучше ... но всё ещё плохо :-(

2. В тех примерах ещё много что нужно поправить после этого в #include и определениях, чтобы оно начало хотя бы находить нужные файлы...
Такое впечатление, что автор статьи сам это не компилировал, а только приводит для иллюстрации, откуда-то из документации (там и в обсуждениях есть какая-то такая оговорка).
Но 1-й пример удаётся собрать ... 2-й - гораздо хуже :-(
Но это - работает.
Кому хочется повозиться - архив приложен.
Вложения
parser.tgz
(3.9 КБ) 536 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Clang

Непрочитанное сообщение Olej » 30 мар 2013, 14:03

Olej писал(а):Clang идёт весьма серьёзно на замену GCC.
Он уже представлен практически во всех репозитариях пакетных систем Linux, а в FreeBSD объявлен заменой GCC.
Вот и в MINIX 3 Э.Таненбаума поспешили заявить, что они переходят полностью на Clang (со своего доисторического C компилятора ACT ... практически "пропуская" GCC, на который они на 1 год перешли). Это симптоматично!

Хотя MINIX 3 уже вряд ли кого может заинтересовать - это тупиковая ветка, хоть её и пытаются как-то реанимировать. Вот и активность (точнее её отсутствие) русскоязычного сайта MINIX 3 тому иллюстрация.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Clang

Непрочитанное сообщение Olej » 30 мар 2013, 14:27

Olej писал(а): Всё таки, пока Clang очень капризный к опциям запуска ... или это кажется с непривычки?
Зато эти опции достаточно хорошо, но одновременно и кратко, описаны.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Clang

Непрочитанное сообщение Olej » 02 апр 2013, 11:02

Ещё интересные вещи ... которые требуют выяснения:

Clang может линковаться со стандартной библиотекой из GCC (опция -stdlib=libstdc++) и с новой библиотекой C++ (опция -stdlib=libc++), которая делается в составе проекта Clang, и утверждается, что она лучше (чем GCC) уже на сейчас, а дальше будет всё лучше и лучше...

Но компиляция с libc++ сразу прерывается по включаемым файлам:

Код: Выделить всё

bash-4.2$ make
clang++ -xc++  -stdlib=libc++ hello.cc -o hellocc
hello.cc:1:10: fatal error: 'cstdlib' file not found
#include <cstdlib>
Можно детальнее посмотреть вывод диагностики Clang по опции -v, и найти чего ему не хватает (каких include) ... например так:

Код: Выделить всё

bash-4.2$ make
clang++ -xc++  -stdlib=libc++ -I /usr/include/c++/4.7.2 -I /usr/include/c++/4.7.2/i686-redhat-linux hello.cc -o hellocc
/usr/bin/ld: cannot find -lc++
clang: error: linker command failed with exit code 1 (use -v to see invocation)
И детализация (-v) покажет:

Код: Выделить всё

bash-4.2$ make
clang++ -xc++ -v -stdlib=libc++ -I /usr/include/c++/4.7.2 -I /usr/include/c++/4.7.2/i686-redhat-linux hello.cc -o hellocc
...
/usr/bin/ld: cannot find -lc++
...
Но это и есть libc++.so !
Этой библиотеки у меня в RFR 17 явно нет... (оттуда и проблемы с -I ...) ... или она не установлена (в качестве пакета).

В Debian (который, вроде бы как ;-) , всегда сильно отстаёт по срокам от Fedora) для использования libc++ устанавливают дополнительные пакеты:
Available in Debian Experimental, this new packages provides both the runtime libraries (libc++abi1) and the C++ headers (libc++-dev).
(там же показаны примеры использования ... полезная заметка ;-) )

Буду разбираться как с этим обстоит дело в Fedora 17.

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 12 гостей