i007.cc

i007.cc

优先队列-降维打击

手把手制作一个vcpkg的安装包及port file相关说明

0. 前言

Windows平台的程序包的依赖管理一直以来都是个大难题。之前有NuGet,现在有vcpkg
本文的重点是先介绍一下vcpkg的特性,然后以一个实际例子说明,说明如何创建一个vcpkg安装包。

1. vcpkg简介

vcpkg是为了在windows平台能够方便获取一个C或者C++库。当前还处于预览版状态。不过已经有很多常见的库了,例如:

  • openssl
  • boost
  • zlib
  • glog
  • libevent
  • curl

等等,很多知名的C/C++库都已经提供vcpkg安装包。

2. vcpkg安装

首先,我们的windows系统必须安装有下列软件

  • Visual Studio 2015 Update 3 or
  • Visual Studio 2017
  • CMake 3.8.0 or higher (note: downloaded automatically if not found)
  • git.exe available in your path

然后,我们在windows命令行终端上运行:

  1. d:\git> git clone https://github.com/Microsoft/vcpkg
  2. d:\git> cd vcpkg
  3. d:\git\vcpkg> .\bootstrap-vcpkg.bat
  4. d:\git\vcpkg> .\vcpkg integrate install

3. 使用vcpkg获取C/C++库

使用vcpkg --help命令查看联席帮助文档:

  1. D:\git\vcpkg>.\vcpkg –help
  2. Commands:
  3. vcpkg search [pat] Search for packages available to be built
  4. vcpkg install <pkg>… Install a package
  5. vcpkg remove <pkg>… Uninstall a package
  6. vcpkg remove –outdated Uninstall all out-of-date packages
  7. vcpkg list List installed packages
  8. vcpkg update Display list of packages for updating
  9. vcpkg hash <file> [alg] Hash a file by specific algorithm, default SHA512
  10. vcpkg integrate install Make installed packages available user-wide. Requires admin privileges on first use
  11. vcpkg integrate remove Remove user-wide integration
  12. vcpkg integrate project Generate a referencing nuget package for individual VS project use
  13. vcpkg export <pkg>… [opt]… Exports a package
  14. vcpkg edit <pkg> Open up a port for editing (uses %EDITOR%, default ‘code’)
  15. vcpkg import <pkg> Import a pre-built library
  16. vcpkg create <pkg> <url>
  17. [archivename] Create a new package
  18. vcpkg owns <pat> Search for files in installed packages
  19. vcpkg cache List cached compiled packages
  20. vcpkg version Display version information
  21. vcpkg contact Display contact information to send feedback
  22. Options:
  23. –triplet <t> Specify the target architecture triplet.
  24. (default: %VCPKG_DEFAULT_TRIPLET%, see ‘vcpkg help triplet’)
  25. –vcpkg-root <path> Specify the vcpkg root directory
  26. (default: %VCPKG_ROOT%)
  27. For more help (including examples) see the accompanying README.md.

这里我们可以看到,很多有用的命令

  • vcpkg search [pattern]
    • 搜索一个C/C++库
  • vcpkg install [pkg]
    • 安装一个C/C++库
  • vcpkg remove [pkg]
    • 卸载(删除)一个C/C++库

下面举例,安装curl这个常用的C语言写的网络库。

  1. D:\git\vcpkg>.\vcpkg install curl
  2. The following packages will be built and installed:
  3. curl:x86-windows
  4. * libssh2:x86-windows
  5. Additional packages (*) will be installed to complete this operation.
  6. Building package libssh2:x86-windows…
  7. — CURRENT_INSTALLED_DIR=D:/git/vcpkg/installed/x86-windows
  8. — DOWNLOADS=D:/git/vcpkg/downloads
  9. — CURRENT_PACKAGES_DIR=D:/git/vcpkg/packages/libssh2_x86-windows
  10. — CURRENT_BUILDTREES_DIR=D:/git/vcpkg/buildtrees/libssh2
  11. — CURRENT_PORT_DIR=D:/git/vcpkg/ports/libssh2/.
  12. — Downloading https://www.libssh2.org/download/libssh2-1.8.0.tar.gz…
  13. — Downloading https://www.libssh2.org/download/libssh2-1.8.0.tar.gz… OK
  14. — Testing integrity of downloaded file…
  15. — Testing integrity of downloaded file… OK
  16. — Extracting source D:/git/vcpkg/downloads/libssh2-1.8.0.tar.gz
  17. — Extracting done
  18. — Applying patch D:/git/vcpkg/ports/libssh2/0001-Fix-UWP.patch
  19. — Applying patch D:/git/vcpkg/ports/libssh2/0001-Fix-UWP.patch done
  20. — Configuring x86-windows-rel
  21. — Configuring x86-windows-rel done
  22. — Configuring x86-windows-dbg
  23. — Configuring x86-windows-dbg done
  24. — Package x86-windows-rel
  25. — Package x86-windows-rel done
  26. — Package x86-windows-dbg
  27. — Package x86-windows-dbg done
  28. Installing: D:/git/vcpkg/packages/libssh2_x86-windows/share/libssh2/copyright
  29. — Performing post-build validation
  30. — Performing post-build validation done
  31. Building package libssh2:x86-windows… done
  32. Installing package libssh2:x86-windows…
  33. Installing package libssh2:x86-windows… done
  34. Building package curl:x86-windows…
  35. — CURRENT_INSTALLED_DIR=D:/git/vcpkg/installed/x86-windows
  36. — DOWNLOADS=D:/git/vcpkg/downloads
  37. — CURRENT_PACKAGES_DIR=D:/git/vcpkg/packages/curl_x86-windows
  38. — CURRENT_BUILDTREES_DIR=D:/git/vcpkg/buildtrees/curl
  39. — CURRENT_PORT_DIR=D:/git/vcpkg/ports/curl/.
  40. — Downloading https://github.com/curl/curl/archive/curl-7_51_0.tar.gz…
  41. — Downloading https://github.com/curl/curl/archive/curl-7_51_0.tar.gz… OK
  42. — Testing integrity of downloaded file…
  43. — Testing integrity of downloaded file… OK
  44. — Extracting source D:/git/vcpkg/downloads/curl-7.51.0.tar.gz
  45. — Extracting done
  46. — Applying patch D:/git/vcpkg/ports/curl/0001_cmake.patch
  47. — Applying patch D:/git/vcpkg/ports/curl/0001_cmake.patch done
  48. — Applying patch D:/git/vcpkg/ports/curl/0002_fix_uwp.patch
  49. — Applying patch D:/git/vcpkg/ports/curl/0002_fix_uwp.patch done
  50. — Configuring x86-windows-rel
  51. — Configuring x86-windows-rel done
  52. — Configuring x86-windows-dbg
  53. — Configuring x86-windows-dbg done
  54. — Package x86-windows-rel
  55. — Package x86-windows-rel done
  56. — Package x86-windows-dbg
  57. — Package x86-windows-dbg done
  58. Installing: D:/git/vcpkg/packages/curl_x86-windows/share/curl/copyright
  59. — Performing post-build validation
  60. — Performing post-build validation done
  61. Building package curl:x86-windows… done
  62. Installing package curl:x86-windows…
  63. Installing package curl:x86-windows… done

可以看到,安装curl所需的依赖安装包libssh2也被自动安装处理好了。这类似与Linux系统下面的yum工具,自动处理rpm包的依赖关系,非常棒。

安装x64版本时,只需要在包名后面追加:x64-windows即可,例如 curl:x64-windows

  1. D:\git\vcpkg>.\vcpkg install curl:x64-windows
  2. The following packages will be built and installed:
  3. curl:x64-windows
  4. * libssh2:x64-windows
  5. Additional packages (*) will be installed to complete this operation.
  6. Building package zlib:x64-windows…

4. Step by step 手把手教你如何制作一个vcpkg安装包

a) 创建一个C库项目

这里我们直接创建项目 https://github.com/zieckey/vcpkgdemo

然后提交了一些简单的代码及 CMakeLists.txt。并打了一个tag 1.0。从而我们得到一个该项目源码的现在的地址https://github.com/zieckey/vcpkgdemo/archive/1.0.zip

b) 从源头开始创建一个vcpkg安装包项目:Bootstrap with create

  1. D:\git\vcpkg>.\vcpkg create vcpkgdemo https://github.com/zieckey/vcpkgdemo/archive/1.0.zip vcpkgdemo-1.0.zip
  2. — Generated portfile: D:\git\vcpkg\ports\vcpkgdemo\portfile.cmake
  3. — Generated CONTROL: D:\git\vcpkg\ports\vcpkgdemo\CONTROL
  4. — To launch an editor for these new files, run
  5. — .\vcpkg edit vcpkgdemo

我们可以看到,在D:\git\vcpkg\ports\目录下多出一个vcpkgdemo目录,并且目录下有两个文件portfile.cmakeCONTROL

c) 定制CONTROL文件

CONTROL文件原始内容如下:

  1. Source: vcpkgdemo
  2. Version:
  3. Description:

我们修改为下面内容:

  1. Source: vcpkgdemo
  2. Version: 1.0
  3. Description: A demo to show how to create a vcpkg package

d) 定制portfile.cmake文件

portfile.cmake文件原始内容如下:

  1. # Common Ambient Variables:
  2. # CURRENT_BUILDTREES_DIR = ${VCPKG_ROOT_DIR}\buildtrees\${PORT}
  3. # CURRENT_PACKAGES_DIR = ${VCPKG_ROOT_DIR}\packages\${PORT}_${TARGET_TRIPLET}
  4. # CURRENT_PORT DIR = ${VCPKG_ROOT_DIR}\ports\${PORT}
  5. # PORT = current port name (zlib, etc)
  6. # TARGET_TRIPLET = current triplet (x86-windows, x64-windows-static, etc)
  7. # VCPKG_CRT_LINKAGE = C runtime linkage type (static, dynamic)
  8. # VCPKG_LIBRARY_LINKAGE = target library linkage type (static, dynamic)
  9. # VCPKG_ROOT_DIR = <C:\path\to\current\vcpkg>
  10. # VCPKG_TARGET_ARCHITECTURE = target architecture (x64, x86, arm)
  11. #
  12. include(vcpkg_common_functions)
  13. set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/vcpkgdemo-1.0)
  14. vcpkg_download_distfile(ARCHIVE
  15. URLS “https://github.com/zieckey/vcpkgdemo/archive/1.0.zip”
  16. FILENAME “vcpkgdemo-1.0.zip”
  17. SHA512 8805850856abdd39afdafa78dbd3a9e1d57d1a19a97579facf4571a0980799483574163e5f9a877a1fa38d541b7a0820c8ae7db61ae896803a8f89c5c22e386a
  18. )
  19. vcpkg_extract_source_archive(${ARCHIVE})
  20. vcpkg_configure_cmake(
  21. SOURCE_PATH ${SOURCE_PATH}
  22. PREFER_NINJA # Disable this option if project cannot be built with Ninja
  23. # OPTIONS -DUSE_THIS_IN_ALL_BUILDS=1 -DUSE_THIS_TOO=2
  24. # OPTIONS_RELEASE -DOPTIMIZE=1
  25. # OPTIONS_DEBUG -DDEBUGGABLE=1
  26. )
  27. vcpkg_install_cmake()
  28. # Handle copyright
  29. #file(COPY ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/vcpkgdemo)
  30. #file(RENAME ${CURRENT_PACKAGES_DIR}/share/vcpkgdemo/LICENSE ${CURRENT_PACKAGES_DIR}/share/vcpkgdemo/copyright)

我们将其修改为下面内容:

  1. include(vcpkg_common_functions)
  2. set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/vcpkgdemo-1.0)
  3. vcpkg_download_distfile(ARCHIVE
  4. URLS “https://github.com/zieckey/vcpkgdemo/archive/1.0.zip”
  5. FILENAME “vcpkgdemo-1.0.zip”
  6. SHA512 5b526b848c05d9b30eac8aede6c6c19591baf45e601c54ed6a0aa40ae3f11545d9648f332fb991f9540e44cfc3fc3ea6dd6db3b6c9d8e076b74af08e9ac69740
  7. )
  8. message(STATUS “Begin to extract files …”)
  9. vcpkg_extract_source_archive(${ARCHIVE})
  10. message(STATUS “Building vcpkgdemo project …”)
  11. vcpkg_configure_cmake(
  12. SOURCE_PATH ${SOURCE_PATH}
  13. OPTIONS -DCMAKE_TOOLCHAIN_FILE=D:/git/vcpkg/scripts/buildsystems/vcpkg.cmake -DEVPP_VCPKG_BUILD=ON
  14. )
  15. vcpkg_install_cmake()
  16. file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/share)
  17. file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/share/vcpkgdemo)
  18. #remove duplicated files
  19. file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)
  20. # remove not used cmake files
  21. file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share )
  22. file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/lib/cmake )
  23. file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/lib/cmake )
  24. # Handle copyright
  25. file(COPY ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/vcpkgdemo)
  26. file(RENAME ${CURRENT_PACKAGES_DIR}/share/vcpkgdemo/LICENSE ${CURRENT_PACKAGES_DIR}/share/vcpkgdemo/copyright)
  27. message(STATUS “Installing done”)

e) 测试

  1. D:\git\vcpkg>.\vcpkg install vcpkgdemo
  2. The following packages will be built and installed:
  3. vcpkgdemo:x86-windows
  4. Building package vcpkgdemo:x86-windows…
  5. — CURRENT_INSTALLED_DIR=D:/git/vcpkg/installed/x86-windows
  6. — DOWNLOADS=D:/git/vcpkg/downloads
  7. — CURRENT_PACKAGES_DIR=D:/git/vcpkg/packages/vcpkgdemo_x86-windows
  8. — CURRENT_BUILDTREES_DIR=D:/git/vcpkg/buildtrees/vcpkgdemo
  9. — CURRENT_PORT_DIR=D:/git/vcpkg/ports/vcpkgdemo/.
  10. — Using cached D:/git/vcpkg/downloads/vcpkgdemo-1.0.zip
  11. — Testing integrity of cached file…
  12. — Testing integrity of cached file… OK
  13. — Begin to extract files …
  14. — Extracting source D:/git/vcpkg/downloads/vcpkgdemo-1.0.zip
  15. — Extracting done
  16. — Building vcpkgdemo project …
  17. — Configuring x86-windows-rel
  18. — Configuring x86-windows-rel done
  19. — Configuring x86-windows-dbg
  20. — Configuring x86-windows-dbg done
  21. — Package x86-windows-rel
  22. — Package x86-windows-rel done
  23. — Package x86-windows-dbg
  24. — Package x86-windows-dbg done
  25. — Installing done
  26. — Performing post-build validation
  27. — Performing post-build validation done
  28. Building package vcpkgdemo:x86-windows… done
  29. Installing package vcpkgdemo:x86-windows…
  30. Installing package vcpkgdemo:x86-windows… done

如果不顺利,有错误发生的话,可以根据错误提示去 D:/git/vcpkg/buildtrees/vcpkgdemo 找错误日志,并解决。

f) 将D:\git\vcpkg\ports\vcpkgdemo整个目录提交到https://github.com/Microsoft/vcpkg

为了让这个vcpkg包能够被其世界上任何他人使用,我们必须将port file提交到https://github.com/Microsoft/vcpkg项目中。

也就是我们需要发起一个Pull Request到vcpkg的官方github地址 https://github.com/Microsoft/vcpkg

这里不再累述。

5. Step by step 手把手教你如何制作一个vcpkg安装包:实际案例

这里我们以evpp项目为例。evpp是一个基于libevent开发的现代化C++11高性能网络服务器,自带TCP/UDP/HTTP等协议的异步非阻塞式的服务器和客户端库。

第1步:从源头开始创建一个项目:Bootstrap with create

首先,我们需要有一个网络上可供下载的安装包地址,在这里我们选择https://github.com/Qihoo360/evpp/archive/v0.5.0.zip
然后,我们需要为项目取一个好记的名字,最好是小写字母,这里我们选择 evpp
最后,使用vcpkg create创建一个项目模板

  1. D:\git\vcpkg>.\vcpkg create evpp https://github.com/Qihoo360/evpp/archive/v0.5.0.zip evpp-0.5.0.zip
  2. — Generated portfile: D:\git\vcpkg\ports\evpp\portfile.cmake
  3. — Generated CONTROL: D:\git\vcpkg\ports\evpp\CONTROL
  4. — To launch an editor for these new files, run
  5. — .\vcpkg edit evpp

我们可以看到,在D:\git\vcpkg\ports\目录下多出一个evpp目录,并且目录下有两个文件portfile.cmakeCONTROL

第2步:定制CONTROL文件

CONTROL文件原始内容如下:

  1. Source: evpp
  2. Version:
  3. Description:

我们修改为下面内容:

  1. Source: evpp
  2. Version: 0.5.0
  3. Description: A modern C++ network library based on libevent for developing high performance network services in TCP/UDP/HTTP protocols.
  4. Build-Depends: glog, libevent

注意上面的依赖库写法,evpp依赖两个项目 glog 和 libevent,所以写法是 Build-Depends: glog, libevent

第3步:定制portfile.cmake文件

portfile.cmake文件原始内容如下:

  1. # Common Ambient Variables:
  2. # CURRENT_BUILDTREES_DIR = ${VCPKG_ROOT_DIR}\buildtrees\${PORT}
  3. # CURRENT_PACKAGES_DIR = ${VCPKG_ROOT_DIR}\packages\${PORT}_${TARGET_TRIPLET}
  4. # CURRENT_PORT DIR = ${VCPKG_ROOT_DIR}\ports\${PORT}
  5. # PORT = current port name (zlib, etc)
  6. # TARGET_TRIPLET = current triplet (x86-windows, x64-windows-static, etc)
  7. # VCPKG_CRT_LINKAGE = C runtime linkage type (static, dynamic)
  8. # VCPKG_LIBRARY_LINKAGE = target library linkage type (static, dynamic)
  9. # VCPKG_ROOT_DIR = <C:\path\to\current\vcpkg>
  10. # VCPKG_TARGET_ARCHITECTURE = target architecture (x64, x86, arm)
  11. #
  12. include(vcpkg_common_functions)
  13. set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/evpp-0.5.0)
  14. vcpkg_download_distfile(ARCHIVE
  15. URLS “https://github.com/Qihoo360/evpp/archive/v0.5.0.zip”
  16. FILENAME “evpp-0.5.0.zip”
  17. SHA512 fce8ebfec8b22b137f827a886f9ef658d70e060cef3950600ac42136d87cdd9357d78897348ed1d1c112c5e04350626fb218b02cba190a2c2a6fb81136eb2d7d
  18. )
  19. vcpkg_extract_source_archive(${ARCHIVE})
  20. vcpkg_configure_cmake(
  21. SOURCE_PATH ${SOURCE_PATH}
  22. PREFER_NINJA # Disable this option if project cannot be built with Ninja
  23. # OPTIONS -DUSE_THIS_IN_ALL_BUILDS=1 -DUSE_THIS_TOO=2
  24. # OPTIONS_RELEASE -DOPTIMIZE=1
  25. # OPTIONS_DEBUG -DDEBUGGABLE=1
  26. )
  27. vcpkg_install_cmake()
  28. # Handle copyright
  29. #file(COPY ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/evpp)
  30. #file(RENAME ${CURRENT_PACKAGES_DIR}/share/evpp/LICENSE ${CURRENT_PACKAGES_DIR}/share/evpp/copyright)

我们将其修改为下面内容:

  1. include(vcpkg_common_functions)
  2. set(EVPP_VERSION 0.5.0)
  3. set(EVPP_HASH fce8ebfec8b22b137f827a886f9ef658d70e060cef3950600ac42136d87cdd9357d78897348ed1d1c112c5e04350626fb218b02cba190a2c2a6fb81136eb2d7d)
  4. set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/evpp-${EVPP_VERSION})
  5. vcpkg_download_distfile(ARCHIVE
  6. URLS “https://github.com/Qihoo360/evpp/archive/v${EVPP_VERSION}.zip”
  7. FILENAME “evpp-${EVPP_VERSION}.zip”
  8. SHA512 ${EVPP_HASH}
  9. )
  10. message(STATUS “Begin to extract files …”)
  11. vcpkg_extract_source_archive(${ARCHIVE})
  12. message(STATUS “Building evpp project …”)
  13. vcpkg_configure_cmake(
  14. SOURCE_PATH ${SOURCE_PATH}
  15. OPTIONS -DCMAKE_TOOLCHAIN_FILE=D:/git/vcpkg/scripts/buildsystems/vcpkg.cmake -DEVPP_VCPKG_BUILD=ON
  16. )
  17. vcpkg_install_cmake()
  18. file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/share)
  19. file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/share/evpp)
  20. #remove duplicated files
  21. file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)
  22. # remove not used cmake files
  23. file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share )
  24. file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/lib/cmake )
  25. file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/lib/cmake )
  26. # Handle copyright
  27. file(COPY ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/evpp)
  28. file(RENAME ${CURRENT_PACKAGES_DIR}/share/evpp/LICENSE ${CURRENT_PACKAGES_DIR}/share/evpp/copyright)
  29. message(STATUS “Installing done”)

第4步:测试

  1. D:\git\vcpkg>.\vcpkg install evpp
  2. The following packages will be built and installed:
  3. evpp:x86-windows
  4. Building package evpp:x86-windows…
  5. — CURRENT_INSTALLED_DIR=D:/git/vcpkg/installed/x86-windows
  6. — DOWNLOADS=D:/git/vcpkg/downloads
  7. — CURRENT_PACKAGES_DIR=D:/git/vcpkg/packages/evpp_x86-windows
  8. — CURRENT_BUILDTREES_DIR=D:/git/vcpkg/buildtrees/evpp
  9. — CURRENT_PORT_DIR=D:/git/vcpkg/ports/evpp/.
  10. — Using cached D:/git/vcpkg/downloads/evpp-0.5.0.zip
  11. — Testing integrity of cached file…
  12. — Testing integrity of cached file… OK
  13. — Begin to extract files …
  14. — Extracting done
  15. — Building evpp project …
  16. — Configuring x86-windows-rel
  17. — Configuring x86-windows-rel done
  18. — Configuring x86-windows-dbg
  19. — Configuring x86-windows-dbg done
  20. — Package x86-windows-rel
  21. — Package x86-windows-rel done
  22. — Package x86-windows-dbg
  23. — Package x86-windows-dbg done
  24. — Installing done
  25. — Performing post-build validation
  26. — Performing post-build validation done
  27. Building package evpp:x86-windows… done
  28. Installing package evpp:x86-windows…
  29. Installing package evpp:x86-windows… done

第5步:将D:\git\vcpkg\ports\evpp整个目录提交到https://github.com/Microsoft/vcpkg

也就是我们需要发起一个Pull Request到vcpkg的官方github地址 https://github.com/Microsoft/vcpkg

这里不再累述。

6. 最后

evpp项目官网地址为:https://github.com/Qihoo360/evpp

vcpkg制作的安装包,已经提交Pull Request :https://github.com/Microsoft/vcpkg/pull/1177

vcpkgdemo的原始代码请见 https://github.com/zieckey/vcpkgdemo

发表回复