Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

"Visual Studio Code + Remote Development"로 윈도우 환경에서 리눅스(CentOS 7) C/C++ 개발

정말이지, "Visual Studo Code"는 명작입니다. ^^; Python, node.js, Java, C# 등의 다양한 언어 지원은 물론이고, 게다가 "Remote Development"도 가능해서 윈도우 환경임에도 전혀 불편하지 않게 리눅스 프로그램 개발을 아주 매끄럽게 할 수 있습니다. 어설픈 ssh 클라이언트 도구로 연결해 불편하게 개발을 해야 했던 시절과 비교하면 정말 천국과 다름없는 ^^ 환경입니다.

자, 그럼 이번에는 C++ 소스 코드를 윈도우에서 실행한 Visual Studio Code로 원격 리눅스에 연결해 작업을 해보겠습니다. 이를 위해 우선 C/C++ 확장을 설치합니다.

C/C++ for Visual Studio Code (Preview)
; https://code.visualstudio.com/docs/languages/cpp

그런 다음 "Remote Development"로 CentOS에 연결해,

로컬의 Visual Studio Code로 원격 리눅스 머신에 접속해 개발하는 방법
; https://www.sysnet.pe.kr/2/0/11942

관련 개발 도구를 설치해 줍니다.

/* 아래의 구성 요소 없이 Visual Studio에서 빌드하면 오류 발생
error : Could not find the specified C/C++ compiler 'g++'. Please make sure that a default C/C++ compiler is installed on the Linux system '...'. You can install a compiler using your system's package manager. If overriding the default compilers, please check that the compiler is installed in the specified path.
*/

$ sudo yum install gcc gcc-c++ make gdb

그럼, 준비는 모두 끝입니다. 이제 C++ 소스 코드 파일 하나 만들어서,

#include <cstdio>

int main()
{
    printf("hello from app1!\n");
    return 0;
}

"Ctrl + Shift + B"를 눌러 빌드 작업을 수행하려고 하면 다음과 같은 선택 메뉴가 뜹니다.

gcc_centos_vscode_1.png

"C/C++: g++ build active file"을 수행하면 현재 에디터에서 선택한 test.cpp 파일이 빌드가 됩니다. ^^ 이제 같은 폴더에 보면 "test" 파일이 생성되어 있고 TERMINAL을 이용해 실행해 볼 수 있습니다.

$ ./test
hello from app1!

당연히 Ctrl + F5 또는 F5를 누르면 디버거로 "C++ (GDB/LLDB)" 항목을 선택해 BreakPoint가 지원되는 환경을 누릴 수 있습니다. 참고로, 디버깅을 하는 경우 tasks.json 파일과 launch.json 파일이 함께 생성됩니다.




디버깅 시도와 함께 생성된 tasks.json 파일을 사용하면 출력 파일명도 바꿀 수 있습니다. 예를 들어, "test"를 "test.out"으로 변경하고 싶다면 관련 "args"를 수정하면 됩니다.

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558 
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "g++ build active file",
            "command": "/usr/bin/g++",
            "args": [
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}.out"
            ],
            "options": {
                "cwd": "/usr/bin"
            },
            "problemMatcher": [
                "$gcc"
            ]
        }
    ]
}

또한, launch.json에 이런 변경 사항을 반영해야 디버깅 시작 시 정상적으로 .out 파일이 실행됩니다.

{
    // 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": "g++ build and debug active file",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/${fileBasenameNoExtension}.out",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "g++ build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}




외부 라이브러리를 추가하는 경우, 가령 다음의 소스 코드를 빌드하면,

#include <cstdio>
#include <dlfcn.h>

#define RTLD_DELAY 0x00001

int main()
{
    printf("hello from app1!\n");

    dlopen("libsayhello.so", RTLD_DELAY);
    return 0;
}

dlopen 함수로 인해 오류 메시지가 발생하는데,

Executing task: /usr/bin/g++ -g /home/tusr/testapp/test.cpp -o /home/tusr/testapp/test <

/tmp/ccGSwEUW.o: In function `main':
/home/tusr/testapp/test.cpp:10: undefined reference to `dlopen'
collect2: error: ld returned 1 exit status
The terminal process terminated with exit code: 1

역시 tasks.json의 "args" 항목에 다음과 같이 g++ 실행 시의 라이브러리 의존 추가 옵션을 넣으면 됩니다.

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558 
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "g++ build active file",
            "command": "/usr/bin/g++",
            "args": [
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}.out",
                "-ldl"
            ],
            "options": {
                "cwd": "/usr/bin"
            },
            "problemMatcher": [
                "$gcc"
            ]
        }
    ]
}




참고로, 빌드(Ctrl + Shift + B)는 반드시 해당 파일이 선택된 상태에서 해야 합니다. 만약, tasks.json 파일을 선택한 상태에서 빌드를 하면 다음과 같은 식으로 test.cpp 파일 대신 tasks.json 파일이 인자로 전달됩니다.

> Executing task: /usr/bin/g++ -g /home/kevin/testcpp/.vscode/tasks.json -o /home/kevin/testcpp/.vscode/tasks -ldl <

/usr/bin/ld:/home/kevin/testcpp/.vscode/tasks.json: file format not recognized; treating as linker script
/usr/bin/ld:/home/kevin/testcpp/.vscode/tasks.json:1: syntax error
collect2: error: ld returned 1 exit status
The terminal process terminated with exit code: 1

물론, tasks.json에 다음과 같이 명시적으로 파일 명을 기록해 주는 것으로 우회할 수는 있습니다.

{
    "tasks": [
        {
            "type": "shell",
            "label": "g++ build active file",
            "command": "/usr/bin/g++",
            "args": [
                "-g",
                "${workspaceFolder}/test.cpp",
                "-o",
                "${workspaceFolder}/test.out",
                "-ldl"
            ],
            "options": {
                "cwd": "/usr/bin"
            },

            // 아래의 옵션을 추가하면 Ctrl + Shift + B를 누른 경우, 메뉴 선택 없이 곧바로 빌드가 수행됨
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ],
    "version": "2.0.0"
}

이 정도면, 대충 어떤 식인지 감이 오셨겠죠?! ^^




tasks.json 등의 파일에서 사용할 수 있는 변수는 다음의 공식 문서를 참고할 수 있습니다.

Variables Reference
; https://code.visualstudio.com/docs/editor/variables-reference

물론 복잡한 프로젝트라면 make 파일 등를 만들어 관리하거나 비주얼 스튜디오를 이용하는 것도 좋겠습니다.

Visual Studio 2019 - 리눅스 프로젝트를 이용한 공유/실행(so/out) 프로그램 개발 환경 설정
; https://www.sysnet.pe.kr/2/0/11844

반면, 저렇게 간단한 코드를 빠르게 테스트하고 싶을 때는 비주얼 스튜디오 코드가 좋은 선택이 될 것입니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 1/23/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




1  2  3  4  5  6  7  8  9  10  11  [12]  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13324정성태4/17/20234257.NET Framework: 2108. C# - Octave의 "save -binary ..."로 생성한 바이너리 파일 분석파일 다운로드1
13323정성태4/16/20234151개발 환경 구성: 677. Octave에서 Excel read/write를 위한 io 패키지 설치
13322정성태4/15/20234948VS.NET IDE: 182. Visual Studio - 32비트로만 빌드된 ActiveX와 작업해야 한다면?
13321정성태4/14/20233750개발 환경 구성: 676. WSL/Linux Octave - Python 스크립트 연동
13320정성태4/13/20233747개발 환경 구성: 675. Windows Octave 8.1.0 - Python 스크립트 연동
13319정성태4/12/20234206개발 환경 구성: 674. WSL 2 환경에서 GNU Octave 설치
13318정성태4/11/20234018개발 환경 구성: 673. JetBrains IDE에서 "Squash Commits..." 메뉴가 비활성화된 경우
13317정성태4/11/20234169오류 유형: 855. WSL 2 Ubuntu 20.04 - error: cannot communicate with server: Post http://localhost/v2/snaps/...
13316정성태4/10/20233495오류 유형: 854. docker-compose 시 "json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)" 오류 발생
13315정성태4/10/20233689Windows: 245. Win32 - 시간 만료를 갖는 컨텍스트 메뉴와 윈도우 메시지의 영역별 정의파일 다운로드1
13314정성태4/9/20233768개발 환경 구성: 672. DosBox를 이용한 Turbo C, Windows 3.1 설치
13313정성태4/9/20233860개발 환경 구성: 671. Hyper-V VM에 Turbo C 2.0 설치 [2]
13312정성태4/8/20233844Windows: 244. Win32 - 시간 만료를 갖는 MessageBox 대화창 구현 (개선된 버전)파일 다운로드1
13311정성태4/7/20234347C/C++: 163. Visual Studio 2022 - DirectShow 예제 컴파일(WAV Dest)
13310정성태4/6/20233899C/C++: 162. Visual Studio - /NODEFAULTLIB 옵션 설정 후 수동으로 추가해야 할 library
13309정성태4/5/20234074.NET Framework: 2107. .NET 6+ FileStream의 구조 변화
13308정성태4/4/20233967스크립트: 47. 파이썬의 time.time() 실숫값을 GoLang / C#에서 사용하는 방법
13307정성태4/4/20233749.NET Framework: 2106. C# - .NET Core/5+ 환경의 Windows Forms 응용 프로그램에서 HINSTANCE 구하는 방법
13306정성태4/3/20233576Windows: 243. Win32 - 윈도우(cbWndExtra) 및 윈도우 클래스(cbClsExtra) 저장소 사용 방법
13305정성태4/1/20233938Windows: 242. Win32 - 시간 만료를 갖는 MessageBox 대화창 구현 (쉬운 버전)파일 다운로드1
13304정성태3/31/20234295VS.NET IDE: 181. Visual Studio - C/C++ 프로젝트에 application manifest 적용하는 방법
13303정성태3/30/20233594Windows: 241. 환경 변수 %PATH%에 DLL을 찾는 규칙
13302정성태3/30/20234227Windows: 240. RDP 환경에서 바뀌는 %TEMP% 디렉터리 경로
13301정성태3/29/20234338Windows: 239. C/C++ - Windows 10 Version 1607부터 지원하는 /DEPENDENTLOADFLAG 옵션파일 다운로드1
13300정성태3/28/20233974Windows: 238. Win32 - Modal UI 창에 올바른 Owner(HWND)를 설정해야 하는 이유
13299정성태3/27/20233752Windows: 237. Win32 - 모든 메시지 루프를 탈출하는 WM_QUIT 메시지
1  2  3  4  5  6  7  8  9  10  11  [12]  13  14  15  ...