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