RaspberryPi: Mac에서 크로스 컴파일 및 디버깅

RaspberryPi 프로그램을 Mac에서 컴파일 및 디버깅



RaspberryPi 프로그램을 Linux상에서 크로스 컴파일 & 디버그하는 기사는 보이지만, Mac상에서 이들을 실시하고 있는 것은 별로 보이지 않으므로, 비망록도 겸해 기록한다.

환경



Mac



macOS Catalina 10.15.7

RaspberryPi



옛날에 샀던 것. 버전 등은 아래와 같습니다. (이러한 확인 방법에 대해서는 참조 사이트 참조)
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 4.19.97+ #1294 Thu Jan 30 13:10:54 GMT 2020 armv6l GNU/Linux
pi@raspberrypi:~ $ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 10 (buster)
Release:    10
Codename:   buster
pi@raspberrypi:~ $ cat /proc/device-tree/model 
Raspberry Pi Model B Plus Rev 1.2

크로스 컴파일러 및 크로스 컴파일



거의, 이 기사에 따른다.

1 Command line tool 및 Homebrew를 인스톨
여기 대로.

2 wget 설치(옵션)
$ brew install wget

3 크로스 컴파일러 용 디렉토리의 작성
$ mkdir -p raspbian-sdk/{prebuilt,sysroot}

4 clang+llvm 다운로드 및 압축 해제
$ wget https://github.com/llvm/llvm-
project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-apple-darwin.tar.xz
$ tar -xzf clang+llvm-11.0.0-x86_64-apple-darwin.tar.xz -C "raspbian-sdk/prebuilt" --strip-components=1

5 binutils 설치
내 환경에서 v2.31 이상의 binutils는 잘 빌드 할 수 없으며 v2.30을 사용합니다.
$ wget http://ftp.gnu.org/gnu/binutils/binutils-2.30.tar.xz
$ tar -xzf binutils-2.30.tar.xz
$ cd binutils-2.30
$ brew install coreutils
$ ./configure --prefix="`/usr/local/bin/realpath ../raspbian-sdk/prebuilt`" \
    --target=arm-linux-gnueabihf \
    --enable-gold=yes \
    --enable-ld=yes \
    --enable-targets=arm-linux-gnueabihf \
    --enable-multilib \
    --enable-interwork \
    --disable-werror \
    --quiet
$ make && make install

6 첫번째 디렉토리로 돌아가기
$ cd ..

7 rsync 도입
Mac에 설치된 rsync에서는, 이 후에 실시하는 무언가의 옵션이 부족한 것 같다(어딘가의 기사에 있어).
$ brew install rsync

8 RaspberryPi에서 라이브러리와 헤더를 Mac에 복사
본제에서 그렇지만, RaspberryPi에는 avahi-daemon이 동작하는 설정을 하고 있으므로, IP 주소가 아니라, "raspberrypi.local"로 RaspberryPi를 지정하는 것이 가능.
$ /usr/local/bin/rsync -rzLR --safe-links \
    [email protected]:/usr/lib/arm-linux-gnueabihf \
    [email protected]:/usr/lib/gcc/arm-linux-gnueabihf \
    [email protected]:/usr/include \
    [email protected]:/lib/arm-linux-gnueabihf \
    raspbian-sdk/sysroot

9 크로스 컴파일용 스크립트 작성
$ vi raspbian-sdk/prebuilt/bin/arm-linux-gnueabihf-clang

arm-linux-gnueabihf-clang
#!/bin/bash
BASE=$(dirname $0)
SYSROOT="${BASE}/../../sysroot"
TARGET=arm-linux-gnueabihf
COMPILER_PATH="${SYSROOT}/usr/lib/gcc/${TARGET}/8"
exec env COMPILER_PATH="${COMPILER_PATH}" \
    "${BASE}/clang" --target=${TARGET} \
        --sysroot="${SYSROOT}" \
        -isysroot "${SYSROOT}" \
        -L"${COMPILER_PATH}" \
        --gcc-toolchain="${BASE}" \
        "$@"
$ chmod +x raspbian-sdk/prebuilt/bin/arm-linux-gnueabihf-clang

10 빌드 & RaspberryPi에 복사
여기에서는 다음의 소스 코드를 빌드 & 디버그의 대상으로 한다.

abc.c
#include <stdio.h>

int main() {
  int i, sum=0;
  printf("Bonjour!\n");
  for (i=1; i<=10; i++) {
    sum += i;
    printf("i=%d sum=%d\n", i, sum);
  }
  printf("Au revoir!\n");
  return(0);
}
$ ls
abc.c
$ ../raspbian-sdk/prebuilt/bin/arm-linux-gnueabihf-clang -g3 -o abc abc.c
$ scp abc [email protected]:

디버그 환경(gdb)



RaspberryPi



gdbserver를 설치합니다.
pi@raspberrypi:~ $ sudo apt install gdbserver

Mac



여기 또는 여기 을 참고하여 ARM용 gdb를 설치.
$ brew install arm-none-eabi-gdb 

등. Linaro 등에도 빌드된 gdb가 발견된다.

디버깅



RaspberryPi


pi@raspberrypi:~ $ gdbserver --multi :5555
Listening on port 5555

Mac(CLI)



gdb용 스크립트(gdb_local)를 준비하고, arm-none-eabi-gdb를 기동한다.
$ cat gdb_load 
target extended-remote raspberrypi.local:5555
file /Users/xyz/proj/pi/abc
remote put /Users/xyz/proj/pi/abc /home/pi/abc
set remote exec-file /home/pi/abc
start
$
$ arm-none-eabi-gdb -x gdb_load

 多数メッセージ省略

Temporary breakpoint 1 at 0x10424: file abc.c, line 4.
warning: A handler for the OS ABI "GNU/Linux" is not built into this configuration
of GDB.  Attempting to continue with the default armv6 settings.


Temporary breakpoint 1, main () at abc.c:4
4     int i, sum=0;
(gdb)

이 때의 RaspberryPi 측 표시.
Remote debugging from host 192.168.10.107
Process /home/pi/abc created; pid = 850

그리고는 끓여서 구워진다.

Mac(VSCode)



VSCode는 사용한 적이 없기 때문에, 이 기사 를 참고로 하고, 아마추어 레벨의 시점으로 기재.

소스 코드가 있는 디렉토리를 연 후 VSCode에서 디버그 시작.

그러면

'C++(GDB/LLDB)'를 선택한다. 그런 다음 launch.json이 열리므로 다음과 같이 편집하십시오.

launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "arm-none-eabi-gcc - アクティブ ファイルのビルドとデバッグ",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/abc",
            "args": [],
            "stopAtEntry": true,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "arm-none-eabi-gdb",
            "setupCommands": [
                {"text": "target extended-remote raspberrypi.local:5555"},
                {"text": "file ${workspaceFolder}/abc"},
                {"text": "remote put ${workspaceFolder}/abc /home/pi/abc"},
                {"text": "set remote exec-file /home/pi/abc"}
            ]
        }
    ]
}

적절한 경우 메뉴에서 "디버그 시작"을 선택하고 설정하려는 행에 중단 점을 설정합니다.

브레이크 포인트 선택 후의 모습(8행째).

변수의 상황을 보려면,

보기를 열기 때문에,

「변수」를 검색하면, 변수를 표시하는 Window가 표시된다.

변수를 클릭하면 값을 변경할 수도 있습니다.

끝에



참고 사이트의 분, 트레비안입니다.

좋은 웹페이지 즐겨찾기