1. Building Dinit
  2. =-=-=-=-=-=-=-
  3. Building Dinit should be a straight-forward process. It requires GNU make and a C++11 compiler
  4. (GCC version 4.9 and later, or Clang ~5.0 and later, should be fine).
  5. Short version
  6. =-=-=-=-=-=-=
  7. Run "make" (or "gmake" if that is GNU make on your system). Your system type will hopefully be
  8. detected automatically and appropriate configuration chosen, and Dinit will be built. Continue
  9. reading instructions at "Running the test suite" or skip straight to "Installation".
  10. If this fails, or if you are cross-compiling, read the "long version" instructions.
  11. Long version
  12. =-=-=-=-=-=-
  13. On the directly supported operating systems - Linux, OpenBSD, FreeBSD and Darwin (macOS) - a
  14. suitable build configuration is provided and will be used automatically if no manual configuration
  15. is supplied - skip directly to running "make" (more details below) if you are on one of these
  16. systems and are happy to use the default configuration.
  17. For other systems, the "configure" script will run and try to generate a suitable "mconfig" file
  18. which specifies the build configuration. If you would prefer, you can run configure yourself
  19. before running "make"; this allows you to specify various options and/or hand-edit the generated
  20. mconfig file.
  21. For more information on available options from the configure script, run:
  22. ./configure --help
  23. As an alternative to running "configure", you can create and edit the "mconfig" file completely by
  24. hand (or start by copying one for a particular OS from the "configs" directory) to choose
  25. appropriate values for the configuration variables defined within. In particular:
  26. CXX : should be set to the name of the C++ compiler (and link driver)
  27. CXXFLAGS : are options passed to the compiler during compilation
  28. CPPFLAGS : are preprocessor options to use during compilation (see note for GCC below)
  29. LDFLAGS : are any options required for linking; should not normally be needed
  30. (FreeBSD requires -lrt; link time optimisation requires -flto and other flags).
  31. TEST_CXXFLAGS : are options passed to the compiler when compiling code for tests
  32. TEST_LDFLAGS : are options to be used when linking test code
  33. Additionally, for cross-compilation, the following can be specified:
  34. CXX_FOR_BUILD : C++ compiler for compiling code to run on the build host
  35. CXXFLAGS_FOR_BUILD : any options for compiling code to run on the build host
  36. CPPFLAGS_FOR_BUILD : any preprocessor options for code to run on the build host
  37. LDFLAGS_FOR_BUILD : any options for linking code to run on the build host
  38. Note that the "eg++" or "clang++" package must be installed on OpenBSD as the default "g++"
  39. compiler is too old. Clang is part of the base system in recent releases.
  40. Then, from the top-level directory, run "make" (or "gmake" if the system make is not GNU make,
  41. such as on most BSD systems):
  42. make
  43. If everything goes smoothly this will build dinit, dinitctl, and optionally the shutdown utility.
  44. Use "make install" to install; you can specify an alternate installation root by setting the
  45. "DESTDIR" variable, eg "make DESTDIR=/tmp/temporary-install-path install".
  46. All of the above variables can be specified on the "make" command line, for example:
  47. make CXX=gcc
  48. In addition to the above variables, the following can be specified on the command line (as a way
  49. to specify additional options without removing the defaults):
  50. CXXFLAGS_EXTRA : additional options to use when compiling code
  51. LDFLAGS_EXTRA : additional options to use when linking
  52. TEST_CXXFLAGS_EXTRA : additional options to use when compiling test code
  53. TEST_LDFLAGS_EXTRA : additional options to use when linking tests
  54. Recommended Compiler options
  55. =-=-=-=-=-=-=-=-=-=-=-=-=-=-
  56. Dinit should generally build fine with no additional options, other than:
  57. -std=c++11 : may be required to select correct C++ standard.
  58. -D_GLIBCXX_USE_CXX11_ABI=1 : see "Special note for GCC/Libstdc++", below. Not needed for
  59. most modern systems.
  60. Recommended options, supported by at least GCC and Clang, are:
  61. -Os : optimise for size
  62. -fno-rtti : disable RTTI (run-time type information), it is not required by Dinit. However, on
  63. some platforms such as Mac OS (and historically FreeBSD, IIRC), this prevents
  64. exceptions working correctly.
  65. -fno-plt : enables better code generation for non-static builds, but may cause unit test
  66. failures on some older versions of FreeBSD (eg 11.2-RELEASE-p4 with clang++ 6.0.0).
  67. -flto : perform link-time optimisation (option required at compile and link).
  68. Consult compiler documentation for further information on the above options.
  69. Other configuration variables
  70. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  71. There are a number of other variables you can set in the mconfig file which affect the build:
  72. SBINDIR=...
  73. Where the "/sbin" directory is. Executables will be installed here.
  74. MANDIR=...
  75. Where the "man" directory is. Man pages will be installed here.
  77. Default full path to the control socket, for when Dinit runs as system service manager.
  78. BUILD_SHUTDOWN=yes|no
  79. Whether to build the "shutdown" (and "halt" etc) utilities. These are only useful
  80. if dinit is the system init (i.e. the PID 1 process). You probably don't want this
  81. unless building for Linux.
  83. Name prefix for "shutdown", "halt" and "reboot" commands (if they are built). This affects
  84. both the output, and what command dinit will execute as part of system shutdown.
  85. If you want to install Dinit alongside another init system with its own shutdown/halt/reboot
  86. commands, set this (for eg. to "dinit-").
  87. USE_UTMPX=1|0
  88. Whether to build support for manipulating the utmp/utmpx database via the related POSIX
  89. functions. This may be required (along with appropriate service configuration) for utilities
  90. like "who" to work correctly (the service configuration items "inittab-id" and "inittab-line"
  91. have no effect if this is disabled). If not set to any value, support is enabled for certain
  92. systems automatically and disabled for all others.
  94. Whether to initialize supplementary groups for run-as services. The C API for this is not
  95. in POSIX, but is in practice supported on just about every relevant system, so it is enabled
  96. by default. If it is not supported on yours, you can explicitly disable it.
  97. DEFAULT_AUTO_RESTART=true|false
  98. Enable/disable auto-restart for services by default. It's true by default.
  100. Specifies the time in seconds allowed for the service to start. If the service takes longer
  101. than this, its process group enters the "stopping" state. It's 60 seconds by default.
  103. Specifies the time in seconds allowed for the service to stop. If the service takes longer than
  104. this, its process group is sent a SIGKILL signal which should cause it to terminate immediately.
  105. It's 10 seconds by default.
  106. Running test suite
  107. =-=-=-=-=-=-=-=-=-
  108. Build the "check" target in order to run the test suite:
  109. make check
  110. The standard mconfig options enable various sanitizers during build of the tests. On Linux you may
  111. see an error such as the following:
  112. make[3]: Leaving directory '/home/davmac/workspace/dinit/src/tests/cptests'
  113. ./tests
  114. ==25332==ERROR: AddressSanitizer failed to allocate 0xdfff0001000 (15392894357504) bytes at
  115. address 2008fff7000 (errno: 12)
  116. ==25332==ReserveShadowMemoryRange failed while trying to map 0xdfff0001000 bytes. Perhaps
  117. you're using ulimit -v
  118. make[2]: *** [Makefile:12: run-tests] Aborted
  119. If you get this, either disable the address sanitizer or make sure you have overcommit enabled:
  120. echo 1 > /proc/sys/vm/overcommit_memory
  121. Any test failures will abort the test suite run immediately.
  122. To run the integration tests:
  123. make check-igr
  124. (The integration tests are more fragile than the unit tests, but give a better indication that
  125. Dinit will actually work correctly on your system).
  126. In addition to the standard test suite, there is experimental support for fuzzing the control
  127. protocol handling using LLVM/clang's fuzzer (libFuzzer). Change to the `src/tests/cptests`
  128. directory and build the "fuzz" target:
  129. make fuzz
  130. Then create a "corpus" directory and run the fuzzer:
  131. mkdir corpus
  132. ./fuzz corpus
  133. This will auto-generate test data as it finds input which triggers new execution paths. Check
  134. libFuzzer documentation for further details.
  135. Installation
  136. =-=-=-=-=-=-
  137. You can install using the "install" target:
  138. make install
  139. If you want to install to an alternate root (eg for packaging purposes), specify that root via
  140. DESTDIR:
  141. make DESTDIR=/some/path install
  142. The dinit executable will be put in /sbin (or rather, in $DESTDIR/sbin), which may not be on the
  143. path for normal users. Consider making a symbolic link to /usr/sbin/dinit.
  144. Special note for GCC/Libstdc++
  145. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  146. (Note: the issue discussed here has apparently been resolved in recent GCC versions, with the fix
  147. backported to GCC 6.x series and newer).
  148. GCC 5.x onwards includes a "dual ABI" in its standard library implementation, aka Libstdc++.
  149. Compiling against the newer (C++11 and later) ABI can be achieved by adding
  150. -D_GLIBCXX_USE_CXX11_ABI=1 to the compiler command line; this uses a non-standard language
  151. extension to differently mangle symbol names in order to link against the new ABI versions.
  152. (Some systems may be configured to build with the new ABI by default, and in that case you build
  153. against the old ABI using -D_GLIBCXX_USE_CXX11_ABI=0).
  154. This is problematic for several reasons. First, it prevents linking against the new ABI with other
  155. compilers that do not understand the language extension (LLVM i.e. clang++ does so in recent
  156. versions, so this is perhaps no longer much of a problem in practice). Secondly, some aspects of
  157. library behaviour are ABI-dependent but cannot be changed using the ABI macro; in particular,
  158. exceptions thrown as a result of failed I/O operations are, in GCC versions 5.x and 6.x, always
  159. "old ABI" exceptions which cannot be caught by code compiled against the new ABI, and in GCC
  160. version 7.x they are always "new ABI" exceptions which cannot be caught by code compiled against
  161. the old ABI. Since the one library object now supposedly houses both ABIs, this means that at
  162. least one of the two ABIs is always broken.
  163. A blog post describing the dual ABI mechanism can be found here:
  165. The bug regarding the issue with catching other-ABI exceptions is here:
  167. Since Dinit is affected by this bug, the unfortunate possibility exists to break Dinit by
  168. upgrading GCC. If you have libstdc++ corresponding to GCC 5.x or 6.x, you *must* build with the
  169. old ABI, but Dinit will be broken if you upgrade to GCC 7. If you have libstdc++ from GCC 7, you
  170. *must* build with the new ABI. If the wrong ABI is used, Dinit may still run successfully but any
  171. attempt to load a non-existing service, for example, will cause Dinit to crash.