BUILD 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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), as well as a handful of
  5. utilities that should be available on any POSIX-compliant system; in particular, the "m4"
  6. processor is required for the manual pages.
  7. Short version
  8. =-=-=-=-=-=-=
  9. Run "make mconfig" (use "gmake mconfig" if GNU make is installed as "gmake"). Edit the generated
  10. "mconfig" file to your liking; typically you will want to adjust SBINDIR and MANDIR, which control
  11. the installation paths for executable files and man pages respectively.
  12. Run "make"/"gmake" to build. Your system type will hopefully be detected automatically and
  13. appropriate configuration chosen, and Dinit will be built. Continue reading instructions at
  14. "Running the test suite" or skip straight to "Installation".
  15. If you run into any problems, or if you are cross-compiling, read the "long version" instructions.
  16. Long version
  17. =-=-=-=-=-=-
  18. On the directly supported operating systems - Linux, OpenBSD, FreeBSD and Darwin (including
  19. macOS) - a suitable build configuration is provided and will be used automatically if no manual
  20. configuration is supplied - skip directly to running "make" (more details below) if you are on one
  21. of these systems and are happy to use the default configuration, but note that you will typically
  22. at least want to alter the installation location.
  23. If you are using a different system, or want to alter the default configuration, first run "make
  24. mconfig" to generate the "mconfig" file which contains the build configuration. You can then edit
  25. this file by hand, before proceeding with the build. Note that the the generated "mconfig" may be
  26. a symbolic link to a system-specific default config file. It is not necessary to edit the file; you
  27. can override variables on the "make" command line if you prefer.
  28. An alternative to "make mconfig" is to use the provided "configure" script. It will try to
  29. generate a suitable "mconfig" file, based on sensible defaults and options provided on the command
  30. line when the script is run.
  31. For more information on available options from the configure script, run:
  32. ./configure --help
  33. You can also create and edit the "mconfig" file completely by hand (or start by copying one for a
  34. particular OS from the "configs" directory) to choose appropriate values for the configuration
  35. variables defined within.
  36. Main build variables
  37. =-=-=-=-=-=-=-=-=-=-
  38. There are some build variables that may typically require adjustment. In particular, some
  39. variables control installation paths or paths that are used at runtime; they are:
  40. SBINDIR : set to the directory where the executable files should be installed
  41. MANDIR : set to the directory where manual pages should be installed
  42. SYSCONTROLSOCKET : set to the default location of the control socket when Dinit is run as a system
  43. manager (as opposed to a user service manager)
  44. Some variables affect whether the "shutdown" utility is included and how it is named:
  45. BUILD_SHUTDOWN : (yes|no)
  46. Whether to build the "shutdown" (and "halt" etc) utilities. These are only useful
  47. if dinit is the system init (i.e. the PID 1 process). You probably don't want this
  48. unless building for Linux as shutdown is not supported on other systems (yet).
  49. SHUTDOWN_PREFIX :
  50. Name prefix for "shutdown", "halt" and "reboot" commands (if they are built). This affects
  51. both the output, and what command dinit will execute as part of system shutdown.
  52. If you want to install Dinit alongside another init system with its own shutdown/halt/reboot
  53. commands, set this (for eg. to "dinit-").
  54. The following variables affect compilation and link options:
  55. CXX : should be set to the name of the C++ compiler (and link driver)
  56. CXXFLAGS : are options passed to the compiler during compilation
  57. CPPFLAGS : are preprocessor options to use during compilation (see note for GCC below)
  58. LDFLAGS : are any options required for linking; should not normally be needed
  59. (FreeBSD requires -lrt; link time optimisation requires -flto and other flags).
  60. TEST_CXXFLAGS : are options passed to the compiler when compiling code for tests
  61. TEST_LDFLAGS : are options to be used when linking test code
  62. LDFLAGS_LIBCAP : addition link options required to link with "libcap" (needed if capabilities
  63. support is enabled).
  64. For convenience, generated configuration also allows setting the following:
  65. LDFLAGS_BASE : any link options that should be used by default for linking (including tests),
  66. if LDFLAGS is not overridden, to which CXXFLAGS will be added if the
  67. configuration enables link-time optimisation (LTO). Will be ignored if LDFLAGS
  68. is set.
  69. TEST_LDFLAGS_BASE : as LDFLAGS_BASE but for tests. The default is to use the same value (if any)
  70. as specified for LDFLAGS_BASE. Ignored if TEST_LDFLAGS is set.
  71. Together, LDFLAGS_BASE and TEST_LDFLAGS_BASE provide a simple way to adjust link options without
  72. interfering with link-time optimisation (LTO). With LTO enabled, LDFLAGS must usually include the
  73. same options used for compilation; by adjusting LDFLAGS_BASE instead, you do not have to
  74. specifically include the compilation options as they will be included in LDFLAGS automatically.
  75. For cross-compilation, the following can be specified:
  76. CXX_FOR_BUILD : C++ compiler for compiling code to run on the build host
  77. CXXFLAGS_FOR_BUILD : any options for compiling code to run on the build host
  78. CPPFLAGS_FOR_BUILD : any preprocessor options for code to run on the build host
  79. LDFLAGS_FOR_BUILD : any options for linking code to run on the build host
  80. Note that the "eg++" or "clang++" package may need to be installed on OpenBSD if the default "g++"
  81. compiler is too old. Clang is part of the base system in recent releases.
  82. Then, from the top-level directory, run "make" (or "gmake" if the system make is not GNU make,
  83. such as on most BSD systems):
  84. make
  85. If everything goes smoothly this will build dinit, dinitctl, and optionally the shutdown utility.
  86. Use "make install" to install; you can specify an alternate installation root by setting the
  87. "DESTDIR" variable, eg "make DESTDIR=/tmp/temporary-install-path install".
  88. All of the above variables can be specified on the "make" command line, for example:
  89. make CXX=gcc
  90. In addition to the above variables, the following can be specified on the command line (as a way
  91. to specify additional options without removing the defaults):
  92. CXXFLAGS_EXTRA : additional options to use when compiling code
  93. LDFLAGS_EXTRA : additional options to use when linking
  94. TEST_CXXFLAGS_EXTRA : additional options to use when compiling test code
  95. TEST_LDFLAGS_EXTRA : additional options to use when linking tests
  96. Recommended compiler options
  97. =-=-=-=-=-=-=-=-=-=-=-=-=-=-
  98. Dinit should generally build fine with no additional options, other than:
  99. -std=c++11 : may be required to select correct C++ standard.
  100. -D_GLIBCXX_USE_CXX11_ABI=1 : see "Special note for GCC/Libstdc++", below. Not needed for
  101. most modern systems.
  102. Recommended options, supported by at least GCC and Clang, are:
  103. -Os : optimise for size
  104. -fno-rtti : disable RTTI (run-time type information), it is not required by Dinit. However, on
  105. some platforms such as Mac OS (and historically FreeBSD, IIRC), this prevents
  106. exceptions working correctly.
  107. -fno-plt : enables better code generation for non-static builds, but may cause unit test
  108. failures on some older versions of FreeBSD (eg 11.2-RELEASE-p4 with clang++ 6.0.0).
  109. -flto : perform link-time optimisation (option required at compile and link).
  110. Consult compiler documentation for further information on the above options.
  111. Other configuration variables
  112. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  113. There are a number of other variables you can set in the mconfig file which affect the build:
  114. USE_UTMPX=1|0
  115. Whether to build support for manipulating the utmp/utmpx database via the related POSIX
  116. functions. This may be required (along with appropriate service configuration) for utilities
  117. like "who" to work correctly (the service configuration items "inittab-id" and "inittab-line"
  118. have no effect if this is disabled). If not set to any value, support is enabled for certain
  119. systems automatically and disabled for all others.
  120. USE_INITGROUPS=1|0
  121. Whether to initialize supplementary groups for run-as services. The C API for this is not
  122. in POSIX, but is in practice supported on just about every relevant system, so it is enabled
  123. by default. If it is not supported on yours, you can explicitly disable it.
  124. DEFAULT_AUTO_RESTART=ALWAYS|ON_FAILURE|NEVER
  125. Default for when to automatically restart services. This controls the default for the
  126. "restart" service setting. ON_FAILURE restarts process/bgprocess services only if they exit
  127. with a non-zero status or are terminated via (most) signals; for other service types it
  128. behaves the same as NEVER. See documentation (dinit-service(5) man page) for details.
  129. DEFAULT_START_TIMEOUT=XXX
  130. Specifies the time in seconds allowed for the service to start. If the service takes longer
  131. than this, service startup will be cancelled (service processes will be signalled to cause
  132. termination). The default if unspecified is 60 seconds. (The value can be overridden for
  133. individual services via the service description).
  134. DEFAULT_STOP_TIMEOUT=XXX
  135. Specifies the time in seconds allowed for the service to stop. If the service takes longer than
  136. this, its process group is sent a SIGKILL signal which should cause it to terminate immediately.
  137. The default if unspecified is 10 seconds. (The value can be overridden for individual services
  138. via the service description).
  139. SUPPORT_CGROUPS=1|0
  140. Whether to include support for cgroups (Linux only).
  141. SUPPORT_CAPABILITIES=1|0
  142. Whether to include support for capabilities (Linux only; requires libcap).
  143. SUPPORT_IOPRIO=1|0
  144. Whether to include support for adjusting IO priority (Linux only).
  145. SUPPORT_OOMADJ=1|0
  146. Whether to include support for adusting OOM-killer score adjustment (Linux only).
  147. Running the test suite
  148. =-=-=-=-=-=-=-=-=-=-=-
  149. Build the "check" target in order to run the test suite:
  150. make check
  151. The standard mconfig options enable various sanitizers during build of the tests. On Linux you may
  152. see an error such as the following:
  153. make[3]: Leaving directory '/home/davmac/workspace/dinit/src/tests/cptests'
  154. ./tests
  155. ==25332==ERROR: AddressSanitizer failed to allocate 0xdfff0001000 (15392894357504) bytes at
  156. address 2008fff7000 (errno: 12)
  157. ==25332==ReserveShadowMemoryRange failed while trying to map 0xdfff0001000 bytes. Perhaps
  158. you're using ulimit -v
  159. make[2]: *** [Makefile:12: run-tests] Aborted
  160. If you get this, either disable the address sanitizer or make sure you have overcommit enabled:
  161. echo 1 > /proc/sys/vm/overcommit_memory
  162. Any test failures will abort the test suite run immediately.
  163. To run the integration tests:
  164. make check-igr
  165. (The integration tests are more fragile than the unit tests, but give a better indication that
  166. Dinit will actually work correctly on your system).
  167. In addition to the standard test suite, there is experimental support for fuzzing the control
  168. protocol handling using LLVM/clang's fuzzer (libFuzzer). Change to the `src/tests/cptests`
  169. directory and build the "fuzz" target:
  170. make fuzz
  171. Then create a "corpus" directory and run the fuzzer:
  172. mkdir corpus
  173. ./fuzz corpus
  174. This will auto-generate test data as it finds input which triggers new execution paths. Check
  175. libFuzzer documentation for further details.
  176. Installation
  177. =-=-=-=-=-=-
  178. You can install using the "install" target:
  179. make install
  180. If you want to install to an alternate root (eg for packaging purposes), specify that root via
  181. DESTDIR:
  182. make DESTDIR=/some/path install
  183. The dinit executable will be put in /sbin (or rather, in $DESTDIR/sbin), which may not be on the
  184. path for normal users. Consider making a symbolic link to /usr/sbin/dinit.
  185. Note that if you specify installation paths via variables on the "make" command line, you should
  186. specify the same values for both build and install steps.
  187. Special note for GCC/Libstdc++
  188. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  189. (Note: the issue discussed here has apparently been resolved in recent GCC versions, with the fix
  190. backported to GCC 6.x series and newer).
  191. GCC 5.x onwards includes a "dual ABI" in its standard library implementation, aka Libstdc++.
  192. Compiling against the newer (C++11 and later) ABI can be achieved by adding
  193. -D_GLIBCXX_USE_CXX11_ABI=1 to the compiler command line; this uses a non-standard language
  194. extension to differently mangle symbol names in order to link against the new ABI versions.
  195. (Some systems may be configured to build with the new ABI by default, and in that case you build
  196. against the old ABI using -D_GLIBCXX_USE_CXX11_ABI=0).
  197. This is problematic for several reasons. First, it prevents linking against the new ABI with other
  198. compilers that do not understand the language extension (LLVM i.e. clang++ does so in recent
  199. versions, so this is perhaps no longer much of a problem in practice). Secondly, some aspects of
  200. library behaviour are ABI-dependent but cannot be changed using the ABI macro; in particular,
  201. exceptions thrown as a result of failed I/O operations are, in GCC versions 5.x and 6.x, always
  202. "old ABI" exceptions which cannot be caught by code compiled against the new ABI, and in GCC
  203. version 7.x they are always "new ABI" exceptions which cannot be caught by code compiled against
  204. the old ABI. Since the one library object now supposedly houses both ABIs, this means that at
  205. least one of the two ABIs is always broken.
  206. A blog post describing the dual ABI mechanism can be found here:
  207. https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/
  208. The bug regarding the issue with catching other-ABI exceptions is here:
  209. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145
  210. Since Dinit is affected by this bug, the unfortunate possibility exists to break Dinit by
  211. upgrading GCC. If you have libstdc++ corresponding to GCC 5.x or 6.x, you *must* build with the
  212. old ABI, but Dinit will be broken if you upgrade to GCC 7. If you have libstdc++ from GCC 7, you
  213. *must* build with the new ABI. If the wrong ABI is used, Dinit may still run successfully but any
  214. attempt to load a non-existing service, for example, will cause Dinit to crash.