Import(['env', 'InstallDirModules', 'InstallDirBootstrap', 'Modules', 'ModulesLinux', 'ModulesCompatibility', 'ExternalModules', 'ModulesBSD', 'uname', 'InternalModules', 'ModulesBase', 'ModulesLinuxNoBundle', 'ModulesLinuxSpecial'])

import os.path

menv = env.Clone (SHLIBPREFIX = '', CCFLAGS = '-DEINIT_MODULE')

CodeInternalModules = ['#build/core/module-configuration.c']

def buildModule(name, location, e):
 e.Install(InstallDirModules, e.LoadableModule(name, location + '/' + name + '.c'))

def buildModuleBootStrap(name, e):
 e.Install(InstallDirBootstrap, e.LoadableModule(name, name + '.c'))

def buildInternalModule(name, location, e):
 tm = name.replace('-', '_')
 return e.Object(location + '/' + name + '.c', CCFLAGS = '-DEINIT_CORE -Dthismodule=' + tm + '_thismodule -Dself=' + tm + '_self')

def buildBundleModule(name, e):
 tm = os.path.basename(name).replace('-', '_')
 return e.SharedObject(name + '.c', CCFLAGS = '-DEINIT_CORE -Dthismodule=private_' + tm + '_thismodule -Dself=private_' + tm + '_self')

def buildBundle(target, name, modules_original, e):
 f = open (name + '.c', 'w')
 if f:
  f.write ('/* this file has partially been written by the build system */' + "\n" +
           '#define module_bundle_name "Bundle (' + name + ')"' + "\n" +
           '#define module_bundle_rid "' + name + '"' + "\n\n")

  o = open ('templates/bundle.c')
  if o:
   f.write(o.read() + "\n")
   o.close()

  for i in modules_original:
   tm = os.path.basename(i).replace('-', '_')
   f.write ('extern const struct smodule * private_' + tm.replace ('-', '_') + "_self;\n")

  f.write ("\n" + 'const struct smodule **module_bundle_contents[] = {' + "\n")

  for i in modules_original:
   tm = os.path.basename(i).replace('-', '_')
   f.write ('  &private_' + tm + '_self,'"\n")

  f.write ('  NULL};'"\n")
  f.close()

 modules = [ e.SharedObject (name + '.c') ]

 for i in modules_original:
  modules += buildBundleModule (i, e)

 e.Install(target, e.LoadableModule(name, modules))

librt = [ 'rt' ]

if uname == 'Darwin':
 menv.Append (LINKFLAGS = '$LINKFLAGS -Wl,-bundle_loader,src/einit-core')
 librt = []

def buildBundleET(target, name, items, dir, e):
 if items:
  mnames = []
  for x in items:
   mnames += [  dir + '/' + x ]

  buildBundle(target, 'bundle-' + name, mnames, e)

def buildBundleE(name, items, dir, e):
 buildBundleET(InstallDirModules, name, items, dir, e)

def buildBundleD(name, items):
 buildBundleE(name, items, name, menv)

buildModuleBootStrap('bootstrap-configuration-stree', menv)
buildModuleBootStrap('bootstrap-configuration-xml-expat', menv.Clone (LIBS = 'expat-local', LIBPATH=['#expat']))

for x in Modules:
 buildModule(x, '.', menv)

for x in ModulesLinuxNoBundle:
 buildModule(x, 'linux', menv)

buildBundleD('bsd', ModulesBSD)
buildBundleD('linux', ModulesLinux)
buildBundleD('compatibility', ModulesCompatibility)

buildBundleE('base', ModulesBase, '.', menv)

if 'ipc-9p' in ExternalModules:
 buildModule ('ipc-9p', '.', menv.Clone (LIBS=['ixp-local'], LIBPATH=['#libixp']))

if 'feedback-visual-textual' in ExternalModules:
 buildModule ('feedback-visual-textual', '.', menv.Clone (LIBS=librt))

if 'module-logic-v4' in ExternalModules:
 buildModule ('module-logic-v4', '.', menv.Clone (LIBS=librt))

for x in InternalModules:
 CodeInternalModules += buildInternalModule(x, '.', env)

env.StaticLibrary ('core-modules', CodeInternalModules, CCFLAGS = '-DEINIT_CORE')
