#!/usr/bin/env python # This is the experimental scons build script for Samba 4. For a proper # build use the old build system (configure + make). scons may # eventually replace this system. # # Copyright (C) 2005 Jelmer Vernooij # Copyright (C) 2005 Tim Potter # # Published under the GNU GPL # # TODO: # - finish fallback code # - support for init functions # - separate config file for lib/replace/ # - Subsystem() ? import cPickle, string, os opts = Options(None, ARGUMENTS) opts.AddOptions( BoolOption('developer','enable developer flags', False), PathOption('prefix','installation prefix','/usr/local/samba'), BoolOption('configure','run configure checks', False), ) class SambaEnvironment(Environment): def Subsystem(self, target, source, **kwargs): """Create a Samba subsystem, basically a static library. By default a prototype file for the subsystem is created, unless the keyword argument 'noproto' is present. A variable corresponding to the target name is exported, unless the keyword argument 'noexport' is present.""" # Generate prototype file for subsystem if not kwargs.has_key('noproto'): self.proto_headers += self.CProtoHeader( '%s_proto.h' % target, [str(x) for x in source]) # Maketh the library result = self.Library(target, source, **kwargs) # Export library symbol if not kwargs.has_key('noexport'): locals()[target] = result # Eww Export(target) return result hostenv = SambaEnvironment( toolpath=['build/scons','.'], tools=['default','pidl','proto','et','asn1','samba'], options=opts, CPPPATH=['#include','#','#lib'], CPPDEFINES={'_SAMBA_BUILD_': None}, ) hostenv.Help(opts.GenerateHelpText(hostenv)) # We don't care about NFS builds... hostenv.SetOption('max_drift', 1) if hostenv['developer']: hostenv.Append(CCFLAGS='-Wall') hostenv.Append(CCFLAGS='-Wshadow') hostenv.Append(CCFLAGS='-Werror-implicit-function-declaration') hostenv.Append(CCFLAGS='-Wstrict-prototypes') hostenv.Append(CCFLAGS='-Wpointer-arith') hostenv.Append(CCFLAGS='-Wcast-qual') hostenv.Append(CCFLAGS='-Wcast-align') hostenv.Append(CCFLAGS='-Wwrite-strings') hostenv.Append(CCFLAGS='-Wmissing-format-attribute') hostenv.Append(CCFLAGS='-Wformat=2') hostenv.Append(CCFLAGS='-Wno-format-y2k') hostenv.Append(CCFLAGS='-Wno-declaration-after-statement') # Some tools get confused if $HOME isn't defined hostenv.Append(ENV={'HOME': os.environ['HOME']}) # Store configuration data in a dictionary. def saveconfig(data): """Save configuration dict to a file.""" cached = cPickle.dump(data, open('sconf.cache', 'w')) def loadconfig(): """Load configuration dict from a file.""" try: return cPickle.load(open('sconf.cache', 'r')) except IOError: return None defines = loadconfig() if defines == None: hostenv['configure'] = 1 if hostenv['configure']: defines = {} Export('defines') hostenv.Append(CPPPATH = ['#heimdal_build', '#heimdal/lib/krb5', '#heimdal/lib/hdb', '#heimdal/lib/gssapi', '#heimdal/lib/asn1', '#heimdal/lib/des', '#heimdal/kdc', '#heimdal/lib/roken', '#heimdal/lib/com_err']) Export('hostenv') buildenv = hostenv Export('buildenv') cross_compiling = 0 if cross_compiling: buildenv = hostenv.Copy() buildenv.BuildDir('build-env','.') dynenv = hostenv.Copy() paths = { 'BINDIR': 'bin', 'SBINDIR': 'sbin', 'CONFIGFILE': 'cfg', 'LOGFILEBASE': 'lfb', 'NCALRPCDIR': 'ncalrpc', 'LMHOSTSFILE': 'lmhosts', 'LIBDIR': 'libdir', 'SHLIBEXT': 'ext', 'LOCKDIR': 'lockdir', 'PIDDIR': 'piddir', 'PRIVATE_DIR': 'private', 'SWATDIR': 'swat' } Export('paths') if hostenv['configure']: conf = hostenv.Configure() for h in ['sys/select.h','fcntl.h','sys/fcntl.h'] + \ ['utime.h','grp.h','sys/id.h','limits.h','memory.h'] + \ ['compat.h','math.h','sys/param.h','ctype.h','sys/wait.h'] + \ ['sys/resource.h','sys/ioctl.h','sys/ipc.h','sys/mode.h'] + \ ['sys/mman.h','sys/filio.h','sys/priv.h','sys/shm.h','string.h'] + \ ['strings.h','stdlib.h','sys/vfs.h','sys/fs/s5param.h','sys/filsys.h'] + \ ['termios.h','termio.h','fnmatch.h','pwd.h','sys/termio.h'] + \ ['sys/time.h','sys/statfs.h','sys/statvfs.h','stdarg.h'] + \ ['sys/syslog.h','syslog.h','stdint.h','inttypes.h','locale.h'] + \ ['shadow.h','nss.h','nss_common.h','ns_api.h','sys/security.h'] + \ ['security/pam_appl.h','sys/capability.h'] + \ ['sys/acl.h','stdbool.h', 'netinet/in.h', 'sys/socket.h', 'arpa/inet.h', 'netdb.h']: if conf.CheckCHeader(h): defines['HAVE_' + h.upper().replace('.','_').replace('/','_')] = 1 for f in ['setsid','pipe','crypt16','getauthuid','strftime','sigprocmask', 'sigblock','sigaction','initgroups','setgroups','sysconf', 'getpwanam', 'setlinebuf','srandom','random','srand','rand','usleep','timegm', 'backtrace','setbuffer']: if conf.CheckFunc(f): defines['HAVE_' + f.upper()] = 1 # Pull in GNU extensions defines['_GNU_SOURCE'] = 1 # Hardcode signal return type for now defines['RETSIGTYPE'] = 'void' if conf.CheckType('comparison_fn_t', '#define _GNU_SOURCE\n#include '): defines['HAVE_COMPARISON_FN_T'] = 1 if conf.CheckType('sig_atomic_t', '#include '): defines['HAVE_SIG_ATOMIC_T_TYPE'] = 1 if conf.TryCompile(""" #include int main() { volatile int i = 0; return 0; }""", '.c'): defines['HAVE_VOLATILE'] = 1 if conf.TryCompile(""" #include int main() { typedef struct {unsigned x;} FOOBAR; #define X_FOOBAR(x) ((FOOBAR) { x }) #define FOO_ONE X_FOOBAR(1) FOOBAR f = FOO_ONE; static struct { FOOBAR y; } f2[] = { {FOO_ONE} }; return 0; }""", '.c'): defines['HAVE_IMMEDIATE_STRUCTURES'] = 1 hostenv.AlwaysBuild('include/config.h') if conf.TryCompile(""" #include #include #include int main () { if ((struct tm *) 0) return 0; return 0; } """, '.c'): defines['TIME_WITH_SYS_TIME'] = 1 if conf.TryCompile(""" #include #include main() { struct timeval tv; exit(gettimeofday(&tv, NULL));} """, '.c'): defines['HAVE_GETTIMEOFDAY_TZ'] = 1 # Check for header that defines "DIR" for h in ['dirent.h','sys/ndir.h','sys/dir.h','ndir.h']: if conf.TryCompile(""" #include <%s> int main() { DIR *x; return 0; }""" % h, '.c'): defines['HAVE_' + h.upper().replace('.','_').replace('/','_')] = 1 break conf.Finish() [dynenv.Append(CPPDEFINES = {p: '\\"%s\\"' % paths[p]}) for p in paths] dynconfig = dynenv.Object('dynconfig.c') Export('dynconfig') hostenv.proto_headers = [] SConscript( dirs=['dsdb', 'libcli', 'lib','torture','rpc_server','cldap_server', 'nbt_server','client','ldap_server','libnet','nsswitch','web_server', 'smbd','dsdb','heimdal_build','ntptr','kdc','smb_server','ntvfs', 'winbind','scripting','auth', 'librpc','script/tests']) # proto.h def create_global_proto(env, target, source): fd = open(str(target[0]), 'w') [fd.write('#include "%s"\n' % x) for x in source] fd.close() def create_global_proto_print(*args, **kwargs): print 'Building global proto.h' hostenv.Command('include/proto.h', hostenv.proto_headers, Action(create_global_proto, create_global_proto_print)) # Save configuration if hostenv['configure']: saveconfig(defines) # How to create config.h file def create_config_h(env, target, source): fd = open(str(target[0]), 'w') [fd.write('#define %s %s\n' % (x, defines[x])) for x in defines] fd.close() def create_config_h_print(*args, **kwargs): print 'Building config.h' hostenv.Command('include/config.h', [], Action(create_config_h, create_config_h_print)) hostenv.Append(CPPDEFINES = {'HAVE_CONFIG_H': 1})