-
Vladimír Čunát authoreda46fc6a3
Building project
Installing from packages
The resolver is packaged for Debian, Fedora, Ubuntu and openSUSE Linux distributions. Refer to project page for information about installing from packages. If packages are not available for your OS, see following sections to see how you can build it from sources (or package it), or use official Docker images.
Platform considerations
Project | Platforms | Compatibility notes |
---|---|---|
daemon |
UNIX-like [1], Microsoft Windows | C99, libuv provides portable I/O |
library |
UNIX-like, Microsoft Windows [2] | MSVC not supported, needs MinGW |
modules |
varies | |
tests/unit |
equivalent to library | |
tests/integration |
UNIX-like | Depends on library injection (see [2]) |
[1] | Known to be running (not exclusively) on FreeBSD, Linux and OS X. |
[2] | Modules are not supported yet, as the PE/DLL loading is different. Library injection is working with ELF (or Mach-O flat namespace) only. |
Requirements
The following is a list of software required to build Knot DNS Resolver from sources.
Requirement | Required by | Notes |
---|---|---|
GNU Make 3.80+ | all | (build only) |
pkg-config | all | (build only) [3] |
C compiler | all | (build only) [4] |
libknot 2.1+ | all | Knot DNS library (requires autotools, GnuTLS and Jansson). |
LuaJIT 2.0+ | daemon |
Embedded scripting language. |
libuv 1.7+ | daemon |
Multiplatform I/O and services (libuv 1.0 with limitations [5]). |
There are also optional packages that enable specific functionality in Knot DNS Resolver, they are useful mainly for developers to build documentation and tests.
Optional | Needed for | Notes |
---|---|---|
lua-http | modules/http |
HTTP/2 client/server for Lua. |
luasocket | trust anchors, modules/stats |
Sockets for Lua. |
luasec | trust anchors |
TLS for Lua. |
libmemcached | modules/memcached |
To build memcached backend module. |
hiredis | modules/redis |
To build redis backend module. |
geoip | modules/tinyweb |
To build a proof-of-concept web interface (needs Go as well). |
Go 1.5+ | modules |
Build modules written in Go. |
cmocka | unit tests |
Unit testing framework. |
Doxygen | documentation |
Generating API documentation. |
Sphinx | documentation |
Building this HTML/PDF documentation. |
breathe | documentation |
Exposing Doxygen API doc to Sphinx. |
libsystemd | daemon |
Systemd socket activation support. |
[3] | Requires C99, __attribute__((cleanup)) and -MMD -MP for dependency file generation. GCC, Clang and ICC are supported. |
[4] | You can use variables <dependency>_CFLAGS and <dependency>_LIBS to configure dependencies manually (i.e. libknot_CFLAGS and libknot_LIBS ). |
[5] | libuv 1.7 brings SO_REUSEPORT support that is needed for multiple forks. libuv < 1.7 can be still used, but only in single-process mode. Use :ref:`different method <daemon-reuseport>` for load balancing. |
Packaged dependencies
Most of the dependencies can be resolved from packages, here's an overview for several platforms.
- Debian (since sid) - current stable doesn't have libknot and libuv, which must be installed from sources.
sudo apt-get install pkg-config libknot-dev libuv1-dev libcmocka-dev libluajit-5.1-dev
- Ubuntu - unknown.
- RHEL/CentOS - unknown.
- openSUSE - there is an experimental package.
- RHEL - unknown.
- FreeBSD - unknown.
- NetBSD - unknown.
- OpenBSD - unknown.
- Mac OS X - most of the dependencies can be found through Homebrew, with the exception of libknot.
brew install pkg-config libuv luajit cmocka
Building from sources
The Knot DNS Resolver depends on the the Knot DNS library, recent version of libuv, and LuaJIT.
$ make info # See what's missing
When you have all the dependencies ready, you can build and install.
$ make PREFIX="/usr/local"
$ make install PREFIX="/usr/local"
Note
Always build with PREFIX
if you want to install, as it is hardcoded in the executable for module search path. If you build the binary with -DNDEBUG
, verbose logging will be disabled as well.
Alternatively you can build only specific parts of the project, i.e. library
.
$ make lib
$ make lib-install
Note
Documentation is not built by default, run make doc
to build it.
Building with security compiler flags
Knot DNS Resolver enables certain security compile-time flags that do not affect performance.
You can add more flags to the build by appending them to CFLAGS variable, e.g. make CFLAGS="-fstack-protector"
.
Method Status Notes -fstack-protector disabled (must be specifically enabled in CFLAGS) -D_FORTIFY_SOURCE=2 enabled -pie enabled enables ASLR for kresd (disable with make HARDENING=no
)RELRO enabled full [6]
You can also disable linker hardening when it's unsupported with make HARDENING=no
.
[6] | See checksec.sh |
Building for packages
The build system supports both DESTDIR and amalgamated builds.
$ make install DESTDIR=/tmp/stage # Staged install
$ make all install AMALG=yes # Amalgamated build
Amalgamated build assembles everything in one source file and compiles it. It is useful for packages, as the compiler sees the whole program and is able to produce a smaller and faster binary. On the other hand, it complicates debugging.
Tip
There is a template for service file and AppArmor profile to help you kickstart the package.
Default paths
The default installation follows FHS with several custom paths for configuration and modules.
All paths are prefixed with PREFIX
variable by default if not specified otherwise.
Component Variable Default Notes library LIBDIR
$(PREFIX)/lib
pkg-config is auto-generated [7] daemon SBINDIR
$(PREFIX)/sbin
configuration ETCDIR
$(PREFIX)/etc/kresd
Configuration file, templates. modules MODULEDIR
$(LIBDIR)/kdns_modules
[8] work directory $(PREFIX)/var/run/kresd
Run directory for daemon.
[7] | The libkres.pc is installed in $(LIBDIR)/pkgconfig . |
[8] | Users may install additional modules in ~/.local/lib/kdns_modules or in the rundir of a specific instance. |
Note
Each module is self-contained and may install additional bundled files within $(MODULEDIR)/$(modulename)
. These files should be read-only, non-executable.
Static or dynamic?
By default the resolver library is built as a dynamic library with versioned ABI. You can revert to static build with BUILDMODE
variable.
$ make BUILDMODE=dynamic # Default, create dynamic library
$ make BUILDMODE=static # Create static library
When the library is linked statically, it usually produces a smaller binary. However linking it to various C modules might violate ODR and increase the size.
Resolving dependencies
The build system relies on pkg-config to find dependencies. You can override it to force custom versions of the software by environment variables.
$ make libknot_CFLAGS="-I/opt/include" libknot_LIBS="-L/opt/lib -lknot -ldnssec"
Optional dependencies may be disabled as well using HAS_x=yes|no
variable.
$ make HAS_go=no HAS_cmocka=no
Warning
If the dependencies lie outside of library search path, you need to add them somehow.
Try LD_LIBRARY_PATH
on Linux/BSD, and DYLD_FALLBACK_LIBRARY_PATH
on OS X.
Otherwise you need to add the locations to linker search path.
Several dependencies may not be in the packages yet, the script pulls and installs all dependencies in a chroot. You can avoid rebuilding dependencies by specifying BUILD_IGNORE variable, see the Dockerfile for example. Usually you only really need to rebuild libknot.
$ export FAKEROOT="${HOME}/.local"
$ export PKG_CONFIG_PATH="${FAKEROOT}/lib/pkgconfig"
$ export BUILD_IGNORE="..." # Ignore installed dependencies
$ ./scripts/bootstrap-depends.sh ${FAKEROOT}
Building extras
The project can be built with code coverage tracking using the COVERAGE=1
variable.
Running unit and integration tests
The unit tests require cmocka and are executed with make check
.
The integration tests use Deckard, the DNS test harness.
$ make check-integration
Note that the daemon and modules must be installed first before running integration tests, the reason is that the daemon is otherwise unable to find and load modules.
Read the documentation for more information about requirements, how to run it and extend it.
Getting Docker image
Docker images require only either Linux or a Linux VM (see boot2docker on OS X).
$ docker run cznic/knot-resolver
See the Docker images page for more information and options. You can hack on the container by changing the container entrypoint to shell like:
$ docker run -it --entrypoint=/bin/bash cznic/knot-resolver
Tip
You can build the Docker image yourself with docker build -t knot-resolver scripts
.