홈브루 개발/Nintendo Switch

[닌텐도 스위치 홈브루 개발] 개발 환경 구축 및 Hello World

일렉트릭캣 2025. 4. 23. 12:00

macOS 기준으로 설명

devkitPro 설치를 위한 pacman 설치

https://github.com/devkitPro/pacman/releases/tag/v6.0.2
위 링크에서 pkg 파일을 받고 아래 명령을 실행

sudo installer -pkg devkitpro-pacman-installer.pkg -target /

libnx 외 기타 개발 툴체인 설치

sudo dkp-pacman -S switch-dev
(base)  ✘ catcat@macbook  ~  sudo dkp-pacman -S switch-dev
:: There are 14 members in group switch-dev:
:: Repository dkp-libs
   1) catnip  2) deko3d  3) devkita64-cmake  4) libnx  5) switch-cmake  6) switch-examples  7) switch-pkg-config
:: Repository dkp-osx
   8) devkitA64  9) devkitA64-gdb  10) flock  11) general-tools  12) pkg-config  13) switch-tools  14) uam

Enter a selection (default=all):
resolving dependencies...
looking for conflicting packages...

Packages (16) devkita64-rules-1.1.1-1  dkp-cmake-common-utils-1.5.2-1  catnip-0.1.0-1  deko3d-0.5.0-1  devkitA64-r27-2
              devkitA64-gdb-14.1-1  devkita64-cmake-1.1.2-1  flock-0.4.0-1  general-tools-1.4.4-1  libnx-4.8.0-1
              pkg-config-0.29.2-3  switch-cmake-1.5.1-1  switch-examples-20241018-1  switch-pkg-config-0.28-4
              switch-tools-1.13.1-1  uam-1.1.0-1

Total Download Size:    90.41 MiB
Total Installed Size:  399.18 MiB

:: Proceed with installation? [Y/n]
:: Retrieving packages...
 deko3d-0.5.0-1-any                               1206.5 KiB   533 KiB/s 00:02 [############################################] 100%
 libnx-4.8.0-1-any                                  10.0 MiB  3.84 MiB/s 00:03 [############################################] 100%
 uam-1.1.0-1-arm64                                 634.1 KiB  1015 KiB/s 00:01 [############################################] 100%
 devkitA64-gdb-14.1-1-arm64                          3.6 MiB   938 KiB/s 00:04 [############################################] 100%
 pkg-config-0.29.2-3-arm64                         174.6 KiB   228 KiB/s 00:01 [############################################] 100%
 switch-tools-1.13.1-1-arm64                        97.2 KiB   152 KiB/s 00:01 [############################################] 100%
 general-tools-1.4.4-1-arm64                        29.2 KiB  46.6 KiB/s 00:01 [############################################] 100%
 catnip-0.1.0-1-any                                 10.5 KiB  35.0 KiB/s 00:00 [############################################] 100%
 flock-0.4.0-1-arm64                                11.9 KiB  16.0 KiB/s 00:01 [############################################] 100%
 dkp-cmake-common-utils-1.5.2-1-any                  8.0 KiB  26.1 KiB/s 00:00 [############################################] 100%
 devkita64-rules-1.1.1-1-any                         5.7 KiB  23.3 KiB/s 00:00 [############################################] 100%
 switch-cmake-1.5.1-1-any                            5.7 KiB  9.92 KiB/s 00:01 [############################################] 100%
 switch-pkg-config-0.28-4-any                        2.5 KiB  11.0 KiB/s 00:00 [############################################] 100%
 devkita64-cmake-1.1.2-1-any                         4.9 KiB  9.36 KiB/s 00:01 [############################################] 100%
 switch-examples-20241018-1-any                    730.1 KiB  92.7 KiB/s 00:08 [############################################] 100%
 devkitA64-r27-2-arm64                              74.0 MiB  3.74 MiB/s 00:20 [############################################] 100%
 Total (16/16)                                      90.4 MiB  4.42 MiB/s 00:20 [############################################] 100%
(16/16) checking keys in keyring                                               [############################################] 100%
(16/16) checking package integrity                                             [############################################] 100%
(16/16) loading package files                                                  [############################################] 100%
(16/16) checking for file conflicts                                            [############################################] 100%
(16/16) checking available disk space                                          [############################################] 100%
:: Processing package changes...
( 1/16) installing dkp-cmake-common-utils                                      [############################################] 100%
( 2/16) installing catnip                                                      [############################################] 100%
( 3/16) installing libnx                                                       [############################################] 100%
( 4/16) installing deko3d                                                      [############################################] 100%
( 5/16) installing devkita64-cmake                                             [############################################] 100%
( 6/16) installing switch-tools                                                [############################################] 100%
( 7/16) installing uam                                                         [############################################] 100%
( 8/16) installing switch-pkg-config                                           [############################################] 100%
( 9/16) installing switch-cmake                                                [############################################] 100%
(10/16) installing switch-examples                                             [############################################] 100%
(11/16) installing flock                                                       [############################################] 100%
(12/16) installing general-tools                                               [############################################] 100%
(13/16) installing devkita64-rules                                             [############################################] 100%
(14/16) installing devkitA64                                                   [############################################] 100%
(15/16) installing devkitA64-gdb                                               [############################################] 100%
(16/16) installing pkg-config                                                  [############################################] 100%

devkitPro 환경변수 등록

본인이 사용하는 쉘마다 다르겠지만, 최신버전 macOS 라면 대부분 zsh 사용 중일 것이다.
필자는 zsh를 사용중이기 때문에 ~./.zshrc 파일에 환경변수를 등록 하였음
참고로 devkitpro는 /opt/devkitpro 경로에 설치되어있다.

...
export DEVKITPRO=/opt/devkitpro

source 명령을 통해 다시 불러오거나, 쉘을 재시작하면 끗

프로젝트 생성

프로젝트 생성이라곤 하는데 첨에 어떻게 해야할지 깝깝하다. 소스 파일들을 보니깐 Makefile 작성이 필요한데, 해본사람은 알겠지만 저거 작성하는거 여간일이 아니다.

Makefile 다운로드

참고할만한 Makefile이 있을까 싶어서 아래 링크에서 예제 샘플들을 찾아봤다. 겁먹었지만 다행히 샘플을 봐도 Makefile 자체는 모두 동일한것 같더라.

 

GitHub - switchbrew/switch-examples: Switch examples for devkitA64 and libnx.

Switch examples for devkitA64 and libnx. . Contribute to switchbrew/switch-examples development by creating an account on GitHub.

github.com

 

필자는 아래 디렉토리에 있는 Makefile을 그대로 사용했다.

 

switch-examples/graphics/printing/hello-world at master · switchbrew/switch-examples

Switch examples for devkitA64 and libnx. . Contribute to switchbrew/switch-examples development by creating an account on GitHub.

github.com

 

디렉토리 구성

디렉토리는 아래와 같이 구성한다. 그래야 make 명령을 실행했을때 바로 빌드 할 수 있다. 기본적으로 소스 파일들을 source 디렉토리에 넣어야 한다.

PROJECT-NAME/
├──source/
│      ├──other_source.c
│      └──main.c
├──deploy.sh
└──Makefile

배포스크립트 작성

macOS 환경에서 개발하기 때문에 MTP 사용하는건 매우 불편하다. 따라서 커펌된 스위치에 sys-ftpd 홈부류를 설치하고 백그라운드에서도 FTP 서버가 가동되도록 하였고, 빌드된 nro 파일을 sdmc:/switch/%PROJECT-NAME%/%PROJECT-NAME%.nro 경로로 업로드 되도록 스크립트를 작성했다.

#!/bin/sh

PROJECTNAME=$(basename "$PWD")
HOSTPORT=$1
FILE=$PROJECTNAME.nro
TARGET_PATH=switch/$PROJECTNAME
REMOTE_PATH=$TARGET_PATH/$PROJECTNAME.nro

HOST=$(echo "$HOSTPORT" | cut -d':' -f1)
PORT=$(echo "$HOSTPORT" | cut -d':' -f2)

ftp -inv "$HOST" "$PORT" <<EOF
user anonymous anonymous
binary
mkdir $TARGET_PATH
cd $TARGET_PATH
delete $FILE
put $FILE
bye
EOF

위 스크립트를 deploy.sh 파일로 저장하면 deploy.sh 192.168.0.111:5500 이런식으로 바로 업로드 할 수 있다.

Hello, World 소스

그냥 예제 소스 전부 가져왔다. 아래 코드를 프로젝트 디렉토리에서 source/main.c 파일에 저장해준다.

#include <string.h>
#include <stdio.h>

#include <switch.h>

int main(int argc, char **argv)
{
    //Initialize console. Using NULL as the second argument tells the console library to use the internal console structure as current one.
    consoleInit(NULL);

    // Configure our supported input layout: a single player with standard controller styles
    padConfigureInput(1, HidNpadStyleSet_NpadStandard);

    // Initialize the default gamepad (which reads handheld mode inputs as well as the first connected controller)
    PadState pad;
    padInitializeDefault(&pad);

    //Move the cursor to row 16 and column 20 and then prints "Hello World!"
    //To move the cursor you have to print "\x1b[r;cH", where r and c are respectively
    //the row and column where you want your cursor to move
    printf("\x1b[16;20HHello World!");

    while(appletMainLoop())
    {
        // Scan the gamepad. This should be done once for each frame
        padUpdate(&pad);

        // padGetButtonsDown returns the set of buttons that have been newly pressed in this frame compared to the previous one
        u64 kDown = padGetButtonsDown(&pad);

        if (kDown & HidNpadButton_Plus) break; // break in order to return to hbmenu

        consoleUpdate(NULL);
    }

    consoleExit(NULL);
    return 0;
}

빌드

단순하다. make 명령이면 된다. 반대로 make clean 명령을 쓰면 링킹전 오브젝트파일들을 삭제 할 수 있다.