Związek między CC1 a GCC?

23

Próbuję zainstalować Ruby w moim katalogu domowym na serwerze Linux (bez dostępu do konta root), co oczywiście wymaga użycia gcc. Najbliższa rzecz, jaką mogę znaleźć, to katalog o tej nazwie, który (jeśli przejdziesz wystarczająco głęboko) zawiera cc1:

>: find / -iname gcc 2> /dev/null
/usr/libexec/gcc


>: tree -if /usr/libexec/gcc
/usr/libexec/gcc
/usr/libexec/gcc/x86_64-redhat-linux
/usr/libexec/gcc/x86_64-redhat-linux/4.1.1
/usr/libexec/gcc/x86_64-redhat-linux/4.1.1/cc1
/usr/libexec/gcc/x86_64-redhat-linux/4.1.2 -> 4.1.1

Fakt, że CC1 przekierowuje do GCC na Wikipedii wydaje się sugerować coś zbliżonego do tożsamości, jednak nie ma innej wzmianki o CC1 na stronie GCC poza notatką o przekierowaniu, a Googling nie przyniósł mi niczego użytecznego, a moje próby użycia cc1w miejsce gcczawiodło.

Jaki dokładnie jest związek między nimi? I czy daje mi to jakąkolwiek nadzieję na skompilowanie Rubiego na tym komputerze?

ikonoklasta
źródło

Odpowiedzi:

28

GCC ma wiele faz do swojej kompilacji i używa różnych wewnętrznych poleceń do wykonania każdej fazy. W szczególności C jest najpierw wstępnie przetwarzane za pomocą cpp, a następnie kompilowane w asemblerze, składane w język maszynowy, a następnie łączone ze sobą.

cc1 to wewnętrzne polecenie, które pobiera wstępnie przetworzone pliki w języku C i konwertuje je na asembler. Jest to właściwa część, która kompiluje C. Dla C ++ istnieje cc1plus i inne wewnętrzne polecenia dla różnych języków.

W Wikibooks jest książka, która wyjaśnia ten proces za pomocą zdjęć .

Niestety, cc1 jest wewnętrznym poleceniem i tylko jednym elementem instalacji, a jeśli to wszystko, co masz, nie będziesz w stanie skompilować rzeczy.

Alan Shutko
źródło
2
Zwykłym terminem jest „front end”.
Keith Thompson
1
Czy na pewno wymaga to wstępnie przetworzonych plików C? I wydają się być zdolne do cc1plików z #includei #definedyrektyw
extremeaxe5
10

gccnazwa pakietu ccto tylko kompilator C z tego pakietu.

słowo ccto jest także ogólną nazwą dla dowolnego kompilatora c w systemach uniksowych, na przykład nierzadko znajduje się zmienną środowiskową wywoływaną CCw danym skrypcie budowlanym lub skrypcie konfiguracyjnym, a jeśli chcesz być pedantyczny, ta zmienna zwykle wskazuje ac kompilator, który niekoniecznie wykonuje łączenie skompilowanego obiektu, zwykle jest używany w odniesieniu do kompilatora, który „po prostu” kompiluje. ccfrom gccjest jednak w stanie wygenerować gotowy plik wykonywalny, więc jest w stanie wykonać ten ostatni krok również za pomocą swojego linkera.

słowo, cc1które często jest używane „wewnętrznie” lub podczas odczytywania dokumentów GNU ( przykład ), służy również do nazewnictwa biblioteki związanej z gcc na podstawie języka lub kompilatora, do którego należą (w tym przypadku cc1 = należy do kompilatora c).

w rzeczywistości, jeśli zapytasz, gccjakie jest znaczenie tego słowacc1

gcc -print-prog-name=cc1

powinien odpowiedzieć ścieżką do biblioteki dla kompilatora cc, więc próbujesz wykonać coś, co jest biblioteką, a nie prawdziwym plikiem wykonywalnym.

o wiele łatwiej jest zapamiętać CC jako kompilator c i uprościć wszystko, omijając ten cc1, nie musisz wiedzieć, jak rzeczy działają wewnętrznie, chyba że chcesz rozpocząć długą podróż.

użytkownik2384250
źródło
4

Jak wspomniano inni, gccużywa cc1.

Dokładny sposób, w jaki cc1i innego podprogramu jak cppi ldnazywa odbywa zależy od specyfikacji plików PDF.

Bieżący plik specyfikacji można wyświetlić za pomocą:

gcc -dumpspecs

Odpowiednią sekcją wydaje się być:

*cc1_options:
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %{!iplugindir*:%{fplugin*:%:find-plugindir()}} %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{aux-info*} %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)}  %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}}  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{Qy:} %{-help:--help} %{-target-help:--target-help} %{-version:--version} %{-help=*:--help=%*} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %{coverage:-fprofile-arcs -ftest-coverage}

I możesz użyć własnego pliku specyfikacji z:

gcc -specs=<specs-file>

Oczywiście opcje wiersza poleceń przekazane do GCC pośrednio zmieniają sposób wywoływania podprocesów. Ale manipulowanie plikami specyfikacji daje większą elastyczność i pozwala robić rzeczy, których nie mogą wykonywać opcje wiersza poleceń, np. Https://stackoverflow.com/questions/7493620/inhibit-default-library-paths-with-gcc

Możesz łatwo obserwować, co jest uruchamiane:

gcc -v hello_world.c |& grep cc1

Przykładowe dane wyjściowe:

/usr/lib/gcc/x86_64-linux-gnu/4.8/cc1 -quiet -v -imultiarch x86_64-linux-gnu hello_world.c -quiet -dumpbase hello_world.c -mtune=generic -march=x86-64 -auxbase hello_world -version -fstack-protector -Wformat -Wformat-security -o /tmp/ccvcVNAX.s
Ciro Santilli
źródło
1

cc1 jest zarówno preprocesorem, jak i kompilatorem, którego wejściem jest kod źródłowy C, a wyjściem kod asemblera.

Możesz zobaczyć, że cc1jest to jedno z wywoływanych poleceń (w rzeczywistości pierwsze), wydając (składnia zależna od wersji):
gcc-8 -v SOMESOURCE.c

flow2k
źródło