def process_header_file(self, fname): """Generate a wrapper around a header file""" # Read the contents of the header file contents = open(fname).read() # Remove comments contents = self._re_comments.sub("", contents) # Get list of includes includes = unique(self._re_includes.findall(contents)) # Get list of structs structs = unique(self._re_structs.findall(contents)) # Get list of batons batons = unique(self._re_batons.findall(contents)) # Get list of callbacks callbacks = (self._re_struct_callbacks.findall(contents) + self._re_typed_callbacks.findall(contents)) # Get the location of the output file base_fname = os.path.basename(fname) # Write the SWIG interface file self._write_swig_interface_file(base_fname, batons, includes, structs, callbacks)
def process_header_file(self, fname): """Generate a wrapper around a header file""" # Read the contents of the header file contents = open(fname).read() # Remove comments contents = self._re_comments.sub("", contents) # Get list of includes includes = unique(self._re_includes.findall(contents)) # Get list of structs structs = unique(self._re_structs.findall(contents)) # Get list of batons batons = unique(self._re_batons.findall(contents)) # Get list of callbacks callbacks = self._re_struct_callbacks.findall(contents) + self._re_typed_callbacks.findall(contents) # Get the location of the output file base_fname = os.path.basename(fname) # Write the SWIG interface file self._write_swig_interface_file(base_fname, batons, includes, structs, callbacks)
def get_win_libs(self, target, cfg): "Return the list of external libraries needed for target" debug = (cfg == 'Debug') if not isinstance(target, gen_base.TargetLinked): return [] if isinstance(target, gen_base.TargetLib) and target.msvc_static: return [] nondeplibs = target.msvc_libs[:] if isinstance(target, gen_base.TargetExe): nondeplibs.append('setargv.obj') # When nls is enabled, all our projects use it directly via the _() macro, # even though only libsvn_subr references it in build.conf if self.enable_nls: lib = self._libraries['intl'] if debug and lib.debug_lib_name: nondeplibs.append(lib.debug_lib_name) else: nondeplibs.append(lib.lib_name) if (isinstance(target, gen_base.TargetSWIG) or isinstance(target, gen_base.TargetSWIGLib)): if target.lang in self._libraries: lib = self._libraries[target.lang] if debug and lib.debug_lib_name: nondeplibs.append(lib.debug_lib_name) elif lib.lib_name: nondeplibs.append(lib.lib_name) for dep in self.get_win_depends(target, FILTER_LIBS): nondeplibs.extend(dep.msvc_libs) if dep.external_lib: for elib in re.findall('\$\(SVN_([^\)]*)_LIBS\)', dep.external_lib): external_lib = elib.lower() if external_lib not in self._libraries: if external_lib not in self._optional_libraries: print( 'Warning: Using undeclared dependency \'$(SVN_%s_LIBS)\'.' % (elib, )) continue lib = self._libraries[external_lib] if debug: nondeplibs.append(lib.debug_lib_name) else: nondeplibs.append(lib.lib_name) return gen_base.unique(nondeplibs)
def get_win_libs(self, target, cfg): "Return the list of external libraries needed for target" debug = (cfg == 'Debug') if not isinstance(target, gen_base.TargetLinked): return [] if isinstance(target, gen_base.TargetLib) and target.msvc_static: return [] nondeplibs = target.msvc_libs[:] # When nls is enabled, all our projects use it directly via the _() macro, # even though only libsvn_subr references it in build.conf if self.enable_nls: lib = self._libraries['intl'] if debug and lib.debug_lib_name: nondeplibs.append(lib.debug_lib_name) else: nondeplibs.append(lib.lib_name) if (isinstance(target, gen_base.TargetSWIG) or isinstance(target, gen_base.TargetSWIGLib)): if target.lang in self._libraries: lib = self._libraries[target.lang] if debug and lib.debug_lib_name: nondeplibs.append(lib.debug_lib_name) elif lib.lib_name: nondeplibs.append(lib.lib_name) for dep in self.get_win_depends(target, FILTER_LIBS): nondeplibs.extend(dep.msvc_libs) if dep.external_lib: for elib in re.findall('\$\(SVN_([^\)]*)_LIBS\)', dep.external_lib): external_lib = elib.lower() if external_lib not in self._libraries: if external_lib not in self._optional_libraries: print('Warning: Using undeclared dependency \'$(SVN_%s_LIBS)\'.' % (elib,)) continue lib = self._libraries[external_lib] if debug: nondeplibs.append(lib.debug_lib_name) else: nondeplibs.append(lib.lib_name) return gen_base.unique(nondeplibs)
def get_win_lib_dirs(self, target, cfg): "Return the list of library directories for target" debug = (cfg == 'Debug') if not isinstance(target, gen_base.TargetLinked): return [] if isinstance(target, gen_base.TargetLib) and target.msvc_static: return [] fakelibdirs = [] # When nls is enabled, all our projects use it directly via the _() macro, # even though only libsvn_subr references it in build.conf if self.enable_nls: lib = self._libraries['intl'] if debug and lib.debug_lib_dir: fakelibdirs.append(lib.debug_lib_dir) else: fakelibdirs.append(lib.lib_dir) if (isinstance(target, gen_base.TargetSWIG) or isinstance(target, gen_base.TargetSWIGLib)): if target.lang in self._libraries: lib = self._libraries[target.lang] if debug and lib.debug_lib_dir: fakelibdirs.append(lib.debug_lib_dir) elif lib.lib_dir: fakelibdirs.append(lib.lib_dir) for dep in self.get_win_depends(target, FILTER_LIBS): if dep.external_lib: for elib in re.findall('\$\(SVN_([^\)]*)_LIBS\)', dep.external_lib): external_lib = elib.lower() if external_lib not in self._libraries: continue lib = self._libraries[external_lib] if debug and lib.debug_lib_dir: lib_dir = self.apath(lib.debug_lib_dir) elif lib.lib_dir: lib_dir = self.apath(lib.lib_dir) else: continue # Dependency without library (E.g. JDK) fakelibdirs.append(lib_dir) return gen_base.unique(fakelibdirs)
def get_win_includes(self, target, cfg='Release'): "Return the list of include directories for target" fakeincludes = [ "subversion/include", "subversion" ] for dep in self.get_win_depends(target, FILTER_EXTERNALLIBS): if dep.external_lib: for elib in re.findall('\$\(SVN_([^\)]*)_LIBS\)', dep.external_lib): external_lib = elib.lower() if external_lib in self._libraries: lib = self._libraries[external_lib] fakeincludes.extend(lib.include_dirs) if target.name == 'mod_authz_svn': fakeincludes.extend([ os.path.join(self.httpd_path, "modules/aaa") ]) if isinstance(target, gen_base.TargetApacheMod): fakeincludes.extend([ os.path.join(self.httpd_path, "include") ]) elif (isinstance(target, gen_base.TargetSWIG) or isinstance(target, gen_base.TargetSWIGLib)): util_includes = "subversion/bindings/swig/%s/libsvn_swig_%s" \ % (target.lang, gen_base.lang_utillib_suffix[target.lang]) fakeincludes.append(util_includes) if (isinstance(target, gen_base.TargetSWIG) or isinstance(target, gen_base.TargetSWIGLib)): # Projects aren't generated unless we have swig assert self.swig_libdir if target.lang == "perl" and self.swig_version >= (1, 3, 28): # At least swigwin 1.3.38+ uses perl5 as directory name. lang_subdir = 'perl5' else: lang_subdir = target.lang # After the language specific includes include the generic libdir, # to allow overriding a generic with a per language include fakeincludes.append(os.path.join(self.swig_libdir, lang_subdir)) fakeincludes.append(self.swig_libdir) if 'cxxhl' in target.name: fakeincludes.append("subversion/bindings/cxxhl/include") return gen_base.unique(map(self.apath, fakeincludes))
def get_win_includes(self, target, cfg='Release'): "Return the list of include directories for target" fakeincludes = ["subversion/include"] for dep in self.get_win_depends(target, FILTER_EXTERNALLIBS): if dep.external_lib: for elib in re.findall('\$\(SVN_([^\)]*)_LIBS\)', dep.external_lib): external_lib = elib.lower() if external_lib in self._libraries: lib = self._libraries[external_lib] fakeincludes.extend(lib.include_dirs) if (isinstance(target, gen_base.TargetSWIG) or isinstance(target, gen_base.TargetSWIGLib)): util_includes = "subversion/bindings/swig/%s/libsvn_swig_%s" \ % (target.lang, gen_base.lang_utillib_suffix[target.lang]) fakeincludes.append(util_includes) if (isinstance(target, gen_base.TargetSWIG) or isinstance(target, gen_base.TargetSWIGLib)): # Projects aren't generated unless we have swig assert self.swig_libdir if target.lang == "perl" and self.swig_version >= (1, 3, 28): # At least swigwin 1.3.38+ uses perl5 as directory name. lang_subdir = 'perl5' else: lang_subdir = target.lang if target.lang == "python": lib = self._libraries['py3c'] fakeincludes.extend(lib.include_dirs) # After the language specific includes include the generic libdir, # to allow overriding a generic with a per language include fakeincludes.append(os.path.join(self.swig_libdir, lang_subdir)) fakeincludes.append(self.swig_libdir) if 'svnxx' in target.name: fakeincludes.append("subversion/bindings/cxx/include") return gen_base.unique(map(self.apath, fakeincludes))
def get_win_forced_includes(self, target, cfg): """Return a list of include files that need to be included before any other header in every c/c++ file""" fakeincludes = [] for dep in self.get_win_depends(target, FILTER_EXTERNALLIBS): if dep.external_lib: for elib in re.findall('\$\(SVN_([^\)]*)_LIBS\)', dep.external_lib): external_lib = elib.lower() if external_lib in self._libraries: lib = self._libraries[external_lib] fakeincludes.extend(lib.forced_includes) return gen_base.unique(fakeincludes)
def get_win_libs(self, target, cfg): "Return the list of external libraries needed for target" dblib = None if self.bdb_lib: dblib = self.bdb_lib + (cfg == 'Debug' and 'd.lib' or '.lib') neonlib = self.neon_lib + (cfg == 'Debug' and 'd.lib' or '.lib') zlib = (cfg == 'Debug' and 'zlibstatD.lib' or 'zlibstat.lib') if not isinstance(target, gen_base.TargetLinked): return [] if isinstance(target, gen_base.TargetLib) and target.msvc_static: return [] nondeplibs = target.msvc_libs[:] nondeplibs.append(zlib) if self.enable_nls: if self.libintl_path: nondeplibs.append( self.apath(self.libintl_path, 'lib', 'intl3_svn.lib')) else: nondeplibs.append('intl3_svn.lib') if isinstance(target, gen_base.TargetExe): nondeplibs.append('setargv.obj') if ((isinstance(target, gen_base.TargetSWIG) or isinstance(target, gen_base.TargetSWIGLib)) and target.lang == 'perl'): nondeplibs.append(self.perl_lib) for dep in self.get_win_depends(target, FILTER_LIBS): nondeplibs.extend(dep.msvc_libs) if dep.external_lib == '$(SVN_DB_LIBS)': nondeplibs.append(dblib) if dep.external_lib == '$(NEON_LIBS)': nondeplibs.append(neonlib) return gen_base.unique(nondeplibs)
def get_win_lib_dirs(self, target, cfg): "Return the list of library directories for target" debug = (cfg == 'Debug') if not isinstance(target, gen_base.TargetLinked): return [] if isinstance(target, gen_base.TargetLib) and target.msvc_static: return [] fakelibdirs = [] for dep in self.get_win_depends(target, FILTER_LIBS): if dep.external_lib: for elib in re.findall('\$\(SVN_([^\)]*)_LIBS\)', dep.external_lib): external_lib = elib.lower() if external_lib not in self._libraries: continue lib = self._libraries[external_lib] if debug and lib.debug_lib_dir: lib_dir = self.apath(lib.debug_lib_dir) elif lib.lib_dir: lib_dir = self.apath(lib.lib_dir) else: continue # Dependency without library (E.g. JDK) fakelibdirs.append(lib_dir) if isinstance(target, gen_base.TargetApacheMod): fakelibdirs.append(self.apath(self.httpd_path, cfg)) if target.name == 'mod_dav_svn': fakelibdirs.append(self.apath(self.httpd_path, "modules/dav/main", cfg)) return gen_base.unique(fakelibdirs)
def get_win_libs(self, target, cfg): "Return the list of external libraries needed for target" debug = (cfg == 'Debug') if not isinstance(target, gen_base.TargetLinked): return [] if isinstance(target, gen_base.TargetLib) and target.msvc_static: return [] nondeplibs = target.msvc_libs[:] if isinstance(target, gen_base.TargetExe): nondeplibs.append('setargv.obj') for dep in self.get_win_depends(target, FILTER_LIBS): nondeplibs.extend(dep.msvc_libs) if dep.external_lib: for elib in re.findall('\$\(SVN_([^\)]*)_LIBS\)', dep.external_lib): external_lib = elib.lower() if external_lib not in self._libraries: if external_lib not in self._optional_libraries: print('Warning: Using undeclared dependency \'$(SVN_%s_LIBS)\'.' % (elib,)) continue lib = self._libraries[external_lib] if debug: nondeplibs.append(lib.debug_lib_name) else: nondeplibs.append(lib.lib_name) return gen_base.unique(nondeplibs)
def write(self): install_deps = self.graph.get_deps(gen_base.DT_INSTALL) install_sources = self.graph.get_all_sources(gen_base.DT_INSTALL) cp = configparser.ConfigParser() cp.read('gen-make.opts') if cp.has_option('options', '--installed-libs'): self.installed_libs = cp.get('options', '--installed-libs').split(',') else: self.installed_libs = [] # ensure consistency between runs install_deps.sort() install_sources.sort(key=lambda s: s.name) class _eztdata(object): def __init__(self, **kw): vars(self).update(kw) data = _eztdata( modules=[], swig_langs=[], swig_c=[], target=[], itargets=[], areas=[], isources=[], deps=[], sql=[], ) ######################################## 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 = target.name[7:].upper() # construct a list of the other .la libs to link against retreat = build_path_retreat(target.path) if target.name in self.installed_libs: deps = [] link = ['-l%s-%s' % (target.name[3:], self.version)] else: 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 elif source.name in self.installed_libs: continue deps.append(source.filename) link.append(build_path_join(retreat, source.filename)) data.modules.append(_eztdata(name=name, deps=deps, link=link)) # write a list of directories in which things are built # get all the test scripts' directories script_dirs = list( 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) data.build_dirs = build_dirs # write lists of test files # deps = all, progs = not including those marked "testing = skip" data.bdb_test_deps = self.bdb_test_deps + self.bdb_scripts data.bdb_test_progs = self.bdb_test_progs + self.bdb_scripts data.test_deps = self.test_deps + self.scripts data.test_progs = self.test_progs + self.scripts data.test_helpers = self.test_helpers # write list of all manpages data.manpages = 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) for script in self.scripts: if script.endswith('.py'): cfiles.append(script + 'c') data.cfiles = sorted(cfiles) # here are all the SQL files and their generated headers. the Makefile # has an implicit rule for generating these, so there isn't much to do # except to clean them out. we only do that for 'make extraclean' since # these are included as part of the tarball. the files are transformed # by gen-make, and developers also get a Make rule to keep them updated. for hdrfile, sqlfile in sorted(self.graph.get_deps(gen_base.DT_SQLHDR), key=lambda t: t[0]): data.sql.append(_eztdata(header=hdrfile, source=sqlfile[0])) data.release_mode = ezt.boolean(self.release_mode) ######################################## if not self.release_mode: swig_rules = StringIO() 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(swig_rules) data.swig_rules = swig_rules.getvalue() ######################################## # write dependencies and build rules for generated .c files swig_c_deps = sorted(self.graph.get_deps(gen_base.DT_SWIG_C), key=lambda t: t[0].filename) swig_lang_deps = {} for lang in self.swig.langs: swig_lang_deps[lang] = [] for objname, sources in swig_c_deps: swig_lang_deps[objname.lang].append(str(objname)) for lang in self.swig.langs: data.swig_langs.append( _eztdata(name=lang, short=self.swig.short[lang], short_upper=self.swig.short[lang].upper(), deps=swig_lang_deps[lang])) ######################################## if not self.release_mode: for objname, sources in swig_c_deps: data.swig_c.append( _eztdata(c_file=str(objname), deps=list(map(str, sources)), opts=self.swig.opts[objname.lang], source=str(sources[0]))) ######################################## 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 = [] objdeps = [] object_srcs = [] headers = [] header_classes = [] header_class_filenames = [] deps = [] libs = [] add_deps = target_ob.add_deps.split() 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 elif link_dep.name in self.installed_libs: libs.append('-l%s-%s' % (link_dep.name[3:], self.version)) 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) objdeps.append(_normstr(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 = target.replace('-', '_') objnames = build_path_strip(path, objects) ezt_target = _eztdata( name=target_ob.name, varname=targ_varname, path=path, install=None, add_deps=add_deps, objects=objects, objdeps=objdeps, deps=deps, when=target_ob.when, ) data.target.append(ezt_target) if hasattr(target_ob, 'link_cmd'): ezt_target.link_cmd = target_ob.link_cmd if hasattr(target_ob, 'output_dir'): ezt_target.output_dir = target_ob.output_dir if hasattr(target_ob, 'headers_dir'): ezt_target.headers_dir = target_ob.headers_dir # Add additional install dependencies if necessary if target_ob.add_install_deps: ezt_target.install = target_ob.install ezt_target.install_deps = target_ob.add_install_deps if isinstance(target_ob, gen_base.TargetJava): ezt_target.type = 'java' ezt_target.headers = headers ezt_target.sources = None ezt_target.jar = None ezt_target.classes = target_ob.classes # Build the headers from the header_classes with one 'javah' call if headers: ezt_target.header_class_filenames = header_class_filenames ezt_target.header_classes = header_classes # Build the objects from the object_srcs with one 'javac' call if object_srcs: ezt_target.sources = object_srcs # Once the bytecodes have been compiled up, we produce the # JAR. if target_ob.jar: ezt_target.jar_path = build_path_join( target_ob.classes, target_ob.jar) ezt_target.packages = target_ob.packages elif isinstance(target_ob, gen_base.TargetI18N): ezt_target.type = 'i18n' else: ezt_target.type = 'n/a' ezt_target.filename = target_ob.filename ezt_target.path = path if (isinstance(target_ob, gen_base.TargetLib) and not target_ob.undefined_lib_symbols): ezt_target.undefined_flag = '$(LT_NO_UNDEFINED)' else: ezt_target.undefined_flag = '' ezt_target.libs = gen_base.unique(libs) ezt_target.objnames = objnames ezt_target.basename = build_path_basename(target_ob.filename) ######################################## 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) data.itargets.append(_eztdata(type=itype, outputs=outputs)) ######################################## # 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) ezt_area_type = (area == 'apache-mod' and 'mods-shared' or area) ezt_area = _eztdata(type=ezt_area_type, files=[], extra_install=None) def file_to_eztdata(file): # cd to dirname before install to work around libtool 1.4.2 bug. dirname, fname = build_path_splitfile(file.filename) return _eztdata( mode=None, dirname=dirname, fullname=file.filename, filename=fname, when=file.when, pc_fullname=None, pc_installdir=None, pc_install_fname=None, ) def apache_file_to_eztdata(file): # cd to dirname before install to work around libtool 1.4.2 bug. dirname, fname = build_path_splitfile(file.filename) base, ext = os.path.splitext(fname) name = base.replace('mod_', '') return _eztdata(mode='apache-mod', fullname=file.filename, dirname=dirname, name=name, filename=fname, when=file.when) if area != 'test' and area != 'bdb-test': data.areas.append(ezt_area) area_var = area.replace('-', '_') upper_var = area_var.upper() ezt_area.varname = area_var ezt_area.uppervar = upper_var for file in files: if isinstance(file.target, gen_base.TargetApacheMod): ezt_file = apache_file_to_eztdata(file) else: ezt_file = file_to_eztdata(file) if area == 'locale': lang, objext = os.path.splitext(ezt_file.filename) installdir = ('$(DESTDIR)$(%sdir)/%s/LC_MESSAGES' % (area_var, lang)) ezt_file.installdir = installdir ezt_file.objext = objext else: ezt_file.install_fname = build_path_join( '$(%sdir)' % area_var, ezt_file.filename) # Install pkg-config files if (isinstance(file.target, gen_base.TargetLib) and ezt_file.fullname.startswith( 'subversion/libsvn_')): ezt_file.pc_fullname = ezt_file.fullname.replace( '-1.la', '.pc') ezt_file.pc_installdir = '$(pkgconfig_dir)' pc_install_fname = ezt_file.filename.replace( '-1.la', '.pc') ezt_file.pc_install_fname = build_path_join( ezt_file.pc_installdir, pc_install_fname) ezt_area.files.append(ezt_file) # 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-' \ or area[:6] == 'svnxx-' \ or area == 'tools': ezt_area.extra_install = 'yes' ######################################## includedir = build_path_join('$(includedir)', 'subversion-%s' % self.version) data.includes = [ _eztdata(file=file, src=build_path_join('$(abs_srcdir)', file), dst=build_path_join(includedir, build_path_basename(file))) for file in self.includes ] data.includedir = includedir ######################################## 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): data.isources.append( _eztdata(name=target.name, filename=target.filename)) ######################################## # 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 = sorted(self.graph.get_deps(gen_base.DT_OBJECT), key=lambda t: t[0].filename) for objname, sources in obj_deps: dep = _eztdata(name=_normstr(objname), when=objname.when, deps=list(map(_normstr, sources)), cmd=objname.compile_cmd, source=_normstr(sources[0])) data.deps.append(dep) dep.generated = ezt.boolean(getattr(objname, 'source_generated', 0)) template = ezt.Template(os.path.join('build', 'generator', 'templates', 'build-outputs.mk.ezt'), compress_whitespace=False) template.generate(open('build-outputs.mk', 'w'), data) self.write_standalone() self.write_transform_libtool_scripts(install_sources) self.write_pkg_config_dot_in_files(install_sources)
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) cp = configparser.ConfigParser() cp.read('gen-make.opts') if cp.has_option('options', '--installed-libs'): self.installed_libs = cp.get('options', '--installed-libs').split(',') else: self.installed_libs = [] # ensure consistency between runs install_deps.sort() install_sources.sort(key = lambda s: s.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 = target.name[7:].upper() # construct a list of the other .la libs to link against retreat = build_path_retreat(target.path) if target.name in self.installed_libs: deps = [] link = [ '-l%s-%s' % (target.name[3:], self.version) ] else: 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 elif source.name in self.installed_libs: 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, ' '.join(deps), name, ' '.join(link))) # write a list of directories in which things are built # get all the test scripts' directories script_dirs = list(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' % ' '.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' % ' '.join(self.bdb_test_deps + self.bdb_scripts)) self.ofile.write('BDB_TEST_PROGRAMS = %s\n\n' % ' '.join(self.bdb_test_progs + self.bdb_scripts)) self.ofile.write('TEST_DEPS = %s\n\n' % ' '.join(self.test_deps + self.scripts)) self.ofile.write('TEST_PROGRAMS = %s\n\n' % ' '.join(self.test_progs + self.scripts)) # write list of all manpages self.ofile.write('MANPAGES = %s\n\n' % ' '.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' % ' '.join(cfiles)) # this is here because autogen-standalone needs it too self.ofile.write('SWIG_INCLUDES = -I$(abs_builddir)/subversion \\\n' ' -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 = sorted(self.graph.get_deps(gen_base.DT_SWIG_C), key = lambda t: t[0].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 = ' '.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 = ' '.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('%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 elif link_dep.name in self.installed_libs: libs.append('-l%s-%s' % (link_dep.name[3:], self.version)) 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 = target.replace('-', '_') objnames = ' '.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, ' '.join(headers), targ_varname, ' '.join(objects), targ_varname, targ_varname, targ_varname, target_ob.add_deps, ' '.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, ' '.join(header_class_filenames), targ_varname, ' '.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, ' '.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, ' '.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, ' '.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, ' '.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, ' '.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, ' '.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' % (' '.join(files))) 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 = base.replace('mod_', '') self.ofile.write('\tcd %s ; ' '$(MKDIR) "$(APACHE_LIBEXECDIR)" ; ' '$(INSTALL_MOD_SHARED) -n %s %s\n' % (dirname, name, fname)) self.ofile.write('\n') elif area != 'test' and area != 'bdb-test': area_var = area.replace('-', '_') upper_var = area_var.upper() self.ofile.write('install-%s: %s\n' '\t$(MKDIR) $(DESTDIR)$(%sdir)\n' % (area, ' '.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' % (' '.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 = sorted(self.graph.get_deps(gen_base.DT_OBJECT), key = lambda t: t[0].filename) for objname, sources in obj_deps: deps = ' '.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, '$(canonicalized_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(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) cp = configparser.ConfigParser() cp.read('gen-make.opts') if cp.has_option('options', '--installed-libs'): self.installed_libs = cp.get('options', '--installed-libs').split(',') else: self.installed_libs = [] # ensure consistency between runs install_deps.sort() install_sources.sort(key=lambda s: s.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 = target.name[7:].upper() # construct a list of the other .la libs to link against retreat = build_path_retreat(target.path) if target.name in self.installed_libs: deps = [] link = ['-l%s-%s' % (target.name[3:], self.version)] else: 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 elif source.name in self.installed_libs: 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, ' '.join(deps), name, ' '.join(link))) # write a list of directories in which things are built # get all the test scripts' directories script_dirs = list( 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' % ' '.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' % ' '.join(self.bdb_test_deps + self.bdb_scripts)) self.ofile.write('BDB_TEST_PROGRAMS = %s\n\n' % ' '.join(self.bdb_test_progs + self.bdb_scripts)) self.ofile.write('TEST_DEPS = %s\n\n' % ' '.join(self.test_deps + self.scripts)) self.ofile.write('TEST_PROGRAMS = %s\n\n' % ' '.join(self.test_progs + self.scripts)) # write list of all manpages self.ofile.write('MANPAGES = %s\n\n' % ' '.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' % ' '.join(cfiles)) # this is here because autogen-standalone needs it too self.ofile.write( 'SWIG_INCLUDES = -I$(abs_builddir)/subversion \\\n' ' -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 = sorted(self.graph.get_deps(gen_base.DT_SWIG_C), key=lambda t: t[0].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 = ' '.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 = ' '.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('%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 elif link_dep.name in self.installed_libs: libs.append('-l%s-%s' % (link_dep.name[3:], self.version)) 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 = target.replace('-', '_') objnames = ' '.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, ' '.join(headers), targ_varname, ' '.join(objects), targ_varname, targ_varname, targ_varname, target_ob.add_deps, ' '.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, ' '.join(header_class_filenames), targ_varname, ' '.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, ' '.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, ' '.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, ' '.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, ' '.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, ' '.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, ' '.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' % (' '.join(files))) 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 = base.replace('mod_', '') self.ofile.write('\tcd %s ; ' '$(MKDIR) "$(APACHE_LIBEXECDIR)" ; ' '$(INSTALL_MOD_SHARED) -n %s %s\n' % (dirname, name, fname)) self.ofile.write('\n') elif area != 'test' and area != 'bdb-test': area_var = area.replace('-', '_') upper_var = area_var.upper() self.ofile.write('install-%s: %s\n' '\t$(MKDIR) $(DESTDIR)$(%sdir)\n' % (area, ' '.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' % (' '.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 = sorted(self.graph.get_deps(gen_base.DT_OBJECT), key=lambda t: t[0].filename) for objname, sources in obj_deps: deps = ' '.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, '$(canonicalized_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(self): install_deps = self.graph.get_deps(gen_base.DT_INSTALL) install_sources = self.graph.get_all_sources(gen_base.DT_INSTALL) cp = configparser.ConfigParser() cp.read('gen-make.opts') if cp.has_option('options', '--installed-libs'): self.installed_libs = cp.get('options', '--installed-libs').split(',') else: self.installed_libs = [] # ensure consistency between runs install_deps.sort() install_sources.sort(key = lambda s: s.name) class _eztdata(object): def __init__(self, **kw): vars(self).update(kw) data = _eztdata( modules=[ ], swig_langs=[ ], swig_c=[ ], target=[ ], itargets=[ ], areas=[ ], isources=[ ], deps=[ ], sql=[], ) ######################################## 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 = target.name[7:].upper() # construct a list of the other .la libs to link against retreat = build_path_retreat(target.path) if target.name in self.installed_libs: deps = [] link = [ '-l%s-%s' % (target.name[3:], self.version) ] else: 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 elif source.name in self.installed_libs: continue deps.append(source.filename) link.append(build_path_join(retreat, source.filename)) data.modules.append(_eztdata(name=name, deps=deps, link=link)) # write a list of directories in which things are built # get all the test scripts' directories script_dirs = list(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) data.build_dirs = build_dirs # write lists of test files # deps = all, progs = not including those marked "testing = skip" data.bdb_test_deps = self.bdb_test_deps + self.bdb_scripts data.bdb_test_progs = self.bdb_test_progs + self.bdb_scripts data.test_deps = self.test_deps + self.scripts data.test_progs = self.test_progs + self.scripts data.test_helpers = self.test_helpers # write list of all manpages data.manpages = 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) for script in self.scripts: if script.endswith('.py'): cfiles.append(script + 'c') data.cfiles = sorted(cfiles) # here are all the SQL files and their generated headers. the Makefile # has an implicit rule for generating these, so there isn't much to do # except to clean them out. we only do that for 'make extraclean' since # these are included as part of the tarball. the files are transformed # by gen-make, and developers also get a Make rule to keep them updated. for hdrfile, sqlfile in sorted(self.graph.get_deps(gen_base.DT_SQLHDR), key=lambda t: t[0]): data.sql.append(_eztdata(header=hdrfile, source=sqlfile[0])) data.release_mode = ezt.boolean(self.release_mode) ######################################## if not self.release_mode: swig_rules = StringIO() 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(swig_rules) data.swig_rules = swig_rules.getvalue() ######################################## # write dependencies and build rules for generated .c files swig_c_deps = sorted(self.graph.get_deps(gen_base.DT_SWIG_C), key=lambda t: t[0].filename) swig_lang_deps = {} for lang in self.swig.langs: swig_lang_deps[lang] = [] for objname, sources in swig_c_deps: swig_lang_deps[objname.lang].append(str(objname)) for lang in self.swig.langs: data.swig_langs.append(_eztdata(short=self.swig.short[lang], deps=swig_lang_deps[lang])) ######################################## if not self.release_mode: for objname, sources in swig_c_deps: data.swig_c.append(_eztdata(c_file=str(objname), deps=list(map(str, sources)), opts=self.swig.opts[objname.lang], source=str(sources[0]))) ######################################## 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 = [ ] objdeps = [ ] object_srcs = [ ] headers = [ ] header_classes = [ ] header_class_filenames = [ ] deps = [ ] libs = [ ] add_deps = target_ob.add_deps.split() 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 elif link_dep.name in self.installed_libs: libs.append('-l%s-%s' % (link_dep.name[3:], self.version)) 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) objdeps.append(_normstr(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 = target.replace('-', '_') objnames = build_path_strip(path, objects) ezt_target = _eztdata(name=target_ob.name, varname=targ_varname, path=path, install=None, add_deps=add_deps, objects=objects, objdeps=objdeps, deps=deps, when=target_ob.when, ) data.target.append(ezt_target) if hasattr(target_ob, 'link_cmd'): ezt_target.link_cmd = target_ob.link_cmd if hasattr(target_ob, 'output_dir'): ezt_target.output_dir = target_ob.output_dir # Add additional install dependencies if necessary if target_ob.add_install_deps: ezt_target.install = target_ob.install ezt_target.install_deps = target_ob.add_install_deps if isinstance(target_ob, gen_base.TargetJava): ezt_target.type = 'java' ezt_target.headers = headers ezt_target.sources = None ezt_target.jar = None ezt_target.classes = target_ob.classes # Build the headers from the header_classes with one 'javah' call if headers: ezt_target.header_class_filenames = header_class_filenames ezt_target.header_classes = header_classes # Build the objects from the object_srcs with one 'javac' call if object_srcs: ezt_target.sources = object_srcs # Once the bytecodes have been compiled up, we produce the # JAR. if target_ob.jar: ezt_target.jar_path = build_path_join(target_ob.classes, target_ob.jar) ezt_target.packages = target_ob.packages elif isinstance(target_ob, gen_base.TargetI18N): ezt_target.type = 'i18n' else: ezt_target.type = 'n/a' ezt_target.filename = target_ob.filename ezt_target.path = path if (isinstance(target_ob, gen_base.TargetLib) and not target_ob.undefined_lib_symbols): ezt_target.undefined_flag = '$(LT_NO_UNDEFINED)' else: ezt_target.undefined_flag = '' ezt_target.libs = gen_base.unique(libs) ezt_target.objnames = objnames ezt_target.basename = build_path_basename(target_ob.filename) ######################################## 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) data.itargets.append(_eztdata(type=itype, outputs=outputs)) ######################################## # 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) ezt_area_type = (area == 'apache-mod' and 'mods-shared' or area) ezt_area = _eztdata(type=ezt_area_type, files=[], extra_install=None) def file_to_eztdata(file): # cd to dirname before install to work around libtool 1.4.2 bug. dirname, fname = build_path_splitfile(file.filename) return _eztdata(mode=None, dirname=dirname, fullname=file.filename, filename=fname, when=file.when, pc_fullname=None, pc_installdir=None, pc_install_fname=None,) def apache_file_to_eztdata(file): # cd to dirname before install to work around libtool 1.4.2 bug. dirname, fname = build_path_splitfile(file.filename) base, ext = os.path.splitext(fname) name = base.replace('mod_', '') return _eztdata(mode='apache-mod', fullname=file.filename, dirname=dirname, name=name, filename=fname, when=file.when) if area != 'test' and area != 'bdb-test': data.areas.append(ezt_area) area_var = area.replace('-', '_') upper_var = area_var.upper() ezt_area.varname = area_var ezt_area.uppervar = upper_var for file in files: if isinstance(file.target, gen_base.TargetApacheMod): ezt_file = apache_file_to_eztdata(file) else: ezt_file = file_to_eztdata(file) if area == 'locale': lang, objext = os.path.splitext(ezt_file.filename) installdir = ('$(DESTDIR)$(%sdir)/%s/LC_MESSAGES' % (area_var, lang)) ezt_file.installdir = installdir ezt_file.objext = objext else: ezt_file.install_fname = build_path_join('$(%sdir)' % area_var, ezt_file.filename) # Install pkg-config files if (isinstance(file.target, gen_base.TargetLib) and ezt_file.fullname.startswith('subversion/libsvn_')): ezt_file.pc_fullname = ezt_file.fullname.replace('-1.la', '.pc') ezt_file.pc_installdir = '$(pkgconfig_dir)' pc_install_fname = ezt_file.filename.replace('-1.la', '.pc') ezt_file.pc_install_fname = build_path_join(ezt_file.pc_installdir, pc_install_fname) ezt_area.files.append(ezt_file) # 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-' \ or area[:6] == 'cxxhl-' \ or area == 'tools': ezt_area.extra_install = 'yes' ######################################## includedir = build_path_join('$(includedir)', 'subversion-%s' % self.version) data.includes = [_eztdata(file=file, src=build_path_join('$(abs_srcdir)', file), dst=build_path_join(includedir, build_path_basename(file))) for file in self.includes] data.includedir = includedir ######################################## 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): data.isources.append(_eztdata(name=target.name, filename=target.filename)) ######################################## # 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 = sorted(self.graph.get_deps(gen_base.DT_OBJECT), key=lambda t: t[0].filename) for objname, sources in obj_deps: dep = _eztdata(name=_normstr(objname), when=objname.when, deps=list(map(_normstr, sources)), cmd=objname.compile_cmd, source=_normstr(sources[0])) data.deps.append(dep) dep.generated = ezt.boolean(getattr(objname, 'source_generated', 0)) template = ezt.Template(os.path.join('build', 'generator', 'templates', 'build-outputs.mk.ezt'), compress_whitespace=False) template.generate(open('build-outputs.mk', 'w'), data) self.write_standalone() self.write_transform_libtool_scripts(install_sources) self.write_pkg_config_dot_in_files(install_sources)
def get_win_libs(self, target, cfg): "Return the list of external libraries needed for target" dblib = None if self.bdb_lib: dblib = self.bdb_lib+(cfg == 'Debug' and 'd.lib' or '.lib') if self.neon_lib: neonlib = self.neon_lib+(cfg == 'Debug' and 'd.lib' or '.lib') if self.serf_lib: serflib = 'serf.lib' zlib = (cfg == 'Debug' and 'zlibstatD.lib' or 'zlibstat.lib') sasllib = None if self.sasl_path: sasllib = 'libsasl.lib' if not isinstance(target, gen_base.TargetLinked): return [] if isinstance(target, gen_base.TargetLib) and target.msvc_static: return [] nondeplibs = target.msvc_libs[:] nondeplibs.append(zlib) if self.enable_nls: if self.libintl_path: nondeplibs.append(self.apath(self.libintl_path, 'lib', 'intl3_svn.lib')) else: nondeplibs.append('intl3_svn.lib') if isinstance(target, gen_base.TargetExe): nondeplibs.append('setargv.obj') if ((isinstance(target, gen_base.TargetSWIG) or isinstance(target, gen_base.TargetSWIGLib)) and target.lang == 'perl'): nondeplibs.append(self.perl_lib) if ((isinstance(target, gen_base.TargetSWIG) or isinstance(target, gen_base.TargetSWIGLib)) and target.lang == 'ruby'): nondeplibs.append(self.ruby_lib) for dep in self.get_win_depends(target, FILTER_LIBS): nondeplibs.extend(dep.msvc_libs) if dep.external_lib == '$(SVN_DB_LIBS)': nondeplibs.append(dblib) if self.neon_lib and dep.external_lib == '$(NEON_LIBS)': nondeplibs.append(neonlib) if self.serf_lib and dep.external_lib == '$(SVN_SERF_LIBS)': nondeplibs.append(serflib) if dep.external_lib == '$(SVN_SASL_LIBS)': nondeplibs.append(sasllib) if dep.external_lib == '$(SVN_APR_LIBS)': nondeplibs.append(self.apr_lib) if dep.external_lib == '$(SVN_APRUTIL_LIBS)': nondeplibs.append(self.aprutil_lib) if dep.external_lib == '$(SVN_XML_LIBS)': nondeplibs.append('xml.lib') return gen_base.unique(nondeplibs)