Hunter Documentation Release 0.23
Total Page:16
File Type:pdf, Size:1020Kb
Hunter Documentation Release 0.23 Ruslan Baratov Aug 20, 2021 Contents 1 Brief overview 3 2 Quick start 15 3 User guides 19 4 Packages 51 5 Creating new package 245 6 FAQ 273 7 Contributing 295 8 Contacts 299 9 Reference 301 Index 345 i ii Hunter Documentation, Release 0.23 Welcome to the Hunter package manager documentation! Hunter is a CMake driven cross-platform package manager for C/C++1 projects. With the help of Hunter you can organize builds for Linux, Windows, macOS, iOS, Android, Raspberry Pi and other platforms. Third-party external projects are highly customizable, effectively allowing you to have myriad variants of directories with them based on combinations of version to build, static/shared, CMake -D options, Release/Debug, etc. Separate root directories will be created for each variant, so they all can be used simultaneously on one machine without conflicts (just like virtualenv but automatically). Going further: each such root directory can be shared between several local projects if configuration of externals matches. So when you are starting another project from scratch and use the same external packages, there will be no additional copy or build triggered; the only overhead is checking the existence of a DONE stamp file for each package. In case your local environment is similar enough to the continuous integration environment of Travis/AppVeyor service, then build will not be triggered at all - cached binaries will be downloaded from GitHub server instead. Mainly Hunter is designed to manage packages with CMake build system under the hood and existing CMake packages can be quite easily integrated into system, but non-CMake packages are also supported too using custom templates (build schemes) with ExternalProject_Add command(s). The Hunter client is a collection of CMake-only modules (i.e. it’s not a binary like apt-get or script like brew) so it supports out-of-the-box all platforms/generators/IDEs which CMake can handle, like Visual Studio, Xcode, Android Studio, QtCreator, NMake, Ninja, Cygwin or MinGW. It works fine with CMake-GUI too. The prime directive used for adding package to the current root is hunter_add_package which companioning CMake’s find_package. For example: hunter_add_package(Boost COMPONENTS system filesystem iostreams) find_package(Boost CONFIG REQUIRED system filesystem iostreams) Sounds interesting? Keep reading! 1 C++ is the main goal, works for other types as well. See Manage anything. Contents 1 Hunter Documentation, Release 0.23 2 Contents CHAPTER 1 Brief overview This is a brief overview of big picture. It takes about 5 minutes of reading but will show you the main features/aspects of using Hunter. Please don’t make any assumptions about how Hunter works without reading this part. Also avoid running real code for now, it will be covered in next Quick start section. 1.1 What is it? Every Hunter release(Atom feed) archive is a meta-package with build instructions and URLs of real packages. The archive will be downloaded and unpacked automatically by the HunterGate CMake module. You only need to set the URL and SHA1: HunterGate( URL "https://github.com/cpp-pm/hunter/archive/v0.23.297.tar.gz" SHA1 "3319fe6a3b08090df7df98dee75134d68e2ef5a3" ) Here is the content of the archive in simplified form: Hunter (0.23.297) = { Boost (1.65.1, 1.65.0, 1.66.0, 1.66.0-p0, 1.67, ...), GTest (1.7.0, ...), OpenCV (4.1.1-p0, 4.0.0-p3, 3.4.6-p0, ...), OpenSSL (1.1.1, 1.1.1a, 1.1.1b, 1.1.1c, 1.1.1d, 1.1.1g, 1.1.1g-p0, ...), ... } If you download and unpack it, you can view some internals. Let’s look at the OpenSSL package properties: wget https://github.com/cpp-pm/hunter/archive/v0.14.5.tar.gz tar xf v0.14.5.tar.gz hunter.cmake holds the list of available versions: 3 Hunter Documentation, Release 0.23 grep -A3 -m3 VERSION hunter-0.14.5/cmake/projects/OpenSSL/hunter.cmake VERSION "1.1.1" URL "https://github.com/openssl/openssl/archive/OpenSSL_1_1_1.tar.gz" -- VERSION "1.1.1a" URL "https://github.com/openssl/openssl/archive/OpenSSL_1_1_1a.tar.gz" -- VERSION "1.1.1b" URL "https://github.com/openssl/openssl/archive/OpenSSL_1_1_1b.tar.gz" Install instructions from build scheme url_sha1_openssl.cmake.in: grep -A1 INSTALL_COMMAND hunter-0.14.5/cmake/projects/OpenSSL/schemes/url_sha1_ ,!openssl.cmake.in INSTALL_COMMAND make install_sw Default version from default.cmake (is customizable, see Config-ID): grep '\<OpenSSL\>' -m1 hunter-0.14.5/cmake/configs/default.cmake hunter_default_version(OpenSSL VERSION 1.1.1) See also: • Detailed sources layout • Creating version on the fly from Git submodule 1.2 Automatic builds 1.2.1 No dependencies in README Build instructions from the Hunter archive are triggered automatically when the hunter_add_package function called, hence there is no need to specify dependencies in a raw README file like: For OSX please do: > brew install foo boo For Ubuntu please do: > sudo apt-get install foo boo Then run build: > cmake -H. -B_builds > cmake --build _builds 4 Chapter 1. Brief overview Hunter Documentation, Release 0.23 Now it’s simply: Just run build: > cmake -H. -B_builds # dependencies installed automatically > cmake --build _builds 1.2.2 Optional dependencies Optional dependency? No problem, optional dependencies are expressed in a straightforward way: # required dependencies hunter_add_package(foo) hunter_add_package(boo) if(BUILD_WITH_BAR) hunter_add_package(bar) endif() Now instead of: Additionally if you want bar support please run: > brew install bar # OSX > sudo apt-get install bar # Ubuntu Then run build: > cmake -H. -B_builds -DBUILD_WITH_BAR=YES It’s simply: > cmake-H.-B_builds-DBUILD_WITH_BAR=YES # + install bar 1.2.3 Compared to a ‘requirements.txt’ style approach Note that Hunter’s approach differs from a requirements.txt-like approach (i.e. when external packages are specified in a separate file). This allows Hunter to avoid duplication of logic in many cases, even if the requirements.txt style approach also automatically downloads dependencies too. Imagine that we have to specify dependencies in some kind of requirements.cmake file and there is a user option BUILD_WITH_BAR: # requirements.cmake if(WIN32 AND BUILD_WITH_BAR) command_to_install(Bar) endif() Or, in the case that it isn’t CMake code, this might by something fancy like requirements.json: { "dependencies": { "package": "Bar", "platform": "windows", "cmake option": "BUILD_WITH_BAR" } } 1.2. Automatic builds 5 Hunter Documentation, Release 0.23 You would have to repeat the same condition in the CMakeLists.txt file: # requirements.cmake if(WIN32 AND BUILD_WITH_BAR) command_to_install(Bar) endif() # CMakeLists.txt if(WIN32 AND BUILD_WITH_BAR) find_package(Bar CONFIG REQUIRED) target_compile_definitions(... PUBLIC "WITH_BAR") endif() Later, when you need to change this dependency in CMakeLists.txt, you’d better not forget to also modify requirements.cmake accordingly. Remember real world libraries can have nontrivial chain of conditions, e.g. OpenCV components. Stackoverflow • Pip: optional dependencies 1.3 Don’t Repeat Yourself If you are already familiar with ExternalProject_Add and have written some super-build projects before, you are probably already aware that writing a complete solution with toolchains, build types, build options, parallel jobs, forwarding of compiler flags, and making it work correctly for all generators is not a trivial task. Hunter stores ExternalProject_Add recipes as a set of templates. Once written, formula (build scheme) can be reused by other projects without copying the collection of super-build files (DRY principle). When a new package with a new scheme is introduced, all you need to do is just update the SHA1/URL of HunterGate command. Stackoverflow • How to use CMake ExternalProject_Add or alternatives in a cross platform way? 1.4 Customization You have full control of how packages will be built. You can create your own mapping of version -> URL, add globals like compiler and flags, or add new build options to external packages. 1.4.1 Hunter-ID First level of customization. Hunter archive. Hunter-ID is the first 7 digits of SHA1 of Hunter archive. This level defines list of available packages and mapping version -> URL/SHA1. Several Hunter-ID can coexist in the same HUNTER_ROOT directory. HunterGate command will control your choice: 6 Chapter 1. Brief overview Hunter Documentation, Release 0.23 Hunter- ID 1eae623 Hunter ver- 0.8.3 sion SHA1 of 1eae623cb5ce9da39c8c3e1b0f6e452f244ddc17 archive Working ${HUNTER_ROOT}/_Base/1eae623/... directory Packages Foo1 1.0.0 mysite.xyz/Foo-1.0.0. tar.gz Boo 2.0.0 mysite.xyz/Boo-2.0.0. tar.gz 2.1.0 mysite.xyz/Boo-2.1.0. tar.gz Roo 1.2.3 mysite.xyz/Roo-1.2.3. tar.gz 1.2.4 mysite.xyz/Roo-1.2.4. tar.gz e07a124 Hunter ver- 0.8.4 sion SHA1 of e07a124192b0a47b0b60ade40fa873a42ec27822 archive Working ${HUNTER_ROOT}/_Base/e07a124/... directory Packages Awesome 1.0.0 example.com/Awesome-1.0.0.tar.gz Best 2.0.0 example.com/Best-2.0.0.tar.gz 2.0.1 example.com/Best-2.0.1.tar.gz Foo1 1.0.0 example.com/Foo-1.0.0-patch-1.tar.gz Message in logs: -- [hunter] [ Hunter-ID: 1eae623 | Toolchain-ID: ... | Config-ID: ... ] -- [hunter] [ Hunter-ID: e07a124 | Toolchain-ID: ... | Config-ID: ... ] Hunter • Releases • Atom feed 1.4.2 Toolchain-ID Second level of customization. Compiler and flags. Each build can be run with different toolchains. In general the result is a completely different root directory (containing (lib/include). For example on Windows you can simultaneously build Visual Studio (32/64), NMake, Cygwin and MinGW projects, on Linux GCC/Clang, on Mac Xcode, Makefile, iOS. Or choose various clang tools like static analyzer/sanitizers and other platforms like Android/Raspberry Pi. Each toolchain file will be forwarded to external project. This means, if you create a toolchain with compiler g++ and flag -std=c++11 all dependent projects will be built by g++ -std=c++11.