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

비밀번호

댓글 작성자
 




... 31  [32]  33  34  35  36  37  38  39  40  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
12820정성태9/1/20217806VC++: 147. Golang - try/catch에 대응하는 panic/recover [1]파일 다운로드1
12819정성태8/31/20217927.NET Framework: 1111. C# - FormattableString 타입
12818정성태8/31/20217151Windows: 198. 윈도우 - 작업 관리자에서 (tensorflow 등으로 인한) GPU 연산 부하 보는 방법
12817정성태8/31/20219681스크립트: 25. 파이썬 - 윈도우 환경에서 directml을 이용한 tensorflow의 AMD GPU 사용 방법
12816정성태8/30/202115106스크립트: 24. 파이썬 - tensorflow 2.6 NVidia GPU 사용 방법 [2]
12815정성태8/30/20218243개발 환경 구성: 602. WSL 2 - docker-desktop-data, docker-desktop (%LOCALAPPDATA%\Docker\wsl\data\ext4.vhdx) 파일을 다른 디렉터리로 옮기는 방법
12814정성태8/30/202110529.NET Framework: 1110. C# 11 - 인터페이스 내에 정적 추상 메서드 정의 가능 (DIM for Static Members) [2]파일 다운로드1
12813정성태8/29/20218753.NET Framework: 1109. C# 10 - (11) Lambda 개선파일 다운로드1
12812정성태8/28/20218394.NET Framework: 1108. C# 10 - (10) 개선된 #line 지시자
12811정성태8/27/20218598Linux: 44. 윈도우 개발자를 위한 리눅스 fork 동작 방식 설명 (파이썬 코드)
12810정성태8/27/20217384.NET Framework: 1107. .NET Core/5+에서 동적 컴파일한 C# 코드를 (Breakpoint도 활용하며) 디버깅하는 방법 - #line 지시자파일 다운로드1
12809정성태8/26/20218035.NET Framework: 1106. .NET Core/5+에서 C# 코드를 동적으로 컴파일/사용하는 방법 [1]파일 다운로드1
12808정성태8/25/20219293오류 유형: 758. go: ...: missing go.sum entry; to add it: go mod download ...
12807정성태8/25/20219234.NET Framework: 1105. C# 10 - (9) 비동기 메서드가 사용할 AsyncMethodBuilder 선택 가능파일 다운로드1
12806정성태8/24/20216861개발 환경 구성: 601. PyCharm - 다중 프로세스 디버깅 방법
12805정성태8/24/20218103.NET Framework: 1104. C# 10 - (8) 분해 구문에서 기존 변수의 재사용 가능파일 다운로드1
12804정성태8/24/20218919.NET Framework: 1103. C# 10 - (7) Source Generator V2 APIs
12803정성태8/23/20218428개발 환경 구성: 600. pip cache 디렉터리 옮기는 방법
12802정성태8/23/20218781.NET Framework: 1102. .NET Conf Mini 21.08 - WinUI 3 따라해 보기 [1]
12801정성태8/23/20218284.NET Framework: 1101. C# 10 - (6) record class 타입의 ToString 메서드를 sealed 처리 허용파일 다운로드1
12800정성태8/22/20218508개발 환경 구성: 599. PyCharm - (반대로) 원격 프로세스가 PyCharm에 디버그 연결하는 방법
12799정성태8/22/20218602.NET Framework: 1100. C# 10 - (5) 속성 패턴의 개선파일 다운로드1
12798정성태8/21/20219881개발 환경 구성: 598. PyCharm - 원격 프로세스를 디버그하는 방법
12797정성태8/21/20217615Windows: 197. TCP의 MSS(Maximum Segment Size) 크기는 고정된 것일까요?
12796정성태8/21/20218296.NET Framework: 1099. C# 10 - (4) 상수 문자열에 포맷 식 사용 가능파일 다운로드1
12795정성태8/20/20218869.NET Framework: 1098. .NET 6에 포함된 신규 BCL API - 스레드 관련
... 31  [32]  33  34  35  36  37  38  39  40  41  42  43  44  45  ...