visual studio code

visual studio code 에서 c/c++ 을 개발하는 환경을 설정하는 것을 설명하도록 하겠다.
필자는 visual studio 2012 주로 사용했었으며, 개인적으로 linux 환경에서 개발한 경혐이 있었고 자주 linux와 window 를 번갈아 가며 개발을 진행하고 있었기 때문에 통합적인 개발환경 세팅이 필요했다.
Linux 환경에서는 eclipse를 처음으로 사용했고 연구실 선배의 도움을 받아 spacemacs 를 세팅하고 c++,python 에 대한 개발을 진행했었던 경험이 있다. 하지만 spacemacs 를 깊이있게 알기 위해서는 lisp 에 대한 이해와 emacs 에 대한 이해가 필요했고 이 과정이 너무 고통스럽고 오래걸린다는 것을 깨닫은 후 새로운 에디터를 찾아다니기 시작했다. 처음으로는 Atom 에디터를 사용했었지만 결과적으로 돌아온 것은 visual studio code 이다.
사실 개발을 하는데 있어서 에디터는 개인적인 선호도에 따라 천차만별로 바뀔 수 있다. 어느 누구는 vim과 vim plugin 만 있으면 충분할 수도 있으며 다른 사람은 ‘난 무조건 visual studio 기능을 전부다 사용해야되기 때문에 window에서만 작업해야되’ 라고 할 수 도 있다. 필자는 현재 학교에서 진행중인 대규모 프로젝트 같은 경우는 이미 visual studio 2012 로 구현되고 있기 때문에 window 운영체제 속에서 개발을 진행했었지만 개인적인 용무나 연구에 있어서 window에서 환경설정을 세팅하는것보다 linux 에서 환경설정하는 것이 편했기 때문에 어쩔 수 없이 linux 운영체제 속에서 사용할 에디터를 찾아야만 했다.
결론적으로 필자가 찾은 마지막 종착지(아닐수도있고…) 는 visual studio code이다.

우선 visual studio code의 장점에 대해 나열하면 다음과 같다.

  • 사용자의 풀이 매우 크기 때문에 원하는 정보를 쉽게 찾을 수 있다.
  • 모든 운영체제에서 거의 동일하게 사용이 가능하다.(window, linux, mac)
  • 레이아웃이 내 맘에 들었다.(깔끔)
  • 다양한 테마가 있었다.
  • git 버젼 컨트롤이 내장되어있고 생각보다 편리하다.
  • 다양한 개발환경(c/cpp , python, java …)을 개별적으로 설정할 수 있다.(workspace)
  • gdb에 익숙하지 않은 나에게 디버깅하기 쉬운 GUI를 제공해준다.
  • vim plugin 을 적절히 이용할 수 있다.
  • 유용한 플러그인이 많다.
  • 현재 운영하고 있는 블로그 관리를하기 용이하다.(GitHub + Jekyll)

나열하고 보니 굉장히 많은 장점이있다. 사실 장점 부분은 사용자마다 원하는 기능일수 도 있고 아닐수 도 있기 때문에 개개인이 알아서 판단하면 될 것 같다.
그럼 이제 본론으로 돌아와서 window 운영체제에서 visual studio code를 c/cpp 개발용 에디터로 만드는 방법에 대해 진행하겠다.

visual studio code 다운받기

VsCode를 받는 방법은 너무나도 쉽기때문에 링크만 걸어둔다. vscode

사용할 플러그인 설치

기본적으로 vscode에서 원하는 기능을 수행하고자 할 때 (예를들면 빌드하고 싶거나, 세팅을 바꾸고싶거나 등등) Ctrl + Shift + p 를 이용하면 찾고자 하는 기능을 검색하여 사용할 수 있다.

이제 Ctrl + Shift + p 를 통해 extension을 검색해보면 extension intaller 페이지로 토글이 되며 여기서 원하는 플러그인을 검색해서 설치할 수 있다. 이 기능을 이용해서 필자는 다음과 같은 플러그인을 설치했다.

  • C/C++
    • intelliSense,debugging 등 필수적인 기능을 가능하게 해줌.
  • C/C++ Snippets (선택사항)
    • code snippets for c/cpp
  • Vim (선택사항)
    • 편집스타일에 따라 설치하고 안하고 결정하면 될듯하다.
    • 새로운 기능을 하나하나 배우는 재미도 쏠쏠하다.

      컴파일러 선택하여 설치하기

      만약 자신의 window 에 visual studio 가 깔려있다면 C/C++ 플러그인이 알아서 intelliSense나 컴파일러를 설정해줬을 것이다.
      하지만 자신이 visual studio나 다른 컴파일러를 설정해놓은 것이 없다면 c/c++ 를 어떤 컴파일러로 빌드할지, 디버깅할지 선택해야될 시간이다.
      필자의 조사에 의하면(연구실형이 알려줌) MinGW, cygWin 이라는 두개의 컴파일러를 window 에서 자주 사용한다고 한다. 둘다 모두 무료이다.
      그런데 둘의 가장 큰 차이점은 다음과 같다.

      MinGW 는 윈도우에서 실행가능한 exe 파일을 바로 만들어주는 컴파일러고 Cygwin 은 cygwin.dll 파일과 함께 빌드가 완료되며 이 dll 파일이 하는 일은 윈도우위에서 unix 운영체제의 환경을 만들어주는 dll 이라고 한다.

결국 자신이 사용하고 싶은 컴파일러를 선택하면 되는데 나는 MinGW 를 선택하였고 MinGW를 window 에 설치하고 환경변수 설정만 해주면 컴파일러를 설치할 수 있다. 그 과정은 다음과 같다.

  • MinGW 설치
    • MinGW setup 파일 다운로드
    • setup 파일 실행 후 default 하게 install 한다.
    • 마지막 continue 버튼을 누르면 intallation Manager 창이 뜬다.
    • 여기서 basic setup 의 package 를 모두 install 해야한다.
    • 그 방법은 그림으로 설명하도록 하겠다.
    • Aplly changes 를 클릭하면 package 들이 설치된다.
  • 환경변수에 MinGw path 등록
    • 시스템 환경변수에 MinGW/bin 을 추가해야된다.

모든 세팅이 끝나면 컴파일러 설치는 다 한 것이다.

Vscode에서 컴파일러 설정하기

VsCode 에서 원하는 컴파일러를 이용하고 싶으면 유저가 직접 세팅을 해야된다. 기본적으로 visual studio 컴파일러가 깔려있었다면 c/c++ 플러그인을 설치했을 때 자동적으로 msvc컴파일러로 설정이 되었을 것이다.(확실치는 않음) 아닌 경우는 잘 모르겠지만, 아무튼 MinGW 컴파일러를 사용하기 위해 c/c++ 플러그인 세팅을 바꿔주어야 한다.

  • Ctrl + Shift + p 키를 입력하여 찾기모드를 토글시키고
    C/CPP:Edit Configurations.. 를 선택한다.
  • 그러면 c_cpp_properties.json 이라는 파일이 생성될 것이다.
    {
      "configurations": [
          {
              "name": "Win32",
              "includePath": [
                  "${workspaceFolder}/**"
              ],
              "defines": [
                  "_DEBUG",
                  "UNICODE",
                  "_UNICODE"
              ],
              "windowsSdkVersion": "10.0.17134.0",
              "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.15.26726/bin/Hostx64/x64/cl.exe",
              "cStandard": "c11",
              "cppStandard": "c++17",
              "intelliSenseMode": "msvc-x64"
          }
      ],
      "version": 4
    }
    

    필자의 상태에서는 위와 같은 json 파일이 있었다.
    여기서 세팅값을 보면 compiler path 와 include path 가 우리가 설치한 MinGW 컴파일러에 대한 경로가 아닌 것을 확인 할 수 있다. 그렇기 때문에 이를 바꿔주어야 한다.

{
    "configurations": [
        {
            "name": "Win32",
            "intelliSenseMode": "clang-x64",
            "compilerPath": "C:/MinGW/bin/g++.exe",
            "includePath": [
                "${workspaceRoot}"
            ],
            "defines": [
                "_DEBUG"
            ],
            "browse": {
                "path": [
                    "C:/MinGW/lib/gcc/mingw32/6.3.0/include",
                    "C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
                    "C:/MinGW/include/*",
                    "${workspaceRoot}"
                ],
                "limitSymbolsToIncludedHeaders": true,
                "databaseFilename": ""
            },
            "cStandard": "c11",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}

이는 필자의 세팅에 적절하게 바꾼 것이며 개개인 별로 mingw 버젼이나 path 가 다를 수 있으므로 그에 맞게 설정하면 된다. 사실 이 부분에서는 컴파일을 실제로 하는 것은 아니기 때문에 intellisense 를 위한 include,browsepath 설정만 잘 하면 될 것 같다.

Vscode에서 빌드 및 디버깅하기

VsCode 에서 빌드를 하고 디버깅을 하는 방법은 tasks.json 파일과 launch.json파일을 이용하는 것이다. VsCode는 tasks.json 파일에 정의되어있는 task 를 실행시키며 launch.json파일에 정의된 방법으로 디버깅을 실행하게 된다.

  • Task 설정하여 빌드하기
    • Ctrl + Shift + p 를 통해 Tasks: Configure task 를 선택한다.
    • Create Tasks.json file 옵션을 선택한다.
    • Others 옵션을 선택한다.
    • 그러면 tasks.json 파일이 생성된다.
    • 생성된 tasks.json 파일에 여러가지 task 를 정의할 수 있다.
    • 기본적으로 g++ 으로 컴파일 하기위해 다음과 같이 task 를 정의한다.
      "tasks": [
        {
            "label": "myLabel",
            "type": "shell",
            "command": "g++",
            "args": [
                "-g",
                "main.cpp"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
        ]
      

      label 은 task의 이름 같은거라고 생각하면 된다. 그리고 command 와 자신이 원하는 arg 값을 넣어서 빌드시킬 수 있다. 그리고 group 으로 설정한 것은 이 task 를 빌드 테스크로 지정하겠다는 이야기 이다.
      이렇게 지정하고 나면 Ctrl + Shift + p 를 통해 Run build task 를 실행시키거나 Ctrl + Shift + b 를 이용해서 빌드시킬 수 있다.

  • 디버깅 이용하기
    • 디버깅 창에서 위의 사진의 초록색 화살표 모양을 클릭하면 디버깅을 시작한다.
    • 디버깅에 대한 세팅을 해주지 않았으면 처음에 새롭게 디버깅을 세팅할 launch.json파일을 생성하게 된다.
    • 여기서 우리는 C++(GDB/LLDB) 옵션을 선택한다.
    • 그러면 skeleton json 파일이 생성된다.
    • 생성된 launch.json파일을 수정하여 디버깅이 가능하도록 한다.
    • 다음과 같이 바꾸면 된다.
      {
        // Use IntelliSense to learn about possible attributes.
        // Hover to view descriptions of existing attributes.
        // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
        "version": "0.2.0",
        "configurations": [
              
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/a.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerPath": "C:/MinGW/bin/gdb.exe",
            "preLaunchTask": "myLabel",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
        ]
      }
      

여기에서 주의해야할 부분은 아래와 같다.

"program": "${workspaceFolder}/a.exe",

윗 부분은 우리가 디버깅 할 프로그램이 어떤것인지 이다. 지금 필자의 예제에서는 workspaceFolder 의 a.exe 파일이 빌드되었고 이를 디버깅하는 것이기 때문에 다음과 같이 정의하였다.

"miDebuggerPath": "C:/MinGW/bin/gdb.exe",

이 부분은 디버거 경로를 설정하는 부분이고 자신이 받은 경로의 gdb.exe 파일 경로로 설정하면 된다.

"preLaunchTask": "myLabel",

마지막 preLaunchTask는 디버깅을 시작하기 전에 수행할 task 를 의미한다. 즉 디버깅을 시작하기 전에 일단 디버깅이 가능하도록 빌드를 해 놓아야하기 때문에 이전에 task 에서 정의해 놓은 myLabel task를 수행하여 우선 빌드를 해놓게하는 부분이다.


이제 세팅은 끝났다. 자신의 프로젝트가 조금 복잡할 수도있다. 하지만 위의 세팅에서 바꿔야 할 부분 얼마 없다.

  • task.json 에서 빌드 옵션과 인자들
    • 자신이 cmake를 사용하면 거의 비슷하게 써도 될 것 같다.
  • launch.json 에서 program, 즉 디버깅할 실행파일

이 두개 정도만 바꾸고 자신만의 스타일로 바꾸면 vscode 를 이용해 빌드하거나 디버깅하는데 큰 문제가 없을 듯 하다.
아직 필자도 간단한 예제에 대해서 진행해봤기 때문에 cmake를 사용하거나 make rule 을 사용해서 빌드해보고 그 결과를 다음 포스팅에 올리도록 하겠다.