수성컴전자방입니다. 여러분이 만든 Windows용 프로그램이 단순히 exe 파일 하나라면 그것을 그냥 배포하면 되겠지만, 여러 파일로 이루어져 있다면(exe 파일이 여러 개이거나 이미지, 데이터 등이 있는 경우) 설치 프로그램(이하 ‘설치기’)을 만들어서 배포하는 것이 깔끔할 것입니다. 설치기는 어떻게 만드는 것일까요? 오늘은 ‘NSIS‘라는 Windows용 오픈소스 설치기 제작 도구를 사용해 보겠습니다. NSIS로 설치기를 만들면 EXE 파일이 생성됩니다. 저는 NSIS 코딩에 도움을 주는 ‘HM NIS Edit‘라는 프로그램도 함께 사용하겠습니다.
목차
1. NSIS + HM NIS Edit 설치
1.1. NSIS 설치
1.2. HM NIS Edit 설치
2. 기본적인 Windows용 설치 프로그램(설치기) 만들기
2.1. 스크립트 작성 마법사
2.2. 마법사로 생성한 코드 분석
2.3. 프로그램 설치 결과
2.4. 프로그램 제거
3. Section과 SectionGroup
4. 환영 이미지, 헤더 이미지, 브랜딩 텍스트, 스플래시 이미지
5. 프로그래밍(분기, 조건문, 반복문)
6. 커스텀 페이지
7. 인터넷에서 내려받기
1. NSIS + HM NIS Edit 설치
1.1. NSIS 설치
1.1.1. https://nsis.sourceforge.io/Download로 접속합니다.
1.1.2. Download를 클릭합니다.
1.1.3. Sourceforge로 연결됩니다. 5초 정도 기다리면 파일을 내려받을 수 있습니다. 내려받아 실행합니다.
1.1.4. Next>를 클릭합니다.
1.1.5. I Agree를 클릭합니다.
1.1.6. 다 체크된 채로 Next>를 클릭하시면 됩니다.
1.1.7. Install을 클릭합니다.
1.1.8. 어차피 HM Nis Edit으로 코딩할 거라서 Run NSIS는 체크 해제하셔도 됩니다. Finish를 클릭합니다.
1.2. HM NIS Edit 설치
1.2.1. https://hmne.sourceforge.net/로 접속합니다.
1.2.2. Download 목록에서 설치 파일(nisedit#.#.#.exe)을 클릭합니다.
1.2.3. Sourceforge로 연결됩니다. 5초 정도 기다리면 파일을 내려받을 수 있습니다. 내려받아 실행합니다.
1.2.4. 언어를 선택하고 OK를 클릭합니다.
1.2.5. 가능한 한 모든 프로그램을 종료하고 다음>을 클릭합니다.
1.2.6. 동의함을 클릭합니다.
1.2.7. 설치를 클릭합니다.
1.2.8. 오류가 뜨면 무시(I)를 클릭합니다.
1.2.9. 마침을 클릭합니다.
1.2.10. 어째서인지 시작 메뉴에 HM NIS Edit이 안 뜨더라고요. 저는 바탕화면 바로가기보다 시작 화면에 고정을 더 좋아하기 때문에 HM NIS Edit 설치 경로(기본 경로: C:\Program Files (x86)\HMSoft\NIS Edit)로 들어가서 nisedit.exe를 오른쪽 클릭→시작 화면에 고정했습니다.
1.2.11. 시작 화면에 nisedit이라는 이름으로 고정되었습니다.
2. 기본적인 Windows용 설치 프로그램(설치기) 만들기
2.1. 스크립트 작성 마법사
2.1.1. HM NIS Edit에서 파일(F) 아래에 있는 아이콘을 클릭합니다.
2.1.2. 다음>을 클릭합니다.
2.1.3. 프로그램 이름, 버전, 배포자, 웹사이트를 입력하고 다음>을 클릭합니다.
2.1.4. 설치 아이콘, 설치 파일, 설치 언어, GUI, 압축을 지정하고 다음>을 클릭합니다.
- 설치 아이콘: ico 파일을 넣으시면 됩니다. ico 파일 만드는 법을 모르시겠다면 이미지 파일(PNG 등)을 만들고 https://convertio.co/kr/에서 ico로 변환하시면 됩니다.
- 설치 파일: 설치기 파일명을 입력합니다.
- 설치 언어: 저는 Korean과 English를 체크했습니다. 만약 언어 목록에 아무것도 안 뜬다면 1.1번 문단에서 NSIS가 제대로 설치되지 않았을 가능성이 있습니다.
- GUI: Modern과 Classic 중에서 고를 수 있는데, 저는 Modern을 선택했습니다.
- 압축
- zlib: deflate 알고리즘을 사용하며, 빠르고 단순한 메서드입니다. 기본 압축 레벨에서 약 300kB의 메모리를 사용합니다.
- bzip2: zlib 보다 더 나은 압축 효율을 내지만 약간 더 느리고 메모리를 조금 더 사용합니다. 기본 압축 레벨에서 약 4MB의 메모리를 사용합니다.
- LZMA: 아주 좋은 압축 효율을 내는 새로운 압축 메서드입니다. 압축 해제 속도는 높으며 (2GHz CPU에서 10-20MB/s) 압축 속도는 낮습니다. 압축 해제에 사용되는 메모리 크기는 사전 크기보다 몇 kB 더 큽니다. 기본적으로 8MB입니다.
2.1.5. 프로그램 기본 디렉토리를 지정합니다. NSIS에서 지원하는 환경 변수 몇 가지를 아래에 적어 드리겠습니다.
- $PROGRAMFILES 또는 $PROGRAMFILES32
- 32-bit 시스템에서 C:\Program Files
- 64-bit 시스템에서 C:\Program Files (x86)
- $PROGRAMFILES64: 64-bit 시스템에서 C:\Program Files
- $APPDATA: %APPDATA%
- $DESKTOP: 바탕화면
- $TEMP: 임시 디렉터리
- $STARTMENU: 시작 메뉴 폴더
- $SMPROGRAMS: 시작 메뉴 폴더\프로그램 폴더
- $DOCUMENTS: 문서 디렉터리
- $INSTDIR: 지금 설정하는 프로그램 기본 디렉토리(즉, 2.1.5번에서는 쓸 수 없고 2.1.6번 이후에서 쓸 수 있는 변수입니다.)
- $EXEDIR: 인스톨러 실행 파일이 위치하는 디렉터리
2.1.6. 라이센스 파일을 지정합니다. 라이센스 파일은 ANSI 또는 EUC-KR 인코딩의 txt 파일을 만들어 연결하시면 됩니다.
2.1.7. 라이센스 계약 확인의 방법을 선택합니다.
2.1.8. 다음>을 클릭합니다.
2.1.9. 프로그램 파일 목록에 파일들이 이미 등록되어 있는데 이것은 예시를 보여주는 것이므로 X를 눌러 삭제합니다.\
2.1.10. 이제 파일을 추가합니다.
2.1.10.A. 먼저, 파일 추가를 해 보겠습니다.
소스 파일에 설치할 파일(예를 들어 여러분이 개발한 프로그램 빌드)을 지정해 줍니다.
설치 디렉토리는 파일이 설치될 경로를 지정해 줍니다. $INSTDIR은 2.1.5번에서 지정한 프로그램 기본 디렉토리입니다.
파일이 이미 존재할 경우 어떻게 할지 설정합니다. 저는 항상 덮어쓰기로 했습니다.
2.1.10.B. 이번에는 폴더째 추가해 보겠습니다.
SelectDirectory 옆 …을 클릭합니다.
삽입할 폴더를 찾아 클릭한 뒤 확인을 클릭합니다.
설치 디렉토리 뒤에 \폴더명을 꼭 써 줍니다.
예1) 기본 설치 경로 안에 ‘assets’라는 폴더를 폴더째로 넣고 싶으면 ‘$INSTDIR\assets’라고 씁니다.
예2) 저는 %APPDATA% 안에 ‘worship_subtitle’이라는 폴더를 폴더째로 넣고 싶어서 ‘$APPDATA\worship_subtitle’이라고 썼습니다.
파일이 이미 존재할 경우는 원하시는 대로 설정합니다.
2.1.10.C. Section은 파일들의 묶음이라고 생각하시면 됩니다.
예를 들어 위의 이미지와 같이 Section을 둘로 나누어 놓고 사용자가 설치할 컴포넌트를 선택할 수 있도록 설정에 체크하면 설치할 때 사용자가 원하는 section만 골라서 설치할 수 있습니다.
2.1.10.D. 사용자가 설치할 컴포넌트를 선택할 수 있도록 설정은 원하는 대로 설정하시면 됩니다.
원하는 대로 다 설정하셨으면 다음>을 클릭합니다.
2.1.11. 프로그램 시작 메뉴 이름을 입력합니다.
2.1.12. 체크하면 2.1.3번에서 입력한 프로그램 웹사이트로 연결되는 바로가기가 시작 메뉴 폴더에 생성됩니다.
2.1.13. 체크하면 시작 메뉴 폴더에 프로그램을 제거하는 파일 바로가기가 생성됩니다.
2.1.14. 그 밖의 바로가기들을 추가/편집/제거하는 부분입니다. 바탕화면 바로가기가 기본적으로 포함되어 있으니, 원하지 않으실 경우 바로 가기 제거를 클릭하여 지우시면 됩니다.
2.1.15. 설치가 완료된 후 실행할 프로그램을 지정합니다.
2.1.16. 언인스톨러 특성을 지정합니다. 빈칸에 원래는 [NAME]을(를) 제거하시겠습니까?와 같은 식으로 되어 있을텐데 그냥 그대로 두셔도 무방합니다. [NAME]이 NSIS 코드에서 $(^Name)로 치환되고, 이는 곧 프로그램 이름과 버전으로 치환됩니다.
2.1.17. 마법사 완료입니다. 스크립트 저장과 파일 경로를 상대 경로로 변경에 체크하시면 NSIS 코드에 설치할 파일 경로들이 상대 경로로 변경됩니다. 그다음 완료를 클릭합니다.
2.1.18. NSIS 코드가 생성되었습니다. 검색(S) 아래에 있는 아이콘을 클릭해 컴파일합니다.
2.1.19. 스크립트 마법사에 문제가 있더라고요. 2.1.10번에서 파일이 이미 존재할 경우 항상 덮어쓰기하도록 설정한 경우 오류가 발생합니다. 해당 Line을 찾아가서 SetOverwrite 뒤에 on을 붙여줍니다.(SetOverwrite on이 되도록 하면 됨.)
2.1.20. NSIS 코드가 있는 폴더에 컴파일 결과물(설치기)이 생성되었습니다.
2.1.21. 생성된 설치기를 실행하고 사용자 계정 컨트롤 창에서 허용해 준 다음 언어를 선택하면 위와 같이 설치 창이 뜰 것입니다. 설치와 제거가 의도한 대로 잘 되는지 확인해 보세요.
2.2. 마법사로 생성한 코드 분석
스크립트 마법사로 생성한 코드를 분석해 보겠습니다. 2.1번 문단에서 설정한 것에 따라 다르게 나오는데 저는 아래와 같이 나왔습니다. 제 코드를 예제로 사용해 보겠습니다.
코드를 분석하기에 앞서 주석 다는 법을 알려드리겠습니다.
- 한 줄 주석: ; 또는 # 이후의 문장
- 블록 주석(여러 줄 주석): /* 주석 */
설치될 파일의 경로는 절대경로와 상대경로 모두 가능합니다.
파일이 설치될 경로(위치)는 절대경로로 입력합니다(NSIS의 환경 변수 사용 가능).
이제 코드를 분석해 봅시다. 편의를 위해 HM NIS Edit에서 기본 생성된 주석은 ;으로, 제가 단 주석은 #으로 구분하겠습니다. Shift를 누르고 마우스 휠을 굴리시면 좌우 스크롤을 편하게 하실 수 있습니다.
; Script generated by the HM NIS Edit Script Wizard.
; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "영상예배 자막 프로그램" #프로그램 이름. ${PRODUCT_NAME}으로 사용 가능.
!define PRODUCT_VERSION "0.9.0" #프로그램 버전
!define PRODUCT_PUBLISHER "주성우(수성컴)" #프로그램 배포자
!define PRODUCT_WEB_SITE "https://sooseongcom.com" #프로그램 웹사이트
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\subtitle_setting.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
#압축방식을 BZIP 또는 LZMA로 선택하면 이 밑에 관련 코드 한 줄이 추가됩니다.
; MUI 1.67 compatible ------
!include "MUI.nsh" #Modern UI를 사용하는 코드입니다.
; MUI Settings
!define MUI_ABORTWARNING
!define MUI_ICON "영상예배 자막 프로그램 아이콘.ico" #설치기 아이콘을 지정(상대경로 가능).
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" #제거 프로그램 아이콘을 지정합니다.
; Language Selection Dialog Settings
!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"
#[Line 28~38] !insertmacro <삽입할매크로페이지> NSIS에서 제공하는 매크로 페이지들이 삽입되어 있습니다.
#위에서부터 순서대로 진행됩니다.
; Welcome page
!insertmacro MUI_PAGE_WELCOME
; License page
!insertmacro MUI_PAGE_LICENSE "licence.txt"
; Directory page
!insertmacro MUI_PAGE_DIRECTORY
; Instfiles page
!insertmacro MUI_PAGE_INSTFILES
; Finish page
!define MUI_FINISHPAGE_RUN "$INSTDIR\subtitle_setting.exe" #설치 후 실행할 프로그램 파일 경로
!insertmacro MUI_PAGE_FINISH
; Uninstaller pages
!insertmacro MUI_UNPAGE_INSTFILES #제거 프로그램에서 뜨는 창입니다.
; Language files #!insertmacro MUI_LANGUAGE "<언어>" 설치/제거 프로그램에서 지원할 언어의 목록을 작성.
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "Korean"
; MUI end ------
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" #설치기 창 상단에 뜨는 이름을 설정하는 부분입니다.
OutFile "Setup.exe" #설치기(컴파일 결과물) 파일명입니다.
InstallDir "$PROGRAMFILES64\worship_subtitle" #프로그램 기본 디렉토리(프로그램이 설치되는 기본 경로)를 설정
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
ShowInstDetails show
ShowUnInstDetails show
Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
Section "MainSection" SEC01 #Section "<section이름>" <고유번호>
SetOutPath "$INSTDIR" #설치 경로를 $INSTDIR로 지정합니다. $INSTDIR에 61~65행대로 설치됩니다.
SetOverwrite on #항상 덮어쓰기
File "subtitle_setting.exe" #설치할 파일을 지정(상대경로 가능).
CreateDirectory "$SMPROGRAMS\영상예배 자막 프로그램" #시작 메뉴에 폴더 생성
CreateShortCut "$SMPROGRAMS\영상예배 자막 프로그램\영상예배 자막 프로그램.lnk" "$INSTDIR\subtitle_setting.exe" #시작 메뉴에 바로가기 생성
CreateShortCut "$DESKTOP\영상예배 자막 프로그램.lnk" "$INSTDIR\subtitle_setting.exe" #바탕화면에 바로가기 생성
SetOutPath "$APPDATA\worship_subtitle\subtitles" #설치 경로를 $APPDATA\worship_subtitle\subtitles로 지정.
# $APPDATA\worship_subtitle\subtitles에 68~70행대로 설치됩니다.
SetOverwrite on #항상 덮어쓰기
File "subtitles\index.html" #설치할 파일을 지정(상대경로 가능).
File "subtitles\stylesheet.css" #설치할 파일을 지정(상대경로 가능).
SectionEnd
Section -AdditionalIcons #Section 이름 앞에 -가 붙어 있으면 숨김 처리됨. 숨김 처리된 section은 자동 설치됨.
SetOutPath $INSTDIR
#[Line 76~77] 시작 메뉴에 프로그램 웹사이트로 연결되는 바로가기를 만드는 코드입니다.
WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
CreateShortCut "$SMPROGRAMS\영상예배 자막 프로그램\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
CreateShortCut "$SMPROGRAMS\영상예배 자막 프로그램\Uninstall.lnk" "$INSTDIR\uninst.exe" #시작 메뉴에 제거 프로그램 바로가기 생성.
SectionEnd
Section -Post
WriteUninstaller "$INSTDIR\uninst.exe"
WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\subtitle_setting.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\subtitle_setting.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
SectionEnd
#이제 제거 프로그램을 보겠습니다.
Function un.onUninstSuccess
HideWindow
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name)는(은) 완전히 제거되었습니다." #프로그램 제거 후 띄울 메시지박스
FunctionEnd
Function un.onInit
!insertmacro MUI_UNGETLANGUAGE
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "$(^Name)을(를) 제거하시겠습니까?" IDYES +2 #제거 프로그램 실행 시 띄울 메시지박스
Abort
FunctionEnd
Section Uninstall #section 이름이 Uninstall이거나 un.으로 시작하면 제거 프로그램에서 사용하는 section이라는 뜻입니다.
Delete "$INSTDIR\${PRODUCT_NAME}.url" #Delete "<파일경로>" 파일을 삭제합니다.
Delete "$INSTDIR\uninst.exe"
Delete "$APPDATA\worship_subtitle\stylesheet.css"
Delete "$APPDATA\worship_subtitle\index.html"
Delete "$INSTDIR\subtitle_setting.exe"
Delete "$SMPROGRAMS\영상예배 자막 프로그램\Uninstall.lnk"
Delete "$SMPROGRAMS\영상예배 자막 프로그램\Website.lnk"
Delete "$DESKTOP\영상예배 자막 프로그램.lnk"
Delete "$SMPROGRAMS\영상예배 자막 프로그램\영상예배 자막 프로그램.lnk"
RMDir "$SMPROGRAMS\영상예배 자막 프로그램" #RMDir "<폴더경로>" 폴더를 삭제합니다.
RMDir "$INSTDIR"
RMDir "$APPDATA\worship_subtitle\subtitles"
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
SetAutoClose true #프로그램 제거 후 제거 프로그램 창을 닫습니다.
SectionEnd
[Line 29]
!insertmacro MUI_PAGE_LICENSE “라이센스 파일 경로“
사용권 계약(License Agreement) 창을 띄웁니다. 라이센스 계약 확인(동의)을 Classic 말고 다른 것으로 하려면 이 위에 아래의 코드를 작성합니다.
라이센스 파일 경로는 상대경로로 지정할 수도 있습니다.
- 체크박스: !define MUI_LICENSEPAGE_CHECKBOX
- 라디오 버튼: !define MUI_LICENSEPAGE_RADIOBUTTONS
[Line 60]
Section “MainSection“ SEC01
MainSection은 section의 이름이며, !insertmacro MUI_PAGE_COMPONENTS 코드가 있을 경우(사용자가 설치할 컴포넌트를 선택할 수 있도록 설정된 경우) 설치 창에 나타날 이름입니다.
SEC01은 설치 창에 나타날 이름은 아니지만, section의 고유 번호라고 생각하시면 됩니다.
[Line 62, 69]
SetOverwrite 옵션
파일이 이미 존재할 경우 어떻게 할지 정하는 부분입니다. 옵션은 아래 4가지 중 선택할 수 있습니다.
- on: 항상 덮어쓰기
- off: 덮어쓰지 않음
- try: 덮어쓰기 시도
- ifnewer: 물음
2.3. 프로그램 설치 결과
NSIS 코드가 완성되었으면 컴파일 및 설치를 진행해 보시면 됩니다. 설치 결과는 소스코드에 따라 다를 것입니다. 저는 아래와 같이 되었습니다.
바탕화면에 바로가기가 생성되었습니다.
시작 메뉴를 여니 직접 만든 프로그램이 최근 추가 항목으로 뜨는 것을 볼 수 있었습니다.
모든 앱 목록에 폴더가 생성되었습니다.
C:\Program Files 폴더 안에 프로그램 폴더가 생성되었습니다.
2.4. 프로그램 제거
프로그램 제거는 시작 폴더에서 Uninstall을 실행하거나 설정 앱에서 제거를 진행하시면 가능합니다. 이 문단에서는 설정에서 프로그램을 제거해 보겠습니다.
2.4.1. 시작을 오른쪽 클릭하거나 Windows+X를 누릅니다.
2.4.2. 설치된 앱을 클릭합니다.
2.4.3. 제거할 프로그램을 찾고 …을 누른 뒤 제거를 클릭합니다.
2.4.4. 제거를 클릭합니다.
2.4.5. NSIS로 만든 제거 프로그램이 실행됩니다. 예를 클릭하면
2.4.6. NSIS 코드에서 설정한 대로 프로그램이 제거됩니다.
*. 글 마무리
제 글을 읽어 주셔서 감사합니다. 다음에 만나요!
**. 참고 자료
1) atoughguy. 2023. “c# install 설치 파일 만들기 - NSIS”, 지극히 개인적인 살아가는 이야기. (2024. 01. 12. 방문). https://atoughguy.tistory.com/64
2) 여승철. 2022. “NSIS 쉬운 문법 설명”, INTP 개발자. (2024. 01. 12. 방문). https://yeo-computerclass.tistory.com/151
3) 도치. 2020. “간편설치기 강좌 | 기초 문법 소개 (feat.NSIS)”, 도치의 티스토리 블로그. (2024. 01. 12. 방문). https://doch12.tistory.com/56
4) moltak. 2010. “NSIS 기초지식”, code toolbox. (2024. 01. 12. 방문). https://moltak.tistory.com/48
5) 애스크. 2019. “[NSIS+HM NIS EDIT]2강 - 기능 소개 및 기초 생성”, YouTube. (2024. 01. 12. 방문). https://youtu.be/faO18LDJXFc?si=7jN6Vge6czHIzGyG
6) WONsX. 2016. “[NSIS] 꼭 필요한 스크립트와 기본적인 MUI 적용”, WONsX. (2024. 01. 12. 방문). https://wonsx.tistory.com/24
7) WONsX. 2016. “[NSIS] 바로가기 생성 및 아이콘 변경”, WONsX. (2024. 01. 12. 방문). https://wonsx.tistory.com/28
8) sam 외 5명. 2018. “4.2 변수”, Opentutorials. (2024. 01. 12. 방문). https://opentutorials.org/module/3650/21919
9) sam 외 5명. 2019. “4.8.2 컴파일러 플래그”, Opentutorials. (2024. 01. 12. 방문). https://opentutorials.org/module/3650/24856