我正在尝试将 Ruby 安装在 Linux 服务器上的主目录中(没有 root 访问权限),这当然需要使用gcc
.我能找到的最接近的东西是一个同名的目录,其中(如果你足够深入的话)包含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
事实是CC1 重定向到维基百科上的 GCC似乎暗示着一些接近身份的东西,但是除了有关重定向的注释之外,GCC 页面上没有其他提到 CC1 的内容,而且谷歌搜索没有给我带来任何有用的东西,我尝试使用cc1
代替gcc
也失败了。
他们之间究竟是什么关系?它是否给我带来了在这台机器上编译 Ruby 的希望?
答案1
GCC 的编译有多个阶段,并且它使用不同的内部命令来完成每个阶段。特别是C,首先用cpp进行预处理,然后编译成汇编,汇编成机器语言,然后链接在一起。
cc1 是内部命令,它获取预处理的 C 语言文件并将其转换为汇编语言。它是编译 C 的实际部分。对于 C++,有 cc1plus 和其他针对不同语言的内部命令。
维基教科书上有一本书用图片解释过程。
不幸的是,cc1 是一个内部命令,并且只是安装的一部分,如果这就是您的全部,您将无法编译东西。
答案2
gcc
是套件的名称cc
,就是该套件中的 C 编译器。
it这个词cc
也是 UNIX 系统下任何给定 c 编译器的通用名称,例如,在给定构建脚本或配置脚本中调用的环境变量并不罕见CC
,如果你想学究气,这个变量通常指向 ac不一定执行编译对象的链接的编译器,它通常用于指“仅”编译的编译器。然而, cc
fromgcc
能够输出完成的可执行文件,因此也能够使用其链接器执行最后一步。
这个词cc1
经常在“内部”使用或者在阅读 GNU 文档时使用(例子),它还用于根据 gcc 相关的库所属的语言或编译器来命名它们(在本例中 cc1 = 属于 c 编译器)。
事实上,如果你问gcc
这个词的意思是什么cc1
gcc -print-prog-name=cc1
它应该用 cc 编译器的库路径来回答,所以您尝试执行的是一个库而不是一个真正的可执行文件。
记住 CC 更简单c编译器并简化一切,绕过这个 cc1,你不需要知道事情内部是如何工作的,除非你想开始一个漫长的旅程。
答案3
正如其他人提到的,gcc
使用cc1
.
这精确的cc1
和其他子程序(如cpp
和)的调用方式ld
由规格文件格式。
当前的规格文件可以通过以下方式查看:
gcc -dumpspecs
相关部分似乎是:
*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}
您可以使用自己的规范文件:
gcc -specs=<specs-file>
当然,传递给 GCC 的命令行选项间接改变了子进程的调用方式。但是操作规范文件可以为您提供更大的灵活性,并允许您执行命令行选项无法执行的操作,例如https://stackoverflow.com/questions/7493620/inhibit-default-library-paths-with-gcc
您可以使用以下命令轻松观察正在运行的内容:
gcc -v hello_world.c |& grep cc1
如所述:https://stackoverflow.com/questions/40572041/how-to-make-gcc-show-the-internal-commands-known
示例输出:
/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
答案4
cc1
既是预处理器又是编译器,其输入是C源代码,输出是汇编代码。
您可以看到cc1
通过发出(语法取决于版本)调用的命令之一(实际上是第一个):
gcc-8 -v SOMESOURCE.c