s4:rpc_server/lsa: specify \\pipe\lsass as ncacn_np_secondary_endpoint
[samba.git] / dynconfig / wscript
1 #!/usr/bin/env python
2
3 import string
4 import os
5 import optparse
6 import textwrap
7 from waflib import Logs, Errors, Options, Build, Context
8 from samba_utils import EXPAND_VARIABLES, os_path_relpath
9
10 class SambaIndentedHelpFormatter (optparse.IndentedHelpFormatter):
11     """Format help with indented section bodies.
12     """
13
14     def __init__(self,
15                  indent_increment=2,
16                  max_help_position=12,
17                  width=None,
18                  short_first=1):
19         optparse.IndentedHelpFormatter.__init__(
20             self, indent_increment, max_help_position, width, short_first)
21
22     def format_option(self, option):
23         # The help for each option consists of two parts:
24         #   * the opt strings and metavars
25         #     eg. ("-x", or "-fFILENAME, --file=FILENAME")
26         #   * the user-supplied help string
27         #     eg. ("turn on expert mode", "read data from FILENAME")
28         #
29         # If possible, we write both of these on the same line:
30         #   -x      turn on expert mode
31         #
32         # But if the opt string list is too long, we put the help
33         # string on a second line, indented to the same column it would
34         # start in if it fit on the first line.
35         #   -fFILENAME, --file=FILENAME
36         #           read data from FILENAME
37         result = []
38         opts = self.option_strings[option]
39         opt_width = self.help_position - self.current_indent - 2
40         if len(opts) > opt_width:
41             opts = "%*s%s\n" % (self.current_indent, "", opts)
42             indent_first = self.help_position
43         else:                       # start help on same line as opts
44             opts = "%*s%-*s  " % (self.current_indent, "", opt_width, opts)
45             indent_first = 0
46         result.append(opts)
47         if option.help:
48             help_text = self.expand_default(option)
49             if help_text.find('\n') == -1:
50                 help_lines = textwrap.wrap(help_text, self.help_width)
51             else:
52                 help_lines = help_text.splitlines()
53             result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
54             result.extend(["%*s%s\n" % (self.help_position, "", line)
55                            for line in help_lines[1:]])
56         elif opts[-1] != "\n":
57             result.append("\n")
58         return "".join(result)
59
60
61 # list of directory options to offer in configure
62 #
63 # 'STD-PATH'  - the default path without --enable-fhs
64 # 'FHS-PATH'  - the default path with --enable-fhs
65 #
66 # 'OPTION'    - the configure option to overwrite the default (optional)
67 # 'HELPTEXT'  - the help text of the configure option (optional)
68 #
69 # 'OVERWRITE' - The option referrs to itself and was already from
70 #               the basic GNU options from the gnu_dirs tool.
71 #               We may overwrite the related path. (Default: False)
72 #
73 # 'DELAY'     - The option referrs to other options in the dynconfig list.
74 #               We delay the intialization into a later stage. This
75 #               makes sure the recursion works. (Default: False)
76 #
77 dynconfig = {
78     'BINDIR' : {
79          'STD-PATH':  '${BINDIR}',
80          'FHS-PATH':  '${BINDIR}',
81          'OVERWRITE': True,
82     },
83     'SBINDIR' : {
84          'STD-PATH':  '${SBINDIR}',
85          'FHS-PATH':  '${SBINDIR}',
86          'OVERWRITE': True,
87     },
88     'LIBDIR' : {
89          'STD-PATH':  '${LIBDIR}',
90          'FHS-PATH':  '${LIBDIR}',
91          'OVERWRITE': True,
92     },
93     'LIBEXECDIR' : {
94          'STD-PATH':  '${LIBEXECDIR}',
95          'FHS-PATH':  '${LIBEXECDIR}',
96          'OVERWRITE': True,
97     },
98     'DATADIR' : {
99          'STD-PATH':  '${DATADIR}',
100          'FHS-PATH':  '${DATADIR}',
101          'OVERWRITE': True,
102     },
103     'LOCALEDIR' : {
104          'STD-PATH':  '${LOCALEDIR}',
105          'FHS-PATH':  '${LOCALEDIR}',
106          'OVERWRITE': True,
107     },
108     'PYTHONDIR' : {
109          'STD-PATH':  '${PYTHONDIR}',
110          'FHS-PATH':  '${PYTHONDIR}',
111          'OVERWRITE': True,
112     },
113     'PYTHONARCHDIR' : {
114          'STD-PATH':  '${PYTHONARCHDIR}',
115          'FHS-PATH':  '${PYTHONARCHDIR}',
116          'OVERWRITE': True,
117     },
118     'PERL_LIB_INSTALL_DIR' : {
119          'STD-PATH':  '${PERL_LIB_INSTALL_DIR}',
120          'FHS-PATH':  '${PERL_LIB_INSTALL_DIR}',
121          'OVERWRITE': True,
122     },
123     'PERL_ARCH_INSTALL_DIR' : {
124          'STD-PATH':  '${PERL_ARCH_INSTALL_DIR}',
125          'FHS-PATH':  '${PERL_ARCH_INSTALL_DIR}',
126          'OVERWRITE': True,
127     },
128     'INCLUDEDIR' : {
129          'STD-PATH':  '${INCLUDEDIR}',
130          'FHS-PATH':  '${INCLUDEDIR}/samba-4.0',
131          'OVERWRITE': True,
132     },
133     'SCRIPTSBINDIR' : {
134          'STD-PATH':  '${SBINDIR}',
135          'FHS-PATH':  '${SBINDIR}',
136     },
137     'SETUPDIR' : {
138          'STD-PATH':  '${DATADIR}/setup',
139          'FHS-PATH':  '${DATADIR}/samba/setup',
140     },
141     'PKGCONFIGDIR' : {
142          'STD-PATH':  '${LIBDIR}/pkgconfig',
143          'FHS-PATH':  '${LIBDIR}/pkgconfig',
144     },
145     'CODEPAGEDIR' : {
146          'STD-PATH':  '${DATADIR}/codepages',
147          'FHS-PATH':  '${DATADIR}/samba/codepages',
148     },
149     'PRIVATELIBDIR' : {
150          'STD-PATH':  '${LIBDIR}/private',
151          'FHS-PATH':  '${LIBDIR}/samba',
152          'OPTION':    '--with-privatelibdir',
153          'HELPTEXT':  'Which directory to use for private Samba libraries',
154          'OVERWRITE': True,
155     },
156     'MODULESDIR' : {
157          'STD-PATH':  '${LIBDIR}',
158          'FHS-PATH':  '${LIBDIR}/samba',
159          'OPTION':    '--with-modulesdir',
160          'HELPTEXT':  'Which directory to use for Samba modules',
161          'OVERWRITE': True,
162     },
163     'PAMMODULESDIR' : {
164          'STD-PATH':  '${LIBDIR}/security',
165          'FHS-PATH':  '${LIBDIR}/security',
166          'OPTION':    '--with-pammodulesdir',
167          'HELPTEXT':  'Which directory to use for PAM modules',
168     },
169     'CONFIGDIR' : {
170          'STD-PATH':  '${SYSCONFDIR}',
171          'FHS-PATH':  '${SYSCONFDIR}/samba',
172          'OPTION':    '--with-configdir',
173          'HELPTEXT':  'Where to put configuration files',
174     },
175     'PRIVATE_DIR' : {
176          'STD-PATH':  '${PREFIX}/private',
177          'FHS-PATH':  '${LOCALSTATEDIR}/lib/samba/private',
178          'OPTION':    '--with-privatedir',
179          'HELPTEXT':  'Where to put sam.ldb and other private files',
180     },
181     'BINDDNS_DIR' : {
182          'STD-PATH':  '${PREFIX}/bind-dns',
183          'FHS-PATH':  '${LOCALSTATEDIR}/lib/samba/bind-dns',
184          'OPTION':    '--with-bind-dns-dir',
185          'HELPTEXT':  'bind-dns config directory',
186     },
187     'LOCKDIR' : {
188          'STD-PATH':  '${LOCALSTATEDIR}/lock',
189          'FHS-PATH':  '${LOCALSTATEDIR}/lock/samba',
190          'OPTION':    '--with-lockdir',
191          'HELPTEXT':  'Where to put short term disposable state files',
192     },
193     'PIDDIR' : {
194          'STD-PATH':  '${LOCALSTATEDIR}/run',
195          'FHS-PATH':  '${LOCALSTATEDIR}/run/samba',
196          'OPTION':    '--with-piddir',
197          'HELPTEXT':  'Where to put pid files',
198     },
199     'STATEDIR' : {
200          'STD-PATH':  '${LOCALSTATEDIR}/locks',
201          'FHS-PATH':  '${LOCALSTATEDIR}/lib/samba',
202          'OPTION':    '--with-statedir',
203          'HELPTEXT':  'Where to put persistent state files',
204     },
205     'CACHEDIR' : {
206          'STD-PATH':  '${LOCALSTATEDIR}/cache',
207          'FHS-PATH':  '${LOCALSTATEDIR}/cache/samba',
208          'OPTION':    '--with-cachedir',
209          'HELPTEXT':  'Where to put temporary cache files',
210     },
211     'LOGFILEBASE' : {
212          'STD-PATH':  '${LOCALSTATEDIR}',
213          'FHS-PATH':  '${LOCALSTATEDIR}/log/samba',
214          'OPTION':    '--with-logfilebase',
215          'HELPTEXT':  'Where to put log files',
216     },
217     'SOCKET_DIR' : {
218          'STD-PATH':  '${LOCALSTATEDIR}/run',
219          'FHS-PATH':  '${LOCALSTATEDIR}/run/samba',
220          'OPTION':    '--with-sockets-dir',
221          'HELPTEXT':  'socket directory',
222     },
223     'PRIVILEGED_SOCKET_DIR' : {
224          'STD-PATH':  '${LOCALSTATEDIR}/lib',
225          'FHS-PATH':  '${LOCALSTATEDIR}/lib/samba',
226          'OPTION':    '--with-privileged-socket-dir',
227          'HELPTEXT':  'privileged socket directory',
228     },
229     'WINBINDD_SOCKET_DIR' : {
230          'STD-PATH':  '${SOCKET_DIR}/winbindd',
231          'FHS-PATH':  '${SOCKET_DIR}/winbindd',
232          'DELAY':     True,
233     },
234     'NMBDSOCKETDIR' : {
235          'STD-PATH':  '${SOCKET_DIR}/nmbd',
236          'FHS-PATH':  '${SOCKET_DIR}/nmbd',
237          'DELAY':     True,
238     },
239     'NTP_SIGND_SOCKET_DIR' : {
240          'STD-PATH':  '${PRIVILEGED_SOCKET_DIR}/ntp_signd',
241          'FHS-PATH':  '${PRIVILEGED_SOCKET_DIR}/ntp_signd',
242          'DELAY':     True,
243     },
244     'NCALRPCDIR' : {
245          'STD-PATH':  '${SOCKET_DIR}/ncalrpc',
246          'FHS-PATH':  '${SOCKET_DIR}/ncalrpc',
247          'DELAY':     True,
248     },
249     'CONFIGFILE' : {
250          'STD-PATH':  '${CONFIGDIR}/smb.conf',
251          'FHS-PATH':  '${CONFIGDIR}/smb.conf',
252          'DELAY':     True,
253     },
254     'LMHOSTSFILE' : {
255          'STD-PATH':  '${CONFIGDIR}/lmhosts',
256          'FHS-PATH':  '${CONFIGDIR}/lmhosts',
257          'DELAY':     True,
258     },
259     'SMB_PASSWD_FILE' : {
260          'STD-PATH':  '${PRIVATE_DIR}/smbpasswd',
261          'FHS-PATH':  '${PRIVATE_DIR}/smbpasswd',
262          'OPTION':    '--with-smbpasswd-file',
263          'HELPTEXT':  'Where to put the smbpasswd file',
264          'DELAY':     True,
265     },
266 }
267
268 def options(opt):
269     opt.parser.formatter = SambaIndentedHelpFormatter()
270     opt.parser.formatter.width=Logs.get_term_cols()
271
272     for k in ('--with-privatelibdir', '--with-modulesdir'):
273         option = opt.parser.get_option(k)
274         if option:
275             opt.parser.remove_option(k)
276     del opt.parser.defaults['PRIVATELIBDIR']
277     del opt.parser.defaults['MODULESDIR']
278
279     # get all the basic GNU options from the gnu_dirs tool
280
281     opt_group=opt.add_option_group('Samba-specific directory layout','')
282
283     fhs_help  = "Use FHS-compliant paths (default no)\n"
284     fhs_help += "You should consider using this together with:\n"
285     fhs_help += "--prefix=/usr --sysconfdir=/etc --localstatedir=/var"
286     opt_group.add_option('--enable-fhs', help=fhs_help,
287                    action="store_true", dest='ENABLE_FHS', default=False)
288
289     for varname in dynconfig.keys():
290         if 'OPTION' not in dynconfig[varname]:
291             continue
292         opt = dynconfig[varname]['OPTION']
293         if 'HELPTEXT' in dynconfig[varname]:
294             txt = dynconfig[varname]['HELPTEXT']
295         else:
296             txt = "dynconfig path %s" % (varname)
297         def_std = dynconfig[varname]['STD-PATH']
298         def_fhs = dynconfig[varname]['FHS-PATH']
299
300         help = "%s\n[STD-Default: %s]\n[FHS-Default: %s]" % (txt, def_std, def_fhs)
301         opt_group.add_option(opt, help=help, dest=varname, action="store")
302
303 def configure(conf):
304     # get all the basic GNU options from the gnu_dirs tool
305
306     if Options.options.ENABLE_FHS:
307         flavor = 'FHS-PATH'
308     else:
309         flavor = 'STD-PATH'
310         if conf.env.PREFIX == '/usr' or conf.env.PREFIX == '/usr/local':
311            Logs.error("Don't install directly under /usr or /usr/local without using the FHS option (--enable-fhs)")
312            raise Errors.WafError("ERROR: invalid --prefix=%s value" % (conf.env.PREFIX))
313
314     explicit_set ={}
315
316     dyn_vars = {}
317     for varname in dynconfig.keys():
318         dyn_vars[varname] = dynconfig[varname][flavor]
319         if 'OVERWRITE' in dynconfig[varname] and dynconfig[varname]['OVERWRITE']:
320             # we may overwrite this option
321             continue
322         conf.ASSERT(varname not in conf.env, "Variable %s already defined" % varname)
323
324     # the explicit block
325     for varname in dynconfig.keys():
326         if 'OPTION' not in dynconfig[varname]:
327             continue
328         value = getattr(Options.options, varname, None)
329         if value is None:
330            continue
331         conf.ASSERT(value != '', "Empty dynconfig value for %s" % varname)
332         conf.env[varname] = value
333         # mark it as explicit from the command line
334         explicit_set[varname] = value
335
336     # defaults stage 1 after the explicit block
337     for varname in dynconfig.keys():
338         if 'DELAY' in dynconfig[varname] and dynconfig[varname]['DELAY']:
339             # this option referrs to other options,
340             # so it needs to wait for stage 2.
341             continue
342         value = EXPAND_VARIABLES(conf, dyn_vars[varname])
343         conf.ASSERT(value != '', "Empty dynconfig value for %s" % varname)
344         if varname not in explicit_set:
345             # only overwrite if not specified explicitly on the command line
346             conf.env[varname] = value
347
348     # defaults stage 2 after the explicit block
349     for varname in dynconfig.keys():
350         if 'DELAY' not in dynconfig[varname] or not dynconfig[varname]['DELAY']:
351             # this option was already handled in stage 1.
352             continue
353         value = EXPAND_VARIABLES(conf, dyn_vars[varname])
354         conf.ASSERT(value != '', "Empty dynconfig value for %s" % varname)
355         if varname not in explicit_set:
356             # only overwrite if not specified explicitly on the command line
357             conf.env[varname] = value
358
359     # display the expanded pathes for the user
360     for varname in dynconfig.keys():
361         value = conf.env[varname]
362         conf.start_msg("Dynconfig[%s]: " % (varname))
363         conf.end_msg("'%s'" % (value), 'GREEN')
364
365 def get_override(bld):
366     override = { 'MODULESDIR'    : 'bin/modules',
367                  'PYTHONDIR'     : 'bin/python',
368                  'PYTHONARCHDIR' : 'bin/python',
369                  'BINDIR'        : 'bin',
370                  'SBINDIR'       : 'bin',
371                  'CODEPAGEDIR'   : 'codepages',
372                  'SCRIPTSBINDIR' : 'source4/scripting/bin',
373                  'SETUPDIR'      : 'source4/setup'
374                  }
375     return override
376
377 def dynconfig_cflags(bld, list=None):
378     '''work out the extra CFLAGS for dynconfig.c'''
379     cflags = []
380     for varname in dynconfig.keys():
381         if list and not varname in list:
382             continue
383         value = bld.env[varname]
384         if not bld.is_install:
385             override = get_override(bld)
386             if varname in override:
387                 value = os.path.join(bld.env.srcdir, override[varname])
388         cflags.append('-D%s="%s"' % (varname, value))
389     return cflags
390 Build.BuildContext.dynconfig_cflags = dynconfig_cflags
391
392 def dynconfig_varnames(bld, list=None):
393     '''work out the dynconfig variables'''
394     varnames = []
395     for varname in dynconfig.keys():
396         if list and not varname in list:
397             continue
398         varnames.append(varname)
399     return varnames
400 Build.BuildContext.dynconfig_varnames = dynconfig_varnames
401
402 def pathconfig_entities(bld, list=None):
403     '''work out the extra entities for the docs'''
404     entities = []
405     for varname in dynconfig.keys():
406         if list and not varname in list:
407             continue
408         value = bld.env[varname]
409         if not bld.is_install:
410             override = get_override(bld)
411             if varname in override:
412                 value = os.path.join(bld.env.srcdir, override[varname])
413         entities.append("<!ENTITY pathconfig.%s   '%s'>" % (varname, value))
414     return entities
415 Build.BuildContext.pathconfig_entities = pathconfig_entities
416
417 def build(bld):
418     cflags = bld.dynconfig_cflags()
419     version_header = 'version.h'
420     bld.SAMBA_SUBSYSTEM('DYNCONFIG',
421                         'dynconfig.c',
422                         deps='replace',
423                         public_headers=os_path_relpath(os.path.join(Context.launch_dir, version_header), bld.path.abspath()),
424                         header_path='samba',
425                         cflags=cflags)
426
427     # install some extra empty directories
428     bld.INSTALL_DIR("${CONFIGDIR}")
429     bld.INSTALL_DIR("${LOGFILEBASE}")
430     bld.INSTALL_DIR("${PRIVILEGED_SOCKET_DIR}")
431     bld.INSTALL_DIR("${PRIVATE_DIR}", 0o700)
432     bld.INSTALL_DIR("${BINDDNS_DIR}", 0o770)
433     bld.INSTALL_DIR("${STATEDIR}")
434     bld.INSTALL_DIR("${CACHEDIR}")
435
436     # these might be on non persistent storage
437     bld.INSTALL_DIRS("", "${LOCKDIR} ${PIDDIR} ${SOCKET_DIR}")