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)
12679정성태6/18/20218877COM 개체 관련: 23. CoInitializeSecurity의 전역 설정을 재정의하는 CoSetProxyBlanket 함수 사용법파일 다운로드1
12678정성태6/17/20218100.NET Framework: 1072. C# - CoCreateInstance 관련 Inteop 오류 정리파일 다운로드1
12677정성태6/17/20219596VC++: 144. 역공학을 통한 lxssmanager.dll의 ILxssSession 사용법 분석파일 다운로드1
12676정성태6/16/20219652VC++: 143. ionescu007/lxss github repo에 공개된 lxssmanager.dll의 CLSID_LxssUserSession/IID_ILxssSession 사용법파일 다운로드1
12675정성태6/16/20217671Java: 20. maven package 명령어 결과물로 (war가 아닌) jar 생성 방법
12674정성태6/15/20218442VC++: 142. DEFINE_GUID 사용법
12673정성태6/15/20219609Java: 19. IntelliJ - 자바(Java)로 만드는 Web App을 Tomcat에서 실행하는 방법
12672정성태6/15/202110748오류 유형: 725. IntelliJ에서 Java webapp 실행 시 "Address localhost:1099 is already in use" 오류
12671정성태6/15/202117463오류 유형: 724. Tomcat 실행 시 Failed to initialize connector [Connector[HTTP/1.1-8080]] 오류
12670정성태6/13/20218987.NET Framework: 1071. DLL Surrogate를 이용한 Out-of-process COM 개체에서의 CoInitializeSecurity 문제파일 다운로드1
12669정성태6/11/20218965.NET Framework: 1070. 사용자 정의 GetHashCode 메서드 구현은 C# 9.0의 record 또는 리팩터링에 맡기세요.
12668정성태6/11/202110719.NET Framework: 1069. C# - DLL Surrogate를 이용한 Out-of-process COM 개체 제작파일 다운로드2
12667정성태6/10/20219336.NET Framework: 1068. COM+ 서버 응용 프로그램을 이용해 CoInitializeSecurity 제약 해결파일 다운로드1
12666정성태6/10/20217955.NET Framework: 1067. 별도 DLL에 포함된 타입을 STAThread Main 메서드에서 사용하는 경우 CoInitializeSecurity 자동 호출파일 다운로드1
12665정성태6/9/20219274.NET Framework: 1066. Wslhub.Sdk 사용으로 알아보는 CoInitializeSecurity 사용 제약파일 다운로드1
12664정성태6/9/20217566오류 유형: 723. COM+ PIA 참조 시 "This operation failed because the QueryInterface call on the COM component" 오류
12663정성태6/9/20219077.NET Framework: 1065. Windows Forms - 속성 창의 디자인 설정 지원: 문자열 목록 내에서 항목을 선택하는 TypeConverter 제작파일 다운로드1
12662정성태6/8/20218234.NET Framework: 1064. C# COM 개체를 PIA(Primary Interop Assembly)로써 "Embed Interop Types" 참조하는 방법파일 다운로드1
12661정성태6/4/202118853.NET Framework: 1063. C# - MQTT를 이용한 클라이언트/서버(Broker) 통신 예제 [4]파일 다운로드1
12660정성태6/3/20219959.NET Framework: 1062. Windows Forms - 폼 내에서 발생하는 마우스 이벤트를 자식 컨트롤 영역에 상관없이 수신하는 방법 [1]파일 다운로드1
12659정성태6/2/202111232Linux: 40. 우분투 설치 후 MBR 디스크 드라이브 여유 공간이 인식되지 않은 경우 - Logical Volume Management
12658정성태6/2/20218659Windows: 194. Microsoft Store에 있는 구글의 공식 Youtube App
12657정성태6/2/20219948Windows: 193. 윈도우 패키지 관리자 - winget 설치
12656정성태6/1/20218166.NET Framework: 1061. 서버 유형의 COM+에 적용할 수 없는 Server GC
12655정성태6/1/20217709오류 유형: 722. windbg/sos - savemodule - Fail to read memory
12654정성태5/31/20217728오류 유형: 721. Hyper-V - Saved 상태의 VM을 시작 시 오류 발생
... 31  32  33  34  35  36  37  [38]  39  40  41  42  43  44  45  ...