0. 시작해봅시다.
- 각 운영체제 (Linux, macOS, Windows) 별 러스트 설치법
- Hello, world! 프로그램 작성하기
러스트 패키지 매니저 및 빌드 도구인 cargo 사용법
1. rust 설치
rustup:러스트 버전 및 러스트 관련 도구를 관리하는 커맨드 라인 도구
- 러스트 컴파일러 최신 stable 버전을 설치
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
- 링커는 기본으로 설치되나, 러스트 컴파일 시에 링커를 실행할 수 없다는 에러가 나타나면 따로 설치하셔야 합니다.
- 이 에러는 C 컴파일러를 설치할 때 같이 설치되는 링커로 해결되므로 플랫폼에 맞는 C 컴파일러를 찾아서 설치하시기 바랍니다.
- 몇 가지 흔히 사용되는 러스트 패키지들이 C 코드를 이용하고 있기 때문에 C 컴파일러가 필요할 수도 있습니다.
- macOS에서는 아래와 같이 실행하여 C 컴파일러를 설치할 수 있습니다:
xcode-select --install
- Linux 사용자의 경우 배포판의 문서에 의하면 일반적으로 GCC나 Clang이 설치되어 있습니다. 예를 들어 우분투 사용자라면 build-essential 패키지를 설치할 수 있습니다.
2. Hellow world
- Note:
- 이 책은 커맨드 라인 위주로 설명하고 있습니다.
- IDE (통합 개발 환경) 를 사용하실 분은 애용하는 IDE를 사용하셔도 좋습니다.
2.2. 러스트 프로그램 작성하고 실행하기
# main.rs
fn main() {
println!("Hello, world!");
}
- 러스트 파일은 항상 .rs 확장자로 끝납니다.
- Linux, macOS 사용자는 다음 명령어를 입력하여 컴파일하고 실행할 수 있습니다:
rustc main.rs
./main
2.2.1. rustc VS Cargo
- 간단한 프로그램에는 rustc를 사용하는 것도 좋습니다.
- 다만 프로젝트가 커질수록 관리할 옵션이 많아지고, 코드 배포도 점점 번거로워지겠죠. 다음 내용에서 소개할 카고 (Cargo) 가 바로 이러한 문제를 해결
- 간단히 말해,
rustc는 Rust 코드를 컴파일하는 도구이고, Cargo는 그런 컴파일을 포함하여 Rust 프로젝트 전체를 효율적으로 관리하는 도구
- Cargo를 사용하면 프로젝트 관리가 훨씬 수월해지며, Rust 개발자들에게 필수적인 도구로 여겨집니다.
2.2.1.1.rustc
rustc는 Rust 프로그래밍 언어의 공식 컴파일러
rustc는 소스 코드를 분석하고, 타입을 체크하며, 최적화된 기계 코드로 변환하는 일련의 과정을 수행
rustc는 직접적으로 사용될 수 있으며, Rust의 복잡한 특성과 메모리 안전성을 강화하는 다양한 기능을 제공
2.2.1.2. Cargo
- Cargo는 Rust의 패키지 매니저 겸 빌드 시스템
Cargo.toml 설정 파일을 사용하여
- 프로젝트의 의존성을 관리하고, 빌드 프로세스를 자동화
- Cargo는
rustc를 내부적으로 사용하여 코드를 컴파일하지만, 사용자는 보통 Cargo를 통해 간접적으로 rustc를 사용합니다.
- Cargo는 프로젝트의 의존성을 다운로드하고, 컴파일하며, 테스트를 실행하고, 패키지를 게시하는 일련의 작업을 쉽고 효율적으로 수행할 수 있게 해 줍니다.
2.2.1.3. rustc와 Cargo의 비교
- 기능성:
rustc는 단순히 Rust 코드를 컴파일하는 역할을 하며, Cargo는 이 컴파일 과정을 포함한 프로젝트 전체의 빌드 및 관리를 담당
- 사용 용도:
rustc는 주로 낮은 수준의 컴파일 설정이나 특수한 경우에 사용될 수 있으며, Cargo는 Rust 프로젝트의 일상적인 개발과 관리에 사용됩니다.
- 사용자 인터페이스:
rustc는 커맨드 라인 옵션을 통해 직접 조작되는 반면, Cargo는 프로젝트 설정 파일을 통해 간접적으로 rustc를 조작하고 추가적인 기능(예: 의존성 관리, 패키지 배포)을 제공
2.3. 러스트 프로그램 뜯어보기
- Note:
- 여러분이 러스트 프로젝트의 코드를 표준 스타일로 통일시키고 싶다면, 코드를 특정 스타일로 포맷팅해주는 rustfmt라는 이름의 자동 포맷팅 도구를 사용할 수 있습니다 (더 자세한 사항은 부록 D에 있습니다.)
- 러스트 팀은 이 도구를 rustc처럼 기본 러스트 배포에 포함시켰으므로, 이미 여러분의 컴퓨터에 설치되어 있습니다!
- 러스트에서는 탭 대신 스페이스 4칸을 사용합니다.
println!는 러스트의 매크로 호출 코드
- 이 코드가 함수 호출 코드였다면 ! 없이 println이라고 되어 있었을 것
- 매크로는 19장에서 자세히 다루며, 지금은 !가 붙으면 함수가 아니라 매크로 호출 코드이고, 매크로는 함수와 항상 같은 규칙을 따르지는 않는다는 것만 알아두자!
- 마지막으로, 이 라인은 세미콜론(;)으로 끝납니다. 이 표현식이 끝났으며 다음 표현식이 시작될 준비가 됐다는 표시지요.
- 러스트 코드의 거의 모든 라인이 세미콜론으로 끝납니다.
2.4. 컴파일과 실행은 별개의 과정입니다
rustc main.rs
- rustc 명령어에 소스 파일명을 넘겨주어 컴파일해야 하는 과정
- 소스 파일 컴파일에 성공하면 실행 가능한 바이너리를 만들어 냅니다.
main 이라는 이름의 바이너리를 만들어 냅니다. (리눅스와 맥에서는)
- C나 C++ 을 다뤄보셨다면 gcc나 clang 사용 방법과 비슷
./main
- 실행하는 방법임.
- 러스트는 AOT(ahead-of-time-compiled) 언어로, 컴파일과 실행이 별개인 대신 여러분의 프로그램을 컴파일하여 만든 실행 파일을 러스트가 설치되지 않은 곳에서도 실행할 수 있습니다.
3. cargo를 사용해봅시다!
- 카고 (Cargo) : 러스트 빌드 시스템 및 패키지 매니저
- 이 도구는 코드 빌드나, 코드 작성에 필요한 외부 라이브러리(dependency)를 다운로드할 때나, 라이브러리를 제작할 때 겪는 귀찮은 일들을 상당수 줄여주는 편리한 도구
- 앞으로 외부 라이브러리는 의존성 (dependency) 이라고 지칭!
3.1. 카고로 프로젝트 생성하기
cargo new hello_cargo (새 프로젝트 생성)
- 디렉터리로 이동해 파일을 살펴보면 Cargo.toml 파일과 src 디렉터리를 확인할 수 있으며, src 디렉터리 내에는 main.rs 파일이 있는 것도 볼 수 있습니다.
- 그 외에도
.gitignore 파일과 함께 새 Git 저장소가 초기화됩니다.
- 여러분이 이미 Git 저장소가 있는 디렉터리에서 cargo new를 실행시킨다면 Git 파일들은 생성되지 않을 것입니다.
- 이 동작은 cargo new --vcs=git 명령을 통해 덮어쓸 수 있습니다.
# Cargo.toml
[package] # section header
# 아래는 카고가 코드를 컴파일하는데 필요한 설정 정보
name = "hello_cargo"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
# 러스트에서는 코드 패키지를 크레이트 (crate) 라고 부릅니다.
- 이 파일은 TOML (Tom’s Obvious, Minimal Language) 포맷으로 되어있고, 이 포맷은 카고 설정에서 사용하는 포맷입니다.
- 카고는 소스 파일이 src 내에 있다고 예상합니다.
- 최상위 프로젝트 디렉터리를 README, 라이선스, 설정 파일 등 코드 자체와는 관련 없는 파일들을 저장하는 데 사용됩니다.
- 이처럼 카고는 각각의 파일을 알맞은 위치에 배치하여, 여러분이 프로젝트를 조직화하는 걸 돕습니다.
3.2. 카고로 프로젝트를 빌드하고 실행하기
cargo build (프로젝트 빌드)
- 처음 cargo build 명령어를 실행하면 최상위 디렉터리에
Cargo.lock 파일이 생성될 텐데,
- 이 파일은 프로젝트에서 사용하는 의존성(dependencies)의 정확한 버전을 자동으로 기록해 두는 파일이니 여러분이 직접 수정할 필요는 없습니다.
- 물론 이번 프로젝트는 의존성을 갖지 않으므로 현재는 파일에 특별한 내용이 없습니다.
- 이 명령어는 현재 디렉터리가 아닌
projects/hello_cargo/target/debug/hello_cargo 에 실행 파일(바이너리)을 생성
- 기본 빌드가 디버그 빌드기 때문에, 카고는 debug라는 디렉터리에 바이너리를 생성
- 실행 파일(바이너리)은 다음 명령어로 실행할 수 있습니다:
./target/debug/hello_cargo
cargo run (프로젝트 빌드 및 실행 한번에)
cargo build + ./target/debug/hello_cargo 을 한번에 수행하는 것
- 대부분의 개발자들이
cargo run을 이용합니다.
- 출력 내용에 hello_cargo를 컴파일 중이라는 내용이 없는 걸 눈치채셨나요?
- 이는 카고가 파일 변경 사항이 없음을 알아채고 기존 바이너리를 그대로 실행했기 때문
- 소스 코드를 수정한 뒤 명령어를 다시 실행해 보면, 프로젝트를 다시 빌드한 후에 바이너리를 실행함을 알 수 있습니다.
cargo check (바이너리를 생성하지 않고, 프로젝트의 에러를 체크할 수 있습니다.)
- 실행 파일은 생성하지 않고, 작성한 소스가 문제없이 컴파일되는지만 빠르게 확인하는 명령어
- 러스타시안은 대부분 주기적으로 이 명령어를 실행해 코드에서 컴파일 문제가 발생하지 않는지 확인하고, 실행 파일이 필요할 경우에만 cargo build를 사용합니다.
3.3. 릴리즈(배포) 빌드 생성하기
cargo build --release (배포 빌드)
- 일반 빌드와 차이점
- target/debug 가 아닌 target/release 에 실행 파일이 생성된다는 점
- 그리고 컴파일 시 최적화를 진행하여 컴파일이 오래 걸리는 대신 러스트 코드가 더 빠르게 작동하는 점
- 릴리즈 빌드가 더 빠르게 작동한다면, 왜 일반 빌드시에는 최적화를 진행하지 않을까요? 이에 대한 해답은 빌드가 두 종류로 나뉘게 된 이유이기도 한데, 개발 중에는 빌드가 잦으며 작업의 흐름을 끊지 않기 위해 빌드 속도 또한 빠를수록 좋지만, 배포용 프로그램은 잦은 빌드가 필요 없으며 빌드 속도보단 프로그램의 작동 속도가 더 중요하기 때문
- 이와 같은 이유로, 작성한 코드 작동 속도를 벤치마킹할 시에는 릴리즈 빌드를 기준으로 해야 한다는 것도 알아두시기 바랍니다.
3.4. 관례로서의 카고
- 카고는 단순한 프로젝트에서는 그냥 rustc만 사용할 때와 비교하여 큰 값어치를 못하지만,
- 프로그램이 더욱 복잡해지면 카고는 그 가치를 증명할 것입니다.
- 여러 개의 파일 혹은 의존성을 필요로 하는 복잡한 프로젝트에서는 카고가 빌드를 조정하게 하는 것이 훨씬 쉽습니다.
- 실제로 기존에 있던 러스트 프로젝트를 Git으로 가져와서, 해당 디렉터리로 이동하고, 빌드하는 과정은 다음과 같은 명령을 이용하면 됩니다.
$ git clone someurl.com/someproject
$ cd someproject
$ cargo build