Rust 에러 E0601: `main` function not found in crate (main 함수가 없음)
E0601은 Rust가 프로그램을 빌드하려고 했는데, 어디서 시작하는지 찾지 못했다는 뜻이에요. 모든 Rust 프로그램은 src/main.rs의 맨 바깥에 쓴, 이름이 정확히 main인 함수에서 시작해요. 그 함수가 없거나, 철자가 틀렸거나, 모듈 안에 들어가 있으면 이 에러가 나요. 튜토리얼이나 라이브러리 문서에서 코드 조각을 복사해 왔을 때 아주 흔하고, 언제나 금방 고칠 수 있어요. 이 페이지는 Rust 컴파일러 에러 해설의 일부예요.
에러 메시지
섹션 제목: “에러 메시지”error[E0601]: `main` function not found in crate `main` --> src/main.rs:7:2 |7 | } // ❌ 파일이 끝났는데, 어디에도 `fn main`이 없어요 | ^ consider adding a `main` function to `src/main.rs`메시지는 “크레이트 main에서 main 함수를 찾을 수 없다”는 뜻이고, 라벨은 “src/main.rs에 main 함수를 추가해 보라”고 해요.
이 에러를 내는 프로그램은 다음과 같아요.
fn total(prices: &[u32]) -> u32 { prices.iter().sum()}
fn average(prices: &[u32]) -> u32 { total(prices) / prices.len() as u32} // ❌ 파일이 끝났는데, 어디에도 `fn main`이 없어요무슨 뜻인가요
섹션 제목: “무슨 뜻인가요”^는 파일의 맨 끝, 마지막 } 바로 뒤를 가리켜요. 이상해 보이지만 말이 돼요. rustc는 fn main을 찾으면서 파일 전체를 읽었고, 찾지 못한 채 끝에 도착했어요. 가리킬 틀린 줄이 없는 거예요. 문제는 없는 줄이니까요.
메시지 속 크레이트 이름은 어떻게 빌드하느냐에 따라 달라요. 위 출력은 rustc src/main.rs로 만든 거라서, 크레이트 이름이 파일 이름을 따라 main이에요. cargo run으로 빌드하면 Cargo.toml에 있는 패키지 이름이 나와요. 예를 들면 `main` function not found in crate `shop`처럼요. 같은 에러이고, 고치는 법도 같아요.
멋진 장면은 많은데 “1막 1장”이 없는 연극 대본과 비슷해요. 배우들은 준비됐는데, 공연이 어디서 시작하는지 아무도 몰라요.
Rust가 이렇게 하는 이유
섹션 제목: “Rust가 이렇게 하는 이유”Rust 바이너리(실행하는 프로그램)에는 정해진 시작점이 하나 있어야 해요. 프로그램을 시작하면 운영체제가 main을 호출하고, 나머지는 모두 main이 호출하기 때문에 실행돼요. Rust는 추측하지 않아요. 파일의 첫 번째 함수도 아니고, start라는 함수도 아니고, Main도 아니에요. 이름은 정확히 main, 모두 소문자여야 하고, 크레이트의 맨 바깥에 있어야 해요.
그 자체로는 프로그램이 아닌 코드, 예를 들어 다른 코드가 가져다 쓰는 도우미 함수 모음은 라이브러리예요. 라이브러리에는 main이 없고, 대신 src/lib.rs에 써요. E0601은 코드는 멀쩡한데 크레이트 종류가 잘못됐다는 뜻일 때도 많아요. 바이너리 크레이트와 라이브러리 크레이트 함께 쓰기와 시작하기를 참고하세요.
고치는 방법
섹션 제목: “고치는 방법”방법 1: main 함수 추가하기(또는 철자 고치기)
섹션 제목: “방법 1: main 함수 추가하기(또는 철자 고치기)”대부분은 이 방법을 고르세요. 어딘가에서 함수들을 복사해 왔거나, 도우미 함수부터 쓰기 시작하고 아직 main을 안 쓴 경우예요. fn main()을 추가하고 거기서 코드를 호출하세요.
fn total(prices: &[u32]) -> u32 { prices.iter().sum()}
fn average(prices: &[u32]) -> u32 { total(prices) / prices.len() as u32}
fn main() { // ✅ 프로그램은 여기서 시작해요 let prices = [250, 199, 1200]; println!("합계: {}센트", total(&prices)); println!("평균: {}센트", average(&prices));}실행 결과:
합계: 1649센트평균: 549센트이미 main이 있다고요? 그럼 철자를 확인하세요. fn Main(), fn mian(), fn main_()은 모두 똑같은 E0601을 내요. Rust에게는 그냥 다른 함수일 뿐이니까요. 이름은 대소문자를 구분하고, 함수여야 해요. 괄호까지 붙인 fn main()이요.
방법 2: main을 모듈 밖으로 옮기기
섹션 제목: “방법 2: main을 모듈 밖으로 옮기기”메시지에 the main function must be defined at the crate level(main 함수는 크레이트 수준에 정의돼야 한다)이 있을 때 이 방법을 고르세요. main은 있지만 mod 안에 있어서, 실제로는 프로그램의 시작점이 아니라 app::main이에요.
error[E0601]: `main` function not found in crate `main` --> src/main.rs:5:2 |5 | } | ^ the main function must be defined at the crate level (in `src/main.rs`) |note: here is a function named `main` --> src/main.rs:2:5 |2 | pub fn main() { // ❌ 모듈 안이라서 맨 바깥이 아니에요 | ^^^^^^^^^^^^^ = note: you have one or more functions named `main` not defined at the crate level = help: consider moving the `main` function definitionsnote:는 “main이라는 함수가 여기 있다”, “크레이트 수준에 정의되지 않은 main 함수가 하나 이상 있다”는 뜻이고, help:는 “main 함수 정의를 옮겨 보라”고 해요. 문제가 되는 프로그램은 이래요.
mod app { pub fn main() { // ❌ 모듈 안이라서 맨 바깥이 아니에요 println!("가게 문을 여는 중..."); }}진짜 main은 맨 바깥에 두세요. 모듈 안의 코드는 그대로 둬도 돼요. run처럼 더 분명한 이름을 붙이고 main에서 호출하세요.
mod app { pub fn run() { println!("가게 문을 여는 중..."); }}
fn main() { // ✅ src/main.rs의 맨 바깥에 있어요 app::run();}실행 결과:
가게 문을 여는 중...다른 파일에 있는 모듈도 마찬가지예요. src/app.rs에 있는 pub fn main()은 app::main이지, 절대 시작점이 아니에요. 모듈을 참고하세요.
방법 3: 혼자 실행할 코드가 아니라면 라이브러리로 만들기
섹션 제목: “방법 3: 혼자 실행할 코드가 아니라면 라이브러리로 만들기”코드가 다른 코드에서 가져다 쓰는 도우미 모음이고, “실행”할 게 없을 때 이 방법을 고르세요. 라이브러리에는 main이 없어요. --lib로 프로젝트를 만드세요.
cargo new --lib cart # src/lib.rs를 만들어요: 라이브러리라서 main이 필요 없어요cargo new shop # fn main()이 있는 src/main.rs를 만들어요: 프로그램이에요도우미 함수는 src/lib.rs에 넣고, 다른 코드가 써도 되는 것에는 pub을 붙이고, cargo run 대신 테스트로 확인하세요.
pub fn total(prices: &[u32]) -> u32 { prices.iter().sum()}
#[cfg(test)]mod tests { use super::*;
#[test] fn adds_prices() { assert_eq!(total(&[3, 4]), 7); }}라이브러리에는 cargo build나 cargo test를 실행하세요. 거기서 cargo run은 안 돼요. error: a bin target must be available for `cargo run`이라고 나오는데, “이 패키지에는 프로그램이 없다”는 Cargo식 표현이에요. 둘 다 원한다면 src/lib.rs 옆에 src/main.rs를 추가하세요. 그 파일은 패키지 이름으로 라이브러리를 가져다 써요.
fn main() { let sum = cart::total(&[250, 199, 1200]); println!("합계: {}센트", sum);}이제 cargo run을 하면 합계: 1649센트가 출력돼요. 바이너리 크레이트와 라이브러리 크레이트 함께 쓰기와 테스트를 참고하세요.
자주 보게 되는 곳
섹션 제목: “자주 보게 되는 곳”문서나 튜토리얼의 코드 조각을 붙여 넣었을 때. 많은 예제가 전체 프로그램이 아니라 함수 하나나 struct만 보여 줘요. 그걸 src/main.rs에 붙여 넣으면 E0601이 나요. 해결: 무언가를 실행하는 줄은 fn main() { ... }으로 감싸고, 함수와 구조체는 그 밖에 두세요. (Rust Playground는 main이 없으면 알아채고 실행 대신 빌드를 제안해서, 거기서는 보통 이 에러를 보지 않아요.)
에디터가 main.rs의 마지막 줄을 빨갛게 표시할 때. rust-analyzer는 백그라운드에서 cargo check를 실행하기 때문에, 아직 도우미 함수를 쓰고 있는 동안에도 마지막 줄에 E0601이 보여요. 괜찮아요. fn main()을 추가하면 바로 사라져요.
src/bin/ 안의 추가 프로그램. src/bin/import.rs처럼 src/bin/에 있는 파일은 하나하나가 별도의 프로그램이라서, 각각 자기만의 fn main()이 필요해요. 해결: 그 파일에 main을 추가하거나, 공통 코드를 src/lib.rs로 옮기세요. 아래 Cargo Targets 링크를 참고하세요.
관련 에러
섹션 제목: “관련 에러”- E0425: cannot find value in this scope: 프로그램의 다른 곳에서 이름의 철자가 틀렸어요. 예를 들어
totl()을 호출한 경우예요. - E0433: failed to resolve:
main.rs가 모듈이나 라이브러리 크레이트를 찾지 못해요. 예를 들어 패키지 이름이 틀린cart::total이요. - E0603: item is private:
main이 라이브러리 함수를 찾았지만, 그 함수가pub이 아니에요. - E0463: can’t find crate:
use한 크레이트가Cargo.toml에 없어요. - 전체 컴파일러 에러: 에러 페이지 전체 목록이에요.
이해도 점검
섹션 제목: “이해도 점검”이해도 점검
1. src/main.rs에 fn Main() { ... }이 있어요. cargo run은 뭐라고 할까요?
2. 실행할 건 없고, 다른 코드가 쓸 도우미 함수를 쓰고 있어요. 올바른 구성은 무엇일까요?
3. rustc가 "the main function must be defined at the crate level"이라고 해요. 무엇이 문제일까요?
점수: 0 / 3
더 알아보기
섹션 제목: “더 알아보기”- E0601 — Rust error codes index (영어): 이 에러의 공식 설명이에요.
- Hello, World! — The Rust Programming Language 한국어판: 첫
main함수와, 모든 프로그램이 왜 거기서 시작하는지 알려 줘요. - 패키지와 크레이트 — The Rust Programming Language 한국어판: 바이너리 크레이트와 라이브러리 크레이트,
src/main.rs와src/lib.rs의 차이를 다뤄요. - Cargo Targets — The Cargo Book (영어): 라이브러리, 바이너리,
src/bin/, 그리고 Cargo가 각각을 어떻게 찾는지 설명해요. - Main functions — The Rust Reference (영어):
main을 어디에 정의할 수 있는지를 포함한 정확한 규칙이에요.