さくらのレンタルサーバでHTTPS (TLS) 対応のGitをビルドした記録

# はじめに

さくらのレンタルサーバにはデフォルトでGitが入っていますが、サーバによってはバージョンが古く、新しいGitを使いたいときのためのメモです。
契約サーバによっては、デフォルトでGit 2.19とかが入っているようですが（何台かお試し契約して確認）、システムのGitだと ``git add -p`` ができないっぽくて地味につらい。

```terminal:terminal
$ git version
git version 2.7.0
```

な環境から始めます。

なお、このサーバはFreeBSDなので、Linuxとはちょっとコマンドが違う部分があります。
例えば、Linuxでいうところの``make``（GNU make）は ``gmake`` です。

# 必要なもの

- Gitのソースコード
- curlのソースコード
- OpenSSLのソースコード

Gitを何も考えずにビルドすると、HTTPSをサポートしないバイナリが生成されます。（おそらくシステムのlibcurlが古いから？）
よって、HTTPSをサポートする新しいcurl (libcurl) をビルドしないといけません。
ところが、TLSをサポートするcurlをビルドするにはOpenSSLも新しいものを入れないといけません。

# 手順

## OpenSSL

```terminal:terminal
$ openssl version
OpenSSL 1.0.2o  27 Mar 2018
```

などと出るのですが、ライブラリやヘッダファイルは「0.9.8」であるらしく、このままだとうまくいきません。
よって、まずはOpenSSLを自前で入れます。

```terminal:terminal
# 作業場所は適当に
$ mkdir -p ~/.local/src
$ cd ~/.local/src
$ wget https://www.openssl.org/source/openssl-1.0.2q.tar.gz
$ tar xvfz openssl-1.0.2q.tar.gz
$ cd openssl-1.0.2q
$ ./config --prefix=${HOME}/.local -fPIC
$ gmake
$ gmake install
```

↑で -fPIC をつけておかないと、次のcurlのビルドで引っかかります。
バージョンを確認。

```terminal:terminal
$ ~/.local/bin/openssl version
OpenSSL 1.0.2q  20 Nov 2018
```

第一段階突破。

## curl

```terminal:terminal
$ cd ~/.local/src
$ wget https://curl.haxx.se/download/curl-7.63.0.tar.gz
$ tar xvfz curl-7.63.0.tar.gz
$ cd curl-7.63.0
$ env LIBS=-L${HOME}/.local/lib CFLAGS=-I${HOME}/.local/include CPPFLAGS=-I${HOME}/.local/include ./configure --prefix=${HOME}/.local
```

環境変数を指定して、先程のOpenSSLのライブラリとヘッダを参照させます。

```terminal:terminal
checking for OpenSSL headers version... 1.0.2 - 0x1000211fL
checking for OpenSSL library version... 1.0.2
checking for OpenSSL headers and library versions matching... yes
```

と出ることを確認しましょう（オプションが違うと、0.9.8とか出てきてしまいます）。
あとは続きを。

```terminal:terminal
$ gmake
$ gmake install
```

確認。

```terminal:terminal
$ ~/.local/bin/curl --version
curl 7.63.0 (x86_64-unknown-freebsd9.1) libcurl/7.63.0 OpenSSL/1.0.2q zlib/1.2.7
Release-Date: 2018-12-12
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP UnixSockets HTTPS-proxy
```

バージョンが7.6.30になっていることと、Featuresに「TLS-SRP」が入っていることを確認します。
さらに、以下がエラーにならずに実行できれば良いです。

```terminal:terminal
# TLS1.2をテスト
$ ~/.local/bin/curl -s -v --tlsv1.2 https://www.google.com/ > /dev/null
```

## Git

```terminal:terminal
$ cd ~/.local/src
$ wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.19.2.tar.gz
$ tar xvfz git-2.19.2.tar.gz
$ cd git-2.19.2
$ ./configure --prefix=${HOME}/.local --with-openssl=${HOME}/.local --with-curl=${HOME}/.local
```

ここでは以下の表示を確認。オプションを間違えると -lcurl が no になります。

```terminal:terminal
configure: Setting OPENSSLDIR to /home/xxxx/.local
:
:
configure: Setting CURLDIR to /home/xxxx/.local
:
:
checking for curl_global_init in -lcurl... yes
checking for curl-config... curl-config
checking if Curl supports SSL... yes
```

ちなみに、以下でもビルドはできましたが、HTTPSアクセスができませんでした（HTTPSで接続しようとするとエラーメッセージを吐かずに死んでしまうというタチの悪さ…）。
ldd を見ると、場所の違うlibsslが2つリンクされていたりして、整合性の取れない状態になっているのかなと予想します。

```terminal:terminal
$ env LIBS=-L${HOME}/.local/lib ./configure --prefix=${HOME}/.local
```

続けます。

```terminal:terminal
$ gmake
$ gmake install
```

これでめでたくGitHubからクローンできるようになっているはず。

```terminal:terminal
$ ~/.local/bin/git version
git version 2.19.2
$ ~/.local/bin/git clone https://github.com/git/git.git
Cloning into 'git'...
:
:
Resolving deltas: 100% (193836/193836), done.
```

OK！
必要に応じて ~/.local/bin にパスを通してくださいませ。

# ちょっと引っかかる

ただし今のGitではコマンドのヘルプが見られません。

```terminal:terminal
$ gmake man
```

とやるとマニュアルをビルドできるはずですが、 ``asciidoc`` のエラーが出ます。そしてそれを入れようとしてハマっています…。

もう一点。

```terminal:terminal
$ ldd ~/.local/libexec/git-core/git-http-fetch
        libcurl.so.8 => /usr/local/lib/libcurl.so.8 (0x8009a0000)
        libz.so.6 => /lib/libz.so.6 (0x800c00000)
        libthr.so.3 => /lib/libthr.so.3 (0x800e14000)
        libc.so.7 => /lib/libc.so.7 (0x801036000)
        libcrypto.so.8 => /usr/local/ssl/lib/libcrypto.so.8 (0x801389000)
        libssl.so.8 => /usr/local/ssl/lib/libssl.so.8 (0x801752000)
```

システムのlibcurlとかlibsslにリンクしている…？
謎な現象なのですが、なぜか動いています。