blob: 72af7ea2d4dc8cd376b05b12839ab7eecec2ddbe [file] [view]
# A Quick Guide for Maintaining Dependencies with Vcpkg
It is recommended to read [vcpkg documents](https://learn.microsoft.com/en-us/vcpkg/).
It is quite easy to understand if you have experience in packaging on linux or mac homebrew.
## How to add a new depends?
Please init vcpkg env first:
``` sh
./dev/vcpkg/init.sh
```
Vcpkg already maintains a lot of libraries.
You can find them by vcpkg cli.
(NOTE: Please always use cli because [packages on vcpkg.io](https://vcpkg.io/en/packages.html) is outdated).
```
$ ./.vcpkg/vcpkg search folly
folly 2022.10.31.00#4 An open-source C++ library developed and used at Facebook. The library is ...
folly[bzip2] Support bzip2 for compression
folly[libsodium] Support libsodium for cryto
folly[liburing] Support compile with liburing
folly[lz4] Support lz4 for compression
folly[lzma] Support LZMA for compression
folly[snappy] Support Snappy for compression
folly[zlib] Support zlib for compression
folly[zstd] Support zstd for compression
```
`[...]` means additional features. Then add the dependency into [vcpkg.json](./vcpkg.json).
``` json
{
"velox": {
"dependencies": [
{
"name": "folly",
"features": ["zstd", "lz4", "lzma", "snappy"]
}
]
}
}
```
Run `./dev/vcpkg/init.sh` again to verify that everything works.
It will only build modified part.
Sometimes the vcpkg port does not meet the requirements.
You can modify the packaging logic of vcpkg for different cases:
**If vcpkg's port is too new (e.g. fmt)**.
Vcpkg allows you to choose a specific version library.
Supported versions can be found in `.vcpkg/versions/$package`.
Then specify version in `vcpkg.json`.
See also [Versioning](https://learn.microsoft.com/en-us/vcpkg/users/versioning).
``` json
{
"overrides": [
{ "name": "fmt", "version": "8.0.1" }
]
}
```
Otherwise, you must create a new port in `./ports/$package` to override the vcpkg's original version.
**If a newer version of a library is supported in a later version of vcpkg**.
Developers can configure `vcpkg-configuration.json` to allow importing a new port, overriding the
corresponding port specified in the `builtin-baseline`. This approach also applies to libraries
that have been removed from vcpkg at the `builtin-baseline`; by setting a historical vcpkg version,
you can import such ports.
**If you want to modify port based on vcpkg version**.
Copy port directory from `./.vcpkg/ports/$package` to `./ports/$package`.
**If you want to create a new port**.
Create a new directory in `./ports/$package`
**or** generate a template via vcpkg cli:
``` sh
./.vcpkg/vcpkg create $package /url/to/source/or/git
mv ./.vcpkg/ports/$package ./ports/$package
```
### About Boost
Vcpkg splits boost into dozens of packages including header-only libraries.
To find out which boost modules you are using,
the easiest way is to grep all `#include <boost/` in source code.
It is not sufficient to just copy the components from `find_package(Boost)` in cmake scripts.
As a result, modifying the boost version is a bit tricky,
see more [Pin old Boost versions](https://learn.microsoft.com/en-us/vcpkg/users/examples/modify-baseline-to-pin-old-boost).
## Write port files
See also [Packaging GitHub repos example: libogg](https://learn.microsoft.com/en-us/vcpkg/examples/packaging-github-repos).
### Create the manifest file
`vcpkg.json` is a json file describing the package's metadata:
``` json
{
"name": "gsasl",
"version": "2.2.0",
"dependencies": [
"krb5",
"libntlm"
]
}
```
See [vcpkg.json reference](https://learn.microsoft.com/en-us/vcpkg/reference/vcpkg-json);
### Create the portfile (aka build script)
`portfile.cmake` is a cmake script describing how to build and install the package.
A typical portfile has 3 stages:
**Download and prepare source**:
``` cmake
# Download from Github
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO gflags/gflags
REF v2.2.2
SHA512 98c4703aab24e81fe551f7831ab797fb73d0f7dfc516addb34b9ff6d0914e5fd398207889b1ae555bac039537b1d4677067dae403b64903577078d99c1bdb447
HEAD_REF master
PATCHES
0001-patch-dir.patch # gflags was estimating a wrong relative path between the gflags-config.cmake file and the include path; "../.." goes from share/gflags/ to the triplet root
fix_cmake_config.patch
)
# Download from source archive
vcpkg_download_distfile(ARCHIVE
URLS "https://ftp.gnu.org/gnu/gsasl/gsasl-2.2.0.tar.gz" "https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/gsasl/gsasl-2.2.0.tar.gz"
FILENAME "gsasl-2.2.0.tar.gz"
SHA512 0ae318a8616fe675e9718a3f04f33731034f9a7ba03d83ccb1a72954ded54ced35dc7c7e173fdcb6fa0f0813f8891c6cbcedf8bf70b37d00b8ec512eb9f07f5f
)
vcpkg_extract_source_archive(
SOURCE_PATH
ARCHIVE "${ARCHIVE}"
PATCHES fix-krb5-config.patch
)
```
**Configure, build and install**. Vcpkg will add extra flags (e.g. `--install-prefix`) for common build system automatically.
``` cmake
# CMake
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
OPTIONS
-DCMAKE_PROGRAM_PATH=${CURRENT_HOST_INSTALLED_DIR}/tools/yasm
-DWITH_KERBEROS=on
)
vcpkg_install_cmake()
# GNU Autotools (Out of tree)
vcpkg_configure_make(SOURCE_PATH ${SOURCE_PATH} AUTOCONFIG)
vcpkg_install_make()
# Meson
vcpkg_configure_meson(SOURCE_PATH ${SOURCE_PATH})
vcpkg_install_meson()
```
Some libraries do not support out-of-tree build. There is a hidden option for `vcpkg_configure_make()`:
```
vcpkg_configure_make(
SOURCE_PATH ${SOURCE_PATH}
COPY_SOURCE
)
```
**Post patch**.
You need to modify the final package in order to
make the binary library work in any location.
Vcpkg will also validate the final package and warn common issues.
``` cmake
# Remove unused files
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share")
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/tools")
# Replace absolute path in pkgconfig
vcpkg_fixup_pkgconfig()
# Missing copyright
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")
```
See portfile [variable](https://learn.microsoft.com/en-us/vcpkg/maintainers/variables)
and [function](https://learn.microsoft.com/en-us/vcpkg/maintainers/functions/vcpkg_acquire_msys) reference.
### Optional Files
* `usage`: A txt file about how to use the package. See [example: gflags](./ports/gflags)
* `vcpkg-cmake-wrapper.cmake`: A cmake script to wrapper library's find module.
If exists, `find_package()` will exec it instead of `Find*.cmake`.
See [example: gflags](./ports/gflags)
### Package Layout
Build intermediate files can be found in `.vcpkg/buildtrees/$package`.
Built packages can be found in `.vcpkg/$package`:
```
packages/thrift_x64-linux-avx/
├── BUILD_INFO
├── CONTROL
├── debug
│ └── lib
│ ├── libthriftd.a
│ ├── ...
│ └── pkgconfig
│ ├── thrift.pc
│ └── ...
├── include
│ └── thrift
│ ├── Thrift.h
│ └── ...
├── lib
│ ├── libthrift.a
│ ├── ...
│ └── pkgconfig
│ ├── thrift.pc
│ └── ...
├── share
│ └── thrift
│ ├── copyright
│ ├── ThriftConfig.cmake
│ ├── ...
│ ├── vcpkg_abi_info.txt
│ └── vcpkg.spdx.json
└── tools
└── thrift
└── thrift
```
Most of them are same as the common linux packages layout, except:
* `debug/lib`: debug-build libraries
* `share/$package`: cmake module (aka `/usr/lib/cmake/$package`), copyright, usage info, vcpkg abi (hash of build scripts).
* `tools/$package`: executables (aka `/bin`)
## About Binary Cache
> Binary caching saves copies of library binaries in a shared location that can be accessed by vcpkg for future installation.
> This means that, as a user, you should only need to build dependencies from source once. If vcpkg is asked to install the
> same library with the same build configuration in the future, it will copy the built binaries from the cache and finish the operation in seconds.
Binary cache is enabled by default. Cache files is located in `~/.cache/vcpkg/archives`. See [binary cache](https://learn.microsoft.com/en-us/vcpkg/users/binarycaching).