36

I'm trying to install Ruby in my home directory on a Linux server (without root access), which of course requires using gcc. The closest thing I can find is a directory by that name which (if you go deep enough) contains 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

The fact that CC1 redirects to GCC on Wikipedia seems to imply something close to identity, however there's no other mention of CC1 on the GCC page besides the note about redirection, and Googling hasn't gotten me anything useful, and my attempts to use cc1 in place of gcc have failed.

What exactly is the relationship between them? And does it offer me any hope of compiling Ruby on this machine?

4 Answers 4

40

GCC has a number of phases to its compilation, and it uses different internal commands to do each phase. C in particular is first preprocessed with cpp, then is compiled into assembly, assembled into machine language, and then linked together.

cc1 is the internal command which takes preprocessed C-language files and converts them to assembly. It's the actual part that compiles C. For C++, there's cc1plus, and other internal commands for different languages.

There is a book on Wikibooks that explains the process with pictures.

Unfortunately, cc1 is an internal command and only one piece of the installation, and if that's all you have, you will not be able to compile things.

2
  • 3
    Are you sure it requires preprocessed C files? I seem to be able to cc1 files with #include and #define directives Apr 15, 2019 at 2:10
  • 3
    @extremeaxe5 For the past 20-ish years -- starting with GCC 3.0, iirc -- the preprocessor has been integrated into 'cc1', so yes, that's expected to work.
    – zwol
    Jan 23, 2021 at 2:56
16

gcc is the name of the suite cc is just the C compiler from this suite.

the word cc it's also a generic name for any given c compiler under unix systems, for example it's not rare to find an environment variable called CC in a given building script or configure script, and if you want to be pedantic, this variable usually points to a c compiler that doesn't necessarily performs the linking of your compiled object, it's usually used to refer to a compiler that "just" compiles. cc from gcc is, however, able to output a finished executable so is able to perform this final step with its linker too.

the word cc1 it's often times used "internally" or when reading GNU docs ( example ), it's also used to name gcc-related library based on what language or compiler they belong to ( in this case cc1 = belongs to the c compiler ).

infact if you ask gcc what is the meaning of the word cc1

gcc -print-prog-name=cc1

it should answer with the path for the library for the cc compiler, so you are trying to execute something that is a library and not a real executable.

it's much simpler to remember CC as c compiler and simplify everything, bypass this cc1, you don't need to know how things work internally unless you want to start a long journey.

5

As others mentioned, gcc uses cc1.

The exact way in which cc1 and other sub-program like cpp and ld are called is done is determined by the spec files format.

The current spec file can viewed with:

gcc -dumpspecs

The relevant section seems to be:

*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}

And you can use your own spec file with:

gcc -specs=<specs-file>

Of course, command line options passed to GCC indirectly change how the sub-processes are called. But manipulating spec files gives you greater flexibility and allows you to do things which command line options cannot, e.g. https://stackoverflow.com/questions/7493620/inhibit-default-library-paths-with-gcc

You can observe what is being run easily with:

gcc -v hello_world.c |& grep cc1

as mentioned at: https://stackoverflow.com/questions/40572041/how-to-make-gcc-show-the-internal-commands-called

Sample output:

/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
0
2

cc1 is both the preprocessor and the compiler, whose input is C source code and output is assembly code.

You can see cc1 is one of the commands invoked (the first, in fact) by issuing (syntax dependent on version):
gcc-8 -v SOMESOURCE.c

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .