Browse Source

Add meson build system support.

Changes by mobin-2008; I've only cleaned up the commits and separated
out unrelated changes.
Mobin 1 year ago
parent
commit
05e6177dad

+ 201 - 0
BUILD_MESON

@@ -0,0 +1,201 @@
+Meson build system for Dinit
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+<!> Special notes about building Dinit via Meson
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+Please keep in mind:
+1. Meson build system for Dinit is an experimental way to build Dinit. 
+   it might have some bugs. Please report bugs on https://github.com/davmac314/dinit/issues
+2. Meson build system for Dinit is "extra" part. The main build system is GNU Make.
+   This means that the feature is first tested on Make. There may also be delays in adding new Dinit's features to Meson builds. 
+3. If you found some bugs in Meson builds, Please also test it on GNU make builds.
+
+Buidling Dinit via Meson
+=-=-=-=-=-=-=-=-=-=-=-=-
+
+Buidling Dinit is available via two "Build system": meson & make.
+Its file tells everything you need to buidling Dinit via meson.
+Bulding dinit via meson requires "meson" and a C++11 compiler (GCC version 4.9 and later, or Clang ~5.0 and later, should be fine)
+
+Meson configures all you need to build Dinit. It detects your OS, detects your compiler & sets something based on your system information.
+By Default no action is required & meson configures everything needed to build Dinit.
+
+Note that the "eg++" or "clang++" package must be installed on OpenBSD as the default "g++"
+compiler is too old. Clang is a part of the base system in recent releases.
+
+in Meson you need to prepare "Buidling Dir". simply just type:
+
+    meson setup builddir/
+
+This command configures "Building dir" in builddir/.
+You can set desired directory (but we suggest dont use dinit's directory such as build/ & src/ or ... as "Buidling dir").
+If everything goes smoothly this will prepare everything to build dinit, dinitctl, and optionaly the shutdown/reboot/halt utilitys by default.
+
+Everything is ready! you can compile Dinit with changing current directory to builddir/ & run:
+
+     meson compile
+
+Note: on old Mesons, you must use "ninja compile" instead of "meson compile".
+This command builds the dinit, dinitctl, and optionaly the shutdown/reboot/halt utilitys by default.
+
+Finally install them via this command:
+
+     meson install
+
+This command installs the programs. you can specify an alternate installation by setting the "DESTDIR" variable,
+eg "DESTDIR=/tmp/temporary-install-path meson install".
+
+
+Dinit's custom options
+=-=-=-=-=-=-=-=-=-=-=-
+
+Dinit should generally build with no additional options, all required options/flags will be added automatically.
+Custom options can be passed with command line:
+
+     meson setup -Doption=value builddir/
+
+or users can modify original "meson_options.txt" and set values.
+
+Custom options:
+ shutdown-prefix           : Name prefix for "shutdown", "halt" and "reboot" commands (if they are built).
+                             This affects both the output, and what command dinit will execute as part of system shutdown.
+                             If you want to install Dinit alongside another init system with its own shutdown/halt/reboot
+                             commands, set this (for eg. to "dinit-").
+                             Available values : everything you want!
+                             Default value : (empty)
+
+ build-shutdown            : Whether to build the "shutdown" (and "halt" etc) utilities. 
+                             These are only useful if dinit is the system init (i.e. the PID 1 process). 
+                             You probably don't want this unless building for Linux.
+                             Available values : enabled, disabled, auto
+                             Default value : auto
+
+ dinit-control-socket-path : Default full path to the control socket, for when Dinit runs as system service manager.
+                             Available values : anywhere you want!
+                             Default value : /run/dinitctl
+
+ unit-tests                : Building Unit tests. see "Running test suite", below.
+                             Available values: true, false
+                             Default value : false
+
+ igr-tests                 : Building Integration tests. see "Running test suite", below.
+                             Available values : true, false
+                             Default value : false
+ 
+ fuzzer                    : Building LLVM's Libfuzzer for Dinit. see "Running fuzzer", below.
+                             Available values : true, false
+                             Default value : false
+
+ use-utmpx                 : Whether to build support for manipulating the utmp/utmpx database via the related POSIX functions.
+                             This may be required (along with appropriate service configuration) for utilities
+                             like "who" to work correctly (the service configuration items "inittab-id" and "inittab-line" have no effect if this is disabled).
+                             If not set to any value, support is enabled for certain
+                             systems automatically and disabled for all others.
+                             Available values : enabled, disabled, auto
+                             Default value : auto
+
+ dinit-sbindir             : Default full path to the dinit executables.
+                             For some reasons Dinit dont follow Meson's default sbindir option. see "Why we use another option for sbindir?", below.
+                             Available values : anywhere you want!
+                             Default value : /sbin
+                             
+ man-pages                 : Building Dinit's man-pages.
+                             Available values : true, false
+                             Default value : true
+                             
+ support-cgroups           : Enable Cgroups supprot.
+                             Available values : enabled, disabled, auto
+                             Default value : auto
+
+ build-shutdown            : Building shutdown/reboot/halt or not.
+                             Available values : enabled, disabled, auto
+                             Default value : auto
+
+
+Running test suite
+=-=-=-=-=-=-=-=-=-
+
+Enable "unit-tests" option to run the test suite:
+
+     meson setup -Dunit-tests=true builddir/
+     
+Unlike Dinit's Make build system, We don't enable -fsanitize by default so if you need that use this option in meson setup step:
+
+     meson setup -Db_sanitizes='address,undefined' dirbuild/
+
+Enable "igr-tests" to run the integration tests:
+
+     meson setup -Digr-tests=true dirbuild/
+
+(The integration tests are more fragile than the unit tests, but give a better indication that
+Dinit will actually work correctly on your system).
+
+Finally switch current directory to Your builddir (eg dirbuild), compile Dinit with meson compile and run tests via:
+
+     meson test
+
+Then Meson report test status.
+
+
+Running fuzzer
+=-=-=-=-=-=-=-
+
+In addition to the standard test suite, there is experimental support for fuzzing the control
+protocol handling using LLVM/clang's fuzzer (libFuzzer). Enable "fuzzer" option to build fuzzer.
+
+    meson setup -Dfuzzer=true dirbuild
+
+Then changing current directory to Your builddir (eg dirbuild)/src/tests/cptests/, create a "corpus" directory and run the fuzzer:
+
+    mkdir corpus
+    ./fuzz corpus
+
+This will auto-generate test data as it finds input which triggers new execution paths. Check
+libFuzzer documentation for further details.
+
+
+Why we use another option for sbindir?
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+For some reasons, Old Mesons force sbindir will prefixed by Meson's prefix (eg /usr + sbin) but Dinit project use /sbin by default as sbindir. 
+in Newer Mesons that fixes this thing but we target Mesons's 0.47.0 as minimum version. So we use "dinit-sbindir" instead of default "sbindir".
+
+
+Special note for GCC/Libstdc++
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+(Note: the issue discussed here has apparently been resolved in recent GCC versions).
+
+GCC 5.x onwards includes a "dual ABI" in its standard library implementation, aka Libstdc++.
+Compiling against the newer (C++11 and later) ABI can be achieved by adding
+-D_GLIBCXX_USE_CXX11_ABI=1 to the compiler command line; this uses a non-standard language
+extension to differently mangle symbol names in order to link against the new ABI versions.
+
+(Some systems may be configured to build with the new ABI by default, and in that case you
+build against the old ABI using -D_GLIBCXX_USE_CXX11_ABI=0).
+
+This is problematic for several reasons. First, it prevents linking against the new ABI with
+other compilers that do not understand the language extension (LLVM i.e. clang++ does so
+in recent versions, so this is perhaps no longer much of a problem in practice). Secondly,
+some aspects of library behaviour are ABI-dependent but cannot be changed using the ABI
+macro; in particular, exceptions thrown as a result of failed I/O operations are, in GCC
+versions 5.x and 6.x, always "old ABI" exceptions which cannot be caught by code compiled
+against the new ABI, and in GCC version 7.x they are always "new ABI" exceptions which cannot
+be caught by code compiled against the old ABI. Since the one library object now supposedly
+houses both ABIs, this means that at least one of the two ABIs is always broken.
+
+A blog post describing the dual ABI mechanism can be found here:
+
+    https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/
+
+The bug regarding the issue with catching other-ABI exceptions is here:
+
+    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145
+
+Since Dinit is affected by this bug, the unfortunate possibility exists to break Dinit by
+upgrading GCC. If you have libstdc++ corresponding to GCC 5.x or 6.x, you *must* build with
+the old ABI, but Dinit will be broken if you upgrade to GCC 7. If you have libstdc++ from
+GCC 7, you *must* build with the new ABI. If the wrong ABI is used, Dinit may still run
+successfully but any attempt to load a non-existing service, for example, will cause Dinit
+to crash.

+ 25 - 0
build/general_variables_for_meson.sh

@@ -0,0 +1,25 @@
+#!/bin/sh
+
+## For some reasons meson cant read variables from env/files.
+## So we need to a wrapper for variables. This script is a wrapper for importing variables to meson.
+## Note: We use "printf" instead of "echo" because we dont need "\n" at end of outputs. "printf" by default dont print "\n" at end of output.
+
+set -e # Exit immediately if a command exits with a non-zero status.
+
+cd $(dirname $0)
+. ./version.conf
+
+case $1 in
+    version)
+        printf $VERSION
+        ;;
+    month)
+        printf $MONTH
+        ;;
+    year)
+        printf $YEAR
+        ;;
+    *)
+        echo "Invalid argument. Please set version or month or year as argument"
+        exit 1
+esac

+ 29 - 0
doc/manpages/meson.build

@@ -0,0 +1,29 @@
+# Included from top-level meson.build
+
+## Generate man-pages
+# Dinit need 'm4' to gen man-pages
+foreach man: ['dinit-service.5', 'dinit.8', 'dinitcheck.8', 'dinitctl.8', 'dinit-monitor.8']
+    section = 'man' + man.split('.')[1]
+    custom_target(
+        man,
+        input: man + '.m4',
+        output: man,
+        command: ['m4', '-DVERSION='+version, '-DMONTH='+month, '-DYEAR='+year, '@INPUT@'],
+        capture: true,
+        install: true,
+        install_dir: join_paths(get_option('mandir'), section),
+    )
+endforeach
+if shutdown_build
+    foreach shutdown_man: ['shutdown.8', 'reboot.8', 'halt.8']
+        custom_target(
+            shutdown_man,
+            input: 'shutdown.8.m4',
+            output: shutdown_prefix + shutdown_man,
+            command: ['m4', '-DVERSION='+version, '-DMONTH='+month, '-DYEAR='+year, '@INPUT@'],
+            capture: true,
+            install: true,
+            install_dir: join_paths(get_option('mandir'), section),
+        )
+    endforeach
+endif

+ 80 - 0
meson.build

@@ -0,0 +1,80 @@
+## Experimetal meson build system for dinit
+project(
+    'dinit', 
+    'cpp', 
+    version : run_command(
+        ['sh', 'build/general_variables_for_meson.sh', 'version'],
+        check : true).stdout(),
+    license : 'Apache-2.0',
+    meson_version : '>= 0.47.0',
+    default_options : [
+        'cpp_std = c++11',
+        'optimization=s',
+        'debug=false'
+    ]
+)
+
+## General Defines
+compiler = meson.get_compiler('cpp')
+mconfig_data = configuration_data()
+version = meson.project_version()
+platform = host_machine.system()
+month = run_command('build/general_variables_for_meson.sh', 'month', check : true).stdout()
+year = run_command('build/general_variables_for_meson.sh', 'year', check : true).stdout()
+build_shutdown = get_option('build-shutdown')
+shutdown_prefix = get_option('shutdown-prefix')
+dinit_control_socket_path = get_option('dinit-control-socket-path')
+unit_tests = get_option('unit-tests')
+igr_tests = get_option('igr-tests')
+fuzzer = get_option('fuzzer')
+man_pages = get_option('man-pages')
+support_cgroups = get_option('support-cgroups')
+use_utmpx = get_option('use-utmpx')
+# We have custom sbindir for install programs (/sbin instead of /usr/sbin/ by default)
+# By default: Prefix = /usr
+# By default: Sbin = /sbin
+# By default: you find dinit on /sbin/dinit
+# Note: Dinit dont follow Meson's default sbindir; Use dinit-sbindir option instead!
+prefix = get_option('prefix')
+sbindir = get_option('dinit-sbindir')
+mandir = get_option('mandir')
+
+## If Meson's default sbindir is modifed; Warn users about it:
+if get_option('sbindir') != 'sbin'
+    warning('Seems like Default "sbindir" is modified. Dinit dont follow Default "sbindir" option. Please use "dinit-sbindir" option instead!')
+endif
+
+## Use -lrt?
+# We need to pass -lrt to c++ linker on FreeBSD. see BUILD_MESON
+if platform == 'freebsd'
+    add_project_link_arguments('-lrt', language : 'cpp')
+endif
+
+## Prepare mconfig.h
+mconfig_data.set('DINIT_VERSION', '"' + meson.project_version() + '"')
+mconfig_data.set('SYSCONTROLSOCKET', '"' + dinit_control_socket_path + '"')
+mconfig_data.set('SBINDIR', '"' + sbindir + '"')
+mconfig_data.set('SHUTDOWN_PREFIX', '"' + shutdown_prefix + '"')
+if support_cgroups.auto() and platform == 'linux' or support_cgroups.enabled()
+    mconfig_data.set('SUPPORT_CGROUPS', '1') 
+endif
+if use_utmpx.enabled()
+    mconfig_data.set('USE_UTMPX', '1')
+elif use_utmpx.disabled()
+    mconfig_data.set('USE_UTMPX', '0')
+endif
+
+## Outputs
+subdir('src')
+if unit_tests
+    subdir('src/tests/')
+endif
+if fuzzer
+    subdir('src/tests/cptests/')
+endif
+if igr_tests
+    subdir('src/igr-tests/')
+endif
+if man_pages
+    subdir('doc/manpages/')
+endif

+ 68 - 0
meson_options.txt

@@ -0,0 +1,68 @@
+## meson_options.txt for dinit
+## You can set dinit's options in here:
+
+## Please see BUILD_MESON for more information.
+
+## General options
+option(
+    'shutdown-prefix',
+    type : 'string',
+    value : '',
+    description : 'Name prefix for "shutdown", "halt" and "reboot" commands (if they are built).'
+)
+option(
+    'dinit-control-socket-path',
+    type : 'string',
+    value : '/run/dinitctl',
+    description : 'Default full path to the control socket, for when Dinit runs as system service manager.'
+)
+option(
+    'unit-tests',
+    type : 'boolean',
+    value : 'false',
+    description : 'Building Unit tests. by default its disabled.'
+)
+option(
+    'igr-tests',
+    type : 'boolean',
+    value : 'false',
+    description : 'Building Integration tests. by default its disabled.'
+)
+option(
+    'fuzzer',
+    type : 'boolean',
+    value : 'false',
+    description : 'Building fuzz target'
+)
+option(
+    'use-utmpx',
+    type : 'feature',
+    value : 'auto',
+    description : 'Whether to build support for manipulating the utmp/utmpx database via the related POSIX functions.'
+)
+option(
+    'dinit-sbindir',
+    type : 'string',
+    value : '/sbin',
+    description : 'Default full path to the dinit executables. For some reasons dinit dont follow default sbindir. see BUILD_MESON for more info.'
+)
+option(
+    'man-pages',
+    type : 'boolean',
+    value : 'true',
+    description : 'Building & installing man-pages.'
+)
+
+## Linux specific options
+option(
+    'support-cgroups',
+    type : 'feature',
+    value : 'auto',
+    description : 'Enable Cgroups supprot.'
+)
+option(
+    'build-shutdown',
+    type : 'feature',
+    value : 'auto',
+    description : 'Building shutdown/reboot/halt or not.'
+)

+ 105 - 0
src/igr-tests/meson.build

@@ -0,0 +1,105 @@
+# Included from top-level meson.build
+
+## Prepare integration tests
+run_command([
+    'cp',
+    '-r',
+    './',
+    meson.current_build_dir()
+    ],
+    check : true
+)
+
+## Outputs
+# Integration tests
+basic_test_script = files(meson.current_build_dir() + '/basic/run-test.sh')
+environ_test_script = files(meson.current_build_dir() + '/environ/run-test.sh')
+psenviron_test_script = files(meson.current_build_dir() + '/ps-environ/run-test.sh')
+chainto_test_script = files(meson.current_build_dir() + '/chain-to/run-test.sh')
+forcestop_test_script = files(meson.current_build_dir() + '/force-stop/run-test.sh')
+restart_test_script = files(meson.current_build_dir() + '/restart/run-test.sh')
+checkbasic_test_script = files(meson.current_build_dir() + '/check-basic/run-test.sh')
+checkcycle_test_script = files(meson.current_build_dir() + '/check-cycle/run-test.sh')
+checklint_test_script = files(meson.current_build_dir() + '/check-lint/run-test.sh')
+reload1_test_script = files(meson.current_build_dir() + '/reload1/run-test.sh')
+reload2_test_script = files(meson.current_build_dir() + '/reload2/run-test.sh')
+nocommanderror_test_script = files(meson.current_build_dir() + '/no-command-error/run-test.sh')
+addrmdep_test_script = files(meson.current_build_dir() + '/add-rm-dep/run-test.sh')
+varsubst_test_script = files(meson.current_build_dir() + '/var-subst/run-test.sh')
+svcstartfail_test_script = files(meson.current_build_dir() + '/svc-start-fail/run-test.sh')
+test(
+     'basic',
+     basic_test_script,
+     env : igr_tests_env
+)
+test(
+     'environ',
+     environ_test_script,
+     env : igr_tests_env,
+     is_parallel : false
+)
+test(
+     'ps-environ',
+     psenviron_test_script,
+     env : igr_tests_env
+)
+test(
+     'chain-to',
+     chainto_test_script,
+     env : igr_tests_env
+)
+test(
+     'force-stop',
+     forcestop_test_script,
+     env : igr_tests_env
+)
+test(
+     'restart',
+     restart_test_script,
+     env : igr_tests_env
+)
+test(
+     'check-basic',
+     checkbasic_test_script,
+     env : igr_tests_env
+)
+test(
+     'check-cycle',
+     checkcycle_test_script,
+     env : igr_tests_env
+)
+test(
+     'check-lint',
+     checklint_test_script,
+     env : igr_tests_env
+)
+test(
+     'reload1',
+     reload1_test_script,
+     env : igr_tests_env
+)
+test(
+     'reload2',
+     reload2_test_script,
+     env : igr_tests_env
+)
+test(
+     'no-command-error',
+     nocommanderror_test_script,
+     env : igr_tests_env
+)
+test(
+     'add-rm-dep',
+     addrmdep_test_script,
+     env : igr_tests_env
+)
+test(
+     'var-subst',
+     varsubst_test_script,
+     env : igr_tests_env
+)
+test(
+     'svc-start-fail',
+     svcstartfail_test_script,
+     env : igr_tests_env
+)

+ 88 - 0
src/meson.build

@@ -0,0 +1,88 @@
+# Included from top-level meson.build
+
+## Includes
+# We include `./includes/` & `../dasynq/include/` as defualt_incdir
+default_incdir = include_directories(
+    'includes/',
+    '../dasynq/include/'
+)
+dinit_source_files = [
+    'dinit-main.cc',
+    'dinit.cc',
+    'load-service.cc',
+    'service.cc',
+    'proc-service.cc',
+    'baseproc-service.cc',
+    'control.cc',
+    'dinit-log.cc',
+    'run-child-proc.cc',
+    'options-processing.cc',
+    'dinit-env.cc'
+]
+
+## src/'s defines for igr-tests/
+if igr_tests
+    igr_tests_env = [
+        'DINIT_EXEC=' + meson.current_build_dir() + '/dinit',
+        'DINITCTL_EXEC=' + meson.current_build_dir() + '/dinitctl',
+        'DINITCHECK_EXEC=' + meson.current_build_dir() + '/dinitcheck',
+        'DINITMONITOR_EXEC=' + meson.current_build_dir() + '/dinit-monitor'
+    ]
+endif
+
+## Write mconfig.h
+configure_file(
+    output : 'mconfig.h',
+    configuration : mconfig_data
+)
+
+## Outputs
+# Standard apps: dinit, dinitctl, dinitcheck, dinit-monitor
+executable(
+    'dinit',
+    dinit_source_files,
+    include_directories : default_incdir,
+    install : true,
+    install_dir : sbindir
+)
+executable(
+    'dinitctl',
+    'dinitctl.cc',
+    include_directories : default_incdir,
+    install : true,
+    install_dir : sbindir
+)
+executable(
+    'dinitcheck',
+    'dinitcheck.cc',
+    'options-processing.cc',
+    include_directories : default_incdir,
+    install : true,
+    install_dir : sbindir
+)
+executable(
+    'dinit-monitor',
+    'dinit-monitor.cc',
+    include_directories : default_incdir,
+    install : true,
+    install_dir : sbindir
+)
+# Shutdown/reboot/halt
+if build_shutdown.auto() and platform == 'linux' or build_shutdown.enabled()
+    shutdown_build = true
+elif build_shutdown.auto() and platform != 'linux'
+    shutdown_build = false
+else
+    shutdown_build = false
+endif
+if shutdown_build
+    foreach exec: ['shutdown', 'reboot', 'halt']
+        executable(
+            shutdown_prefix + exec,
+            'shutdown.cc',
+            include_directories : default_incdir,
+            install : true,
+            install_dir : sbindir
+        )
+    endforeach
+endif

+ 70 - 0
src/tests/cptests/meson.build

@@ -0,0 +1,70 @@
+# Included from top-level meson.build
+
+## Includes
+incdir = include_directories(
+    'includes',
+    '../../../dasynq/include/'
+)
+if fuzzer
+    fuzz_sources = [
+        '../test-bpsys.cc',
+        '../test-dinit.cc',
+        '../test-run-child-proc.cc',
+        '../../control.cc',
+        '../../dinit-log.cc',
+        '../../service.cc',
+        '../../load-service.cc',
+        '../../proc-service.cc',
+        '../../baseproc-service.cc',
+        '../../dinit-env.cc'
+    ]
+endif
+if unit_tests
+    cptests_sources = [
+        '../../service.cc', 
+        '../../proc-service.cc',
+        '../../dinit-log.cc',
+        '../../load-service.cc',
+        '../../baseproc-service.cc',
+        '../../dinit-env.cc',
+        '../../control.cc',
+        '../test-dinit.cc',
+        '../test-bpsys.cc',
+        '../test-run-child-proc.cc'
+    ]
+endif
+
+## dinit with libfuzzer can't be compiled without clang/clang++. For some reasons, Meson don't support set default compiler in default_options.
+if fuzzer and compiler.get_id() != 'clang'
+    error('Fuzz target must compiles with clang instead of @0@'.format(compiler.get_id()))
+endif
+
+## Write mconfig.h
+configure_file(
+    output : 'mconfig.h',
+    configuration : mconfig_data
+)
+
+## Outputs
+# Cptests
+if unit_tests
+    cptests_exec = executable(
+        'cptests',
+        'cptests.cc',
+        cptests_sources,
+        include_directories : incdir
+    )
+    test('cptests', cptests_exec)
+endif
+# LLVM's Libfuzzer
+if fuzzer
+    executable(
+        'fuzz',
+        'fuzz.cc',
+        fuzz_sources,
+        include_directories : incdir,
+        install : false,
+        cpp_args : '-fsanitize=address,undefined,fuzzer-no-link,leak',
+        link_args : '-fsanitize=fuzzer,address,undefined,leak'
+    )
+endif

+ 62 - 0
src/tests/meson.build

@@ -0,0 +1,62 @@
+# Included from top-level meson.build
+
+## Includes
+for_tests_incdir = include_directories(
+    'includes/',
+    '../../dasynq/include/'
+)
+for_tests_dinit_sources = [
+    '../service.cc', 
+    '../proc-service.cc',
+    '../dinit-log.cc',
+    '../load-service.cc',
+    '../baseproc-service.cc',
+    '../dinit-env.cc'
+]
+for_tests_general_sources = [
+    'test-dinit.cc',
+    'test-bpsys.cc',
+    'test-run-child-proc.cc'
+]
+
+## Write mconfig.h from top-level meson.build
+configure_file(
+    output : 'mconfig.h',
+    configuration : mconfig_data
+)
+
+## Outputs
+# Unit tests
+tests_exec = executable(
+    'tests',
+    'tests.cc',
+    for_tests_general_sources,
+    for_tests_dinit_sources,
+    include_directories : for_tests_incdir
+)
+proctests_exec = executable(
+    'proctests',
+    'proctests.cc',
+    for_tests_general_sources,
+    for_tests_dinit_sources,
+    include_directories : for_tests_incdir
+)
+loadtests_exec = executable(
+    'loadtests',
+    'loadtests.cc',
+    for_tests_general_sources,
+    for_tests_dinit_sources,
+    include_directories : for_tests_incdir
+)
+envtests_exec = executable(
+    'envtests',
+    'envtests.cc',
+    for_tests_general_sources,
+    for_tests_dinit_sources, 
+    include_directories : for_tests_incdir
+)
+test('tests', tests_exec)
+test('proctests', proctests_exec)
+test('loadtests', loadtests_exec, should_fail : true)
+test('envtests', envtests_exec)
+subdir('cptests/')