🍵

Guix上でPCCを使ってTCCをコンパイル

2021/07/14に公開

はじめに

GuixPCCを使ってTCCをコンパイルしてみます

Guixのインストール

調べたらVirtual Boxにインストールしている方がいたので、私もVirtual Boxにインストールしてみました。
使用したイメージは
https://ftp.gnu.org/gnu/guix/guix-system-install-1.3.0.x86_64-linux.iso
です。

特に大きく嵌るところはなく、インストールはできました。

PCCのインストール

インストールは以下のコマンドでできます。

$ guix install pcc

バージョンは1.2.0がインストールされました。

$ pcc -v
Portable C Compiler 1.2.0.DEVEL 20161212 for x86_64-unknown-linux-gnu
error: no input files
$ 

TCCのビルド

ソースを取得します。バージョンは0.9.27が最新のようなのでこちらを使用します。

$ git clone https://repo.or.cz/tinycc.git
$ cd tinycc
$ git checkout release_0_9_27

./configureを以下のようにオプションを付けます。長いです。

./configure --cc=pcc --extra-cflags="-U __GNUC__ -I /home/USERNAME/.guix-profile/include -I /gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/include -I /gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/include-fixed -I /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/include"

改行を入れると以下のようになります。

./configure
--cc=pcc
--extra-cflags="
   -U __GNUC__
   -I /home/USERNAME/.guix-profile/include
   -I /gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/include
   -I /gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/include-fixed
   -I /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/include"

--cc=pccでpccを指定します。
--extra-cflags=で必要なオプションを指定します。
必要なのはインクルードパスの指定と-U __GNUC____GNUC__を無効にします。

Makefileを修正します。
修正しないとリンクもpccで行うようになってしまうのでここはgnu ldを
使用するように修正しました。
(pccでもできるのかも知れませんがやり方がわかりませんでした)

Makefile
-	$(CC) -o $@ $^ $(LIBS) $(LDFLAGS) $(LINK_LIBTCC)
+	ld -plugin /gnu/store/jc90jrkd40az0zggw84s3ax6m351jlkg-gcc-10.3.0/libexec/gcc/x86_64-unknown-linux-gnu/10.3.0/liblto_plugin.so -plugin-opt=/gnu/store/jc90jrkd40az0zggw84s3ax6m351jlkg-gcc-10.3.0/libexec/gcc/x86_64-unknown-linux-gnu/10.3.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccrMnSjy.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -m elf_x86_64 -dynamic-linker /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 /home/USERNAME/.guix-profile/lib/crt1.o /home/USERNAME/.guix-profile/lib/crti.o /gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/crtbegin.o -L/home/USERNAME/.guix-profile/lib -L/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0 -L/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/../../.. -L/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib tcc.o libtcc.a -lm -ldl -lgcc --push-state --as-needed -lgcc_s --pop-state -L/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib -rpath=/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib -rpath=/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib -lgcc_s -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/crtend.o /home/USERNAME/.guix-profile/lib/crtn.o -o tcc

この修正はgcc -vでの出力をヒントにしています。
(collect2以降のパラメタ)

$ cat hello.c
#include <stdio.h>
int main(){
 printf("hello\n");
 return 0;
}
$ gcc -v hello.c
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/gnu/store/jc90jrkd40az0zggw84s3ax6m351jlkg-gcc-10.3.0/libexec/gcc/x86_64-unknown-linux-gnu/10.3.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: 
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.3.0 (GCC) 

<省略>

LIBRARY_PATH=/home/USERNAME/.guix-profile/lib/:/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/:/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/../../../:/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib
COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=x86-64'
 /gnu/store/jc90jrkd40az0zggw84s3ax6m351jlkg-gcc-10.3.0/libexec/gcc/x86_64-unknown-linux-gnu/10.3.0/collect2 -plugin /gnu/store/jc90jrkd40az0zggw84s3ax6m351jlkg-gcc-10.3.0/libexec/gcc/x86_64-unknown-linux-gnu/10.3.0/liblto_plugin.so -plugin-opt=/gnu/store/jc90jrkd40az0zggw84s3ax6m351jlkg-gcc-10.3.0/libexec/gcc/x86_64-unknown-linux-gnu/10.3.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccvPdxK1.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -m elf_x86_64 -dynamic-linker /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 /home/USERNAME/.guix-profile/lib/crt1.o /home/USERNAME/.guix-profile/lib/crti.o /gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/crtbegin.o -L/home/USERNAME/.guix-profile/lib -L/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0 -L/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/../../.. -L/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib /tmp/ccWq1lj0.o -lgcc --push-state --as-needed -lgcc_s --pop-state -L/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib -rpath=/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib -rpath=/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib -lgcc_s -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/crtend.o /home/USERNAME/.guix-profile/lib/crtn.o
COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=x86-64'
$ 

makeして、出来上がったtccを確認してみます。

$ make
...
$ readelf -p .comment tcc

String dump of section '.comment':
  [     0]  GCC: (GNU) 7.5.0
  [    11]  GCC: (GNU) 10.3.0
  [    23]  PCC: Portable C Compiler 1.2.0.DEVEL 20161212 for x86_64-unknown-linux-gnu

PCC: Portable C Compiler 1.2.0.DEVEL 20161212 for x86_64-unknown-linux-gnu
と出ているので、期待通りPCCでコンパイルできているようです。
GCC: (GNU) 7.5.0GCC: (GNU) 10.3.0はリンクしたライブラリが
GCCでビルドされているものだからですかね????

作成したTCCでコンパイル

作成したtccでコンパイルをしてみます。
リンクは GNU ldを使用します。

$ cat hello.c
#include <stdio.h>
int main(){
 printf("hello tcc\n");
 return 0;
}
$ ./tcc -c -I/gnu/store/chbr585py6b9fx2gsr59dpj8s4cjg1d7-tcc-0.9.27/lib/tcc/include hello.c
$ ld -plugin /gnu/store/jc90jrkd40az0zggw84s3ax6m351jlkg-gcc-10.3.0/libexec/gcc/x86_64-unknown-linux-gnu/10.3.0/liblto_plugin.so -plugin-opt=/gnu/store/jc90jrkd40az0zggw84s3ax6m351jlkg-gcc-10.3.0/libexec/gcc/x86_64-unknown-linux-gnu/10.3.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccrMnSjy.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -m elf_x86_64 -dynamic-linker /gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/ld-linux-x86-64.so.2 /home/USERNAME/.guix-profile/lib/crt1.o /home/USERNAME/.guix-profile/lib/crti.o /gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/crtbegin.o -L/home/USERNAME/.guix-profile/lib -L/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0 -L/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/../../.. -L/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib hello.o -lgcc --push-state --as-needed -lgcc_s --pop-state -L/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib -rpath=/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib -rpath=/gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib -lgcc_s -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /gnu/store/rgj02zlyqrg7ygcynwv8w35nc5czxi9l-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/crtend.o /home/USERNAME/.guix-profile/lib/crtn.o
$ ./a.out
hello tcc

できました!

まとめ

pccでtccをコンパイルする時は、

  • ./configureで必要な設定を行い
  • Makefileのリンク箇所を修正
    する必要がある。
    リンク時のパラメタはgcc -v [適当な*.cファイル]の出力を参考にする。

Discussion