brane@tigris.org writes:
> trunk/build/gen_make.py
> Modified:
> trunk/build/gen_base.py
> Log:
> Working on issue #850.
>
> * build/gen_base.py: Load svn-dev.el.
> * build/gen_make.py: New file -- the Makefile generator. Not active yet.
So let me get this straight:
We have a file named "gen-make.py" at the top level, and another one
named "gen_make.py" in build/.
There's some potential for confusion here, I would say. :-)
Is build/gen_make.py the new Windows-specific generator referred to in
issue #850? If so, can it say so in its name, and in the summary at
the top of the file? (And why does it live at a different level than
gen-make.py?) Whatever the case, the relationship between the two
files needs to be clarified somehow...
-Karl
> Modified: trunk/build/gen_base.py
> ==============================================================================
> --- trunk/build/gen_base.py (original)
> +++ trunk/build/gen_base.py Tue Aug 6 06:35:40 2002
> @@ -636,3 +636,9 @@
>
> class CircularDependencies(Exception):
> pass
> +
> +
> +### End of file.
> +# local variables:
> +# eval: (load-file "../tools/dev/svn-dev.el")
> +# end:
>
> Added: trunk/build/gen_make.py
> ==============================================================================
> --- trunk/build/gen_make.py (original)
> +++ trunk/build/gen_make.py Tue Aug 6 06:35:41 2002
> @@ -0,0 +1,328 @@
> +#
> +# gen_make.py -- generate makefiles and dependencies
> +#
> +
> +import os, sys
> +import string, glob, re
> +import fileinput
> +import gen_base
> +
> +
> +__all__ = ['MakefileGenerator']
> +
> +
> +class MakefileGenerator(_GeneratorBase):
> +
> + _extension_map = {
> + ('exe', 'target'): '',
> + ('exe', 'object'): '.o',
> + ('lib', 'target'): '.la',
> + ('lib', 'object'): '.lo',
> + ('script', 'target'): '',
> + ('script', 'object'): '',
> + }
> +
> + def __init__(self, fname, oname):
> + _GeneratorBase.__init__(self, fname)
> +
> + self.ofile = open(oname, 'w')
> + self.ofile.write('# DO NOT EDIT -- AUTOMATICALLY GENERATED\n\n')
> +
> + def write(self):
> + # write this into the file first so the RA_FOO_DEPS variables are
> + # defined before their use in dependency lines.
> + self.write_ra_modules()
> +
> + errors = 0
> + for target in self.target_names:
> + target_ob = self.targets[target]
> +
> + path = target_ob.path
> + bldtype = target_ob.type
> + objext = target_ob.objext
> +
> + if bldtype == 'script':
> + # there is nothing to build
> + continue
> +
> + tpath = target_ob.output
> + tfile = os.path.basename(tpath)
> +
> + if target_ob.install == 'test' and bldtype == 'exe':
> + self.test_deps.append(tpath)
> + if self.parser.get(target, 'testing') != 'skip':
> + self.test_progs.append(tpath)
> +
> + if target_ob.install == 'fs-test' and bldtype == 'exe':
> + self.fs_test_deps.append(tpath)
> + if self.parser.get(target, 'testing') != 'skip':
> + self.fs_test_progs.append(tpath)
> +
> + s_errors = target_ob.find_sources(self.parser.get(target, 'sources'))
> + errors = errors or s_errors
> +
> + objects = [ ]
> + for src in target_ob.sources:
> + if src[-2:] == '.c':
> + objname = src[:-2] + objext
> + objects.append(objname)
> + self.file_deps.append((src, objname))
> + else:
> + print 'ERROR: unknown file extension on', src
> + errors = 1
> +
> + retreat = _retreat_dots(path)
> + libs = [ ]
> + deps = [ ]
> + for lib in string.split(self.parser.get(target, 'libs')):
> + if lib in self.target_names:
> + tlib = self.targets[lib]
> + target_ob.deps.append(tlib)
> + deps.append(tlib.output)
> +
> + # link in the library with a relative link to the output file
> + libs.append(os.path.join(retreat, tlib.output))
> + else:
> + # something we don't know, so just include it directly
> + libs.append(lib)
> +
> + for man in string.split(self.parser.get(target, 'manpages')):
> + self.manpages.append(man)
> +
> + for info in string.split(self.parser.get(target, 'infopages')):
> + self.infopages.append(info)
> +
> + targ_varname = string.replace(target, '-', '_')
> + ldflags = self.parser.get(target, 'link-flags')
> + add_deps = self.parser.get(target, 'add-deps')
> + objnames = string.join(_strip_path(path, objects))
> + custom = self.parser.get(target, 'custom')
> + if custom == 'apache-mod':
> + linkcmd = '$(LINK_APACHE_MOD)'
> + else:
> + linkcmd = '$(LINK)'
> +
> + 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, string.join(objects + deps), add_deps,
> + targ_varname, objnames,
> + tpath, targ_varname,
> + path, linkcmd, tfile, ldflags, targ_varname, string.join(libs))
> + )
> +
> + if custom == 'apache-mod':
> + # special build, needing Apache includes
> + self.ofile.write('# build these special -- use APACHE_INCLUDES\n')
> + for src in target_ob.sources:
> + if src[-2:] == '.c':
> + self.ofile.write('%s%s: %s\n\t$(COMPILE_APACHE_MOD)\n'
> + % (src[:-2], objext, src))
> + self.ofile.write('\n')
> + elif custom == 'swig-py':
> + self.ofile.write('# build this with -DSWIGPYTHON\n')
> + for src in target_ob.sources:
> + if src[-2:] == '.c':
> + self.ofile.write('%s%s: %s\n\t$(COMPILE_SWIG_PY)\n'
> + % (src[:-2], objext, src))
> + self.ofile.write('\n')
> +
> + for g_name, g_targets in self.install.items():
> + self.target_names = [ ]
> + for i in g_targets:
> + self.target_names.append(i.output)
> +
> + self.ofile.write('%s: %s\n\n' % (g_name, string.join(self.target_names)))
> +
> + cfiles = [ ]
> + for target in self.targets.values():
> + # .la files are handled by the standard 'clean' rule; clean all the
> + # other targets
> + if target.type != 'script' and target.output[-3:] != '.la':
> + cfiles.append(target.output)
> + self.ofile.write('CLEAN_FILES = %s\n\n' % string.join(cfiles))
> +
> + for area, inst_targets in self.install.items():
> + # get the output files for these targets, sorted in dependency order
> + files = _sorted_files(inst_targets)
> +
> + 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 = os.path.split(file)
> + base, ext = os.path.splitext(fname)
> + name = string.replace(base, 'mod_', '')
> + self.ofile.write('\tcd %s ; $(INSTALL_MOD_SHARED) -n %s %s\n'
> + % (dirname, name, fname))
> + if ext == '.la':
> + la_tweaked[file + '-a'] = None
> +
> + for t in inst_targets:
> + for dep in t.deps:
> + bt = dep.output
> + if bt[-3:] == '.la':
> + la_tweaked[bt + '-a'] = None
> + la_tweaked = la_tweaked.keys()
> +
> + s_files, s_errors = _collect_paths(self.parser.get('static-apache',
> + 'paths'))
> + errors = errors or s_errors
> +
> + # 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) %s\n'
> + % (string.join(la_tweaked + s_files),
> + os.path.join('$(APACHE_TARGET)', '.libs')))
> + for file in la_tweaked:
> + dirname, fname = os.path.split(file)
> + base = os.path.splitext(fname)[0]
> + self.ofile.write('\t$(INSTALL_MOD_STATIC) %s %s\n'
> + '\t$(INSTALL_MOD_STATIC) %s %s\n'
> + % (os.path.join(dirname, '.libs', base + '.a'),
> + os.path.join('$(APACHE_TARGET)',
> + '.libs',
> + base + '.a'),
> + file,
> + os.path.join('$(APACHE_TARGET)', base + '.la')))
> +
> + # copy the other files to the target dir
> + for file in s_files:
> + self.ofile.write('\t$(INSTALL_MOD_STATIC) %s %s\n'
> + % (file, os.path.join('$(APACHE_TARGET)',
> + os.path.basename(file))))
> + self.ofile.write('\n')
> +
> + elif area != 'test' and area != 'fs-test':
> + area_var = string.replace(area, '-', '_')
> + self.ofile.write('install-%s: %s\n'
> + '\t$(MKDIR) $(%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 = os.path.split(file)
> + self.ofile.write('\tcd %s ; $(INSTALL_%s) %s %s\n'
> + % (dirname,
> + string.upper(area_var),
> + fname,
> + os.path.join('$(%sdir)' % area_var, fname)))
> + self.ofile.write('\n')
> +
> + # generate .dsp files for each target
> + #for t in inst_targets:
> + # t.write_dsp()
> + # pass
> +
> + self.includes, i_errors = _collect_paths(self.parser.get('includes',
> + 'paths'))
> + errors = errors or i_errors
> +
> + includedir = os.path.join('$(includedir)', 'subversion-%s' % self.version)
> + self.ofile.write('install-include: %s\n'
> + '\t$(MKDIR) %s\n'
> + % (string.join(self.includes), includedir))
> + for file in self.includes:
> + self.ofile.write('\t$(INSTALL_INCLUDE) %s %s\n'
> + % (os.path.join('$(top_srcdir)', file),
> + os.path.join(includedir, os.path.basename(file))))
> +
> + self.ofile.write('\n# handy shortcut targets\n')
> + for name, target in self.targets.items():
> + if target.type != 'script':
> + self.ofile.write('%s: %s\n' % (name, target.output))
> + self.ofile.write('\n')
> +
> + scripts, s_errors = _collect_paths(self.parser.get('test-scripts',
> + 'paths'))
> + errors = errors or s_errors
> +
> + fs_scripts, fs_errors = _collect_paths(self.parser.get('fs-test-scripts',
> + 'paths'))
> + errors = errors or fs_errors
> +
> + # get all the test scripts' directories
> + script_dirs = map(os.path.dirname, scripts + fs_scripts)
> +
> + # remove duplicate directories
> + build_dirs = self.target_dirs.copy()
> + for d in script_dirs:
> + build_dirs[d] = None
> +
> + self.ofile.write('BUILD_DIRS = %s\n\n' % string.join(build_dirs.keys()))
> +
> + self.ofile.write('FS_TEST_DEPS = %s\n\n' %
> + string.join(self.fs_test_deps + fs_scripts))
> + self.ofile.write('FS_TEST_PROGRAMS = %s\n\n' %
> + string.join(self.fs_test_progs + fs_scripts))
> + self.ofile.write('TEST_DEPS = %s\n\n' %
> + string.join(self.test_deps + scripts))
> + self.ofile.write('TEST_PROGRAMS = %s\n\n' %
> + string.join(self.test_progs + scripts))
> +
> + self.ofile.write('MANPAGES = %s\n\n' % string.join(self.manpages))
> + self.ofile.write('INFOPAGES = %s\n\n' % string.join(self.infopages))
> +
> + if errors:
> + raise GenError("Makefile generation failed.")
> +
> +
> + def write_depends(self):
> + #
> + # Find all the available headers and what they depend upon. the
> + # include_deps is a dictionary mapping a short header name to a tuple
> + # of the full path to the header and a dictionary of dependent header
> + # names (short) mapping to None.
> + #
> + # Example:
> + # { 'short.h' : ('/path/to/short.h',
> + # { 'other.h' : None, 'foo.h' : None }) }
> + #
> + # Note that this structure does not allow for similarly named headers
> + # in per-project directories. SVN doesn't have this at this time, so
> + # this structure works quite fine. (the alternative would be to use
> + # the full pathname for the key, but that is actually a bit harder to
> + # work with since we only see short names when scanning, and keeping
> + # a second variable around for mapping the short to long names is more
> + # than I cared to do right now)
> + #
> + include_deps = _create_include_deps(self.includes)
> + for d in self.target_dirs.keys():
> + hdrs = glob.glob(os.path.join(d, '*.h'))
> + if hdrs:
> + more_deps = _create_include_deps(hdrs, include_deps)
> + include_deps.update(more_deps)
> +
> + for src, objname in self.file_deps:
> + hdrs = [ ]
> + for short in _find_includes(src, include_deps):
> + hdrs.append(include_deps[short][0])
> + self.ofile.write('%s: %s %s\n' % (objname, src, string.join(hdrs)))
> +
> + def write_ra_modules(self):
> + for target in self.target_names:
> + if self.parser.get(target, 'custom') != 'ra-module':
> + continue
> +
> + mod = self.targets[target]
> + name = string.upper(mod.name[7:]) # strip 'libsvn_' and upper-case it
> +
> + # construct a list of the other .la libs to link against
> + retreat = _retreat_dots(mod.path)
> + deps = [ mod.output ]
> + link = [ os.path.join(retreat, mod.output) ]
> + for dep in mod.deps:
> + deps.append(dep.output)
> + link.append(os.path.join(retreat, dep.output))
> + self.ofile.write('%s_DEPS = %s\n'
> + '%s_LINK = %s\n\n' % (name, string.join(deps, ' '),
> + name, string.join(link, ' ')))
> +
> +
> +### End of file.
> +# local variables:
> +# eval: (load-file "../tools/dev/svn-dev.el")
> +# end:
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: svn-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: svn-help@subversion.tigris.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue Aug 6 16:29:37 2002