소개
vcpkg는 microsoft에서 개발한 패키지 매니저로, 파이썬의 pip와 같이 커맨드라인을 통해 패키지를 설치할 수 있도록 하는 프로그램이다.
이 글에서는 내가 직접 Microsoft/vcpkg 레포지토리에 PR을 올려 머지된 경험을 바탕으로 작성되었다.
더 자세한 내용은 여기를 참고해보자.
순서
vcpkg에 새로운 패키지를 업로드하는 과정은 다음과 같다.
- CMakeList 수정
- vcpkg 포크(fork) 후 리모트 변경
- port 작성 후 커밋 & push
- 최종적 PR 보내기
vcpkg에서 port란
vcpkg에는 우리가 작성한 라이브러리 코드가 들어있지 않고, 저장소의 이름과 버전 SHA 해시를 가지고 있다.
우리가 작성해야 하는 port는 각각의 라이브러리의 버전과 설치 방법에 대한 내용이 담겨있는 정보이다.
사용자는 개발자가 작성한 port를 통해 원격 저장소를 통해 라이브러리를 설치하게 된다.
1. CMakeList 수정
먼저 라이브러리의 CMakeList.txt를 수정해보자. 만약 Visual Studio나 Xcode를 사용하고 있다면 CMake로 전환하자. CMakeList.txt에서 수정 할 것은 vcpkg의 규격에 맞도록 네임스페이스와 export, install 명령어를 추가해야 한다.
대략적인 명령어 구문은 다음과 같다.
# definition
string(REPLACE "/${CMAKE_LIBRARY_ARCHITECTURE}" "" CMAKE_INSTALL_LIBDIR_ARCHIND "${CMAKE_INSTALL_LIBDIR}")
set(EXPORT_NAMESPACE "${PROJECT_NAME}::")
set(CMAKE_CONFIG_FILE_BASENAME "${PROJECT_NAME}Config.cmake")
set(CMAKE_EXPORT_FILE_BASENAME "${PROJECT_NAME}Export.cmake")
# install & export
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
export(TARGETS "${PROJECT_NAME}"
NAMESPACE "${EXPORT_NAMESPACE}"
FILE "${CMAKE_EXPORT_FILE_BASENAME}"
EXPORT_LINK_INTERFACE_LIBRARIES)
install(EXPORT "${PROJECT_NAME}"
FILE "${CMAKE_CONFIG_FILE_BASENAME}"
NAMESPACE "${EXPORT_NAMESPACE}"
DESTINATION "${CMAKE_INSTALL_LIBDIR_ARCHIND}/cmake/${PROJECT_NAME}")
2. vcpkg 포크(fork) 후 리모트 변경
vcpkg가 설치되어있지 않다면 이 글을 참고해 설치하자.
먼저 vcpkg의 레포지토리에서 fork를 한 뒤, vcpkg가 설치된 디렉토리로 이동 후 다음 명령어를 통해 remote를 추가해주자.
> git remote add myfork <내가_포크한_vcpkg레포지토리_URL>
3. port 작성
port의 요소로는 portfile.cmake, usage, vcpkg.json이 있다. portfile.cmake는 라이브러리의 설치에 대한 정보를 작성하고, usage는 라이브러리의 타겟, vcpkg에는 라이브러리의 릴리즈 버전, 종속성을 작성한다.
먼저 작업할 branch를 만들고, vcpkg/ports/ 에 새로운 폴더를 만들어 작업하자.
※주의 파일의 맨 끝은 공백줄로 끝나야 한다.
vcpkg.json
{
"name": <이름>,
"version": <릴리즈_버전>,
"description": <소개_및_설명>,
"homepage": <홈페이지_URL>,
"license": <라이선스>,
"supports": <지원_플랫폼>
"dependencies": [
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
},
<추가_종속성>...
]
}
visual studio로 작성하게 되면 scheme를 자동으로 인식한다.
usage
<이름> provides CMake targets:
find_package(<이름> CONFIG REQUIRED)
target_link_libraries(main PRIVATE <CMAKE_네임스페이스>::<이름>)
portfile.cmake
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO <레포지토리_URL>
REF "${VERSION}" # VERSION은 vcpkg.json에서 작성한 version값이다. 깃허브의 릴리즈 태그와 일치해야 한다.
SHA512 0 # 나중에 채워 넣을 예정
HEAD_REF <메인_브렌치>
)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
)
vcpkg_cmake_install()
vcpkg_cmake_config_fixup(CONFIG_PATH lib/cmake/<이름> PACKAGE_NAME <이름>)
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
configure_file("${CMAKE_CURRENT_LIST_DIR}/usage" "${CURRENT_PACKAGES_DIR}/share/${PORT}/usage" COPYONLY)
추가적인 vcpkg명령어는 learn.microsoft를 참고.
작성이 완료됬다면 커맨드 라인으로 다음을 실행해 해시값을 추출해보자.
vcpkg install <이름>
그럼 애러와 함께 다음이 출력될 것이다.
Expected hash: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Actual hash: <해시값>
portfile.cmake의 SHA512에서 0으로 지정된 값을 출력된 해시로 변경하자.
다시 설치를 시도하면 설치에 성공하는것을 볼 수 있다.
설치에 성공했다면 다음 명령어를 실행해 vcpkg의 버전 데이터베이스에 추가하자.
vcpkg x-add-version <이름>
마지막으로 변경사항을 커밋 한 뒤 myfork로 push하자.
4. PR 보내기
최종적으로 패키지를 publish하기 위해 github에서 내가 fork한 vcpkg로 가서 PR를 보내보자.
PR의 형식은 다음과 같이 [<이름>] 요청사항 으로 작성하면 된다.
그리고 무수히 많은 체크박스가 있는데, 약관사항?이라 보면 된다. 하나씩 읽어본 뒤 체크하면 된다.
만약 마이크로소프트에 처음 PR을 보내면 봇의 코멘트가 올 수 있다.
마이크로소프트 기여에 대한 약관이므로 자세히 잃어본 뒤 @microsoft-github-policy-service agree 를 코멘트로 보내 약관을 수락하자.
PR을 보내거나, 새로 커밋을 한다면 깃허브에서 CI 액션이 시작될 것이다. PR 요청자는 모든 항목이 통과해야 master에 머지를 할 수 있게 된다. CI와 별개로 마이크로소프의 코드 리뷰어의 리뷰가 시작된다.
코드를 수정하게 된다면, 반드시 vcpkg x-add-version <이름> --overwrite-version를 통해 갱신시켜줘야 한다.
리뷰어의 모든 요청사항 수정을 마친다면 info:reviewed 태그가 붙게 된다. 다른 리뷰어의 approve를 받게 된다면 최종적으로 master에 머지가 된다.
이로써 vcpkg에서 내가 개발한 라이브러리를 설치할 수 있게 된다.
처음으로 마소에 PR을 보내는 정말 특별한 경험이였다. 물론 직접적인 기여는 아니지만, 대형 오픈소스의 개발 방식에 대한 경험을 쌓을 수 있는 정말 좋은 경험이 된 것 같다.
'C++' 카테고리의 다른 글
[C++] 메모리 뷰에서의 다중 상속, 캐스팅 (0) | 2024.08.15 |
---|---|
[C++] 제대로 알고 사용하자. atd::async (0) | 2024.07.13 |
[C++] C++에서 라이브러리를 관리해보자 (0) | 2024.06.27 |
[C++/Unreal] 커스텀 RPC 구현 기록 (0) | 2024.05.31 |
[C++] 에러코드를 메세지로 format하기 (0) | 2023.11.17 |