본문 바로가기
프로그래밍/c

vs code에서 wsl을 이용한 c/c++ 컴파일

by 신일석 2019. 5. 16.

vs code에서 wsl을 이용한 c/c++ 컴파일

vs code에서 c/c++ 컴파일을 하기 위한 환경을 구성해 보겠습니다.
이 내용은 https://code.visualstudio.com/docs/languages/cpphttps://code.visualstudio.com/docs/cpp/config-wsl를 참고하였습니다.

사전준비

  • 윈도우10
  • visual studio code 설치(이하 vs code)
  • vs code에 c/c++ 확장 설치
  • 윈도우10에서 wsl 설치(설명에서는 ubuntu를 사용하고 있음.)

목표

vs code에서 컴파일 환경을 갖추고
c++ 코드를 작성하고 우분투에서 'Hello World!'를 출력하는 것까지 해 보겠습니다.

참고. c 프로그래밍을 하는 경우에도 컴파일 환경을 갖추려면 c++코드가 필요합니다. 컴파일 환경을 갖춘 후에 c 프로그래밍을 하시면 됩니다.

c 소스코드 작성

<윈도우에서>

  1. vs code 작업폴더 열기

윈도우 cmd창에서 D:\projects\helloworld 폴더를 만듭니다.(필요에 따라 바꿔서 만드세요.)
helloworld 폴더에서 'code .'을 입력하면 vs code가 현재 폴더를 열면서 실행됩니다.
실행할때 code 뒤에 '.'을 넣어 주어야 합니다.

cd d:
mkdir projects
cd helloworld
mkdir helloworld
cd helloworld
code .
  1. hello world! 코드 작성

vs code에서 새 파일을 열고, 아래 코드를 참고해 helloworld.cpp파일을 만듭니다.
우분투 shell에서 Hello World!를 출력는 코드입니다.

helloworld.cpp

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{

    vector<string> msg {"Hello", "C++", "World", "from", "VS Code!",
    "and the C++ extension!"};

    for (const string& word : msg)
    {
        cout << word << " ";
    }
    cout << endl;
}

GNU 컴파일러와 GDB 디버거 설치

<우분투 bash 쉘에서>

  1. 우분투 업데이트

컴파일러를 설치하기 전에 패키지 목록을 최신으로 업데이트하고 업그레이드까지 진행합니다.

'''
sudo apt-get update && sudo apt-get dist-upgrade
'''

  1. 컴파일러와 디버거 설치
sudo apt-get install build-essential gdb
  1. 설치확인

아래 두 명령을 실행하여 g++와 gdb의 위치를 확인합니다.
설치가 잘 되었다면 g++: /usr/bin/g++ /mnt/c/Program Files (x86)/Dev-Cpp/MinGW64/bin/g++.exe
/usr/share/man/man1/g++.1.gz 와 같이 파일의 경로를 출력됩니다. g++ 예 였습니다.

whereis g++
whereis gdb

우분투에 컴파일 폴더 준비

<윈도우 cmd에서>
윈도우에서 vs code로 컴파일을 하면 우분투에 실행파일이 만들어지는데, 이 폴더에 생성됩니다.
폴더는 윈도우와 같이 만들어 줍니다.

mkdir projects
cd projects
mkdir helloworld

vs code 설정

<윈도우 vs code에서>

이 작업을 통해 3개의 파일이 만들어 집니다. 하나씩 만들어 나가겠습니다.

  • c_cpp_properties.json
  • tasks.json
  • launch.json

c_cpp_properties.json : 컴파일 경로설정

c_cpp_properties.json 생성 및 설정

커맨드 팔렛트를 열기 위해 Ctrl+Shift+P를 누릅니다.
"C/C++"를 입력하며 나타나는 목록중에 다음을 찾아 선택합니다.

C/C++: Edit configutations (JSON)

.vscode/c_cpp_properties.json 파일이 만들어지면서 파일 열립니다.
우분투에 설치한 g++(컴파일러)의 경로를 설정하기 위해
초기 파일의 내용을 모두 지우고 아래 내용을 복사해 붙여넣기 해 주세요.

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "compilerPath": "/usr/bin/g++",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "clang-x64",
            "browse": {
                "path": [
                    "${workspaceFolder}"
                ],
                "limitSymbolsToIncludedHeaders": true,
                "databaseFilename": ""
            }
        }
    ],
    "version": 4
}

tasks.json : 빌드 task 만들기

tasks.json 생성 및 설정

vs code가 우분투의 g++컴파일러를 호출해 실행파일을 만들도록 설정하는 과정입니다.

명령 팔렛트(Ctrl+Shift+P)에서 'Tasks"를 입력하면 나오는 목록중에
'Tasks: Configure default build task'를 선택합니다.
이어서 '템플릿에서 tasks.json 파일 만들기'를 선택하고 'Others'를 선택합니다.

tasks.json에서 "tasks"부분을 아래와 같이 수정합니다.

아이디는 자신의 우분투 아이디를 입력합니다.

{
    "version": "2.0.0",
    "windows": {
        "options": {
            "shell": {
                "executable": "c:\\windows\\sysnative\\bash.exe",
                "args": ["-c"]
            }
        }
    },
    "tasks": [
        {
            "label": "build c on WSL",
            "type": "shell",
            "command": "g++",
            "args": [
                "-g",
                "-o",
                "/home/<우분투 아이디>/projects/helloworld/${fileBasenameNoExtension}.out",
                "${fileBasenameNoExtension}.c"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": []
        },
        {
            "label": "build cpp on WSL",
            "type": "shell",
            "command": "g++",
            "args": [
                "-g",
                "-o",
                "/home/<우분투 아이디>/projects/helloworld/${fileBasenameNoExtension}.out",
                "${fileBasenameNoExtension}.cpp"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

빌드테스트

helloworld.out 만들기
명령 팔렛트에서 Tasks: Run Task를 실행하거나 Ctrl+Shift+B를 누르면 'build c on WSL' task를 실행할 수 있습니다.
실행해서 우분투에 실행파일(helloworld.out)이 만들어지는지 확인해 봅니다.

Run Task를 실행하면 우분투 helloworld 폴더에 helloworld.out파일이 빌드됩니다. 쉘에서 실행합니다.

./helloworld.out
Hello World!

launch.json : vs code에서 디버그하기 위한 설정

마지막으로 launch.json을 만들겠습니다. 앞서 우분투에 설치한 GDB를 이용해 보겠습니다.

launch.json 생성 및 설정

메뉴바로 이동해 '디버그 > 구성 추가'를 선택하면 나타나는 목록에서 C++ (GDB/LLDB)를 선택합니다.
.vscode에 생성된 launch.json파일의 내용을 지우고 아래 내용을 붙여넣기 해 주세요.

참고

  • 아이디에는 우분투 아이디로 바뀌줍니다.
  • path는 리터럴 경로(전체 경로)를 사용합니다.
  • sourceFileMap의 설정은 하단 내용을 참고합니다.
{
"version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "/home/<우분투 아이디>/projects/helloword/helloworld.out",
            "args": ["-fThreading"],
            "stopAtEntry": true,
            "cwd": "/home/<우분투 아이디>/projects/helloword/",
            "environment": [],
            "externalConsole": true,
            "windows": {
                "MIMode": "gdb",
                "miDebuggerPath": "/usr/bin/gdb",
                "setupCommands": [
                    {
                        "description": "Enable pretty-printing for gdb",
                        "text": "-enable-pretty-printing",
                        "ignoreFailures": true
                    }
                ]
            },
            "pipeTransport": {
                "pipeCwd": "",
                "pipeProgram": "c:\\windows\\sysnative\\bash.exe",
                "pipeArgs": ["-c"],
                "debuggerPath": "/usr/bin/gdb"
            },
            "sourceFileMap": {
                "/mnt/c": "${env:systemdrive}/",
                "/usr": "나중에 wsl 경로는 넣게 됩니다."
            }
        }
    ]
}

sourceFileMap의 설정

두 가지를 확인해야 합니다.. 하나는 소스파일 드라이브이고 다른 하나는 윈도우에 설치된 wsl 우분투의 '/usr' 경로입니다.

먼저 소스파일 드라이브입니다.
wsl에서 윈도우 시스템의 c드라이브 루트는 /mnt/c로 접근합니다. 우리는 D:\projects\helloworld에서 작업을 하기 때문에 /mnt/d가 됩니다.

/mnt/d --> D:\

적용 결과

"sourceFileMap": {
    "/mnt/d": "${env:systemdrive}/",
    "/usr": "나중에 wsl 경로는 넣게 됩니다."
}

다음으로 wsl에 있는 /usr의 윈도우에서의 경로를 알아 보겠습니다.
vs code에서 helloworld.cpp파일을 열고 10번째 줄에 있는 string에서 오른쪽 클릭을 합니다. 그럼 컨텍스트 메뉴가 나오고 'Go to Declaration'을 선택합니다.

에디터에 stringfwd.h파일이 열리게 됩니다. 여기서 경로복사를 선택합니다.

메모장에서 붙여넣기 하여 복사된 경로를 확인합니다.
C:\Users<자신의 윈도우 아이디>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs\usr\include\c++\7\bits\stringfwd.h

우리에게 필요한 부분은 C:\부터 usr\까지 입니다.

C:\Users<자신의 윈도우 아이디>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs\usr\

\ --> \ 바꾼 후 적용합니다.

적용 결과

"sourceFileMap": {
    "/mnt/d": "${env:systemdrive}/",
    "/usr": "C:\\Users\\<자신의 윈도우 아이디>\\AppData\\Local\\Packages\\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\\LocalState\\rootfs\\usr\\"
}

launch.json의 설정이 완료된 상태는 아래과 같습니다.

{
"version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "/home/<우분투 아이디>/projects/helloword/helloworld.out",
            "args": ["-fThreading"],
            "stopAtEntry": true,
            "cwd": "/home/<우분투 아이디>/projects/helloword/",
            "environment": [],
            "externalConsole": true,
            "windows": {
                "MIMode": "gdb",
                "miDebuggerPath": "/usr/bin/gdb",
                "setupCommands": [
                    {
                        "description": "Enable pretty-printing for gdb",
                        "text": "-enable-pretty-printing",
                        "ignoreFailures": true
                    }
                ]
            },
            "pipeTransport": {
                "pipeCwd": "",
                "pipeProgram": "c:\\windows\\sysnative\\bash.exe",
                "pipeArgs": ["-c"],
                "debuggerPath": "/usr/bin/gdb"
            },
            "sourceFileMap": {
                "/mnt/d": "${env:systemdrive}/",
                "/usr": "C:\\Users\\<자신의 윈도우 아이디>\\AppData\\Local\\Packages\\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\\LocalState\\rootfs\\usr\\"
            }
        }
    ]
}

컴파일

helloworld.cpp를 빌드하도록 하겠습니다.
vs code에서 파일을 열고
커맨드 팔렛트에서 'Tasks: Run Build Task' --> 'build cpp on WSL' 순으로 선택하거나
Ctrl+Shift+B를 누르고 'build cpp on WSL' 순으로 선택합니다.

vs code 하단 터미널에 아래 내용이 출력이 됩니다.

> Executing task: g++ -g -o /home/<우분투 아이디>/projects/helloworld/helloworld.out helloworld.cpp <
터미널이 작업에서 다시 사용됩니다. 닫으려면 아무 키나 누르세요.

이제 우분투에서 확인해 보겠습니다.
윈도우에서 wsl 우분투를 실행하고 프로젝트 폴더로 이동합니다.
빌드된 파일을 실행할때는 './helloworld.out'을 입력하면 됩니다. ('.'로 시작합니다.)

cd ~/projects/helloworld/
./helloworld.out

아래 메세지가 출력됩니다.

Hello C++ World from VS Code! and the C++ extension!

디버깅

마지막으로 디버깅입니다.
vs code에서 파일을 열고 F5키를 누룹니다.

편집기는 main()의 첫번째 구문에서 자동으로 멈추게 됩니다.

디버깅을 준비가 완료되었습니다.

마치며

고생하셨습니다. 글이 길어지다 보니 설명이나 스샷을 충분히 넣지 못한 부분이 있습니다. 다음에 좀 더 보완하도록 하겠습니다.
감사합니다.

'프로그래밍 > c' 카테고리의 다른 글

C언어에서 기억 클래스의 종류  (0) 2019.05.26