AtCoderの開発環境(c/c++20, python3)

# AtCoderの開発環境
メンテナンスをしたので内容を記事にします。
2024/11/21のバージョンです。  
今後、c/c++23などの対応でメインブランチの内容が変わる可能性はあります。  
- githubのリポジトリ
[AtCoder-dev](https://github.com/RubyLrving/AtCoder-dev)  

## 環境
c/c++23, python3, pypy3

## 外部モジュール
numpy

## 解説
自身で考察したc/c++, python3+numpy, pypy3の設定

```dockerfile: dockerfile
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.134.0/containers/cpp/.devcontainer/base.Dockerfile
ARG VARIANT="debian"
FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT}
# インタラクティブモードにならないようにする
ENV DEBIAN_FRONTEND=noninteractive

# 必要なパッケージのインストール
RUN apt-get update && \
    apt-get -y install --no-install-recommends \
    git gdb \
    # python pypy3
    python3-numpy \ 
    python3-pip pypy3 nodejs npm locales-all expect build-essential && \
    rm -rf /var/lib/apt/lists/*

# Pipのアップグレード
RUN pip3 install --upgrade pip

# 必要なツールのインストール
# online-judge-tools atcoder-cli atcoderでも使えるpythonのライブラリ
RUN pip3 install online-judge-tools && \ 
    npm install -g atcoder-cli --unsafe-perm && \
    rm -rf ~/.cache/pip && \
    npm cache clean --force

ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ=Asia/Tokyo

# C++でAtCoder Library(ACL)を使えるようにする
RUN git clone https://github.com/atcoder/ac-library.git /lib/ac-library
ENV CPLUS_INCLUDE_PATH /lib/ac-library

```

- image
microsoftが公開しているc/c++用のイメージです。  
c++20まで設定がされています。  
osのdebian11は、ubuntu24.04よりビルドの処理が軽い？気がするので選んでいます。 

```
FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT}
``` 

- `ENV DEBIAN_FRONTEND=noninteractive`
インタラクティブモード  
yes/noなどの対話モードへならないようにします。

- `apt-get update`
インストール可能なパッケージの「一覧」を更新する。    
- `-y`
全てyesを選択  
- `--no-install-recommends`  
「推奨」パッケージをインストールしません。  

```
apt-get -y install --no-install-recommends
```

- `locales-all`
全ての言語のlocaleをインストール。  

- `expect`
ExpectはLinuxのCLIコマンドを自動化する化するパッケージの一つです。

- `build-essential`
開発に必須のビルドツールを提供しているパッケージ。
gcc、g++、makeとかその他色々。

- `rm -rf /var/lib/apt/lists/*`
ここには `apt-get update` で取得したリポジトリのパッケージのリストが保存されています。
削除した方が軽くなります。

```
git gdb \
# python pypy3
python3-numpy \ 
python3-pip pypy3 nodejs npm locales-all expect build-essential && \
rm -rf /var/lib/apt/lists/*
```

- Pipのアップグレード  

```
RUN pip3 install --upgrade pip
```

- `online-judge-tools`  
atcoderのコンテストのサンプルテストをローカルで実行する時に役に立ちます。  
- `atcoder-cli`
コンテスト時にcppファイルを用意するのに役に立ちます。
- `rm -rf ~/.cache/pip`
pipを使用してできたキャッシュを削除します。
- `npm cache clean --force`


```
RUN pip3 install online-judge-tools && \ 
    npm install -g atcoder-cli --unsafe-perm && \
    rm -rf ~/.cache/pip && \
    npm cache clean --force
```

- C++でAtCoder Library(ACL)を使えるようにする
事前にgitをインストールしてます。
ac-libraryをダウンロードして、環境変数を設定します。

```
RUN git clone https://github.com/atcoder/ac-library.git /lib/ac-library
ENV CPLUS_INCLUDE_PATH /lib/ac-library
```

## 今後の改良点  
- c/c++23に対応
- 最新のpython3のバージョンに対応する
- 最新のpypy3のバージョンに対応する
- pypy3のNumPyに対応する

## 上記を行う為の課題  
- microsoftのimageはもう更新されないのでubuntuかdabianを自分で設定する
   - ubuntu:24.04
   - ubuntu:25.04
   - dabian:12
- ubuntu24.04ではonline-judge-toolsのインストールを工夫する必要がある
   - Python 3.12 以降で distutils が削除された
   - pip3を使用するために仮想環境を使用する
     `python3 -m venv /opt/venv`  
   - 仮想環境を有効にする
   　`. /opt/venv/bin/activate`  
- `devcontainer.json`にて、remoteUserを`ubuntu`にする

## 現時点での調整中  
下記のファイルはonline-judge-toolsのコマンドが動作しません。  
ubuntu24.04から`python3-distutils`がない為です。  
綺麗な解決策は浮かばないです。  

```dockerfile:dockerfile
# ベースイメージをUbuntu 24.04に設定
FROM ubuntu:24.04

# インタラクティブモードにならないようにする
ENV DEBIAN_FRONTEND=noninteractive

# 必要なパッケージのインストール
RUN apt-get update && \
    apt-get -y install --no-install-recommends \
    software-properties-common \
    git gdb \
    python3 python3-numpy python3-pip python3-venv \
    pypy3 nodejs npm locales-all expect build-essential && \
    rm -rf /var/lib/apt/lists/*

# Pipのアップグレード (externally-managed-environmentを回避)
RUN python3 -m venv /opt/venv && \
    . /opt/venv/bin/activate && \
    pip3 install --upgrade pip

# 必要なツールのインストール
RUN . /opt/venv/bin/activate && \
    pip3 install online-judge-tools && \ 
    npm install -g atcoder-cli --unsafe-perm && \
    rm -rf ~/.cache/pip && \
    npm cache clean --force

# GCCの最新バージョンをインストール (C++23対応)
RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test && \
    apt-get update && \
    apt-get -y install gcc-13 g++-13 && \
    update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 100 && \
    update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 100 && \
    rm -rf /var/lib/apt/lists/*

# ロケール設定
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ=Asia/Tokyo

# C++でAtCoder Library(ACL)を使えるようにする
RUN git clone https://github.com/atcoder/ac-library.git /lib/ac-library
ENV CPLUS_INCLUDE_PATH /lib/ac-library

```

Ubuntu 24.04以降のDockerイメージを使用する場合には、下記のようにremoteUserをubuntuに指定します。
これに２日ほど引っかかりました。

```json:devcontainer.json
{
	"name": "C++",
	"build": {
		"dockerfile": "./Dockerfile",
	},
	"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
    "features": {
        "ghcr.io/devcontainers/features/common-utils:2": {
            "installZsh": true,
            "configureZshAsDefaultShell": true,
            "installOhMyZsh": true,
            "installOhMyZshConfig": true,
            "upgradePackages": true,
            "nonFreePackages": false
        }
    },
	"remoteUser": "ubuntu"
}
```