0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

acc/oj ワークフローで単一ファイル Rust + proconio をローカルテストする

0
Posted at

Python や C++ と同じディレクトリ構成(acc / online-judge-tools による 1 問題 1 ディレクトリ・単一ファイル形式)のまま、ローカルで proconio を含んだ Rust コード(main.rs)をテストするための設定メモ。

1. 背景・前提

  • cargo-compete は Rust 特化のツールであり、Cargo Workspace 前提の階層構造になるため、Python や C++ と同じリポジトリで共通管理しにくい。
  • 問題ごとに Cargo.toml を作らず、main.rs 単一ファイルのまま oj t でテストを行いたい。
  • rustc 単体実行では外部クレート(proconio 等)がデフォルトで解決できないため、リポジトリルートに 1 つだけ依存解決用のプロジェクトを用意してリンクする。

2. 環境構築

① 依存解決用 Cargo プロジェクトの作成

リポジトリルートに .atcoder_deps を作成し、必要なクレートを追加してビルドする。

# リポジトリルートで実行
cargo new --bin .atcoder_deps --name atcoder_deps
cd .atcoder_deps

# proconio (deriveマクロ含む) や ACL を追加
cargo add proconio --features derive
cargo add itertools ac-library-rs

# ビルドして target/release/deps を生成
cargo build --release

.gitignore の設定

肥大化するビルド成果物のみ除外する。

.atcoder_deps/target/

3. テストスクリプト(ojt.sh

C++ / Python / Rust の拡張子を自動判別してテストを実行するシェル関数。

ojt() {
    local target="$1"
    
    # 引数未指定時はカレントディレクトリのファイルを自動検出
    if [ -z "$target" ]; then
        if [ -f "main.py" ]; then target="main.py"
        elif [ -f "main.cpp" ]; then target="main.cpp"
        elif [ -f "main.rs" ]; then target="main.rs"
        else
            echo "[ERROR] No source file found (main.py, main.cpp, main.rs)"
            return 1
        fi
    fi

    local ext="${target##*.}"
    local bin="/tmp/a.out"

    case "$ext" in
        py)
            echo "[RUN] Python: $target"
            oj t -c "python3 $target" "${@:2}"
            ;;
        cpp|cc|cxx)
            echo "[BUILD & RUN] C++: $target"
            g++ -std=c++23 -O2 "$target" -o "$bin" && oj t -c "$bin" "${@:2}"
            ;;
        rs)
            echo "[BUILD & RUN] Rust: $target"
            
            local repo_root
            repo_root="$(git rev-parse --show-toplevel 2>/dev/null)"
            local deps_dir="${repo_root}/.atcoder_deps/target/release/deps"

            if [ -n "$repo_root" ] && [ -d "$deps_dir" ]; then
                # --edition 2021 を明示して外部クレートを探索パスに追加
                rustc --edition 2021 -O \
                    -L "dependency=$deps_dir" \
                    -L "crate=$deps_dir" \
                    "$target" -o "$bin" && oj t -c "$bin" "${@:2}"
            else
                echo "[WARN] .atcoder_deps not found. Building with standard rustc."
                rustc --edition 2021 -O "$target" -o "$bin" && oj t -c "$bin" "${@:2}"
            fi
            ;;
        *)
            echo "[ERROR] Unsupported file extension: .$ext"
            return 1
            ;;
    esac
}

4. ハマったポイント

発生したエラー

rustc コマンドで -L を指定したにもかかわらず、以下のエラーが発生した。

error[E0432]: unresolved import `proconio`
 --> main.rs:1:5
  |
1 | use proconio::input;
  |     ^^^^^^^^ use of unresolved module or unlinked crate `proconio`
  |
help: you might be missing a crate named `proconio`, add it to your project and import it in your code
  |
1 + extern crate proconio;

原因

  • rustc--edition を明示しない場合、デフォルトで旧式の Rust 2015 Edition としてコンパイルされる。
  • Rust 2015 では extern crate proconio; の宣言がないと外部クレートを直接 use できない。また、手続き型マクロの挙動も 2018 以降と異なる。

対処

  • rustc の引数に --edition 2021 を明示的に指定することで解消。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?