From 94a5b8e8c1c01752c3be369fadda9f632fef6e9c Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Tue, 2 Apr 2019 15:30:35 +0200 Subject: [PATCH] Improve development docs for macOS & Windows for 2.11 - macOS doesn't require sudo anymore - Windows builds must use Boost 1.66+ - Fix link in About section - Add recommended books: Boost application programming --- doc/01-about.md | 3 +- doc/21-development.md | 387 ++++++++++-------- .../windows_boost_build_dev_cmd.png | Bin 0 -> 14058 bytes 3 files changed, 220 insertions(+), 170 deletions(-) create mode 100644 doc/images/development/windows_boost_build_dev_cmd.png diff --git a/doc/01-about.md b/doc/01-about.md index 554c077b9..0e8186591 100644 --- a/doc/01-about.md +++ b/doc/01-about.md @@ -34,8 +34,7 @@ Please continue reading in the [Contributing chapter](https://github.com/Icinga/ The Git repository is located on [GitHub](https://github.com/Icinga/icinga2). Icinga 2 is written in C++ and can be built on Linux/Unix and Windows. -Read more about development builds in the [INSTALL.md](https://github.com/Icinga/icinga2/blob/master/INSTALL.md) -file. +Read more about development builds in the [development chapter](21-development.md#development). ## What's New diff --git a/doc/21-development.md b/doc/21-development.md index 72bca8f33..3fb6b5fcc 100644 --- a/doc/21-development.md +++ b/doc/21-development.md @@ -468,6 +468,7 @@ Here's a few books we can recommend: * [Accelerated C++: Practical Programming by Example](https://www.amazon.com/Accelerated-C-Practical-Programming-Example/dp/020170353X) (Andrew Koenig, Barbara E. Moo) * [Effective C++](https://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876) (Scott Meyers) +* [Boost C++ Application Development Cookbook - Second Edition: Recipes to simplify your application development](https://www.amazon.com/dp/1787282244/ref=cm_sw_em_r_mt_dp_U_dN1OCbERS00EQ) (Antony Polukhin) * [Der C++ Programmierer](https://www.amazon.de/Programmierer-lernen-Professionell-anwenden-L%C3%B6sungen/dp/3446416447), German (Ulrich Breymann) * [C++11 programmieren](https://www.amazon.de/gp/product/3836217325/), German (Torsten T. Will) @@ -676,24 +677,7 @@ It is advised to use Homebrew to install required build dependencies. Macports have been reported to work as well, typically you'll get more help with Homebrew from Icinga developers. -#### Users and Groups - -First off, create the following from `Settings - Users & Groups`: - -* Users: `icinga` -* Groups: `icinga` with `icinga` as member -* Groups: `icingaweb2` - -Then disallow login for these users. - -``` -dscl -list Local/Default/Users -read Local/Default/Users/icinga -change Local/Default/Users/icinga UserShell /bin/bash /usr/bin/false -sudo dscl . create /Users/icinga IsHidden 1 -sudo dseditgroup -o edit -a _www -t user icingaweb2 -``` +The idea is to run Icinga with the current user, avoiding root permissions. #### Requirements @@ -711,48 +695,50 @@ sudo mkdir /opt/ccache sudo ln -s `which ccache` /opt/ccache/clang sudo ln -s `which ccache` /opt/ccache/clang++ -vim $HOME/.bashrc +vim $HOME/.bash_profile # ccache is managed with symlinks to avoid collision with cgo export PATH="/opt/ccache:$PATH" -source $HOME/.bashrc +source $HOME/.bash_profile ``` #### Builds -We will build two different flavors on macOS. +Icinga is built as release (optimized build for packages) and debug (more symbols and details for debugging). Debug builds +typically run slower than release builds and must not be used for performance benchmarks. ``` mkdir -p release debug cd debug -cmake -DICINGA2_UNITY_BUILD=OFF -DICINGA2_WITH_STUDIO=ON -DCMAKE_INSTALL_PREFIX=/usr/local/icinga2 -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl@1.1/include -DOPENSSL_SSL_LIBRARY=/usr/local/opt/openssl@1.1/lib/libssl.dylib -DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/openssl@1.1/lib/libcrypto.dylib .. +cmake -DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF -DCMAKE_INSTALL_PREFIX=/usr/local/icinga2 -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl@1.1/include -DOPENSSL_SSL_LIBRARY=/usr/local/opt/openssl@1.1/lib/libssl.dylib -DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/openssl@1.1/lib/libcrypto.dylib -DICINGA2_PLUGINDIR=/usr/local/sbin .. cd .. make -j4 -C debug -sudo make -j4 install -C debug +make -j4 install -C debug ``` ##### Build Aliases -This is derived from dnsmichi's flavour and not generally best practice. +This is derived from [dnsmichi's flavour](https://github.com/dnsmichi/dotfiles) and not generally best practice. ``` -vim $HOME/.bashrc +vim $HOME/.bash_profile -export PATH=/usr/local/icinga2/sbin/:$PATH -source /usr/local/icinga2/etc/bash_completion.d/icinga2 - -export I2_GENERIC="-DCMAKE_INSTALL_PREFIX=/usr/local/icinga2 -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl@1.1/include -DOPENSSL_SSL_LIBRARY=/usr/local/opt/openssl@1.1/lib/libssl.dylib -DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/openssl@1.1/lib/libcrypto.dylib -DICINGA2_PLUGINDIR=/usr/local/sbin" +export I2_GENERIC="-DCMAKE_INSTALL_PREFIX=/usr/local/icinga/icinga2 -DICINGA2_USER=`id -u -n` -DICINGA2_GROUP=`id -g -n` -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl@1.1/include -DOPENSSL_SSL_LIBRARY=/usr/local/opt/openssl@1.1/lib/libssl.dylib -DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/openssl@1.1/lib/libcrypto.dylib -DICINGA2_PLUGINDIR=/usr/local/sbin -DICINGA2_WITH_PGSQL=OFF" export I2_DEBUG="-DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF $I2_GENERIC" export I2_RELEASE="-DCMAKE_BUILD_TYPE=RelWithDebInfo -DICINGA2_WITH_TESTS=ON -DICINGA2_UNITY_BUILD=ON $I2_GENERIC" -alias i2_debug="mkdir -p debug; cd debug; cmake $I2_DEBUG ..; make -j4; sudo make -j4 install; cd .." -alias i2_release="mkdir -p release; cd release; cmake $I2_RELEASE ..; make -j4; sudo make -j4 install; cd .." +alias i2_debug="mkdir -p debug; cd debug; cmake $I2_DEBUG ..; make -j4; make -j4 install; cd .." +alias i2_release="mkdir -p release; cd release; cmake $I2_RELEASE ..; make -j4; make -j4 install; cd .." + +export PATH=/usr/local/icinga/icinga2/sbin/:$PATH +test -f /usr/local/icinga/icinga2/etc/bash_completion.d/icinga2 && source /usr/local/icinga/icinga2/etc/bash_completion.d/icinga2 -source $HOME/.bashrc + +source $HOME/.bash_profile ``` #### Run @@ -767,18 +753,26 @@ icinga2 daemon #### Plugins ``` -brew install nagios-plugins +brew install monitoring-plugins sudo vim /usr/local/icinga2/etc/icinga2/constants.conf const PluginDir = "/usr/local/sbin" ``` +#### Backends: Redis + +``` +brew install redis +brew services start redis +``` + #### Databases: MariaDB ``` brew install mariadb -ln -sfv /usr/local/opt/mariadb/*.plist ~/Library/LaunchAgents -launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mariadb.plist +mkdir -p /usr/local/etc/my.cnf.d +brew services start mariadb + mysql_secure_installation ``` @@ -795,14 +789,20 @@ exit ``` ``` -cd $HOME/coding/icinga/icinga2 +mysql -e 'create database icinga;' +mysql -e "grant all on icinga.* to 'icinga'@'localhost' identified by 'icinga';" +mysql icinga < $HOME/dev/icinga/icinga2/lib/db_ido_mysql/schema/mysql.sql +``` -sudo mysql +#### API -CREATE DATABASE icinga; -GRANT SELECT, INSERT, UPDATE, DELETE, DROP, CREATE VIEW, INDEX, EXECUTE ON icinga.* TO 'icinga'@'localhost' IDENTIFIED BY 'icinga'; -quit -sudo mysql icinga < lib/db_ido_mysql/schema/mysql.sql +``` +icinga2 api setup +cd /usr/local/icinga/icinga2/var/lib/icinga2/certs +HOST_NAME=mbpmif.int.netways.de +icinga2 pki new-cert --cn ${HOST_NAME} --csr ${HOST_NAME}.csr --key ${HOST_NAME}.key +icinga2 pki sign-csr --csr ${HOST_NAME}.csr --cert ${HOST_NAME}.crt +echo "const NodeName = \"${HOST_NAME}\"" >> /usr/local/icinga/icinga2/etc/icinga2/constants.conf ``` @@ -830,28 +830,47 @@ the web installer and start the installation. You need a free Microsoft account to download and also store your preferences. -Choose the following minimal set: - -* .NET Framework 4.x SDK -* C# Compiler -* Visual Studio C++ core features -* VC++ toolset -* Windows 10 SDK (10.0.10240.0 - required) -* Just-in-time debugger -* Windows 8 SDK (includes mscoree.lib required by clrchecktask) -* C++/CLI support -* Windows Universal C Runtime -* Git for Windows -* .NET Framework 3.5 development tools -* Github extension for Visual Studio +Choose these individual components on Visual Studio 2017: + +* .NET + * .NET Framework 3.5 development tools + * .NET Framework 4.6.1 SDK + * .NET Framework 4.6.1 targeting pack +* Code tools + * Git for Windows + * Static analysis tools +* Compilers, build tools and runtimes + * C# and Visual Basic Roslyn compilers + * C++/CU Support + * VC++ 2017 v141 toolset (x86_64) +* Debugging and testing + * C++ profiling tools + * Just-in-Time debugger +* Development activities + * Visual Studio C++ core features +* Games and Graphics + * Graphics debugger and GPU profiler for DirectX (required by C++ profiling tools) +* SDKs, libraries and frameworks + * Graphics Tools Windows 8.1 SDK (required by C++ profiling tools) + * Windows 10 SDK **10.0.10240.0 - exactly this version** + * Windows 8.1 SDK + * Windows Universal C Runtime +* Uncategorized + * GitHub Extension for Visual Studio + After a while, Visual Studio will be ready. #### .NET Framework 3.5 -Windows 10 only have .NET Framework >= 4.6 installed by default, the Icinga Agent Wizard is built on .NET Framework 2.0 which is not included in .NET Framework 4.6. Thankfully Windows 10 have .NET Framework 3.5 (which includes .NET Framework 2.0) as a component on board, you just need to activate it. +Windows 10 has .NET Framework >= 4.6 installed by default. The Icinga Agent Wizard +is built on .NET Framework 2.0 which is not included in .NET Framework 4.6. -Go to `Control Panel` -> `Programs` -> `Turn Windows features on or off`. Tick `.NET Framework 3.5 (includes .NET 2.0 and 3.0)` and wait until the installation process succseded. +Windows 10 provides .NET Framework 3.5 which includes .NET Framework 2.0. + +Navigate into `Control Panel` -> `Programs` -> `Turn Windows features on or off`. +Select `.NET Framework 3.5 (includes .NET 2.0 and 3.0)` and wait until the installation process +is finished. #### Flex and Bison @@ -875,42 +894,38 @@ will automatically detect them for builds and packaging. > > We cannot use the chocolatey package as this one does not provide any development headers. > -> Choose 1.0.2 LTS from manual downloads for best compatibility if unsure. +> Choose 1.1.1 LTS from manual downloads for best compatibility. #### Boost In order to use the boost development header and library files you need to [download](http://www.boost.org/users/download/) -Boost and then extract it to e.g. `C:\boost_1_65_1`. +Boost and then extract it to e.g. `C:\boost_1_69_0`. > **Note** > > Just use `C:`, the zip file already contains the sub folder. Extraction takes a while, -> the archive contains more than 10k files. +> the archive contains more than 70k files. -For integrating Boost into Visual Studio 2017, open the `Developer Command Prompt` from the start menu, -and navigate to `C:\boost_1_65_1`. +In order to integrate Boost into Visual Studio 2017, open the `Developer Command Prompt` from the start menu, +and navigate to `C:\boost_1_69_0`. Execute `bootstrap.bat` first. ``` -cd C:\boost_1_65_1 +cd C:\boost_1_69_0 bootstrap.bat ``` Once finished, specify the required `toolset` to compile boost against Visual Studio. -This takes quite some time in a Windows VM. - -Visual Studio 2015: +This takes quite some time in a Windows VM. Boost Context uses Assembler code, +which isn't treated as exception safe by the VS compiler. Therefore set the +additional compilation flag according to [this entry](https://lists.boost.org/Archives/boost/2015/08/224570.php). ``` -b2 --toolset=msvc-14.0 +b2 --toolset=msvc-14.1 asmflags=\safeseh ``` -Visual Studio 2017: - -``` -b2 --toolset=msvc-14.1 -``` +![Windows Boost Build in VS2017 Development Console](images/development/windows_boost_build_dev_cmd.png) #### TortoiseGit @@ -928,10 +943,9 @@ Start the setup routine and choose `OpenSSH` as default secure transport when as Open a Windows Explorer window and navigate into -Version | Project Location ---------------------|------------------------------ -Visual Studio 2015 | `C:\Users\michi\Documents\Visual Studio 2015\Projects` -Visual Studio 2017+ | `C:\Users\michi\source\repos` +``` +cd %HOMEPATH%\source\repos +``` Right click and select `Git Clone` from the context menu. @@ -943,18 +957,14 @@ Icinga 2 uses CMake to manage the build environment. You can generate the Visual using CMake. [Download](https://cmake.org/download/) and install CMake. Select to add it to PATH for all users when asked. -Once setup is completed, open a command prompt and navigate to - -Visual Studio 2015 - -``` -cd C:\Users\\Documents\Visual Studio 2015\Projects\icinga2 -``` +> **Note** +> +> In order to properly detect the Boost libraries, install the CMake 3.14+. -Visual Studio 2017 +Once setup is completed, open a command prompt and navigate to ``` -cd C:\Users\michi\source\repos +cd %HOMEPATH%\source\repos ``` Run CMake with the following command. This generates a new Visual Studio project file called `icinga2.sln`. @@ -963,7 +973,8 @@ You need to specify the previously installed component paths: Variable | Value | Description ----------------------|----------------------------------------------------------------------|------------------------------------------------------- -`BOOST_ROOT` | `C:\boost_1_65_1` | Root path where you've extracted and compiled Boost. +`BOOST_ROOT` | `C:\boost_1_69_0` | Root path where you've extracted and compiled Boost. +`BOOST_LIBRARYDIR` | `C:\boost_1_69_0\stage` | Path to the static compiled Boost libraries, directory must contain `lib`. `BISON_EXECUTABLE` | `C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe` | Path to the Bison executable. `FLEX_EXECUTABLE` | `C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe` | Path to the Flex executable. `ICINGA2_WITH_MYSQL` | OFF | Requires extra setup for MySQL if set to `ON`. Not supported for client setups. @@ -973,20 +984,34 @@ Variable | Value Tip: If you have previously opened a terminal, run `refreshenv` to re-read updated PATH variables. ``` -cmake . -DBOOST_ROOT=C:\boost_1_65_1 -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DICINGA2_WITH_MYSQL=OFF -DICINGA2_WITH_PGSQL=OFF -DICINGA2_UNITY_BUILD=OFF +cmake . -DCPACK_GENERATOR=WIX -DCMAKE_BUILD_TYPE=Debug -DBOOST_ROOT=C:\boost_1_69_0 -DBOOST_LIBRARYDIR=C:\boost_1_69_0\stage -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DICINGA2_WITH_MYSQL=OFF -DICINGA2_WITH_PGSQL=OFF -DICINGA2_UNITY_BUILD=OFF ``` Best is write a small batch/Powershell script which just executes these lines. +``` +@echo off + +cd icinga2 +mkdir debug +cd debug +del CMakeCache.txt + +cmake . -DCPACK_GENERATOR=WIX -DCMAKE_BUILD_TYPE=Debug -DBOOST_ROOT=C:\boost_1_69_0 -DBOOST_LIBRARYDIR=C:\boost_1_69_0\stage -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DICINGA2_WITH_MYSQL=OFF -DICINGA2_WITH_PGSQL=OFF -DICINGA2_UNITY_BUILD=OFF + +cmake --build . --target PACKAGE --config Debug + +cd .. +``` + #### Icinga 2 in Visual Studio Navigate to -Version | Project location ---------------------|------------------------- -Visual Studio 2015 | `C:\Users\michi\Documents\Visual Studio 2015\Projects\icinga2` -Visual Studio 2017+ | `C:\Users\michi\source\repos\icinga2` +``` +cd %HOMEPATH%\source\repos\icinga2 +``` Open `icinga2.sln`. Log into Visual Studio when asked. @@ -997,10 +1022,8 @@ project directory. Navigate there and run `icinga2.exe --version`. -Example for Visual Studio 2017: - ``` -cd C:\Users\michi\source\repos\icinga2\Bin\Release\Debug +cd %HOMEPATH%\source\repos\icinga2\Bin\Release\Debug icinga2.exe --version ``` @@ -1018,11 +1041,12 @@ choco install -y wixtoolset ``` Once completed open an administrative shell and navigate to your Visual Studio project. + Let CMake to build a release package. ``` -cd "c:\Users\michi\Documents\Visual Studio 2015\Projects\icinga2" -cmake --build . --target PACKAGE --config Release +cd %HOMEPATH%\source\repos\icinga2 +cmake --build debug --target PACKAGE --config Release ``` Note: This will still use the debug builds. A yet more clean approach @@ -1030,14 +1054,37 @@ is to run CMake with changed release parameters beforehand and then re-run the release package builder. ``` -C:\Users\michi\Documents\Visual Studio 2015\Projects\icinga2> -cmake . -DCPACK_GENERATOR=WIX -DCMAKE_BUILD_TYPE=Release -DBOOST_ROOT=C:\boost_1_65_1 -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DICINGA2_WITH_MYSQL=OFF -DICINGA2_WITH_PGSQL=OFF -DICINGA2_UNITY_BUILD=OFF +cd %HOMEPATH%\source\repos\icinga2 +mkdir release +cd release + +cmake .. -DCPACK_GENERATOR=WIX -DCMAKE_BUILD_TYPE=Release -DBOOST_ROOT=C:\boost_1_69_0 -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DICINGA2_WITH_MYSQL=OFF -DICINGA2_WITH_PGSQL=OFF -DICINGA2_UNITY_BUILD=OFF +cd .. -cmake --build . --target PACKAGE --config Release +cmake --build release --target PACKAGE --config Release ``` Again, put these lines into a batch/Powershell script and execute that. +``` +@echo off +cd icinga2 + +mkdir release +cd release + +del CMakeCache.txt + +; set gen=Visual Studio 15 2017 Win64 +set gen=Visual Studio 15 2017 + +cmake .. -G "%gen%" -DCPACK_GENERATOR=WIX -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBOOST_ROOT=C:\boost_1_69_0 -DBOOST_LIBRARYDIR=C:\boost_1_69_0\stage -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DICINGA2_WITH_MYSQL=OFF -DICINGA2_WITH_PGSQL=OFF -DICINGA2_UNITY_BUILD=ON +cd .. + +cmake --build release --target PACKAGE --config Release + +cd .. +``` ### Embedded Dev Env: Pi @@ -1085,44 +1132,44 @@ Icinga application using a dist tarball (including notes for distributions): * cmake >= 2.6 * GNU make (make) or ninja-build * C++ compiler which supports C++11 - - RHEL/Fedora/SUSE: gcc-c++ >= 4.7 (extra Developer Tools on RHEL5/6 see below) - - Debian/Ubuntu: build-essential - - Alpine: build-base - - you can also use clang++ + * RHEL/Fedora/SUSE: gcc-c++ >= 4.7 (extra Developer Tools on RHEL5/6 see below) + * Debian/Ubuntu: build-essential + * Alpine: build-base + * you can also use clang++ * pkg-config * OpenSSL library and header files >= 1.0.1 - - RHEL/Fedora: openssl-devel - - SUSE: libopenssl-devel (for SLES 11: libopenssl1-devel) - - Debian/Ubuntu: libssl-dev - - Alpine: libressl-dev + * RHEL/Fedora: openssl-devel + * SUSE: libopenssl-devel (for SLES 11: libopenssl1-devel) + * Debian/Ubuntu: libssl-dev + * Alpine: libressl-dev * Boost library and header files >= 1.66.0 - - RHEL/Fedora: boost166-devel - - Debian/Ubuntu: libboost-all-dev - - Alpine: boost-dev + * RHEL/Fedora: boost166-devel + * Debian/Ubuntu: libboost-all-dev + * Alpine: boost-dev * GNU bison (bison) * GNU flex (flex) >= 2.5.35 * systemd headers - - Only required when using systemd - - Debian/Ubuntu: libsystemd-dev - - RHEL/Fedora: systemd-devel + * Only required when using systemd + * Debian/Ubuntu: libsystemd-dev + * RHEL/Fedora: systemd-devel ### Optional features * MySQL (disable with CMake variable `ICINGA2_WITH_MYSQL` to `OFF`) - - RHEL/Fedora: mysql-devel - - SUSE: libmysqlclient-devel - - Debian/Ubuntu: default-libmysqlclient-dev | libmysqlclient-dev - - Alpine: mariadb-dev + * RHEL/Fedora: mysql-devel + * SUSE: libmysqlclient-devel + * Debian/Ubuntu: default-libmysqlclient-dev | libmysqlclient-dev + * Alpine: mariadb-dev * PostgreSQL (disable with CMake variable `ICINGA2_WITH_PGSQL` to `OFF`) - - RHEL/Fedora: postgresql-devel - - Debian/Ubuntu: libpq-dev - - postgresql-dev on Alpine + * RHEL/Fedora: postgresql-devel + * Debian/Ubuntu: libpq-dev + * postgresql-dev on Alpine * libedit (CLI console) - - RHEL/Fedora: libedit-devel on CentOS (RHEL requires rhel-7-server-optional-rpms) - - Debian/Ubuntu/Alpine: libedit-dev + * RHEL/Fedora: libedit-devel on CentOS (RHEL requires rhel-7-server-optional-rpms) + * Debian/Ubuntu/Alpine: libedit-dev * Termcap (only required if libedit doesn't already link against termcap/ncurses) - - RHEL/Fedora: libtermcap-devel - - Debian/Ubuntu: (not necessary) + * RHEL/Fedora: libtermcap-devel + * Debian/Ubuntu: (not necessary) ### Special requirements @@ -1191,66 +1238,70 @@ For all variables regarding defaults paths on in CMake, see Also see `CMakeLists.txt` for details. -**System Environment** -- `CMAKE_INSTALL_SYSCONFDIR`: The configuration directory; defaults to `CMAKE_INSTALL_PREFIX/etc` -- `CMAKE_INSTALL_LOCALSTATEDIR`: The state directory; defaults to `CMAKE_INSTALL_PREFIX/var` -- `ICINGA2_CONFIGDIR`: Main config directory; defaults to `CMAKE_INSTALL_SYSCONFDIR/icinga2` usually `/etc/icinga2` -- `ICINGA2_CACHEDIR`: Directory for cache files; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/cache/icinga2` usually `/var/cache/icinga2` -- `ICINGA2_DATADIR`: Data directory for the daemon; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/lib/icinga2` usually `/var/lib/icinga2` -- `ICINGA2_LOGDIR`: Logfiles of the daemon; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/log/icinga2 usually `/var/log/icinga2` -- `ICINGA2_SPOOLDIR`: Spooling directory ; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/spool/icinga2` usually `/var/spool/icinga2` -- `ICINGA2_INITRUNDIR`: Runtime data for the init system; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/run/icinga2` usually `/run/icinga2` -- `ICINGA2_GIT_VERSION_INFO`: Whether to use Git to determine the version number; defaults to `ON` -- `ICINGA2_USER`: The user Icinga 2 should run as; defaults to `icinga` -- `ICINGA2_GROUP`: The group Icinga 2 should run as; defaults to `icinga` -- `ICINGA2_COMMAND_GROUP`: The command group Icinga 2 should use; defaults to `icingacmd` -- `ICINGA2_SYSCONFIGFILE`: Where to put the config file the initscript/systemd pulls it's dirs from; - defaults to `CMAKE_INSTALL_PREFIX/etc/sysconfig/icinga2` -- `ICINGA2_PLUGINDIR`: The path for the Monitoring Plugins project binaries; defaults to `/usr/lib/nagios/plugins` - -**Build Optimization** -- `ICINGA2_UNITY_BUILD`: Whether to perform a unity build; defaults to `ON`. Note: This requires additional memory and is not advised for building VMs, Docker for Mac and embedded hardware. -- `ICINGA2_LTO_BUILD`: Whether to use link time optimization (LTO); defaults to `OFF` - -**Init System** -- `USE_SYSTEMD=ON|OFF`: Use systemd or a classic SysV initscript; defaults to `OFF` -- `INSTALL_SYSTEMD_SERVICE_AND_INITSCRIPT=ON|OFF` Force install both the systemd service definition file +#### System Environment + +* `CMAKE_INSTALL_SYSCONFDIR`: The configuration directory; defaults to `CMAKE_INSTALL_PREFIX/etc` +* `CMAKE_INSTALL_LOCALSTATEDIR`: The state directory; defaults to `CMAKE_INSTALL_PREFIX/var` +* `ICINGA2_CONFIGDIR`: Main config directory; defaults to `CMAKE_INSTALL_SYSCONFDIR/icinga2` usually `/etc/icinga2` +* `ICINGA2_CACHEDIR`: Directory for cache files; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/cache/icinga2` usually `/var/cache/icinga2` +* `ICINGA2_DATADIR`: Data directory for the daemon; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/lib/icinga2` usually `/var/lib/icinga2` +* `ICINGA2_LOGDIR`: Logfiles of the daemon; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/log/icinga2 usually `/var/log/icinga2` +* `ICINGA2_SPOOLDIR`: Spooling directory ; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/spool/icinga2` usually `/var/spool/icinga2` +* `ICINGA2_INITRUNDIR`: Runtime data for the init system; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/run/icinga2` usually `/run/icinga2` +* `ICINGA2_GIT_VERSION_INFO`: Whether to use Git to determine the version number; defaults to `ON` +* `ICINGA2_USER`: The user Icinga 2 should run as; defaults to `icinga` +* `ICINGA2_GROUP`: The group Icinga 2 should run as; defaults to `icinga` +* `ICINGA2_COMMAND_GROUP`: The command group Icinga 2 should use; defaults to `icingacmd` +* `ICINGA2_SYSCONFIGFILE`: Where to put the config file the initscript/systemd pulls it's dirs from; +* defaults to `CMAKE_INSTALL_PREFIX/etc/sysconfig/icinga2` +* `ICINGA2_PLUGINDIR`: The path for the Monitoring Plugins project binaries; defaults to `/usr/lib/nagios/plugins` + +#### Build Optimization + +* `ICINGA2_UNITY_BUILD`: Whether to perform a unity build; defaults to `ON`. Note: This requires additional memory and is not advised for building VMs, Docker for Mac and embedded hardware. +* `ICINGA2_LTO_BUILD`: Whether to use link time optimization (LTO); defaults to `OFF` + +#### Init System + +* `USE_SYSTEMD=ON|OFF`: Use systemd or a classic SysV initscript; defaults to `OFF` +* `INSTALL_SYSTEMD_SERVICE_AND_INITSCRIPT=ON|OFF` Force install both the systemd service definition file and the SysV initscript in parallel, regardless of how `USE_SYSTEMD` is set. Only use this for special packaging purposes and if you know what you are doing. Defaults to `OFF`. -**Features:** -- `ICINGA2_WITH_CHECKER`: Determines whether the checker module is built; defaults to `ON` -- `ICINGA2_WITH_COMPAT`: Determines whether the compat module is built; defaults to `ON` -- `ICINGA2_WITH_DEMO`: Determines whether the demo module is built; defaults to `OFF` -- `ICINGA2_WITH_HELLO`: Determines whether the hello module is built; defaults to `OFF` -- `ICINGA2_WITH_LIVESTATUS`: Determines whether the Livestatus module is built; defaults to `ON` -- `ICINGA2_WITH_NOTIFICATION`: Determines whether the notification module is built; defaults to `ON` -- `ICINGA2_WITH_PERFDATA`: Determines whether the perfdata module is built; defaults to `ON` -- `ICINGA2_WITH_TESTS`: Determines whether the unit tests are built; defaults to `ON` +#### Features + +* `ICINGA2_WITH_CHECKER`: Determines whether the checker module is built; defaults to `ON` +* `ICINGA2_WITH_COMPAT`: Determines whether the compat module is built; defaults to `ON` +* `ICINGA2_WITH_LIVESTATUS`: Determines whether the Livestatus module is built; defaults to `ON` +* `ICINGA2_WITH_NOTIFICATION`: Determines whether the notification module is built; defaults to `ON` +* `ICINGA2_WITH_PERFDATA`: Determines whether the perfdata module is built; defaults to `ON` +* `ICINGA2_WITH_TESTS`: Determines whether the unit tests are built; defaults to `ON` -**MySQL or MariaDB:** +#### MySQL or MariaDB The following settings can be tuned for the MySQL / MariaDB IDO feature. -- `ICINGA2_WITH_MYSQL`: Determines whether the MySQL IDO module is built; defaults to `ON` -- `MYSQL_CLIENT_LIBS`: Client implementation used (mysqlclient / mariadbclient); defaults searches for `mysqlclient` and `mariadbclient` -- `MYSQL_INCLUDE_DIR`: Directory containing include files for the mysqlclient; default empty - +* `ICINGA2_WITH_MYSQL`: Determines whether the MySQL IDO module is built; defaults to `ON` +* `MYSQL_CLIENT_LIBS`: Client implementation used (mysqlclient / mariadbclient); defaults searches for `mysqlclient` and `mariadbclient` +* `MYSQL_INCLUDE_DIR`: Directory containing include files for the mysqlclient; default empty - checking multiple paths like `/usr/include/mysql` -See [FindMySQL.cmake](third-party/cmake/FindMySQL.cmake) for the implementation. +See [FindMySQL.cmake](https://github.com/Icinga/icinga2/blob/master/third-party/cmake/FindMySQL.cmake) +for implementation details. -**PostgreSQL:** +#### PostgreSQL The following settings can be tuned for the PostgreSQL IDO feature. -- `ICINGA2_WITH_PGSQL`: Determines whether the PostgreSQL IDO module is built; defaults to `ON` -- `PostgreSQL_INCLUDE_DIR`: Top-level directory containing the PostgreSQL include directories -- `PostgreSQL_LIBRARY`: File path to PostgreSQL library : libpq.so (or libpq.so.[ver] file) +* `ICINGA2_WITH_PGSQL`: Determines whether the PostgreSQL IDO module is built; defaults to `ON` +* `PostgreSQL_INCLUDE_DIR`: Top-level directory containing the PostgreSQL include directories +* `PostgreSQL_LIBRARY`: File path to PostgreSQL library : libpq.so (or libpq.so.[ver] file) -See [FindMySQL.cmake](third-party/cmake/FindPostgreSQL.cmake) for the implementation. +See [FindPostgreSQL.cmake](https://github.com/Icinga/icinga2/blob/master/third-party/cmake/FindPostgreSQL.cmake) +for implementation details. -**Version detection:** +#### Version detection CMake determines the Icinga 2 version number using `git describe` if the source directory is contained in a Git repository. Otherwise the version number diff --git a/doc/images/development/windows_boost_build_dev_cmd.png b/doc/images/development/windows_boost_build_dev_cmd.png new file mode 100644 index 0000000000000000000000000000000000000000..1a3c30c387bd9db007dacc249f6c55d9e4a94346 GIT binary patch literal 14058 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 literal 0 HcmV?d00001 -- 2.40.0