# 크로스 컴파일러 사용법

크로스 컴파일러는 한 시스템(호스트)에서 실행되는 프로그램이 다른 시스템(타겟)에서 실행될 수 있도록 바이너리를 생성한다. Yocto 프로젝트에서는 크로스 컴파일러를 이용해 다양한 임베디드 시스템을 위한 소프트웨어를 빌드할 수 있다.

#### 크로스 컴파일러 설정

Yocto 프로젝트에서 제공하는 환경을 통해 크로스 컴파일러를 설정할 수 있다. 일반적으로 `source oe-init-build-env` 명령을 실행하여 빌드 환경을 초기화한다.

```sh
source oe-init-build-env
```

#### 크로스 컴파일러 사용

Yocto 프로젝트에서는 `bitbake` 명령어를 사용해 특정 레시피를 빌드함으로써 크로스 컴파일을 수행할 수 있다. 다음은 예제 명령어이다:

```sh
bitbake core-image-minimal
```

위 명령어는 `core-image-minimal`이라는 레시피를 빌드하여 타겟 시스템에 필요한 이미지를 생성한다.

#### 컴파일러 변수 환경 설정

컴파일 시 필요한 다양한 환경 변수를 설정해야 한다. 이는 크로스 컴파일러가 올바른 라이브러리와 헤더 파일을 찾을 수 있도록 돕는다.

주로 사용되는 환경 변수는 다음과 같다:

* `CC` (C 컴파일러)
* `CXX` (C++ 컴파일러)
* `LD` (링커)
* `AR` (아카이버)
* `AS` (어셈블러)

예를 들면, 다음과 같은 방식으로 환경 변수를 설정할 수 있다:

```sh
export CC=arm-poky-linux-gnueabi-gcc
export CXX=arm-poky-linux-gnueabi-g++
export LD=arm-poky-linux-gnueabi-ld
export AR=arm-poky-linux-gnueabi-ar
export AS=arm-poky-linux-gnueabi-as
```

#### 타겟 툴체인 설치

`populate_sdk` 클래스를 사용해 타겟 SDK를 생성할 수 있다. 다음 명령어는 SDK를 생성하여 포함된 크로스 컴파일러 툴체인을 설치한다:

```sh
bitbake core-image-minimal -c populate_sdk
```

SDK 설치는 앞서 생성된 SDK 설치 스크립트를 실행하면 된다:

```sh
sh ./tmp/deploy/sdk/poky-glibc-x86_64-core-image-minimal-cortexa7hf-neon-toolchain-2.5.sh
```

#### 크로스 컴파일 활용

일반적으로 Makefile 또는 CMake를 통해 프로젝트를 구성할 때 크로스 컴파일러를 지정한다.

#### Makefile 예제

Makefile을 사용해 크로스 컴파일을 수행하는 방법은 다음과 같다:

```makefile
CC=arm-poky-linux-gnueabi-gcc
CFLAGS=-O2

all: myapp

myapp: myapp.o
	$(CC)$(CFLAGS) -o myapp myapp.o

myapp.o: myapp.c
	$(CC)$(CFLAGS) -c myapp.c
```

#### CMake 예제

CMake를 사용한 크로스 컴파일 설정 예제는 다음과 같다:

```sh
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake ..
make
```

`toolchain.cmake` 파일 내용 예시:

```cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_COMPILER arm-poky-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER arm-poky-linux-gnueabi-g++)

set(CMAKE_FIND_ROOT_PATH /path/to/sysroot)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
```

이렇게 하면 CMake를 통해 크로스 컴파일을 위한 설정이 완료된다.

### 디버깅 크로스 컴파일된 코드

크로스 컴파일한 실행 파일을 디버깅하려면 타겟 시스템에서 실행하거나, qemu 같은 에뮬레이터를 사용하여 호스트 시스템에서 디버깅할 수 있다. 이는 gdb와 같은 디버거를 활용하여 가능한다.

#### GDB를 사용한 원격 디버깅

1. **타겟 시스템에서 실행:**

   * 타겟 시스템에서 `gdbserver`를 실행한다.

   ```sh
   gdbserver :1234 /path/to/executable
   ```
2. **호스트 시스템에서 원격 접속:**

   * 호스트 시스템에서 gdb를 실행하고 타겟 시스템에 원격으로 접속한다.

   ```sh
   gdb /path/to/executable
   (gdb) target remote <target-ip>:1234
   ```

### 최적화와 디버깅 옵션

크로스 컴파일 시 최적화와 디버깅을 위해 다양한 옵션을 사용할 수 있다. 다음은 몇 가지 주요 컴파일러 플래그이다:

* `-O2`: 최적화 옵션 (ex. `-O2`, `-O3`, `-Os` 등)
* `-g`: 디버깅 정보를 포함

예제:

```sh
export CFLAGS="-O2 -g"
```

### 크로스 컴파일 시 자주 발생하는 문제

1. **내부 또는 외부 링크 오류:**
   * 해결방안: 올바른 라이브러리 경로와 헤더 파일을 지정하고, 환경 변수를 설정한다.
2. **미스매치된 아키텍처:**
   * 해결방안: 타겟 아키텍처가 올바르게 설정되었는지 확인한다.
3. **패키지 의존성 문제:**
   * 해결방안: 필요한 모든 패키지와 라이브러리가 빌드 환경과 타겟 시스템에 존재하는지 확인한다.

### Referencing Additional Resources

Yocto 프로젝트와 크로스 컴파일에 대한 더 상세한 정보는 아래의 링크를 통해 얻을 수 있다:

* [Yocto Project Documentation](https://www.yoctoproject.org/docs)
* [GNU Compiler Collection (GCC) Documentation](https://gcc.gnu.org/onlinedocs/)
* [CMake Documentation](https://cmake.org/cmake/help/latest/)

이를 통해 크로스 컴파일러의 이해도와 활용 능력을 높일 수 있다.
