#
# gen_make.py -- generate makefiles and dependencies
#

import os
import sys
import string

import gen_base
import generator.swig.header_wrappers
import generator.swig.checkout_swig_header
import generator.swig.external_runtime
import generator.util.executable
_exec = generator.util.executable

from gen_base import build_path_join, build_path_strip, build_path_splitfile, \
      build_path_basename, build_path_dirname, build_path_retreat, unique

try:
  True
except NameError:
  True = 1
  False = 0

class Generator(gen_base.GeneratorBase):

  _extension_map = {
    ('exe', 'target'): '$(EXEEXT)',
    ('exe', 'object'): '.o',
    ('lib', 'target'): '.la',
    ('lib', 'object'): '.lo',
    }

  def __init__(self, fname, verfname, options=None):
    gen_base.GeneratorBase.__init__(self, fname, verfname, options)
    self.section_counter = 0
    self.assume_shared_libs = False
    if ('--assume-shared-libs', '') in options:
      self.assume_shared_libs = True

  def begin_section(self, description):
    self.section_counter = self.section_counter + 1
    count = self.section_counter

    self.ofile.write('\n########################################\n')
    self.ofile.write('# Section %d: %s\n' % (count, description))
    self.ofile.write('########################################\n\n')

  def write(self):
    self.ofile = open('build-outputs.mk', 'w')
    self.ofile.write('# DO NOT EDIT -- AUTOMATICALLY GENERATED\n')

    install_deps = self.graph.get_deps(gen_base.DT_INSTALL)
    install_sources = self.graph.get_all_sources(gen_base.DT_INSTALL)

    # ensure consistency between runs
    install_deps.sort()
    install_sources.sort(lambda s1, s2: cmp(s1.name, s2.name))

    ########################################
    self.begin_section('Global make variables')

    for target in install_sources:
      if isinstance(target, gen_base.TargetRaModule) or \
         isinstance(target, gen_base.TargetFsModule):
        # name of the module: strip 'libsvn_' and upper-case it
        name = string.upper(target.name[7:])

        # construct a list of the other .la libs to link against
        retreat = build_path_retreat(target.path)
        deps = [ target.filename ]
        link = [ build_path_join(retreat, target.filename) ]
        for source in self.graph.get_sources(gen_base.DT_LINK, target.name):
          if not isinstance(source, gen_base.TargetLib) or source.external_lib:
            continue
          deps.append(source.filename)
          link.append(build_path_join(retreat, source.filename))

        self.ofile.write('%s_DEPS = %s\n'
                         '%s_LINK = %s\n\n' % (name, string.join(deps, ' '),
                                               name, string.join(link, ' ')))

    # write a list of directories in which things are built
    #   get all the test scripts' directories
    script_dirs = map(build_path_dirname, self.scripts + self.bdb_scripts)

    #   remove duplicate directories between targets and tests
    build_dirs = unique(self.target_dirs + script_dirs + self.swig_dirs)

    self.ofile.write('BUILD_DIRS = %s\n\n' % string.join(build_dirs))

    # write lists of test files
    # deps = all, progs = not including those marked "testing = skip"
    self.ofile.write('BDB_TEST_DEPS = %s\n\n' %
                     string.join(self.bdb_test_deps + self.bdb_scripts))
    self.ofile.write('BDB_TEST_PROGRAMS = %s\n\n' %
                     string.join(self.bdb_test_progs + self.bdb_scripts))
    self.ofile.write('TEST_DEPS = %s\n\n' %
                     string.join(self.test_deps + self.scripts))
    self.ofile.write('TEST_PROGRAMS = %s\n\n' %
                     string.join(self.test_progs + self.scripts))

    # write list of all manpages
    self.ofile.write('MANPAGES = %s\n\n' % string.join(self.manpages))

    # write a list of files to remove during "make clean"
    cfiles = [ ]
    for target in install_sources:
      # .la files are handled by the standard 'clean' rule; clean all the
      # other targets
      if not isinstance(target, gen_base.TargetScript) \
         and not isinstance(target, gen_base.TargetProject) \
         and not isinstance(target, gen_base.TargetI18N) \
         and not isinstance(target, gen_base.TargetJava) \
         and not target.external_lib \
         and target.filename[-3:] != '.la':
        cfiles.append(target.filename)
    cfiles.sort()
    self.ofile.write('CLEAN_FILES = %s\n\n' % string.join(cfiles))

    # this is here because autogen-standalone needs it too
    self.ofile.write('SWIG_INCLUDES = -I$(abs_srcdir)/subversion/include \\\n'
        '  -I$(abs_srcdir)/subversion/bindings/swig \\\n'
        '  -I$(abs_srcdir)/subversion/bindings/swig/include \\\n'
        '  -I$(abs_srcdir)/subversion/bindings/swig/proxy \\\n'
        '  -I$(abs_builddir)/subversion/bindings/swig/proxy \\\n'
        '  $(SVN_APR_INCLUDES) $(SVN_APRUTIL_INCLUDES)\n\n')

    if self.release_mode:
      self.ofile.write('RELEASE_MODE = 1\n\n')

    ########################################
    self.begin_section('SWIG headers (wrappers and external runtimes)')

    if not self.release_mode:
      for swig in (generator.swig.header_wrappers,
                   generator.swig.checkout_swig_header,
                   generator.swig.external_runtime):
        gen = swig.Generator(self.conf, "swig")
        gen.write_makefile_rules(self.ofile)

    ########################################
    self.begin_section('SWIG autogen rules')

    # write dependencies and build rules for generated .c files
    swig_c_deps = self.graph.get_deps(gen_base.DT_SWIG_C)
    swig_c_deps.sort(lambda (t1, s1), (t2, s2): cmp(t1.filename, t2.filename))

    swig_lang_deps = {}
    for lang in self.swig.langs:
      swig_lang_deps[lang] = []

    short = self.swig.short
    for objname, sources in swig_c_deps:
      lang = objname.lang
      swig_lang_deps[lang].append(str(objname))

    for lang in self.swig.langs:
      lang_deps = string.join(swig_lang_deps[lang])
      self.ofile.write(
        'autogen-swig-%s: %s\n' % (short[lang], lang_deps) +
        'autogen-swig: autogen-swig-%s\n' % short[lang] +
        '\n')
    self.ofile.write('\n')

    ########################################
    self.begin_section('Rules to build SWIG .c files from .i files')

    for objname, sources in swig_c_deps:
      deps = string.join(map(str, sources))
      source = str(sources[0])
      source_dir = build_path_dirname(source)
      opts = self.swig.opts[objname.lang]
      if not self.release_mode:
        self.ofile.write('$(top_builddir)/%s: %s\n' % (objname, deps) +
          '\t$(SWIG) $(SWIG_INCLUDES) %s ' % opts +
          '-o $@ $(top_srcdir)/%s\n' % source
        )

    self.ofile.write('\n')

    ########################################
    self.begin_section('Individual target build rules')

    for target_ob in install_sources:

      if isinstance(target_ob, gen_base.TargetScript):
        # there is nothing to build
        continue

      target = target_ob.name
      if isinstance(target_ob, gen_base.TargetJava):
        path = target_ob.output_dir
      else:
        path = target_ob.path

      retreat = build_path_retreat(path)

      # get the source items (.o and .la) for the link unit
      objects = [ ]
      object_srcs = [ ]
      headers = [ ]
      header_classes = [ ]
      header_class_filenames = [ ]
      deps = [ ]
      libs = [ ]

      for link_dep in self.graph.get_sources(gen_base.DT_LINK, target_ob.name):
        if isinstance(link_dep, gen_base.TargetJava):
          deps.append(link_dep.name)
        elif isinstance(link_dep, gen_base.TargetLinked):
          if link_dep.external_lib:
            libs.append(link_dep.external_lib)
          elif link_dep.external_project:
            # FIXME: This is a temporary workaround to fix build breakage
            # expeditiously.  It is of questionable validity for a build
            # node to have external_project but not have external_lib.
            pass
          else:
            # append the output of the target to our stated dependencies
            if not self.assume_shared_libs:
              deps.append(link_dep.filename)

            # link against the library
            libs.append(build_path_join(retreat, link_dep.filename))
        elif isinstance(link_dep, gen_base.ObjectFile):
          # link in the object file
          objects.append(link_dep.filename)
          for dep in self.graph.get_sources(gen_base.DT_OBJECT, link_dep, gen_base.SourceFile):
            object_srcs.append(
              build_path_join('$(abs_srcdir)', dep.filename))
        elif isinstance(link_dep, gen_base.HeaderFile):
          # link in the header file
          # N.B. that filename_win contains the '_'-escaped class name
          headers.append(link_dep.filename_win)
          header_classes.append(link_dep.classname)
          for dep in self.graph.get_sources(gen_base.DT_OBJECT, link_dep, gen_base.ObjectFile):
            header_class_filenames.append(dep.filename)
        else:
          ### we don't know what this is, so we don't know what to do with it
          raise UnknownDependency

      for nonlib in self.graph.get_sources(gen_base.DT_NONLIB, target_ob.name):
        if isinstance(nonlib, gen_base.TargetLinked):
          if not nonlib.external_lib:
            deps.append(nonlib.filename)

      targ_varname = string.replace(target, '-', '_')
      objnames = string.join(build_path_strip(path, objects))

      # Output value of path variable
      self.ofile.write('%s_PATH = %s\n' % (targ_varname, path))

      # Add additional install dependencies if necessary
      if target_ob.add_install_deps:
        self.ofile.write('install-%s: %s\n'
          % (target_ob.install, target_ob.add_install_deps))

      if isinstance(target_ob, gen_base.TargetJava):
        self.ofile.write(
          '%s_HEADERS = %s\n'
          '%s_OBJECTS = %s\n'
          '%s_DEPS = $(%s_HEADERS) $(%s_OBJECTS) %s %s\n'
          '%s: $(%s_DEPS)\n'
          % (targ_varname, string.join(headers),

             targ_varname, string.join(objects),

             targ_varname, targ_varname, targ_varname, target_ob.add_deps,
             string.join(deps),

             target_ob.name, targ_varname))

        # Build the headers from the header_classes with one 'javah' call
        if headers:
          self.ofile.write(
            '%s_CLASS_FILENAMES = %s\n'
            '%s_CLASSES = %s\n'
            '$(%s_HEADERS): $(%s_CLASS_FILENAMES)\n'
            '\t%s -d %s -classpath %s:$(%s_CLASSPATH) $(%s_CLASSES)\n'
            % (targ_varname, string.join(header_class_filenames),

               targ_varname, string.join(header_classes),

               targ_varname, targ_varname,

               target_ob.link_cmd, target_ob.output_dir, target_ob.classes,
               targ_varname, targ_varname))

        # Build the objects from the object_srcs with one 'javac' call
        if object_srcs:
          self.ofile.write(
            '%s_SRC = %s\n'
            '$(%s_OBJECTS): $(%s_SRC)\n'
            '\t%s -d %s -classpath %s:$(%s_CLASSPATH) $(%s_SRC)\n'
            % (targ_varname, string.join(object_srcs),

               targ_varname, targ_varname,

               target_ob.link_cmd, target_ob.output_dir, target_ob.classes,
               targ_varname, targ_varname))

        # Once the bytecodes have been compiled up, we produce the
        # JAR.
        if target_ob.jar:
          self.ofile.write('\n\t$(JAR) cf %s -C %s %s' %
                           (build_path_join(target_ob.classes, target_ob.jar),
                            target_ob.classes,
                            string.join(target_ob.packages, ' ')))

        self.ofile.write('\n\n')
      elif isinstance(target_ob, gen_base.TargetI18N):
        self.ofile.write(
          '%s_DEPS = %s %s\n'
          '%s: $(%s_DEPS)\n\n'
          % (targ_varname, target_ob.add_deps, string.join(objects + deps),
             target_ob.name, targ_varname))
      else:
        self.ofile.write(
          '%s_DEPS = %s %s\n'
          '%s_OBJECTS = %s\n'
          '%s: $(%s_DEPS)\n'
          '\tcd %s && %s -o %s %s $(%s_OBJECTS) %s $(LIBS)\n\n'
          % (targ_varname, target_ob.add_deps, string.join(objects + deps),

             targ_varname, objnames,

             target_ob.filename, targ_varname,

             path, target_ob.link_cmd,
             build_path_basename(target_ob.filename),
             (isinstance(target_ob, gen_base.TargetLib) and not
               target_ob.undefined_lib_symbols) and '$(LT_NO_UNDEFINED)' or "",
             targ_varname, string.join(gen_base.unique(libs)))
          )

    ########################################
    self.begin_section('Install-Group build targets')

    for itype, i_targets in install_deps:

      # perl bindings do their own thing, "swig-pl" target is
      # already specified in Makefile.in
      if itype == "swig-pl":
        continue

      outputs = [ ]
      for t in i_targets:
        if hasattr(t, 'filename'):
          outputs.append(t.filename)
      self.ofile.write('%s: %s\n\n' % (itype, string.join(outputs)))

    ########################################
    self.begin_section('Install-Group install targets')

    # for each install group, write a rule to install its outputs
    for area, inst_targets in install_deps:

      # perl bindings do their own thing, "install-swig-pl" target is
      # already specified in Makefile.in
      if area == "swig-pl":
        continue

      # get the output files for these targets, sorted in dependency order
      files = gen_base._sorted_files(self.graph, area)

      if area == 'apache-mod':
        self.ofile.write('install-mods-shared: %s\n' % (string.join(files),))
        la_tweaked = { }
        for file in files:
          # cd to dirname before install to work around libtool 1.4.2 bug.
          dirname, fname = build_path_splitfile(file)
          base, ext = os.path.splitext(fname)
          name = string.replace(base, 'mod_', '')
          self.ofile.write('\tcd %s ; '
                           '$(MKDIR) "$(APACHE_LIBEXECDIR)" ; '
                           '$(INSTALL_MOD_SHARED) -n %s %s\n'
                           % (dirname, name, fname))
          if ext == '.la':
            la_tweaked[file + '-a'] = None

        for apmod in inst_targets:
          for source in self.graph.get_sources(gen_base.DT_LINK, apmod.name,
                                               gen_base.Target):
            if not source.external_lib:
              bt = source.filename
              if bt[-3:] == '.la':
                la_tweaked[bt + '-a'] = None
        la_tweaked = la_tweaked.keys()
        la_tweaked.sort()

        # Construct a .libs directory within the Apache area and populate it
        # with the appropriate files. Also drop the .la file in the target dir.
        self.ofile.write('\ninstall-mods-static: %s\n'
                         '\t$(MKDIR) $(DESTDIR)%s\n'
                         % (string.join(la_tweaked + self.apache_files),
                            build_path_join('$(APACHE_TARGET)', '.libs')))
        for file in la_tweaked:
          dirname, fname = build_path_splitfile(file)
          base = os.path.splitext(fname)[0]
          self.ofile.write('\t$(INSTALL_MOD_STATIC) %s $(DESTDIR)%s\n'
                           '\t$(INSTALL_MOD_STATIC) %s $(DESTDIR)%s\n'
                           % (build_path_join(dirname, '.libs', base + '.a'),
                              build_path_join('$(APACHE_TARGET)', '.libs',
                                              base + '.a'),
                              file,
                              build_path_join('$(APACHE_TARGET)', base + '.la')))

        # copy the other files to the target dir
        for file in self.apache_files:
          self.ofile.write('\t$(INSTALL_MOD_STATIC) %s $(DESTDIR)%s\n'
                           % (file, build_path_join('$(APACHE_TARGET)',
                                                 build_path_basename(file))))
        self.ofile.write('\n')

      elif area != 'test' and area != 'bdb-test':
        area_var = string.replace(area, '-', '_')
        upper_var = string.upper(area_var)
        self.ofile.write('install-%s: %s\n'
                         '\t$(MKDIR) $(DESTDIR)$(%sdir)\n'
                         % (area, string.join(files), area_var))
        for file in files:
          # cd to dirname before install to work around libtool 1.4.2 bug.
          dirname, fname = build_path_splitfile(file)
          if area == 'locale':
            lang, objext = os.path.splitext(fname)
            installdir = '$(DESTDIR)$(%sdir)/%s/LC_MESSAGES' % (area_var, lang)
            self.ofile.write('\t$(MKDIR) %s\n'
                             '\tcd %s ; $(INSTALL_%s) %s '
                             '%s/$(PACKAGE_NAME)%s\n'
                             % (installdir,
                                dirname, upper_var, fname,
                                installdir, objext))
          else:
            self.ofile.write('\tcd %s ; $(INSTALL_%s) %s $(DESTDIR)%s\n'
                             % (dirname, upper_var, fname,
                                build_path_join('$(%sdir)' % area_var, fname)))
        # certain areas require hooks for extra install rules defined
        # in Makefile.in
        ### we should turn AREA into an object, then test it instead of this
        if area[:5] == 'swig-' and area[-4:] != '-lib' or \
           area[:7] == 'javahl-':
          self.ofile.write('\t$(INSTALL_EXTRA_%s)\n' % upper_var)
        self.ofile.write('\n')

    ########################################
    self.begin_section('The install-include rule')

    includedir = build_path_join('$(includedir)',
                                 'subversion-%s' % self.version)
    self.ofile.write('install-include: %s\n'
                     '\t$(MKDIR) $(DESTDIR)%s\n'
                     % (string.join(self.includes), includedir))
    for file in self.includes:
      self.ofile.write('\t$(INSTALL_INCLUDE) %s $(DESTDIR)%s\n'
                       % (build_path_join('$(abs_srcdir)', file),
                          build_path_join(includedir,
                                          build_path_basename(file))))

    ########################################
    self.begin_section('Shortcut targets for manual builds of specific items')

    for target in install_sources:
      if not isinstance(target, gen_base.TargetScript) and \
         not isinstance(target, gen_base.TargetJava) and \
         not isinstance(target, gen_base.TargetI18N):
        self.ofile.write('%s: %s\n' % (target.name, target.filename))

    ########################################
    self.begin_section('Rules to build all other kinds of object-like files')

    # write dependencies and build rules (when not using suffix rules)
    # for all other generated files which will not be installed
    # (or will be installed, but not by the main generated build)
    obj_deps = self.graph.get_deps(gen_base.DT_OBJECT)
    obj_deps.sort(lambda (t1, s1), (t2, s2): cmp(t1.filename, t2.filename))

    for objname, sources in obj_deps:
      deps = string.join(map(str, sources))
      self.ofile.write('%s: %s\n' % (objname, deps))
      cmd = objname.compile_cmd
      if cmd:
        if not getattr(objname, 'source_generated', 0):
          self.ofile.write('\t%s %s\n\n'
                           % (cmd, build_path_join('$(abs_srcdir)',
                              str(sources[0]))))
        else:
          self.ofile.write('\t%s %s\n\n' % (cmd, sources[0]))
      else:
        self.ofile.write('\n')


    self.ofile.close()
    self.write_standalone()

  def write_standalone(self):
    """Write autogen-standalone.mk"""

    standalone = open("autogen-standalone.mk", "w")
    standalone.write('# DO NOT EDIT -- AUTOMATICALLY GENERATED\n')
    standalone.write('abs_srcdir = %s\n' % os.getcwd())
    standalone.write('abs_builddir = %s\n' % os.getcwd())
    standalone.write('top_srcdir = .\n')
    standalone.write('top_builddir = .\n')
    standalone.write('SWIG = swig\n')
    standalone.write('PYTHON = python\n')
    standalone.write('\n')
    standalone.write(open("build-outputs.mk","r").read())
    standalone.close()

class UnknownDependency(Exception):
  "We don't know how to deal with the dependent to link it in."
  pass

### End of file.
