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を明示的に指定することで解消。