cannot read spec file ‘/usr/lib/rpm/redhat/redhat-hardened-cc1’: に対して脳死でsudo dnf install redhat-rpm-configしないための調査

# はじめに

諸般の事情でalmalinux8上で古いopensslとrubyを入れるためにrpmを自作していた。

rpm自体は出来上がり、これをインストールしてさあ、gemいれっぞとやっていたら

```
Installing bcrypt 3.1.18 with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native
extension.

/usr/local/bin/ruby extconf.rb
creating Makefile

make
compiling bcrypt_ext.c
gcc: 致命的エラー: cannot read spec file ‘/usr/lib/rpm/redhat/redhat-hardened-cc1’:
そのようなファイルやディレクトリはありません
コンパイルを停止しました。
make: *** [Makefile:207: bcrypt_ext.o] エラー 1
```

このようにエラーが出た。

# `cannot read spec file ‘/usr/lib/rpm/redhat/redhat-hardened-cc1’`への一般的な対処方法

https://stackoverflow.com/questions/34624428/g-error-usr-lib-rpm-redhat-redhat-hardened-cc1-no-such-file-or-directory

https://bugzilla.redhat.com/show_bug.cgi?id=1636613

よく知られているように、`sudo dnf install redhat-rpm-config`すると問題は解決する。

# なぜ解決するのか

脳みそ空っぽで対処を行うと大体ろくな目に合わないのでそもそも`redhat-rpm-config`が果たす役割を調べていく。

## redhat-rpm-config の中身

```
[yumetodo@yumetodo-vm-almalinux8-rvm ~]$ dnf repoquery -l redhat-rpm-config
メタデータの期限切れの最終確認: 0:00:04 前の 2023年06月07日 17時16分49秒 に実施しました。
/usr/lib/rpm/fileattrs/kabi.attr
/usr/lib/rpm/fileattrs/kmod.attr
/usr/lib/rpm/fileattrs/libsymlink.attr
/usr/lib/rpm/kabi.sh
/usr/lib/rpm/kmod.prov
/usr/lib/rpm/macros.d/macros.dwz
/usr/lib/rpm/macros.d/macros.fedora-misc
/usr/lib/rpm/macros.d/macros.fedora-misc-srpm
/usr/lib/rpm/macros.d/macros.forge
/usr/lib/rpm/macros.d/macros.kernel-srpm
/usr/lib/rpm/macros.d/macros.ldc-srpm
/usr/lib/rpm/macros.d/macros.ldconfig
/usr/lib/rpm/macros.d/macros.mono-srpm
/usr/lib/rpm/macros.d/macros.nodejs-srpm
/usr/lib/rpm/macros.d/macros.valgrind-srpm
/usr/lib/rpm/macros.d/macros.vpath
/usr/lib/rpm/redhat
/usr/lib/rpm/redhat/brp-ldconfig
/usr/lib/rpm/redhat/brp-mangle-shebangs
/usr/lib/rpm/redhat/config.guess
/usr/lib/rpm/redhat/config.sub
/usr/lib/rpm/redhat/dist.sh
/usr/lib/rpm/redhat/find-provides
/usr/lib/rpm/redhat/find-requires
/usr/lib/rpm/redhat/gpgverify
/usr/lib/rpm/redhat/macros
/usr/lib/rpm/redhat/redhat-annobin-cc1
/usr/lib/rpm/redhat/redhat-annobin-plugin-select.sh
/usr/lib/rpm/redhat/redhat-annobin-select-annobin-built-plugin
/usr/lib/rpm/redhat/redhat-annobin-select-gcc-built-plugin
/usr/lib/rpm/redhat/redhat-hardened-cc1
/usr/lib/rpm/redhat/redhat-hardened-ld
/usr/lib/rpm/redhat/rpmrc
/usr/share/doc/redhat-rpm-config
/usr/share/doc/redhat-rpm-config/buildflags.md
```

確かに話題にしていた`/usr/lib/rpm/redhat/redhat-hardened-cc1`が含まれているのがわかる

## `/usr/lib/rpm/redhat/redhat-hardened-cc1`の中身

```
[yumetodo@yumetodo-vm-almalinux8-rvm ~]$ cat /usr/lib/rpm/redhat/redhat-hardened-cc1
*cc1_options:
+ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fPIE}}}}}}
```

実に記号に満ち溢れていてよくわからない。しかしどうもPICとかPIEとかいうワードが見える。

PIC (Position Independent Code:位置独立コード), PIE (Positon Independent Executable) についての詳細を言及するのは避けて

https://tanakamura.github.io/pllp/docs/pic_pie.html

に解説を譲ることとするが、`.so`(共有ライブラリ)のためだったり、他のプロセスからのメモリー改ざんに対抗するASLR(アドレス空間配置のランダム化)のために用いられる。

さて、記号たちを読解していく。最初さっぱりわからないと社内Slackで書いたところ、社内のC++有識者から

>そもそも"%{!"でググった。
>https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html
>こんなのがあるんですね。知らなかった。

という情報提供があった。これを手がかりに読み進める。

<blockquote>
<dl>
<dt>%{!S:X}</dt>
<dd>Substitutes <code>X</code>, if the <code>-S</code> switch is not given to GCC.</dd>
</dl>
</blockquote>

```
%{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fPIE}}}}}}
```

は言い換えると

もし以下のオプションがいずれも付与されていなければ

- `-r`
- `-fpie`
- `-fPIE`
- `-fpic`
- `-fPIC`
- `-fno-pic`

 `-fPIE`を渡す、と読める。

雰囲気的には明示的にPICにしたくないか、すでにPIC/PIEにするオプションが渡されてるときは何もせず、そうじゃなかったら`-fPIE`を指定するというように見える

## `/usr/lib/rpm/redhat/redhat-hardened-cc1`を誰が要求しているのか

gem insatllする時に要求されたということはどうも自作したrubyのrpmに原因があると推論できる。作ったrpmをバラして見てみる。

```
[yumetodo@yumetodo-vm-almalinux8-rvm tmp]$ rpm2cpio ../ruby-19-1.9.3-2.el8.x86_64.rpm  | cpio -id
35231 ブロック
[yumetodo@yumetodo-vm-almalinux8-rvm tmp]$ grep -r "redhat-hardened-cc1" .
./usr/local/lib/ruby/1.9.1/x86_64-linux/rbconfig.rb:  CONFIG["configure_args"] = " '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--program-prefix=' '--disable-dependency-tracking' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64' '--libexecdir=/usr/libexec' '--localstatedir=/var' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--prefix=/usr/local' '--enable-shared' '--disable-rpath' '--disable-install-rdoc' '--with-opt-dir=/usr/local/openssl_1_0_2/' '--without-X11' '--without-tk' '--bindir=/usr/local/bin' '--includedir=/usr/local/include/ruby' '--libdir=/usr/local/lib' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'CFLAGS=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wall -fno-strict-aliasing' 'LDFLAGS=-Wl,-rpath,/usr/local/openssl_1_0_2/lib/,-rpath,/usr/local/libxml2_2_8_0/lib/' 'CXXFLAGS=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'"
./usr/local/lib/ruby/1.9.1/x86_64-linux/rbconfig.rb:  CONFIG["CXXFLAGS"] = "-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection"
./usr/local/lib/ruby/1.9.1/x86_64-linux/rbconfig.rb:  CONFIG["CFLAGS"] = "-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wall -fno-strict-aliasing -fPIC"
```

`-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1`という指定が見える。

そして冒頭の

```
compiling bcrypt_ext.c
gcc: 致命的エラー: cannot read spec file ‘/usr/lib/rpm/redhat/redhat-hardened-cc1’:
```

につながるのであろう。