인프콘 2022 - Rust 크로스 플랫폼 프로그래밍

Chris Ohk
Chris OhkEngine Engineer em Momenti, Inc
Rust 크로스 플랫폼 프로그래밍
하나의 코드를 여기저기 써볼래요?
Momenti 옥찬호
옥찬호 Chris Ohk
• 현 Momenti Engine Engineer
• 전 Nexon Korea Game Programmer
• Microsoft Developer Technologies MVP
• C Korea Founder Administrator
• Reinforcement Learning KR Administrator
• IT 전문서 집필 및 번역 다수
• 게임샐러드로 코드 한 줄 없이 게임 만들기 2013
• 유니티 Shader와 Effect 제작 2014
• 2D 게임 프로그래밍 2014 , 러스트 핵심 노트 2017
• 모던 C 입문 2017 , C 최적화 2019
utilForever gmail.com
utilForever
• Rust 언어의 핵심 기능을 가볍게 살펴봅니다. 자세하게 공부하고 싶다면 공식 문서를 참고하세요.
https://doc.rust lang.org/book/
• 발표 시간을 맞추기 위해 크로스 플랫폼 프로그래밍을 설명할 때 라이브러리/바이너리 파일을 만드는 단계까지만 설명하며,
iOS 앱 또는 웹 사이트랑 연동하는 부분은 저장소에서 별도로 설명합니다.
• 발표 자료와 예제 코드는 다음 저장소에서 확인 가능합니다.
https://github.com/utilForever/2022 INFCON Rust CrossPlatform
들어가며
1
콘텐츠
목차
content
크로스 플랫폼 프로그래밍을 하게 된 이유
기존 개발 상황 및 문제점, 왜 Rust를 선택했는가
2 Rust 언어 소개
Rust 언어의 역사, 기본 문법 맛보기
3 Rust로 크로스 플랫폼 프로그래밍 해보기
Swift for iOS, WebAssembly for Web
4 몇 가지 팁들
애플리케이션 프리징, WebAssembly 디버깅
1
크로스 플랫폼 프로그래밍을 하게 된 이유
https://ppss.kr/archives/149603
• 여러 플랫폼에서 사용할 수 있는 코어 엔진을 만들어주세요.
• iOS
• Android
• Backend
• Web
• …
이직 후 첫번째 업무
• 똑같은 기능을 하는 엔진 코드가 여러 플랫폼에 각각 구현되어 있었다.
• iOS 앱 C Objective C 기반
• 프론트엔드 TypeScript 기반
• 새로운 기능을 구현하거나 기존 기능을 수정해달라는 요청이 들어오면,
• iOS 앱 C 코드를 구현한 뒤, Objective C 코드를 통해 앱에 적용한다.
• 프론트엔드 TypeScript 코드를 구현해 웹에 적용한다.
기존에는 어떻게 개발되고 있었는가
• 어떤 기능을 추가/삭제하거나 변경해야 할 때 지원하는 플랫폼마다 작업을 해줘야 한다.
• 유지보수 측면에서 비효율적이다.
• 지원하는 플랫폼이 늘어날수록 작업량이 늘어난다.
• 똑같은 기능을 수행했을 때 플랫폼마다 동작 결과가 달라질 수 있다.
• 플랫폼마다 서로 다른 사람이 구현하기 때문에 발생하는 문제다.
• 서로 다른 동작으로 인해 사용자에게 불편을 초래할 수 있다.
문제점
• 플랫폼마다 로직을 구현하지 않고, 한 곳에서 작업하면 좋겠다.
• 다양한 플랫폼에 어떻게 대응해야 할까?
• iOS 앱 Swift API 제공
• Android 앱 Kotlin API 제공
• 백엔드 Elixir API 제공
• 웹 사이트 웹어셈블리 바이너리 파일 제공
어떻게 개선할 것인가
• 다양한 언어를 지원하기 위한 API와 웹 어셈블리 코드를 만들 수 있는 언어
• C , Rust, Java, Go, …
• Rust를 선택한 이유
• 타입 안전성
• 메모리 안전성
• 동시성 프로그래밍 안전성
• FFI를 통해 API 지원을 쉽게 할 수 있음
• WebAssembly 바이너리를 쉽게 만들 수 있음
왜 Rust를 선택했는가
• 같은 동작을 하는 프로그램을 여러 플랫폼에서 사용할 수 있도록 만들고 있다.
• iOS 앱 Swift
• Android 앱 Kotlin
• 프론트엔드 TypeScript
• 백엔드 Elixir
• 각 플랫폼에서 사용자 입력에 따라 로직을 처리하고 결과물을 보여주기 위한 코드를 개별적으로 작성한다.
프로젝트 구조
코어 엔진
Rust
FFI
Foreign Function Interface
트랜스파일 Transpile
Swift API
Kotlin API
Elixir API
WebAssembly
ReactiveX
2
Rust 언어 소개
Rust란?
• https://www.rust lang.org/
• 모질라 재단에서 2010년 7월 7일 처음 발표
• 현재는 러스트 재단으로 독립해서 개발되고 있다.
• Rust 언어의 특징
• 안전한 메모리 관리
• 철저한 예외나 에러 관리
• 특이한 enum 시스템
• 트레이트
• 하이지닉 매크로
• 비동기 프로그래밍
• 제네릭
• let 키워드를 사용
• 변수의 자료형을 대부분 유추할 수 있다.
• 변수 숨김 Variable Shadowing 을 지원
• 변수의 이름은 언제나 snake case 형태로 짓는다.
• Rust에서 변수는 기본적으로 변경 불가 Immutable 타입이다.
• 변경 가능 Mutable 한 값을 원한다면 mut 키워드로 표시해줘야 한다.
Rust 기본 문법 변수
• 상수는 변수와 달리 반드시 명시적으로 자료형을 지정해야 한다.
• 상수의 이름은 언제나 SCREAMING SNAKE CASE 형태로 짓는다.
Rust 기본 문법 상수
• switch를 대체하는 구문
• 모든 케이스를 빠짐 없이 처리해야 한다.
Rust 기본 문법 match
• null을 쓰지 않고도 Nullable한 값을 표현할 수 있는 내장된 Generic 열거체
Rust 기본 문법 Option
• 실패할 가능성이 있는 값을 반환할 수 있도록 해주는 내장된 Generic 열거체
Rust 기본 문법 Result
• 소유자가 함수의 인자로 전달되면, 소유권은 그 함수의 매개 변수로 이동 Move 된다.
• 이동된 이후에는 원래 함수에 있던 변수는 더 이상 사용할 수 없다.
• Rust의 참조 규칙
• 단 하나의 변경 가능한 참조 또는 여러개의 변경 불가능한 참조만 허용하며, 둘 다는 안된다.
• 참조는 그 소유자보다 더 오래 살 수 없다.
Rust 기본 문법 소유권
• Rust의 컴파일러는 모든 변수의 생명 주기를 이해하며 참조가 절대로 그 소유자보다 더 오래 존재하지 못하도록 검증을 시도한다.
• 함수에서는 어떤 매개 변수와 리턴 값이 서로 같은 생명 주기를 공유하는지 식별할 수 있도록
심볼로 표시해 명시적으로 생명 주기를 지정할 수 있다.
Rust 기본 문법 생명 주기
• Rust에서는 어떠한 방법으로도 데이터와 동작의 상속이 불가능하다.
• 구조체는 부모 구조체로부터 필드를 상속받을 수 없다.
• 구조체는 부모 구조체로부터 함수를 상속받을 수 없다.
• 대신 Rust는 트레잇으로 다형성을 지원한다. 트레잇은 다른 트레잇의 메소드들을 상속받을 수 있다.
Rust 기본 문법 OOP
3
Rust로 크로스 플랫폼 프로그래밍 해보기
• 다양한 플랫폼에서 Rust 라이브러리에 있는 add 함수와 sub 함수를 호출해 결과를 받은 뒤 출력하는 예제를 만들어 보자.
무엇을 만들 것인가
Rust
Swift
WebAssembly
TypeScript
Objective C
• rust cross : 핵심 코드를 구현하는 크레이트. add 함수와 sub 함수를 구현한다.
• rust cross ios : Swift API를 만들기 위한 코드를 구현하는 크레이트.
• rust cross web : WebAssembly로 트랜스파일하기 위한 코드를 구현하는 크레이트.
프로젝트 구조
Root
rust cross
Core Code
rust cross ios
Swift API
rust cross web
WebAssembly
• 빈 디렉토리에 Cargo.toml 파일을 만든 뒤 다음과 같이 입력한다.
프로젝트 구조 잡기
• cargo new 명령을 통해 만들 수 있다.
• 라이브러리 프로젝트를 만들려면 lib를 붙어야 한다.
• 그렇지 않으면, 바이너리 파일을 생성하는 프로젝트가 만들어진다.
새 Rust 라이브러리 프로젝트 만들기
• 외부에서 사용할 수 있도록 pub 키워드를 붙이자.
• 구현을 완료했다면 cargo build release 명령을 통해 빌드가 되는지 확인한다.
rust cross : add/sub 함수 구현하기
• Xcode를 설치한다.
• App Store에서 설치할 수 있다.
• Xcode 빌드 툴을 설치한다.
• xcode select install
• 그리고 크로스 컴파일이 가능하도록 iOS 아키텍처를 추가한다.
• rustup target add aarch64 apple ios aarch64 apple ios sim x86 64 apple ios
• 크로스 컴파일을 쉽게 할 수 있도록 도와주는 툴인 cargo lipo를 설치한다.
• cargo install cargo lipo
rust cross ios : iOS를 위한 라이브러리 빌드 준비
• Cargo.toml 파일을 연 뒤, 다음과 같이 수정한다.
• 정적/동적 라이브러리를 만들기 위해 lib 의 crate type을 staticlib , cdylib 로 설정한다.
• rust cross 크레이트에 있는 함수들을 사용하므로 dependencies 에 추가한다.
rust cross ios : 프로젝트 설정
• 함수의 이름이 맹글링되지 않도록 # no mangle 을 추가한다.
맹글링 Mangling 이란 소스 코드에 선언된 함수나 변수의 이름을 컴파일 단계에서 일정한 규칙을 갖고 변형하는 걸 말한다.
rust cross ios : C 브릿지에서 호출할 코드 작성
• Rust에서 사용한 매개 변수 타입과 리턴 타입에 호환되는 타입을 사용해야 한다.
• 예 : i32 또는 i64 int
• 구현을 완료했다면 cargo lipo release 명령을 통해 라이브러리 파일 .a 가 생성되는지 확인한다.
rust cross ios : C 브릿지 헤더 파일 작성
• Rust로 WebAssembly 바이너리 파일을 빌드해주는 툴인 wasm pack을 설치한다.
• curl https://rustwasm.github.io/wasm pack/installer/init.sh sSf sh
• JavaScript 번들러를 설치하고 실행할 수 있도록 패키지 매니저인 npm을 설치한다.
• npm install npm latest g
rust cross web : WebAssembly를 위한 라이브러리 빌드 준비
• Cargo.toml 파일을 연 뒤, 다음과 같이 수정한다.
• 동적 시스템/러스트 라이브러리를 만들기 위해 lib 의 crate type을 cdylib , rlib 로 설정한다.
• rust cross 크레이트에 있는 함수들을 사용하므로 dependencies 에 추가한다.
• WebAssembly 빌드를 위해 wasm bindgen을 dependencies 에 추가한다.
rust cross web : 프로젝트 설정
• 필요할 경우 Wrapper로 처리할 수 있도록 # wasm bindgen 을 추가한다.
• 구현을 완료했다면 wasm pack build 명령을 통해 wasm 파일이 생성되는지 확인한다.
rust cross web : WebAssembly로 빌드할 코드 작성
4
몇 가지 팁들
애플리케이션 프리징 문제
• Swift 앱에서 어떤 동작을 수행하기 위해 UI에서 버튼을 누르면, 엔진에서 처리되는 동안에 앱이 멈추는 문제가 발생한다.
• 원인은 Swift에서 필요한 함수들을 직접 호출하며, 모든 함수 호출은 동기적으로 동작하기 때문이다.
Swift
Rust 인스턴스 포인터
Swift UI
Swift UI
Rust
Rust 코드
애플리케이션 프리징 문제
• 이를 해결하려면, 엔진에 대한 모든 요청을 처리하는 워커를 구현해 백그라운드 스레드에서 동작하게 만들어야 한다.
• 백그라운드 스레드에서 워커 Worker 를 통해 요청들을 Job Queue에 넣으면 작업을 비동기적으로 수행한다.
Rust 인스턴스 포인터
Swift UI
Swift UI
Rust
Swift
백그라운드 스레드
워커 Worker
Job Queue
Fetch
Process
Rust 코드
WebAssembly에서의 함수 맹글링 문제
• Rust WebAssembly로 빌드하면 함수 이름들이 맹글링된다.
• 맹글링된 함수 이름 때문에 콜 스택을 제대로 확인할 수 없는 문제가 있다.
WebAssembly에서의 함수 맹글링 문제
• 이 문제를 해결하려면 WebAssembly 코드를 배포하는 크레이트의 Cargo.toml에 각 빌드에 따른 설정을 해줘야 한다.
디버깅을 위해, dev 빌드에서 demangle name section을 true로 설정하고 wasm opt에 플래그 _g를 추가한다.
• 이제 wasm 파일이 빌드되면 웹쪽 코드에 pkg 폴더를 붙여넣기하고 실행하면 된다.
• npm을 실행했을 때 Failed to decode custom name section 2024365; ignoring Maximum call stack size exceeded
오류가 발생하는 경우가 있다. 이 때는 node를 실행할 때 stack size 10000을 추가해서 스택 크기를 늘려야 한다.
• 하지만 보안 이슈로 인해 NODE OPTIONS를 사용할 수는 없고, package.json에서 npm start에 해당하는 부분에 추가하면 된다.
• 심볼 정보를 전부 포함한 채로 실행하기 때문에 불러오는데 꽤 오랜 시간이 걸릴 수 있다. 인내하고 기다리자!
WebAssembly에서의 함수 맹글링 문제
• 이제 잘 실행되고 디맹글링된 함수 이름들을 볼 수 있다.
WebAssembly에서의 함수 맹글링 문제
모멘티와 함께 성장할 분들을 찾습니다!
https://rebrand.ly/momenti
감사합니다!
utilForever gmail.com
https://github.com/utilForever
Facebook, Twitter: utilForever
1 de 44

Mais conteúdo relacionado

Mais procurados(20)

임태현, 게임 서버 디자인 가이드, NDC2013임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013
devCAT Studio, NEXON20.1K visualizações
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
YEONG-CHEON YOU1.6K visualizações
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현
noerror7.7K visualizações
Massive service basicMassive service basic
Massive service basic
DaeMyung Kang11.1K visualizações
webservice scaling for newbiewebservice scaling for newbie
webservice scaling for newbie
DaeMyung Kang21.8K visualizações
How to build massive service for advanceHow to build massive service for advance
How to build massive service for advance
DaeMyung Kang13.2K visualizações
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012
devCAT Studio, NEXON6.1K visualizações
KGC 2014: 분산 게임 서버 구조론KGC 2014: 분산 게임 서버 구조론
KGC 2014: 분산 게임 서버 구조론
Hyunjik Bae5.2K visualizações
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용
흥배 최5.1K visualizações
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략
YEONG-CHEON YOU3.7K visualizações

Similar a 인프콘 2022 - Rust 크로스 플랫폼 프로그래밍(20)

DevOps with AWS EdgeDevOps with AWS Edge
DevOps with AWS Edge
GS Neotek149 visualizações
SOSCON 2017 - Backend.AISOSCON 2017 - Backend.AI
SOSCON 2017 - Backend.AI
Joongi Kim327 visualizações
React native developmentReact native development
React native development
SangSun Park1.2K visualizações
이클립스 플랫폼이클립스 플랫폼
이클립스 플랫폼
Kenu, GwangNam Heo216 visualizações
AngularJS In ProductionAngularJS In Production
AngularJS In Production
MooYeol Lee1.2K visualizações
Ansible과 CloudFormation을 이용한 배포 자동화Ansible과 CloudFormation을 이용한 배포 자동화
Ansible과 CloudFormation을 이용한 배포 자동화
AWSKRUG - AWS한국사용자모임6.7K visualizações
강좌 04 펌웨어 구조 설계강좌 04 펌웨어 구조 설계
강좌 04 펌웨어 구조 설계
chcbaram6K visualizações
웹 IDE 비교웹 IDE 비교
웹 IDE 비교
Junyoung Lee16.4K visualizações

Mais de Chris Ohk(20)

Momenti Seminar - 5 Years of RosettaStoneMomenti Seminar - 5 Years of RosettaStone
Momenti Seminar - 5 Years of RosettaStone
Chris Ohk1.3K visualizações
Momenti Seminar - A Tour of Rust, Part 2Momenti Seminar - A Tour of Rust, Part 2
Momenti Seminar - A Tour of Rust, Part 2
Chris Ohk622 visualizações
Momenti Seminar - A Tour of Rust, Part 1Momenti Seminar - A Tour of Rust, Part 1
Momenti Seminar - A Tour of Rust, Part 1
Chris Ohk795 visualizações
C++20 Key Features SummaryC++20 Key Features Summary
C++20 Key Features Summary
Chris Ohk9.9K visualizações
[NDC 2018] 유체역학 엔진 개발기[NDC 2018] 유체역학 엔진 개발기
[NDC 2018] 유체역학 엔진 개발기
Chris Ohk12.4K visualizações
My Way, Your WayMy Way, Your Way
My Way, Your Way
Chris Ohk1.7K visualizações

Último(8)

AD의 TAD와 협업.pptxAD의 TAD와 협업.pptx
AD의 TAD와 협업.pptx
Visual Tech Dev49 visualizações
Flutter & FirebaseFlutter & Firebase
Flutter & Firebase
Wonjun Hwang15 visualizações
이스티오 (Istio) 자습서 v0.5.0이스티오 (Istio) 자습서 v0.5.0
이스티오 (Istio) 자습서 v0.5.0
Jo Hoon695 visualizações
WebRTCWebRTC
WebRTC
Wonjun Hwang20 visualizações
CES 처음 가는 분을 위한 가이드CES 처음 가는 분을 위한 가이드
CES 처음 가는 분을 위한 가이드
Minsuk Lee626 visualizações

인프콘 2022 - Rust 크로스 플랫폼 프로그래밍

  • 1. Rust 크로스 플랫폼 프로그래밍 하나의 코드를 여기저기 써볼래요? Momenti 옥찬호
  • 2. 옥찬호 Chris Ohk • 현 Momenti Engine Engineer • 전 Nexon Korea Game Programmer • Microsoft Developer Technologies MVP • C Korea Founder Administrator • Reinforcement Learning KR Administrator • IT 전문서 집필 및 번역 다수 • 게임샐러드로 코드 한 줄 없이 게임 만들기 2013 • 유니티 Shader와 Effect 제작 2014 • 2D 게임 프로그래밍 2014 , 러스트 핵심 노트 2017 • 모던 C 입문 2017 , C 최적화 2019 utilForever gmail.com utilForever
  • 3. • Rust 언어의 핵심 기능을 가볍게 살펴봅니다. 자세하게 공부하고 싶다면 공식 문서를 참고하세요. https://doc.rust lang.org/book/ • 발표 시간을 맞추기 위해 크로스 플랫폼 프로그래밍을 설명할 때 라이브러리/바이너리 파일을 만드는 단계까지만 설명하며, iOS 앱 또는 웹 사이트랑 연동하는 부분은 저장소에서 별도로 설명합니다. • 발표 자료와 예제 코드는 다음 저장소에서 확인 가능합니다. https://github.com/utilForever/2022 INFCON Rust CrossPlatform 들어가며
  • 4. 1 콘텐츠 목차 content 크로스 플랫폼 프로그래밍을 하게 된 이유 기존 개발 상황 및 문제점, 왜 Rust를 선택했는가 2 Rust 언어 소개 Rust 언어의 역사, 기본 문법 맛보기 3 Rust로 크로스 플랫폼 프로그래밍 해보기 Swift for iOS, WebAssembly for Web 4 몇 가지 팁들 애플리케이션 프리징, WebAssembly 디버깅
  • 7. • 여러 플랫폼에서 사용할 수 있는 코어 엔진을 만들어주세요. • iOS • Android • Backend • Web • … 이직 후 첫번째 업무
  • 8. • 똑같은 기능을 하는 엔진 코드가 여러 플랫폼에 각각 구현되어 있었다. • iOS 앱 C Objective C 기반 • 프론트엔드 TypeScript 기반 • 새로운 기능을 구현하거나 기존 기능을 수정해달라는 요청이 들어오면, • iOS 앱 C 코드를 구현한 뒤, Objective C 코드를 통해 앱에 적용한다. • 프론트엔드 TypeScript 코드를 구현해 웹에 적용한다. 기존에는 어떻게 개발되고 있었는가
  • 9. • 어떤 기능을 추가/삭제하거나 변경해야 할 때 지원하는 플랫폼마다 작업을 해줘야 한다. • 유지보수 측면에서 비효율적이다. • 지원하는 플랫폼이 늘어날수록 작업량이 늘어난다. • 똑같은 기능을 수행했을 때 플랫폼마다 동작 결과가 달라질 수 있다. • 플랫폼마다 서로 다른 사람이 구현하기 때문에 발생하는 문제다. • 서로 다른 동작으로 인해 사용자에게 불편을 초래할 수 있다. 문제점
  • 10. • 플랫폼마다 로직을 구현하지 않고, 한 곳에서 작업하면 좋겠다. • 다양한 플랫폼에 어떻게 대응해야 할까? • iOS 앱 Swift API 제공 • Android 앱 Kotlin API 제공 • 백엔드 Elixir API 제공 • 웹 사이트 웹어셈블리 바이너리 파일 제공 어떻게 개선할 것인가
  • 11. • 다양한 언어를 지원하기 위한 API와 웹 어셈블리 코드를 만들 수 있는 언어 • C , Rust, Java, Go, … • Rust를 선택한 이유 • 타입 안전성 • 메모리 안전성 • 동시성 프로그래밍 안전성 • FFI를 통해 API 지원을 쉽게 할 수 있음 • WebAssembly 바이너리를 쉽게 만들 수 있음 왜 Rust를 선택했는가
  • 12. • 같은 동작을 하는 프로그램을 여러 플랫폼에서 사용할 수 있도록 만들고 있다. • iOS 앱 Swift • Android 앱 Kotlin • 프론트엔드 TypeScript • 백엔드 Elixir • 각 플랫폼에서 사용자 입력에 따라 로직을 처리하고 결과물을 보여주기 위한 코드를 개별적으로 작성한다. 프로젝트 구조 코어 엔진 Rust FFI Foreign Function Interface 트랜스파일 Transpile Swift API Kotlin API Elixir API WebAssembly ReactiveX
  • 14. Rust란? • https://www.rust lang.org/ • 모질라 재단에서 2010년 7월 7일 처음 발표 • 현재는 러스트 재단으로 독립해서 개발되고 있다. • Rust 언어의 특징 • 안전한 메모리 관리 • 철저한 예외나 에러 관리 • 특이한 enum 시스템 • 트레이트 • 하이지닉 매크로 • 비동기 프로그래밍 • 제네릭
  • 15. • let 키워드를 사용 • 변수의 자료형을 대부분 유추할 수 있다. • 변수 숨김 Variable Shadowing 을 지원 • 변수의 이름은 언제나 snake case 형태로 짓는다. • Rust에서 변수는 기본적으로 변경 불가 Immutable 타입이다. • 변경 가능 Mutable 한 값을 원한다면 mut 키워드로 표시해줘야 한다. Rust 기본 문법 변수
  • 16. • 상수는 변수와 달리 반드시 명시적으로 자료형을 지정해야 한다. • 상수의 이름은 언제나 SCREAMING SNAKE CASE 형태로 짓는다. Rust 기본 문법 상수
  • 17. • switch를 대체하는 구문 • 모든 케이스를 빠짐 없이 처리해야 한다. Rust 기본 문법 match
  • 18. • null을 쓰지 않고도 Nullable한 값을 표현할 수 있는 내장된 Generic 열거체 Rust 기본 문법 Option
  • 19. • 실패할 가능성이 있는 값을 반환할 수 있도록 해주는 내장된 Generic 열거체 Rust 기본 문법 Result
  • 20. • 소유자가 함수의 인자로 전달되면, 소유권은 그 함수의 매개 변수로 이동 Move 된다. • 이동된 이후에는 원래 함수에 있던 변수는 더 이상 사용할 수 없다. • Rust의 참조 규칙 • 단 하나의 변경 가능한 참조 또는 여러개의 변경 불가능한 참조만 허용하며, 둘 다는 안된다. • 참조는 그 소유자보다 더 오래 살 수 없다. Rust 기본 문법 소유권
  • 21. • Rust의 컴파일러는 모든 변수의 생명 주기를 이해하며 참조가 절대로 그 소유자보다 더 오래 존재하지 못하도록 검증을 시도한다. • 함수에서는 어떤 매개 변수와 리턴 값이 서로 같은 생명 주기를 공유하는지 식별할 수 있도록 심볼로 표시해 명시적으로 생명 주기를 지정할 수 있다. Rust 기본 문법 생명 주기
  • 22. • Rust에서는 어떠한 방법으로도 데이터와 동작의 상속이 불가능하다. • 구조체는 부모 구조체로부터 필드를 상속받을 수 없다. • 구조체는 부모 구조체로부터 함수를 상속받을 수 없다. • 대신 Rust는 트레잇으로 다형성을 지원한다. 트레잇은 다른 트레잇의 메소드들을 상속받을 수 있다. Rust 기본 문법 OOP
  • 23. 3 Rust로 크로스 플랫폼 프로그래밍 해보기
  • 24. • 다양한 플랫폼에서 Rust 라이브러리에 있는 add 함수와 sub 함수를 호출해 결과를 받은 뒤 출력하는 예제를 만들어 보자. 무엇을 만들 것인가 Rust Swift WebAssembly TypeScript Objective C
  • 25. • rust cross : 핵심 코드를 구현하는 크레이트. add 함수와 sub 함수를 구현한다. • rust cross ios : Swift API를 만들기 위한 코드를 구현하는 크레이트. • rust cross web : WebAssembly로 트랜스파일하기 위한 코드를 구현하는 크레이트. 프로젝트 구조 Root rust cross Core Code rust cross ios Swift API rust cross web WebAssembly
  • 26. • 빈 디렉토리에 Cargo.toml 파일을 만든 뒤 다음과 같이 입력한다. 프로젝트 구조 잡기
  • 27. • cargo new 명령을 통해 만들 수 있다. • 라이브러리 프로젝트를 만들려면 lib를 붙어야 한다. • 그렇지 않으면, 바이너리 파일을 생성하는 프로젝트가 만들어진다. 새 Rust 라이브러리 프로젝트 만들기
  • 28. • 외부에서 사용할 수 있도록 pub 키워드를 붙이자. • 구현을 완료했다면 cargo build release 명령을 통해 빌드가 되는지 확인한다. rust cross : add/sub 함수 구현하기
  • 29. • Xcode를 설치한다. • App Store에서 설치할 수 있다. • Xcode 빌드 툴을 설치한다. • xcode select install • 그리고 크로스 컴파일이 가능하도록 iOS 아키텍처를 추가한다. • rustup target add aarch64 apple ios aarch64 apple ios sim x86 64 apple ios • 크로스 컴파일을 쉽게 할 수 있도록 도와주는 툴인 cargo lipo를 설치한다. • cargo install cargo lipo rust cross ios : iOS를 위한 라이브러리 빌드 준비
  • 30. • Cargo.toml 파일을 연 뒤, 다음과 같이 수정한다. • 정적/동적 라이브러리를 만들기 위해 lib 의 crate type을 staticlib , cdylib 로 설정한다. • rust cross 크레이트에 있는 함수들을 사용하므로 dependencies 에 추가한다. rust cross ios : 프로젝트 설정
  • 31. • 함수의 이름이 맹글링되지 않도록 # no mangle 을 추가한다. 맹글링 Mangling 이란 소스 코드에 선언된 함수나 변수의 이름을 컴파일 단계에서 일정한 규칙을 갖고 변형하는 걸 말한다. rust cross ios : C 브릿지에서 호출할 코드 작성
  • 32. • Rust에서 사용한 매개 변수 타입과 리턴 타입에 호환되는 타입을 사용해야 한다. • 예 : i32 또는 i64 int • 구현을 완료했다면 cargo lipo release 명령을 통해 라이브러리 파일 .a 가 생성되는지 확인한다. rust cross ios : C 브릿지 헤더 파일 작성
  • 33. • Rust로 WebAssembly 바이너리 파일을 빌드해주는 툴인 wasm pack을 설치한다. • curl https://rustwasm.github.io/wasm pack/installer/init.sh sSf sh • JavaScript 번들러를 설치하고 실행할 수 있도록 패키지 매니저인 npm을 설치한다. • npm install npm latest g rust cross web : WebAssembly를 위한 라이브러리 빌드 준비
  • 34. • Cargo.toml 파일을 연 뒤, 다음과 같이 수정한다. • 동적 시스템/러스트 라이브러리를 만들기 위해 lib 의 crate type을 cdylib , rlib 로 설정한다. • rust cross 크레이트에 있는 함수들을 사용하므로 dependencies 에 추가한다. • WebAssembly 빌드를 위해 wasm bindgen을 dependencies 에 추가한다. rust cross web : 프로젝트 설정
  • 35. • 필요할 경우 Wrapper로 처리할 수 있도록 # wasm bindgen 을 추가한다. • 구현을 완료했다면 wasm pack build 명령을 통해 wasm 파일이 생성되는지 확인한다. rust cross web : WebAssembly로 빌드할 코드 작성
  • 37. 애플리케이션 프리징 문제 • Swift 앱에서 어떤 동작을 수행하기 위해 UI에서 버튼을 누르면, 엔진에서 처리되는 동안에 앱이 멈추는 문제가 발생한다. • 원인은 Swift에서 필요한 함수들을 직접 호출하며, 모든 함수 호출은 동기적으로 동작하기 때문이다. Swift Rust 인스턴스 포인터 Swift UI Swift UI Rust Rust 코드
  • 38. 애플리케이션 프리징 문제 • 이를 해결하려면, 엔진에 대한 모든 요청을 처리하는 워커를 구현해 백그라운드 스레드에서 동작하게 만들어야 한다. • 백그라운드 스레드에서 워커 Worker 를 통해 요청들을 Job Queue에 넣으면 작업을 비동기적으로 수행한다. Rust 인스턴스 포인터 Swift UI Swift UI Rust Swift 백그라운드 스레드 워커 Worker Job Queue Fetch Process Rust 코드
  • 39. WebAssembly에서의 함수 맹글링 문제 • Rust WebAssembly로 빌드하면 함수 이름들이 맹글링된다. • 맹글링된 함수 이름 때문에 콜 스택을 제대로 확인할 수 없는 문제가 있다.
  • 40. WebAssembly에서의 함수 맹글링 문제 • 이 문제를 해결하려면 WebAssembly 코드를 배포하는 크레이트의 Cargo.toml에 각 빌드에 따른 설정을 해줘야 한다. 디버깅을 위해, dev 빌드에서 demangle name section을 true로 설정하고 wasm opt에 플래그 _g를 추가한다. • 이제 wasm 파일이 빌드되면 웹쪽 코드에 pkg 폴더를 붙여넣기하고 실행하면 된다.
  • 41. • npm을 실행했을 때 Failed to decode custom name section 2024365; ignoring Maximum call stack size exceeded 오류가 발생하는 경우가 있다. 이 때는 node를 실행할 때 stack size 10000을 추가해서 스택 크기를 늘려야 한다. • 하지만 보안 이슈로 인해 NODE OPTIONS를 사용할 수는 없고, package.json에서 npm start에 해당하는 부분에 추가하면 된다. • 심볼 정보를 전부 포함한 채로 실행하기 때문에 불러오는데 꽤 오랜 시간이 걸릴 수 있다. 인내하고 기다리자! WebAssembly에서의 함수 맹글링 문제
  • 42. • 이제 잘 실행되고 디맹글링된 함수 이름들을 볼 수 있다. WebAssembly에서의 함수 맹글링 문제
  • 43. 모멘티와 함께 성장할 분들을 찾습니다! https://rebrand.ly/momenti