Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 2개 있습니다.)
(시리즈 글이 6개 있습니다.)
사물인터넷: 9. Visual Studio 2017에서 Raspberry Pi C++ 응용 프로그램 제작
; https://www.sysnet.pe.kr/2/0/11358

개발 환경 구성: 339. WSL을 이용해 윈도우 PC 1대에서 Linux 응용 프로그램을 Visual Studio로 개발하는 방법
; https://www.sysnet.pe.kr/2/0/11390

개발 환경 구성: 340. WSL을 이용해 윈도우 PC 1대에서 openSUSE 응용 프로그램을 Visual Studio로 개발하는 방법
; https://www.sysnet.pe.kr/2/0/11391

개발 환경 구성: 428. Visual Studio 2019 - CMake를 이용한 리눅스 빌드 환경 설정
; https://www.sysnet.pe.kr/2/0/11825

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

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




Visual Studio 2019 - CMake를 이용한 리눅스 빌드 환경 설정

저도 이제 리눅스를 피해 갈 수가 없군요. ^^ 그래서, 간단한 예제 프로젝트를 CMake로 구성해 봤습니다.

우선, 아래의 글로 SSH 연결까지 완료하고,

WSL을 이용해 윈도우 PC 1대에서 Linux 응용 프로그램을 Visual Studio로 개발하는 방법
; https://www.sysnet.pe.kr/2/0/11390

남은 작업은 아래의 글에 따라 진행하면 됩니다.

Visual C++ for Linux Development with CMake
; https://devblogs.microsoft.com/cppblog/visual-c-for-linux-development-with-cmake/

위의 글을 대충 정리해 보면,

1. 폴더를 만든 후 (예: cmtest)

2. 폴더에 다음의 내용을 담은 CMakeList.txt 파일을 생성합니다. (CMakeList.txt는 비주얼 스튜디오의 경우 .csproj 파일이라고 보면 됩니다.)

project (hello)
add_executable(hello hello.cpp)

의미는, project 이름이 "hello"이고 hello.cpp를 빌드해 "hello"라는 이름의 실행 파일이 생성된다는 것입니다.

큰 의미가 없지만 hello.cpp는 예제로 다음과 같이 간단하게 만들고,

#include <iostream>
#include <unistd.h>

int main(int argc, char* argv[])
{
	std::cout << "Hello" << std::endl;
}

3. Visual Studio에서 "File" / "Open" / "Folder..." 메뉴를 이용해 CMakeList.txt 파일이 있는 폴더(이 글에서는 "c:\cmtest")를 엽니다. 그럼 기본적으로 Configuration 설정이 "x64-Debug (default)"로 나오고 "Select Startup Item..."에는 "Current Document"와 "hello" 항목이 보입니다.

Startup Item을 "hello"로 설정하고 빌드 버튼을 누르면 unistd.h 파일이 윈도우에서는 제공되지 않으므로 빌드 오류가 발생합니다. (당연히 인텔리센스 기능도 제공받지 못합니다.) 물론, 해당 include 라인을 주석 처리하고 빌드하면 기본적으로 Windows x64 대상의 바이너리가 생성됩니다.




하지만, 우리가 원하는 것은 리눅스 머신에 연결해 ELF 바이너리를 생성하는 것입니다. 따라서 "Configuration" 목록을 열어 "x64-Debug (default)" 대신 "Manage Configurations..."를 선택해 리눅스 용 CMake 설정을 추가합니다. 그럼 프로젝트 폴더에 "CMakeSettings.json" 파일이 생성되고 비주얼 스튜디오는 그 파일을 편집할 수 있는 "CMake Settings" 화면을 띄웁니다.

linux_basic_build_env_1.png

위의 상태에서 "Remote Machine Name" 항목에 우측의 "Connection" 버튼을 눌러 빌드를 위한 원격 리눅스 머신의 SSH 연결을 설정합니다. 그럼 이와 함께 비주얼 스튜디오는 자동으로 대상 리눅스 머신의 환경을 열람해 C/C++ 헤더 파일을 로컬에 다음의 하위 폴더로 캐시합니다.

%LOCALAPPDATA%\Microsoft\Linux\HeaderCache

이제 "$(defaultRemoteMachineName)" 항목을 새롭게 생성된 연결 정보로 바꾼 후 "CMakeSettings.json" 파일을 명시적으로 저장해 줍니다. 그럼, 비주얼 스튜디오는 대상 머신에 연결해 적절한 버전의 "CMake"가 설치되어 있는지 확인합니다. 만약 없다면 비주얼 스튜디오 툴바 하단에 다음과 같은 메시지로 자동 설치를 유도합니다.

Supported CMake version is not present on '...[linux_machine_addr]...'. Instal CMake binaries build by Micrsofot? Yes No

이때 "Yes" 버튼을 누르면 비주얼 스튜디오는 대상 리눅스 측에 연결한 계정의 프로파일 폴더 하위로 cmake를 설치합니다.

~/.vs/cmake/bin

현재 버전을 보면 3.13이 설치됩니다.

~/.vs/cmake/bin$ ./cmake --version
cmake version 3.13.18112701-MSVC_2

CMake suite maintained and supported by Kitware (kitware.com/cmake).

개발 환경 설정은 이걸로 끝입니다. 이제 Configuration 설정은 "Linux-Debug"로 되고 "Build" / "Build All" 메뉴를 선택하면 소스 코드 파일이 다음의 경로에 배포되고,

/var/tmp/src/0b05273f-166e-a43b-8180-0c36846c9dce/Linux-Debug/

${workspaceHash} == 0b05273f-166e-a43b-8180-0c36846c9dce

바이너리 파일도 유사한 경로에 놓입니다.

/var/tmp/build/0b05273f-166e-a43b-8180-0c36846c9dce/build/Linux-Debug/

${workspaceHash} == 0b05273f-166e-a43b-8180-0c36846c9dce




참고로, WSL(Windows Subsystem for Linux)의 경우 설정이 매끄럽게 안 됩니다. 가령 인텔리센스를 위한 헤더 파일 다운로드가 안 되는 등의 문제(어떤 경우에는 잘 되고. ^^;)가 있는데 차라리 처음부터 간단한 예제 만들 거 아니면 리눅스 전용 빌드 머신을 구성하는 것을 권장합니다. 이 부분은 점차로 나아지겠지만 아직은 아닌 것 같습니다.

부가적으로, 빌드 결과물이 "/var/tmp/build/0b05273f-166e-a43b-8180-0c36846c9dce/build/Linux-Debug/"처럼 복잡하니까 좀 더 간단한 경로로 복사하고 싶을 텐데요. 그래서 install 명령어를 다음과 같이 추가할 수 있습니다.

cmake_minimum_required(VERSION 3.9)

project (hello)

set (BINDIR "~/bin")
add_executable(hello hello.cpp)

install(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})

그런 다음 비주얼 스튜디오의 "Build" / "Install ${PROJECT_NAME}" 메뉴를 실행하면 "/var/tmp/build/0b05273f-166e-a43b-8180-0c36846c9dce/build/Linux-Debug/" 경로에 있는 ${PROJECT_NAME}에 해당하는 파일을 ${BINDIR}에 복사하게 됩니다.




CMake를 비주얼 스튜디오가 아닌 소스 코드 파일이 복사된 머신에서 하고 싶다면 다음과 같은 식으로 하면 된다고. ^^

# ${workspaceHash} == 0b05273f-166e-a43b-8180-0c36846c9dce

cd /var/tmp/src/0b05273f-166e-a43b-8180-0c36846c9dce/Linux-Debug/
cmake .
make install

또한, install 명령어에서 빌드 디렉터리(/var/tmp/build/0b05273f-166e-a43b-8180-0c36846c9dce/build/Linux-Debug/) 기준이 아닌, 소스 코드가 복사된 디렉터리(/var/tmp/src/0b05273f-166e-a43b-8180-0c36846c9dce/Linux-Debug/)를 기준으로 하고 싶다면 TARGETS 대신 FILES나 PROGRAMS를 사용하면 됩니다.

cmake_minimum_required(VERSION 3.9)

project (hello)

set (BINDIR "~/bin")
add_executable(hello hello.cpp)

install(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})

install(FILES ${PROJECT_NAME}.cpp DESTINATION ${BINDIR})

FILES와 PROGRAMS는 사용법은 같은데, PROGRAMS의 경우에만 복사된 파일에 대해 실행 권한 등의 속성을 부여한다고 합니다. ^^ (리눅스 초보라 회사 동료에게 여러 가지 물어보게 되는군요. ^^)




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

[연관 글]






[최초 등록일: ]
[최종 수정일: 2/25/2019]

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

비밀번호

댓글 작성자
 



2019-09-17 08시10분
[참조합니다.] 저도 어디서 퍼온건데 WSL에서는 이렇게 하니까 해더파일을 긁어와서 intellisense가 되더라구요.
1. Rename the HeaderCache?settings.xml.unused?file to?settings.xml
2. Change the syncMethod to?sftp_ssh
3. Update?from Tools->Options->Cross Platform->Connection Manager->Remote Headers Intellisense Manager

[guest]

... 31  32  33  34  [35]  36  37  38  39  40  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
12754정성태8/5/20218094오류 유형: 750. manage.py - Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
12753정성태8/5/20218362오류 유형: 749. PyCharm - Error: Django is not importable in this environment
12752정성태8/4/20216440개발 환경 구성: 592. JetBrains의 IDE(예를 들어, PyCharm)에서 Visual Studio 키보드 매핑 적용
12751정성태8/4/20219518개발 환경 구성: 591. Windows 10 WSL2 환경에서 docker-compose 빌드하는 방법
12750정성태8/3/20216302디버깅 기술: 181. windbg - 콜 스택의 "Call Site" 오프셋 값이 가리키는 위치
12749정성태8/2/20215722개발 환경 구성: 590. Visual Studio 2017부터 단위 테스트에 DataRow 특성 지원
12748정성태8/2/20216322개발 환경 구성: 589. Azure Active Directory - tenant의 관리자(admin) 계정 로그인 방법
12747정성태8/1/20216929오류 유형: 748. 오류 기록 - MICROSOFT GRAPH – HOW TO IMPLEMENT IAUTHENTICATIONPROVIDER파일 다운로드1
12746정성태7/31/20218947개발 환경 구성: 588. 네트워크 장비 환경을 시뮬레이션하는 Packet Tracer 프로그램 소개
12745정성태7/31/20216777개발 환경 구성: 587. Azure Active Directory - tenant의 관리자 계정 로그인 방법
12744정성태7/30/20217386개발 환경 구성: 586. Azure Active Directory에 연결된 App 목록을 확인하는 방법?
12743정성태7/30/20218065.NET Framework: 1083. Azure Active Directory - 외부 Token Cache 저장소를 사용하는 방법파일 다운로드1
12742정성태7/30/20217327개발 환경 구성: 585. Azure AD 인증을 위한 사용자 인증 유형
12741정성태7/29/20218535.NET Framework: 1082. Azure Active Directory - Microsoft Graph API 호출 방법파일 다운로드1
12740정성태7/29/20217215오류 유형: 747. SharePoint - InvalidOperationException 0x80131509
12739정성태7/28/20217169오류 유형: 746. Azure Active Directory - IDW10106: The 'ClientId' option must be provided.
12738정성태7/28/20217753오류 유형: 745. Azure Active Directory - Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI).
12737정성태7/28/20216722오류 유형: 744. Azure Active Directory - The resource principal named api://...[client_id]... was not found in the tenant
12736정성태7/28/20217226오류 유형: 743. Active Azure Directory에서 "API permissions"의 권한 설정이 "Not granted for ..."로 나오는 문제
12735정성태7/27/20217755.NET Framework: 1081. C# - Azure AD 인증을 지원하는 데스크톱 애플리케이션 예제(Windows Forms) [2]파일 다운로드1
12734정성태7/26/202123754스크립트: 20. 특정 단어로 시작하거나/끝나는 문자열을 포함/제외하는 정규 표현식 - Look-around
12733정성태7/23/202111098.NET Framework: 1081. Self-Contained/SingleFile 유형의 .NET Core/5+ 실행 파일을 임베딩한다면? [1]파일 다운로드2
12732정성태7/23/20216384오류 유형: 742. SharePoint - The super user account utilized by the cache is not configured.
12731정성태7/23/20217529개발 환경 구성: 584. Add Internal URLs 화면에서 "Save" 버튼이 비활성화 된 경우
12730정성태7/23/20219053개발 환경 구성: 583. Visual Studio Code - Go 코드에서 입력을 받는 경우
12729정성태7/22/20218001.NET Framework: 1080. xUnit 단위 테스트에 메서드/클래스 수준의 문맥 제공 - Fixture
... 31  32  33  34  [35]  36  37  38  39  40  41  42  43  44  45  ...