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

비밀번호

댓글 작성자
 




... 181  182  183  184  185  186  187  188  189  190  191  192  193  194  [195]  ...
NoWriterDateCnt.TitleFile(s)
68정성태10/31/200422026.NET Framework: 17. Win32_NTLogEvent를 c#에서 wmi 쿼리할 때..에러..
67정성태10/22/200419245COM 개체 관련: 12. Microsoft.XMLHTTP 개체에서 Microsoft.XMLDOM 개체를 전송할 때 charset 지정 문제?
66정성태10/16/200420414.NET Framework: 16. [닷넷 리모팅] 프록시가 죽은 것을 원격 개체가 알 수 있는 방법은?
65정성태10/16/200419428VS.NET IDE: 8. Windows 가상 메모리 사용 해제
64정성태10/3/200423119.NET Framework: 15. ASP.NET에서 .NET COM+ 개체 등록 시 "Local System"이어야 하는 이유.
63정성태10/3/200423253.NET Framework: 14. Response.Cookies.Clear는 기존 설정된 Cookie 헤더를 삭제하는 것이 아닙니다.
62정성태10/3/200422221기타: 7. DB 트랜잭션에서 Lock이 걸릴 수 있는 전형적인 예.
61정성태10/3/200421744.NET Framework: 13. Main 메서드에 붙은 STAThread 의미
60정성태10/3/200420461.NET Framework: 12. IDispatch::GetIDsOfNames 역변환 메서드 작성 힌트 ( DISPID 로 메서드 이름 알아내는 것 )
58정성태10/3/200423557.NET Framework: 11. HttpContext의 간략이해
56정성태10/3/200420019.NET Framework: 10. [.NET 리모팅] 원격개체를 호출한 클라이언트의 연결이 유효한지 판단하는 방법.
55정성태10/3/200420781COM 개체 관련: 11. 내가 생각해 보는 COM의 현재 위치
54정성태8/30/200426439VC++: 10. 내가 생각해 보는 MFC OCX와 ATL DLL에 선택 기준
53정성태11/20/200525775VC++: 9. CFtpFileFind/FtpFileFind가 일부 Unix FTP 서버에서 목록을 제대로 못 가져오는 문제
184정성태11/23/200519427    답변글 VC++: 9.1. FTP 관련 토픽파일 다운로드1
51정성태6/24/200424345VC++: 8. BSTR 메모리 할당 및 해제(MSDN Library 발췌) [1]
50정성태6/16/200417703기타: 6. 1차 데스크톱 컴퓨터 사양
49정성태6/16/200418189기타: 5. 53만 원대 Second PC 마련. ^^
48정성태3/2/200420086.NET Framework: 9. 윈도우즈 발전사를 모아 둔 사이트. [1]
47정성태11/14/200518589VS.NET IDE: 7. 한글 OS에서 Internet Explorer 6.0 with SP1의 UI 언어 바꾸는 방법
45정성태1/26/200417980기타: 4. MCAD 시험
44정성태1/26/200418775VS.NET IDE: 6. 터미널 서비스 포트 변경 ( 서버 및 클라이언트 )
46정성태1/26/200423823    답변글 VS.NET IDE: 6.1. Windows 2003 터미널 서비스 라이센스 서버 없이 접속
114정성태11/14/200515208    답변글 VS.NET IDE: 6.2. [터미널 서버 라이센스] : 활성화 시 오류
43정성태12/23/200318415기타: 3. XP/2003 개인 방화벽 설정파일 다운로드1
40정성태7/23/200321905COM 개체 관련: 10. IE BHO 개체를 개발할 때, 인터넷 익스플로러가 아닌 탐색기에서 활성화 되는 문제 해결 [1]
... 181  182  183  184  185  186  187  188  189  190  191  192  193  194  [195]  ...