r10918: - fixed standalone ldb build
[kamenim/samba.git] / source4 / SConstruct
1 #!/usr/bin/env python
2
3 # This is the experimental scons build script for Samba 4. For a proper 
4 # build use the old build system (configure + make). scons may
5 # eventually replace this system.
6 #
7 # Copyright (C) 2005 Jelmer Vernooij <jelmer@samba.org>
8 # Copyright (C) 2005 Tim Potter <tpot@samba.org>
9 #
10 # Published under the GNU GPL
11 #
12 # TODO:
13 # - finish fallback code
14 # - support for init functions
15 # - separate config file for lib/replace/
16 # - Subsystem() ?
17
18 import cPickle, string, os
19
20 opts = Options(None, ARGUMENTS)
21 opts.AddOptions(
22                 BoolOption('developer','enable developer flags', False),
23                 PathOption('prefix','installation prefix','/usr/local/samba'),
24                 BoolOption('configure','run configure checks', False),
25 )
26
27 class SambaEnvironment(Environment):
28     def Subsystem(self, target, source, **kwargs):
29         """Create a Samba subsystem, basically a static library.
30
31         By default a prototype file for the subsystem is created,
32         unless the keyword argument 'noproto' is present.  A variable
33         corresponding to the target name is exported, unless the
34         keyword argument 'noexport' is present."""
35
36         # Generate prototype file for subsystem
37
38         if not kwargs.has_key('noproto'):
39             self.proto_headers += self.CProtoHeader(
40                 '%s_proto.h' % target, [str(x) for x in source])
41
42         # Maketh the library
43
44         result = self.Library(target, source, **kwargs)
45
46         # Export library symbol
47
48         if not kwargs.has_key('noexport'):
49             locals()[target] = result   # Eww
50             Export(target)
51
52         return result
53
54 hostenv = SambaEnvironment(
55                 toolpath=['build/scons','.'],
56                 tools=['default','pidl','proto','et','asn1','samba'],
57                 options=opts,
58                 CPPPATH=['#include','#','#lib'], 
59         CPPDEFINES={'_SAMBA_BUILD_': None},
60                 )
61
62 hostenv.Help(opts.GenerateHelpText(hostenv))
63
64 # We don't care about NFS builds...
65 hostenv.SetOption('max_drift', 1)
66
67 if hostenv['developer']:
68         hostenv.Append(CCFLAGS='-Wall')
69         hostenv.Append(CCFLAGS='-Wshadow')
70         hostenv.Append(CCFLAGS='-Werror-implicit-function-declaration')
71         hostenv.Append(CCFLAGS='-Wstrict-prototypes')
72         hostenv.Append(CCFLAGS='-Wpointer-arith')
73         hostenv.Append(CCFLAGS='-Wcast-qual')
74         hostenv.Append(CCFLAGS='-Wcast-align')
75         hostenv.Append(CCFLAGS='-Wwrite-strings')
76         hostenv.Append(CCFLAGS='-Wmissing-format-attribute')
77         hostenv.Append(CCFLAGS='-Wformat=2')
78         hostenv.Append(CCFLAGS='-Wno-format-y2k')
79         hostenv.Append(CCFLAGS='-Wno-declaration-after-statement')
80
81 # Some tools get confused if $HOME isn't defined
82 hostenv.Append(ENV={'HOME': os.environ['HOME']})
83
84 # Store configuration data in a dictionary.
85
86 def saveconfig(data):
87         """Save configuration dict to a file."""
88         cached = cPickle.dump(data, open('sconf.cache', 'w'))
89
90 def loadconfig():
91         """Load configuration dict from a file."""
92         try:
93                 return cPickle.load(open('sconf.cache', 'r'))
94         except IOError:
95                 return None
96
97 defines = loadconfig()
98
99 if defines == None:
100         hostenv['configure'] = 1
101
102 if hostenv['configure']:
103         defines = {}
104
105 Export('defines')
106
107 hostenv.Append(CPPPATH = ['#heimdal_build', '#heimdal/lib/krb5',
108                           '#heimdal/lib/hdb', '#heimdal/lib/gssapi',
109                           '#heimdal/lib/asn1', '#heimdal/lib/des',
110                           '#heimdal/kdc', '#heimdal/lib/roken',
111                           '#heimdal/lib/com_err'])
112
113 Export('hostenv')
114
115 buildenv = hostenv
116
117 Export('buildenv')
118
119 cross_compiling = 0
120
121 if cross_compiling:
122         buildenv = hostenv.Copy()
123         buildenv.BuildDir('build-env','.')
124
125 dynenv = hostenv.Copy()
126
127 paths = { 
128         'BINDIR': 'bin',
129         'SBINDIR': 'sbin',
130         'CONFIGFILE': 'cfg',
131         'LOGFILEBASE': 'lfb',
132         'NCALRPCDIR': 'ncalrpc',
133         'LMHOSTSFILE': 'lmhosts',
134         'LIBDIR': 'libdir',
135         'SHLIBEXT': 'ext',
136         'LOCKDIR': 'lockdir',
137         'PIDDIR': 'piddir',
138         'PRIVATE_DIR': 'private',
139         'SWATDIR': 'swat'
140 }
141
142 Export('paths')
143
144 if hostenv['configure']:
145         
146         conf = hostenv.Configure()
147
148         for h in ['sys/select.h','fcntl.h','sys/fcntl.h'] + \
149                 ['utime.h','grp.h','sys/id.h','limits.h','memory.h'] + \
150                 ['compat.h','math.h','sys/param.h','ctype.h','sys/wait.h'] + \
151                 ['sys/resource.h','sys/ioctl.h','sys/ipc.h','sys/mode.h'] + \
152                 ['sys/mman.h','sys/filio.h','sys/priv.h','sys/shm.h','string.h'] + \
153                 ['strings.h','stdlib.h','sys/vfs.h','sys/fs/s5param.h','sys/filsys.h'] + \
154                 ['termios.h','termio.h','fnmatch.h','pwd.h','sys/termio.h'] + \
155                 ['sys/time.h','sys/statfs.h','sys/statvfs.h','stdarg.h'] + \
156                 ['sys/syslog.h','syslog.h','stdint.h','inttypes.h','locale.h'] + \
157                 ['shadow.h','nss.h','nss_common.h','ns_api.h','sys/security.h'] + \
158                 ['security/pam_appl.h','sys/capability.h'] + \
159                 ['sys/acl.h','stdbool.h', 'netinet/in.h', 'sys/socket.h', 'arpa/inet.h', 'netdb.h']:
160                 if conf.CheckCHeader(h):
161                         defines['HAVE_' + h.upper().replace('.','_').replace('/','_')] = 1
162
163         for f in ['setsid','pipe','crypt16','getauthuid','strftime','sigprocmask',
164                 'sigblock','sigaction','initgroups','setgroups','sysconf', 'getpwanam',
165                 'setlinebuf','srandom','random','srand','rand','usleep','timegm',
166                 'backtrace','setbuffer']:
167                 if conf.CheckFunc(f):
168                         defines['HAVE_' + f.upper()] = 1
169
170         # Pull in GNU extensions
171         defines['_GNU_SOURCE'] = 1
172
173         # Hardcode signal return type for now
174         defines['RETSIGTYPE'] = 'void'
175         
176         if conf.CheckType('comparison_fn_t', '#define _GNU_SOURCE\n#include <stdlib.h>'):
177                 defines['HAVE_COMPARISON_FN_T'] = 1
178
179         if conf.CheckType('sig_atomic_t', '#include <signal.h>'):
180                 defines['HAVE_SIG_ATOMIC_T_TYPE'] = 1
181
182         if conf.TryCompile("""
183 #include <sys/types.h>
184
185 int main() 
186 {
187         volatile int i = 0;
188         return 0;
189 }""", '.c'):
190                 defines['HAVE_VOLATILE'] = 1
191
192         if conf.TryCompile("""
193 #include <stdio.h>
194
195 int main() 
196 {
197    typedef struct {unsigned x;} FOOBAR;
198    #define X_FOOBAR(x) ((FOOBAR) { x })
199    #define FOO_ONE X_FOOBAR(1)
200    FOOBAR f = FOO_ONE;   
201    static struct {
202         FOOBAR y; 
203         } f2[] = {
204                 {FOO_ONE}
205         };   
206         return 0;
207 }""", '.c'):
208                 defines['HAVE_IMMEDIATE_STRUCTURES'] = 1
209
210         hostenv.AlwaysBuild('include/config.h')
211
212         if conf.TryCompile("""
213 #include <sys/types.h>
214 #include <sys/time.h>
215 #include <time.h>
216
217 int
218 main ()
219 {
220 if ((struct tm *) 0)
221 return 0;
222   return 0;
223 }
224 """, '.c'):
225                 defines['TIME_WITH_SYS_TIME'] = 1
226
227         if conf.TryCompile("""
228 #include <sys/time.h>
229 #include <unistd.h>
230 main() { struct timeval tv; exit(gettimeofday(&tv, NULL));}
231 """, '.c'):
232                 defines['HAVE_GETTIMEOFDAY_TZ'] = 1
233
234         # Check for header that defines "DIR"
235         for h in ['dirent.h','sys/ndir.h','sys/dir.h','ndir.h']:
236                 if conf.TryCompile("""
237 #include <%s>
238
239 int main() { DIR *x; return 0; }""" % h, '.c'):
240                         defines['HAVE_' + h.upper().replace('.','_').replace('/','_')] = 1
241                         break
242
243         conf.Finish()
244
245 [dynenv.Append(CPPDEFINES = {p: '\\"%s\\"' % paths[p]}) for p in paths]
246         
247 dynconfig = dynenv.Object('dynconfig.c')
248 Export('dynconfig')
249
250 hostenv.proto_headers = []
251
252 SConscript(
253                 dirs=['dsdb', 'libcli', 'lib','torture','rpc_server','cldap_server',
254                 'nbt_server','client','ldap_server','libnet','nsswitch','web_server',
255                 'smbd','dsdb','heimdal_build','ntptr','kdc','smb_server','ntvfs',
256                 'winbind','scripting','auth', 'librpc','script/tests'])
257
258 # proto.h
259
260 def create_global_proto(env, target, source):
261         fd = open(str(target[0]), 'w')
262         [fd.write('#include "%s"\n' % x) for x in source]
263         fd.close()
264
265 def create_global_proto_print(*args, **kwargs):
266         print 'Building global proto.h'
267
268 hostenv.Command('include/proto.h', hostenv.proto_headers,
269         Action(create_global_proto, create_global_proto_print))
270
271 # Save configuration
272
273 if hostenv['configure']:
274         saveconfig(defines)
275
276 # How to create config.h file
277 def create_config_h(env, target, source):
278         fd = open(str(target[0]), 'w')
279         [fd.write('#define %s %s\n' % (x, defines[x])) for x in defines]
280         fd.close()
281
282 def create_config_h_print(*args, **kwargs):
283         print 'Building config.h'
284
285 hostenv.Command('include/config.h', [],
286                 Action(create_config_h, create_config_h_print))
287 hostenv.Append(CPPDEFINES = {'HAVE_CONFIG_H': 1})