dynconfig: add SambaIndentedHelpFormatter in order to support \n in option help text
[amitay/samba.git] / dynconfig / wscript
1 #!/usr/bin/env python
2
3 import string, Utils, Options, sys, Build, os, intltool, optparse, textwrap
4 from samba_utils import EXPAND_VARIABLES, os_path_relpath
5
6 class SambaIndentedHelpFormatter (optparse.IndentedHelpFormatter):
7     """Format help with indented section bodies.
8     """
9
10     def __init__(self,
11                  indent_increment=2,
12                  max_help_position=12,
13                  width=None,
14                  short_first=1):
15         optparse.IndentedHelpFormatter.__init__(
16             self, indent_increment, max_help_position, width, short_first)
17
18     def format_option(self, option):
19         # The help for each option consists of two parts:
20         #   * the opt strings and metavars
21         #     eg. ("-x", or "-fFILENAME, --file=FILENAME")
22         #   * the user-supplied help string
23         #     eg. ("turn on expert mode", "read data from FILENAME")
24         #
25         # If possible, we write both of these on the same line:
26         #   -x      turn on expert mode
27         #
28         # But if the opt string list is too long, we put the help
29         # string on a second line, indented to the same column it would
30         # start in if it fit on the first line.
31         #   -fFILENAME, --file=FILENAME
32         #           read data from FILENAME
33         result = []
34         opts = self.option_strings[option]
35         opt_width = self.help_position - self.current_indent - 2
36         if len(opts) > opt_width:
37             opts = "%*s%s\n" % (self.current_indent, "", opts)
38             indent_first = self.help_position
39         else:                       # start help on same line as opts
40             opts = "%*s%-*s  " % (self.current_indent, "", opt_width, opts)
41             indent_first = 0
42         result.append(opts)
43         if option.help:
44             help_text = self.expand_default(option)
45             if string.find(help_text, '\n') == -1:
46                 help_lines = textwrap.wrap(help_text, self.help_width)
47             else:
48                 help_lines = help_text.splitlines()
49             result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
50             result.extend(["%*s%s\n" % (self.help_position, "", line)
51                            for line in help_lines[1:]])
52         elif opts[-1] != "\n":
53             result.append("\n")
54         return "".join(result)
55
56 # list of directory options to offer in configure
57 dir_options = {
58     'with-piddir'                         : [ '${PREFIX}/var/run', 'where to put pid files' ],
59     'with-privatedir'                     : [ '${PREFIX}/private', 'Where to put sam.ldb and other private files' ],
60     'with-winbindd-socket-dir'            : [ '${PREFIX}/var/lib/winbindd', 'winbind socket directory' ],
61     'with-winbindd-privileged-socket-dir' : [ '${PREFIX}/var/lib/winbindd_privileged', 'winbind privileged socket directory'],
62     'with-ntp-signd-socket-dir'           : [ '${PREFIX}/var/run/ntp_signd', 'NTP signed directory'],
63     'with-lockdir'                        : [ '${PREFIX}/var/locks', 'where to put lock files' ]
64     }
65
66 # list of cflags to use for dynconfig.c
67 dyn_cflags = {
68     'BINDIR'                         : '${BINDIR}',
69     'SBINDIR'                        : '${SBINDIR}',
70     'SCRIPTSBINDIR'                  : '${SBINDIR}',
71     'CONFIGDIR'                      : '${SYSCONFDIR}',
72     'CONFIGFILE'                     : '${SYSCONFDIR}/smb.conf',
73     'LMHOSTSFILE'                    : '${SYSCONFDIR}/lmhosts',
74     'PRIVATE_DIR'                    : '${PRIVATEDIR}',
75     'LOGFILEBASE'                    : '${LOCALSTATEDIR}',
76     'LOCKDIR'                        : '${LOCALSTATEDIR}/locks',
77     'PIDDIR'                         : '${LOCALSTATEDIR}/run',
78     'DATADIR'                        : '${DATADIR}',
79     'LOCALEDIR'                      : '${LOCALEDIR}',
80     'SETUPDIR'                       : '${DATADIR}/setup',
81     'WINBINDD_SOCKET_DIR'            : '${WINBINDD_SOCKET_DIR}',
82     'WINBINDD_PRIVILEGED_SOCKET_DIR' : '${WINBINDD_PRIVILEGED_SOCKET_DIR}',
83     'NTP_SIGND_SOCKET_DIR'           : '${NTP_SIGND_SOCKET_DIR}',
84     'NCALRPCDIR'                     : '${LOCALSTATEDIR}/ncalrpc',
85     'PYTHONDIR'                      : '${PYTHONDIR}',
86     'PYTHONARCHDIR'                  : '${PYTHONARCHDIR}',
87     'MODULESDIR'                     : '${PREFIX}/modules',
88     'INCLUDEDIR'                     : '${PREFIX}/include',
89     'PKGCONFIGDIR'                   : '${LIBDIR}/pkgconfig',
90     'SWATDIR'                        : '${DATADIR}/swat',
91     'CODEPAGEDIR'                    : '${LIBDIR}/samba',
92     'LIBDIR'                         : '${LIBDIR}',
93     'LIBEXECDIR'                     : '${MODULESDIR}',
94     'STATEDIR'                       : '${LOCALSTATEDIR}',
95     'CACHEDIR'                       : '${LOCKDIR}',
96     'SMB_PASSWD_FILE'                : '${PRIVATEDIR}/smbpasswd',
97     'NMBDSOCKETDIR'                  : '${LOCALSTATEDIR}/nmbd',
98     }
99
100 # changes for when FHS is enabled
101 dyn_cflags_fhs = {
102     'BINDIR'                         : '${BINDIR}',
103     'SBINDIR'                        : '${SBINDIR}',
104     'SCRIPTSBINDIR'                  : '${SBINDIR}',
105     'CONFIGDIR'                      : '${SYSCONFDIR}/samba',
106     'CONFIGFILE'                     : '${SYSCONFDIR}/samba/smb.conf',
107     'LMHOSTSFILE'                    : '${SYSCONFDIR}/samba/lmhosts',
108     'PRIVATE_DIR'                    : '${LOCALSTATEDIR}/lib/samba/private',
109     'LOGFILEBASE'                    : '${LOCALSTATEDIR}/log/samba',
110     'LOCKDIR'                        : '${LOCALSTATEDIR}/lib/samba',
111     'PIDDIR'                         : '${LOCALSTATEDIR}/run/samba',
112     'SETUPDIR'                       : '${DATADIR}/samba/setup',
113     'WINBINDD_SOCKET_DIR'            : '${LOCALSTATEDIR}/run/samba/winbindd',
114     'WINBINDD_PRIVILEGED_SOCKET_DIR' : '${LOCALSTATEDIR}/run/samba/winbindd_privileged',
115     'NTP_SIGND_SOCKET_DIR'           : '${LOCALSTATEDIR}/run/samba/ntp_signd',
116     'NCALRPCDIR'                     : '${LOCALSTATEDIR}/run/samba/ncalrpc',
117     'PYTHONARCHDIR'                  : '${PYTHONARCHDIR}',
118     'MODULESDIR'                     : '${LIBDIR}/samba',
119     'LIBEXECDIR'                     : '${MODULESDIR}',
120     'INCLUDEDIR'                     : '${INCLUDEDIR}/samba-4.0',
121     'PKGCONFIGDIR'                   : '${LIBDIR}/pkgconfig',
122     'SWATDIR'                        : '${DATADIR}/swat',
123     'CODEPAGEDIR'                    : '${DATADIR}/samba',
124     'NMBDSOCKETDIR'                  : '${LOCALSTATEDIR}/run/samba/nmbd',
125     }
126
127 def get_varname(v):
128     '''work out a variable name from a configure option name'''
129     if v.startswith('with-'):
130         v = v[5:]
131     v = v.upper()
132     v = v.replace('-', '_')
133     return v
134
135
136 def set_options(opt):
137     # get all the basic GNU options from the gnu_dirs tool
138     opt.parser.formatter = SambaIndentedHelpFormatter()
139     opt.parser.formatter.width=Utils.get_term_cols()
140
141     opt_group=opt.add_option_group('Samba-specific directory layout','')
142
143     opt_group.add_option('--enable-fhs',
144                    help=("Use FHS-compliant paths (default no)"),
145                    action="store_true", dest='ENABLE_FHS', default=False)
146     for option in dir_options.keys():
147         default = dir_options[option][0]
148         help    = dir_options[option][1]
149         varname = get_varname(option)
150         opt_group.add_option('--%s' % option,
151                        help=(help + ' [%s]' % default),
152                        action="store", dest=varname, default=default)
153
154 def configure(conf):
155     # get all the basic GNU options from the gnu_dirs tool
156
157     explicit_set = {}
158
159     for option in dir_options.keys():
160         default = dir_options[option][0]
161         varname = get_varname(option)
162         value = getattr(Options.options, varname, None)
163         conf.ASSERT(value is not None, "Missing configure option %s" % varname)
164         conf.ASSERT(varname not in conf.env, "Variable %s already defined" % varname)
165         conf.env[varname] = value
166         if value is not default:
167             explicit_set[varname] = "%s:%s" % (default, value)
168
169     for f in dyn_cflags.keys():
170         v = EXPAND_VARIABLES(conf, dyn_cflags[f])
171         conf.ASSERT(v != '', "Empty dynconfig value for %s" % f)
172         if f not in explicit_set:
173             conf.env[f] = v
174
175     if Options.options.ENABLE_FHS:
176         for f in dyn_cflags_fhs.keys():
177             v = EXPAND_VARIABLES(conf, dyn_cflags_fhs[f])
178             conf.ASSERT(v != '', "Empty dynconfig value for %s" % f)
179             if f not in explicit_set:
180                 conf.env[f] = v
181
182     if (not Options.options.ENABLE_FHS and
183         (conf.env.PREFIX == '/usr' or conf.env.PREFIX == '/usr/local')):
184         print("ERROR: Don't install directly under /usr or /usr/local without using the FHS option (--enable-fhs)")
185         sys.exit(1)
186
187
188 def dynconfig_cflags(bld, list=None):
189     '''work out the extra CFLAGS for dynconfig.c'''
190     cflags = []
191     # override some paths when running from the build directory
192     override = { 'MODULESDIR'    : 'bin/modules',
193                  'PYTHONDIR'     : 'bin/python',
194                  'PYTHONARCHDIR' : 'bin/python',
195                  'CODEPAGEDIR'   : os.path.join(bld.env.srcdir, 'codepages'),
196                  'SCRIPTSBINDIR' : os.path.join(bld.env.srcdir, 'source4/scripting/bin'),
197                  'SETUPDIR'      : os.path.join(bld.env.srcdir, 'source4/setup') }
198     for f in dyn_cflags.keys():
199         if list and not f in list:
200             continue
201         value = bld.env[f]
202         if not Options.is_install:
203             if f in override:
204                 value = os.path.join(os.getcwd(), override[f])
205         cflags.append('-D%s="%s"' % (f, value))
206     return cflags
207 Build.BuildContext.dynconfig_cflags = dynconfig_cflags
208
209 def build(bld):
210     cflags = bld.dynconfig_cflags()
211     version_header = 'version.h'
212     if not os.getenv('TOPLEVEL_BUILD'):
213         version_header = 'include/version.h'
214     bld.SAMBA_SUBSYSTEM('DYNCONFIG',
215                         'dynconfig.c',
216                         deps='replace talloc',
217                         public_headers=os_path_relpath(os.path.join(Options.launch_dir, version_header), bld.curdir),
218                         header_path='samba',
219                         cflags=cflags)