libndr: Avoid assigning duplicate versions to symbols
[amitay/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     'SAMBA_DATADIR' : {
104          'STD-PATH':  '${DATADIR}/samba',
105          'FHS-PATH':  '${DATADIR}/samba',
106          'OVERWRITE': True,
107     },
108     'LOCALEDIR' : {
109          'STD-PATH':  '${LOCALEDIR}',
110          'FHS-PATH':  '${LOCALEDIR}',
111          'OVERWRITE': True,
112     },
113     'PYTHONDIR' : {
114          'STD-PATH':  '${PYTHONDIR}',
115          'FHS-PATH':  '${PYTHONDIR}',
116          'OVERWRITE': True,
117     },
118     'PYTHONARCHDIR' : {
119          'STD-PATH':  '${PYTHONARCHDIR}',
120          'FHS-PATH':  '${PYTHONARCHDIR}',
121          'OVERWRITE': True,
122     },
123     'PERL_LIB_INSTALL_DIR' : {
124          'STD-PATH':  '${PERL_LIB_INSTALL_DIR}',
125          'FHS-PATH':  '${PERL_LIB_INSTALL_DIR}',
126          'OVERWRITE': True,
127     },
128     'PERL_ARCH_INSTALL_DIR' : {
129          'STD-PATH':  '${PERL_ARCH_INSTALL_DIR}',
130          'FHS-PATH':  '${PERL_ARCH_INSTALL_DIR}',
131          'OVERWRITE': True,
132     },
133     'INCLUDEDIR' : {
134          'STD-PATH':  '${INCLUDEDIR}',
135          'FHS-PATH':  '${INCLUDEDIR}/samba-4.0',
136          'OVERWRITE': True,
137     },
138     'SCRIPTSBINDIR' : {
139          'STD-PATH':  '${SBINDIR}',
140          'FHS-PATH':  '${SBINDIR}',
141     },
142     'SETUPDIR' : {
143          'STD-PATH':  '${DATADIR}/setup',
144          'FHS-PATH':  '${DATADIR}/samba/setup',
145     },
146     'PKGCONFIGDIR' : {
147          'STD-PATH':  '${LIBDIR}/pkgconfig',
148          'FHS-PATH':  '${LIBDIR}/pkgconfig',
149     },
150     'CODEPAGEDIR' : {
151          'STD-PATH':  '${DATADIR}/codepages',
152          'FHS-PATH':  '${DATADIR}/samba/codepages',
153     },
154     'PRIVATELIBDIR' : {
155          'STD-PATH':  '${LIBDIR}/private',
156          'FHS-PATH':  '${LIBDIR}/samba',
157          'OPTION':    '--with-privatelibdir',
158          'HELPTEXT':  'Which directory to use for private Samba libraries',
159          'OVERWRITE': True,
160     },
161     'MODULESDIR' : {
162          'STD-PATH':  '${LIBDIR}',
163          'FHS-PATH':  '${LIBDIR}/samba',
164          'OPTION':    '--with-modulesdir',
165          'HELPTEXT':  'Which directory to use for Samba modules',
166          'OVERWRITE': True,
167     },
168     'PAMMODULESDIR' : {
169          'STD-PATH':  '${LIBDIR}/security',
170          'FHS-PATH':  '${LIBDIR}/security',
171          'OPTION':    '--with-pammodulesdir',
172          'HELPTEXT':  'Which directory to use for PAM modules',
173     },
174     'CONFIGDIR' : {
175          'STD-PATH':  '${SYSCONFDIR}',
176          'FHS-PATH':  '${SYSCONFDIR}/samba',
177          'OPTION':    '--with-configdir',
178          'HELPTEXT':  'Where to put configuration files',
179     },
180     'PRIVATE_DIR' : {
181          'STD-PATH':  '${PREFIX}/private',
182          'FHS-PATH':  '${LOCALSTATEDIR}/lib/samba/private',
183          'OPTION':    '--with-privatedir',
184          'HELPTEXT':  'Where to put sam.ldb and other private files',
185     },
186     'BINDDNS_DIR' : {
187          'STD-PATH':  '${PREFIX}/bind-dns',
188          'FHS-PATH':  '${LOCALSTATEDIR}/lib/samba/bind-dns',
189          'OPTION':    '--with-bind-dns-dir',
190          'HELPTEXT':  'bind-dns config directory',
191     },
192     'LOCKDIR' : {
193          'STD-PATH':  '${LOCALSTATEDIR}/lock',
194          'FHS-PATH':  '${LOCALSTATEDIR}/lock/samba',
195          'OPTION':    '--with-lockdir',
196          'HELPTEXT':  'Where to put short term disposable state files',
197     },
198     'PIDDIR' : {
199          'STD-PATH':  '${LOCALSTATEDIR}/run',
200          'FHS-PATH':  '${LOCALSTATEDIR}/run/samba',
201          'OPTION':    '--with-piddir',
202          'HELPTEXT':  'Where to put pid files',
203     },
204     'STATEDIR' : {
205          'STD-PATH':  '${LOCALSTATEDIR}/locks',
206          'FHS-PATH':  '${LOCALSTATEDIR}/lib/samba',
207          'OPTION':    '--with-statedir',
208          'HELPTEXT':  'Where to put persistent state files',
209     },
210     'CACHEDIR' : {
211          'STD-PATH':  '${LOCALSTATEDIR}/cache',
212          'FHS-PATH':  '${LOCALSTATEDIR}/cache/samba',
213          'OPTION':    '--with-cachedir',
214          'HELPTEXT':  'Where to put temporary cache files',
215     },
216     'LOGFILEBASE' : {
217          'STD-PATH':  '${LOCALSTATEDIR}',
218          'FHS-PATH':  '${LOCALSTATEDIR}/log/samba',
219          'OPTION':    '--with-logfilebase',
220          'HELPTEXT':  'Where to put log files',
221     },
222     'SOCKET_DIR' : {
223          'STD-PATH':  '${LOCALSTATEDIR}/run',
224          'FHS-PATH':  '${LOCALSTATEDIR}/run/samba',
225          'OPTION':    '--with-sockets-dir',
226          'HELPTEXT':  'socket directory',
227     },
228     'PRIVILEGED_SOCKET_DIR' : {
229          'STD-PATH':  '${LOCALSTATEDIR}/lib',
230          'FHS-PATH':  '${LOCALSTATEDIR}/lib/samba',
231          'OPTION':    '--with-privileged-socket-dir',
232          'HELPTEXT':  'privileged socket directory',
233     },
234     'WINBINDD_SOCKET_DIR' : {
235          'STD-PATH':  '${SOCKET_DIR}/winbindd',
236          'FHS-PATH':  '${SOCKET_DIR}/winbindd',
237          'DELAY':     True,
238     },
239     'NMBDSOCKETDIR' : {
240          'STD-PATH':  '${SOCKET_DIR}/nmbd',
241          'FHS-PATH':  '${SOCKET_DIR}/nmbd',
242          'DELAY':     True,
243     },
244     'NTP_SIGND_SOCKET_DIR' : {
245          'STD-PATH':  '${PRIVILEGED_SOCKET_DIR}/ntp_signd',
246          'FHS-PATH':  '${PRIVILEGED_SOCKET_DIR}/ntp_signd',
247          'DELAY':     True,
248     },
249     'NCALRPCDIR' : {
250          'STD-PATH':  '${SOCKET_DIR}/ncalrpc',
251          'FHS-PATH':  '${SOCKET_DIR}/ncalrpc',
252          'DELAY':     True,
253     },
254     'CONFIGFILE' : {
255          'STD-PATH':  '${CONFIGDIR}/smb.conf',
256          'FHS-PATH':  '${CONFIGDIR}/smb.conf',
257          'DELAY':     True,
258     },
259     'LMHOSTSFILE' : {
260          'STD-PATH':  '${CONFIGDIR}/lmhosts',
261          'FHS-PATH':  '${CONFIGDIR}/lmhosts',
262          'DELAY':     True,
263     },
264     'SMB_PASSWD_FILE' : {
265          'STD-PATH':  '${PRIVATE_DIR}/smbpasswd',
266          'FHS-PATH':  '${PRIVATE_DIR}/smbpasswd',
267          'OPTION':    '--with-smbpasswd-file',
268          'HELPTEXT':  'Where to put the smbpasswd file',
269          'DELAY':     True,
270     },
271 }
272
273 def options(opt):
274     opt.parser.formatter = SambaIndentedHelpFormatter()
275     opt.parser.formatter.width=Logs.get_term_cols()
276
277     for k in ('--with-privatelibdir', '--with-modulesdir'):
278         option = opt.parser.get_option(k)
279         if option:
280             opt.parser.remove_option(k)
281     del opt.parser.defaults['PRIVATELIBDIR']
282     del opt.parser.defaults['MODULESDIR']
283
284     # get all the basic GNU options from the gnu_dirs tool
285
286     opt_group=opt.add_option_group('Samba-specific directory layout','')
287
288     fhs_help  = "Use FHS-compliant paths (default no)\n"
289     fhs_help += "You should consider using this together with:\n"
290     fhs_help += "--prefix=/usr --sysconfdir=/etc --localstatedir=/var"
291     opt_group.add_option('--enable-fhs', help=fhs_help,
292                    action="store_true", dest='ENABLE_FHS', default=False)
293
294     for varname in dynconfig.keys():
295         if 'OPTION' not in dynconfig[varname]:
296             continue
297         opt = dynconfig[varname]['OPTION']
298         if 'HELPTEXT' in dynconfig[varname]:
299             txt = dynconfig[varname]['HELPTEXT']
300         else:
301             txt = "dynconfig path %s" % (varname)
302         def_std = dynconfig[varname]['STD-PATH']
303         def_fhs = dynconfig[varname]['FHS-PATH']
304
305         help = "%s\n[STD-Default: %s]\n[FHS-Default: %s]" % (txt, def_std, def_fhs)
306         opt_group.add_option(opt, help=help, dest=varname, action="store")
307
308 def configure(conf):
309     # get all the basic GNU options from the gnu_dirs tool
310
311     if Options.options.ENABLE_FHS:
312         flavor = 'FHS-PATH'
313     else:
314         flavor = 'STD-PATH'
315         if conf.env.PREFIX == '/usr' or conf.env.PREFIX == '/usr/local':
316            Logs.error("Don't install directly under /usr or /usr/local without using the FHS option (--enable-fhs)")
317            raise Errors.WafError("ERROR: invalid --prefix=%s value" % (conf.env.PREFIX))
318
319     explicit_set ={}
320
321     dyn_vars = {}
322     for varname in dynconfig.keys():
323         dyn_vars[varname] = dynconfig[varname][flavor]
324         if 'OVERWRITE' in dynconfig[varname] and dynconfig[varname]['OVERWRITE']:
325             # we may overwrite this option
326             continue
327         conf.ASSERT(varname not in conf.env, "Variable %s already defined" % varname)
328
329     # the explicit block
330     for varname in dynconfig.keys():
331         if 'OPTION' not in dynconfig[varname]:
332             continue
333         value = getattr(Options.options, varname, None)
334         if value is None:
335            continue
336         conf.ASSERT(value != '', "Empty dynconfig value for %s" % varname)
337         conf.env[varname] = value
338         # mark it as explicit from the command line
339         explicit_set[varname] = value
340
341     # defaults stage 1 after the explicit block
342     for varname in dynconfig.keys():
343         if 'DELAY' in dynconfig[varname] and dynconfig[varname]['DELAY']:
344             # this option referrs to other options,
345             # so it needs to wait for stage 2.
346             continue
347         value = EXPAND_VARIABLES(conf, dyn_vars[varname])
348         conf.ASSERT(value != '', "Empty dynconfig value for %s" % varname)
349         if varname not in explicit_set:
350             # only overwrite if not specified explicitly on the command line
351             conf.env[varname] = value
352
353     # defaults stage 2 after the explicit block
354     for varname in dynconfig.keys():
355         if 'DELAY' not in dynconfig[varname] or not dynconfig[varname]['DELAY']:
356             # this option was already handled in stage 1.
357             continue
358         value = EXPAND_VARIABLES(conf, dyn_vars[varname])
359         conf.ASSERT(value != '', "Empty dynconfig value for %s" % varname)
360         if varname not in explicit_set:
361             # only overwrite if not specified explicitly on the command line
362             conf.env[varname] = value
363
364     # display the expanded pathes for the user
365     for varname in dynconfig.keys():
366         value = conf.env[varname]
367         conf.start_msg("Dynconfig[%s]: " % (varname))
368         conf.end_msg("'%s'" % (value), 'GREEN')
369
370 def get_override(bld):
371     override = { 'MODULESDIR'    : 'bin/modules',
372                  'PYTHONDIR'     : 'bin/python',
373                  'PYTHONARCHDIR' : 'bin/python',
374                  'BINDIR'        : 'bin',
375                  'SBINDIR'       : 'bin',
376                  'CODEPAGEDIR'   : 'codepages',
377                  'SCRIPTSBINDIR' : 'source4/scripting/bin',
378                  'SETUPDIR'      : 'source4/setup'
379                  }
380     return override
381
382 def dynconfig_cflags(bld, list=None):
383     '''work out the extra CFLAGS for dynconfig.c'''
384     cflags = []
385     for varname in dynconfig.keys():
386         if list and not varname in list:
387             continue
388         value = bld.env[varname]
389         if not bld.is_install:
390             override = get_override(bld)
391             if varname in override:
392                 value = os.path.join(bld.env.srcdir, override[varname])
393         cflags.append('-D%s="%s"' % (varname, value))
394     return cflags
395 Build.BuildContext.dynconfig_cflags = dynconfig_cflags
396
397 def dynconfig_varnames(bld, list=None):
398     '''work out the dynconfig variables'''
399     varnames = []
400     for varname in dynconfig.keys():
401         if list and not varname in list:
402             continue
403         varnames.append(varname)
404     return varnames
405 Build.BuildContext.dynconfig_varnames = dynconfig_varnames
406
407 def pathconfig_entities(bld, list=None):
408     '''work out the extra entities for the docs'''
409     entities = []
410     for varname in dynconfig.keys():
411         if list and not varname in list:
412             continue
413         value = bld.env[varname]
414         if not bld.is_install:
415             override = get_override(bld)
416             if varname in override:
417                 value = os.path.join(bld.env.srcdir, override[varname])
418         entities.append("<!ENTITY pathconfig.%s   '%s'>" % (varname, value))
419     return entities
420 Build.BuildContext.pathconfig_entities = pathconfig_entities
421
422 def build(bld):
423     cflags = bld.dynconfig_cflags()
424     version_header = 'version.h'
425     bld.SAMBA_SUBSYSTEM('DYNCONFIG',
426                         'dynconfig.c',
427                         deps='replace',
428                         public_headers=os_path_relpath(os.path.join(Context.launch_dir, version_header), bld.path.abspath()),
429                         header_path='samba',
430                         cflags=cflags)
431
432     # install some extra empty directories
433     bld.INSTALL_DIR("${CONFIGDIR}")
434     bld.INSTALL_DIR("${LOGFILEBASE}")
435     bld.INSTALL_DIR("${PRIVILEGED_SOCKET_DIR}")
436     bld.INSTALL_DIR("${PRIVATE_DIR}", 0o700)
437     bld.INSTALL_DIR("${BINDDNS_DIR}", 0o770)
438     bld.INSTALL_DIR("${STATEDIR}")
439     bld.INSTALL_DIR("${CACHEDIR}")
440
441     # these might be on non persistent storage
442     bld.INSTALL_DIRS("", "${LOCKDIR} ${PIDDIR} ${SOCKET_DIR}")