Esempio n. 1
0
def build_direct_deps(bld, tgt_list):
    '''build the direct_objects and direct_libs sets for each target'''

    targets  = LOCAL_CACHE(bld, 'TARGET_TYPE')
    syslib_deps  = LOCAL_CACHE(bld, 'SYSLIB_DEPS')

    global_deps = bld.env.GLOBAL_DEPENDENCIES
    global_deps_exclude = set()
    for dep in global_deps:
        t = bld.get_tgen_by_name(dep)
        for d in t.samba_deps:
            # prevent loops from the global dependencies list
            global_deps_exclude.add(d)
            global_deps_exclude.add(d + '.objlist')

    for t in tgt_list:
        t.direct_objects = set()
        t.direct_libs = set()
        t.direct_syslibs = set()
        deps = t.samba_deps_extended[:]
        if getattr(t, 'samba_use_global_deps', False) and not t.sname in global_deps_exclude:
            deps.extend(global_deps)
        for d in deps:
            if d == t.sname: continue
            if not d in targets:
                Logs.error("Unknown dependency '%s' in '%s'" % (d, t.sname))
                sys.exit(1)
            if targets[d] in [ 'EMPTY', 'DISABLED' ]:
                continue
            if targets[d] == 'PYTHON' and targets[t.sname] != 'PYTHON' and t.sname.find('.objlist') == -1:
                # this check should be more restrictive, but for now we have pidl-generated python
                # code that directly depends on other python modules
                Logs.error('ERROR: Target %s has dependency on python module %s' % (t.sname, d))
                sys.exit(1)
            if targets[d] == 'SYSLIB':
                t.direct_syslibs.add(d)
                if d in syslib_deps:
                    for implied in TO_LIST(syslib_deps[d]):
                        if BUILTIN_LIBRARY(bld, implied):
                            t.direct_objects.add(implied)
                        elif targets[implied] == 'SYSLIB':
                            t.direct_syslibs.add(implied)
                        elif targets[implied] in ['LIBRARY', 'MODULE']:
                            t.direct_libs.add(implied)
                        else:
                            Logs.error('Implied dependency %s in %s is of type %s' % (
                                implied, t.sname, targets[implied]))
                            sys.exit(1)
                continue
            t2 = bld.get_tgen_by_name(d)
            if t2 is None:
                Logs.error("no task %s of type %s in %s" % (d, targets[d], t.sname))
                sys.exit(1)
            if t2.samba_type in [ 'LIBRARY', 'MODULE' ]:
                t.direct_libs.add(d)
            elif t2.samba_type in [ 'SUBSYSTEM', 'ASN1', 'PYTHON' ]:
                t.direct_objects.add(d)
    debug('deps: built direct dependencies')
Esempio n. 2
0
def collect(self):
    pidl_headers = LOCAL_CACHE(self.bld, 'PIDL_HEADERS')
    for (name, hd) in pidl_headers.items():
        y = self.bld.get_tgen_by_name(name)
        self.bld.ASSERT(y is not None, 'Failed to find PIDL header {0!s}'.format(name))
        y.post()
        for node in hd:
            self.bld.ASSERT(node is not None, 'Got None as build node generating PIDL table for {0!s}'.format(name))
            self.source += " " + node.relpath_gen(self.path)
Esempio n. 3
0
def collect(self):
    pidl_headers = LOCAL_CACHE(self.bld, 'PIDL_HEADERS')
    for (name, hd) in pidl_headers.items():
        y = self.bld.get_tgen_by_name(name)
        self.bld.ASSERT(y is not None, 'Failed to find PIDL header %s' % name)
        y.post()
        for node in hd:
            self.bld.ASSERT(
                node is not None,
                'Got None as build node generating PIDL table for %s' % name)
            self.source += " " + node.relpath_gen(self.path)
Esempio n. 4
0
def collect(self):
    pidl_headers = LOCAL_CACHE(self.bld, 'PIDL_HEADERS')
    # The first source is tables.pl itself
    self.source = Utils.to_list(self.source)
    for (name, hd) in pidl_headers.items():
        y = self.bld.get_tgen_by_name(name)
        self.bld.ASSERT(y is not None, 'Failed to find PIDL header %s' % name)
        y.post()
        for node in hd:
            self.bld.ASSERT(
                node is not None,
                'Got None as build node generating PIDL table for %s' % name)
            self.source.append(node)
Esempio n. 5
0
def replace_grouping_libraries(bld, tgt_list):
    '''replace dependencies based on grouping libraries

    If a library is marked as a grouping library, then any target that
    depends on a subsystem that is part of that grouping library gets
    that dependency replaced with a dependency on the grouping library
    '''

    targets  = LOCAL_CACHE(bld, 'TARGET_TYPE')

    grouping = {}

    # find our list of grouping libraries, mapped from the subsystems they depend on
    for t in tgt_list:
        if not getattr(t, 'grouping_library', False):
            continue
        for dep in t.samba_deps_extended:
            bld.ASSERT(dep in targets, "grouping library target %s not declared in %s" % (dep, t.sname))
            if targets[dep] == 'SUBSYSTEM':
                grouping[dep] = t.sname

    # now replace any dependencies on elements of grouping libraries
    for t in tgt_list:
        for i in range(len(t.samba_deps_extended)):
            dep = t.samba_deps_extended[i]
            if dep in grouping:
                if t.sname != grouping[dep]:
                    debug("deps: target %s: replacing dependency %s with grouping library %s" % (t.sname, dep, grouping[dep]))
                    t.samba_deps_extended[i] = grouping[dep]
Esempio n. 6
0
def build_autodeps(bld, t):
    '''build the set of dependencies for a target'''
    deps = set()
    name = real_name(t.sname)

    targets    = LOCAL_CACHE(bld, 'TARGET_TYPE')

    for sym in t.undefined_symbols:
        if sym in t.public_symbols:
            continue
        if sym in bld.env.symbol_map:
            depname = bld.env.symbol_map[sym]
            if depname == [ name ]:
                # self dependencies aren't interesting
                continue
            if t.in_library == depname:
                # no need to depend on the library we are part of
                continue
            if depname[0] in ['c', 'python']:
                # these don't go into autodeps
                continue
            if targets[depname[0]] in [ 'SYSLIB' ]:
                deps.add(depname[0])
                continue
            t2 = bld.get_tgen_by_name(depname[0])
            if len(t2.in_library) != 1:
                deps.add(depname[0])
                continue
            if t2.in_library == t.in_library:
                # if we're part of the same library, we don't need to autodep
                continue
            deps.add(t2.in_library[0])
    t.autodeps = deps
Esempio n. 7
0
def show_object_duplicates(bld, tgt_list):
    '''show a list of object files that are included in more than
    one library or binary'''

    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

    used_by = {}

    Logs.info("showing duplicate objects")

    for t in tgt_list:
        if not targets[t.sname] in [ 'LIBRARY', 'PYTHON' ]:
            continue
        for n in getattr(t, 'final_objects', set()):
            t2 = bld.get_tgen_by_name(n)
            if not n in used_by:
                used_by[n] = set()
            used_by[n].add(t.sname)

    for n in used_by:
        if len(used_by[n]) > 1:
            Logs.info("target '%s' is used by %s" % (n, used_by[n]))

    Logs.info("showing indirect dependency counts (sorted by count)")

    def indirect_count(t1, t2):
        return len(t2.indirect_objects) - len(t1.indirect_objects)

    sorted_list = sorted(tgt_list, cmp=indirect_count)
    for t in sorted_list:
        if len(t.indirect_objects) > 1:
            Logs.info("%s depends on %u indirect objects" % (t.sname, len(t.indirect_objects)))
Esempio n. 8
0
def show_final_deps(bld, tgt_list):
    '''show the final dependencies for all targets'''

    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

    for t in tgt_list:
        if not targets[t.sname] in ['LIBRARY', 'BINARY', 'PYTHON', 'SUBSYSTEM']:
            continue
        debug('deps: final dependencies for target %s: uselib=%s uselib_local=%s add_objects=%s',
              t.sname, t.uselib, getattr(t, 'uselib_local', []), getattr(t, 'add_objects', []))
Esempio n. 9
0
def check_duplicate_sources(bld, tgt_list):
    '''see if we are compiling the same source file more than once
       without an allow_duplicates attribute'''

    debug('deps: checking for duplicate sources')

    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')
    ret = True

    global tstart

    for t in tgt_list:
        source_list = TO_LIST(getattr(t, 'source', ''))
        tpath = os.path.normpath(
            os_path_relpath(t.path.abspath(bld.env),
                            t.env.BUILD_DIRECTORY + '/default'))
        obj_sources = set()
        for s in source_list:
            p = os.path.normpath(os.path.join(tpath, s))
            if p in obj_sources:
                Logs.error("ERROR: source %s appears twice in target '%s'" %
                           (p, t.sname))
                sys.exit(1)
            obj_sources.add(p)
        t.samba_source_set = obj_sources

    subsystems = {}

    # build a list of targets that each source file is part of
    for t in tgt_list:
        sources = []
        if not targets[t.sname] in ['LIBRARY', 'BINARY', 'PYTHON']:
            continue
        for obj in t.add_objects:
            t2 = t.bld.get_tgen_by_name(obj)
            source_set = getattr(t2, 'samba_source_set', set())
            for s in source_set:
                if not s in subsystems:
                    subsystems[s] = {}
                if not t.sname in subsystems[s]:
                    subsystems[s][t.sname] = []
                subsystems[s][t.sname].append(t2.sname)

    for s in subsystems:
        if len(subsystems[s]) > 1 and Options.options.SHOW_DUPLICATES:
            Logs.warn("WARNING: source %s is in more than one target: %s" %
                      (s, subsystems[s].keys()))
        for tname in subsystems[s]:
            if len(subsystems[s][tname]) > 1:
                raise Utils.WafError(
                    "ERROR: source %s is in more than one subsystem of target '%s': %s"
                    % (s, tname, subsystems[s][tname]))

    return ret
Esempio n. 10
0
def expand_subsystem_deps(bld):
    '''expand the reverse dependencies resulting from subsystem
       attributes of modules. This is walking over the complete list
       of declared subsystems, and expands the samba_deps_extended list for any
       module<->subsystem dependencies'''

    subsystem_list = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

    for subsystem_name in subsystem_list:
        bld.ASSERT(subsystem_name in targets,
                   "Subsystem target %s not declared" % subsystem_name)
        type = targets[subsystem_name]
        if type == 'DISABLED' or type == 'EMPTY':
            continue

        # for example,
        #    subsystem_name = dcerpc_server (a subsystem)
        #    subsystem      = dcerpc_server (a subsystem object)
        #    module_name    = rpc_epmapper (a module within the dcerpc_server subsystem)
        #    module         = rpc_epmapper (a module object within the dcerpc_server subsystem)

        subsystem = bld.get_tgen_by_name(subsystem_name)
        bld.ASSERT(subsystem is not None,
                   "Unable to find subsystem %s" % subsystem_name)
        for d in subsystem_list[subsystem_name]:
            module_name = d['TARGET']
            module_type = targets[module_name]
            if module_type in ['DISABLED', 'EMPTY']:
                continue
            bld.ASSERT(
                subsystem is not None,
                "Subsystem target %s for %s (%s) not found" %
                (subsystem_name, module_name, module_type))
            if module_type in ['SUBSYSTEM']:
                # if a module is a plain object type (not a library) then the
                # subsystem it is part of needs to have it as a dependency, so targets
                # that depend on this subsystem get the modules of that subsystem
                subsystem.samba_deps_extended.append(module_name)
        subsystem.samba_deps_extended = unique_list(
            subsystem.samba_deps_extended)
Esempio n. 11
0
def save_samba_deps(bld, tgt_list):
    '''save the dependency calculations between builds, to make
       further builds faster'''
    denv = ConfigSet.ConfigSet()

    denv.version = savedeps_version
    denv.savedeps_inputs = savedeps_inputs
    denv.savedeps_outputs = savedeps_outputs
    denv.input = {}
    denv.output = {}
    denv.outenv = {}
    denv.caches = {}
    denv.envvar = {}
    denv.files = {}

    for f in savedeps_files:
        denv.files[f] = os.stat(os.path.join(bld.srcnode.abspath(),
                                             f)).st_mtime

    for c in savedeps_caches:
        denv.caches[c] = LOCAL_CACHE(bld, c)

    for e in savedeps_envvars:
        denv.envvar[e] = bld.env[e]

    for t in tgt_list:
        # save all the input attributes for each target
        tdeps = {}
        for attr in savedeps_inputs:
            v = getattr(t, attr, None)
            if v is not None:
                tdeps[attr] = v
        if tdeps != {}:
            denv.input[t.sname] = tdeps

        # save all the output attributes for each target
        tdeps = {}
        for attr in savedeps_outputs:
            v = getattr(t, attr, None)
            if v is not None:
                tdeps[attr] = v
        if tdeps != {}:
            denv.output[t.sname] = tdeps

        tdeps = {}
        for attr in savedeps_outenv:
            if attr in t.env:
                tdeps[attr] = t.env[attr]
        if tdeps != {}:
            denv.outenv[t.sname] = tdeps

    depsfile = os.path.join(bld.cache_dir, "sambadeps")
    denv.store_fast(depsfile)
Esempio n. 12
0
def symbols_dupcheck(task, fail_on_error=False):
    '''check for symbols defined in two different subsystems'''
    bld = task.env.bld
    tgt_list = get_tgt_list(bld)

    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

    build_library_dict(bld, tgt_list)
    for t in tgt_list:
        if t.samba_type == 'BINARY':
            binname = os_path_relpath(t.link_task.outputs[0].abspath(bld.env), os.getcwd())
            symbols_dupcheck_binary(bld, binname, fail_on_error)
Esempio n. 13
0
def add_samba_attributes(bld, tgt_list):
    '''ensure a target has a the required samba attributes'''

    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

    for t in tgt_list:
        if t.name != '':
            t.sname = t.name
        else:
            t.sname = t.target
        t.samba_type = targets[t.sname]
        t.samba_abspath = t.path.abspath(bld.env)
        t.samba_deps_extended = t.samba_deps[:]
        t.samba_includes_extended = TO_LIST(t.samba_includes)[:]
        t.cflags = getattr(t, 'samba_cflags', '')
Esempio n. 14
0
def check_orphaned_targets(bld, tgt_list):
    '''check if any build targets are orphaned'''

    target_dict = LOCAL_CACHE(bld, 'TARGET_TYPE')

    debug('deps: checking for orphaned targets')

    for t in tgt_list:
        if getattr(t, 'samba_used', False):
            continue
        type = target_dict[t.sname]
        if not type in ['BINARY', 'LIBRARY', 'MODULE', 'ET', 'PYTHON']:
            if re.search('^PIDL_', t.sname) is None:
                Logs.warn(
                    "Target %s of type %s is unused by any other target" %
                    (t.sname, type))
Esempio n. 15
0
def check_group_ordering(bld, tgt_list):
    '''see if we have any dependencies that violate the group ordering

    It is an error for a target to depend on a target from a later
    build group
    '''
    def group_name(g):
        tm = bld.task_manager
        return [x for x in tm.groups_names
                if id(tm.groups_names[x]) == id(g)][0]

    for g in bld.task_manager.groups:
        gname = group_name(g)
        for t in g.tasks_gen:
            t.samba_group = gname

    grp_map = {}
    idx = 0
    for g in bld.task_manager.groups:
        name = group_name(g)
        grp_map[name] = idx
        idx += 1

    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

    ret = True
    for t in tgt_list:
        tdeps = getattr(t, 'add_objects', []) + getattr(t, 'uselib_local', [])
        for d in tdeps:
            t2 = bld.get_tgen_by_name(d)
            if t2 is None:
                continue
            map1 = grp_map[t.samba_group]
            map2 = grp_map[t2.samba_group]

            if map2 > map1:
                Logs.error(
                    "Target %r in build group %r depends on target %r from later build group %r"
                    % (t.sname, t.samba_group, t2.sname, t2.samba_group))
                ret = False

    return ret
Esempio n. 16
0
def rewrite_compile_targets():
    '''cope with the bin/ form of compile target'''
    if not Options.options.compile_targets:
        return

    bld = fake_build_environment(info=False)
    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')
    tlist = []

    for t in Options.options.compile_targets.split(','):
        if not os.path.islink(t):
            tlist.append(t)
            continue
        link = os.readlink(t)
        list = link.split('/')
        for name in [list[-1], '/'.join(list[-2:])]:
            if name in targets:
                tlist.append(name)
                continue
    Options.options.compile_targets = ",".join(tlist)
Esempio n. 17
0
def includes_objects(bld, t, chain, inc_loops):
    '''recursively calculate the includes object dependencies for a target

    includes dependencies come from either library or object dependencies
    '''
    ret = getattr(t, 'includes_objects', None)
    if ret is not None:
        return ret

    ret = t.direct_objects.copy()
    ret = ret.union(t.direct_libs)

    for obj in t.direct_objects:
        if obj in chain:
            dependency_loop(inc_loops, t, obj)
            continue
        chain.add(obj)
        t2 = bld.get_tgen_by_name(obj)
        r2 = includes_objects(bld, t2, chain, inc_loops)
        chain.remove(obj)
        ret = ret.union(t2.direct_objects)
        ret = ret.union(r2)

    for lib in t.direct_libs:
        if lib in chain:
            dependency_loop(inc_loops, t, lib)
            continue
        chain.add(lib)
        t2 = bld.get_tgen_by_name(lib)
        if t2 is None:
            targets = LOCAL_CACHE(bld, 'TARGET_TYPE')
            Logs.error('Target %s of type %s not found in direct_libs for %s' % (
                lib, targets[lib], t.sname))
            sys.exit(1)
        r2 = includes_objects(bld, t2, chain, inc_loops)
        chain.remove(lib)
        ret = ret.union(t2.direct_objects)
        ret = ret.union(r2)

    t.includes_objects = ret
    return ret
Esempio n. 18
0
def check_dependencies(bld, t):
    '''check for depenencies that should be changed'''

    if bld.get_tgen_by_name(t.sname + ".objlist"):
        return

    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

    remaining = t.undefined_symbols.copy()
    remaining = remaining.difference(t.public_symbols)

    sname = real_name(t.sname)

    deps = set(t.samba_deps)
    for d in t.samba_deps:
        if targets[d] in ['EMPTY', 'DISABLED', 'SYSLIB', 'GENERATOR']:
            continue
        bld.ASSERT(d in bld.env.public_symbols,
                   "Failed to find symbol list for dependency '%s'" % d)
        diff = remaining.intersection(bld.env.public_symbols[d])
        if not diff and targets[sname] != 'LIBRARY':
            Logs.info("Target '%s' has no dependency on %s" % (sname, d))
        else:
            remaining = remaining.difference(diff)

    t.unsatisfied_symbols = set()
    needed = {}
    for sym in remaining:
        if sym in bld.env.symbol_map:
            dep = bld.env.symbol_map[sym]
            if not dep[0] in needed:
                needed[dep[0]] = set()
            needed[dep[0]].add(sym)
        else:
            t.unsatisfied_symbols.add(sym)

    for dep in needed:
        Logs.info("Target '%s' should add dep '%s' for symbols %s" %
                  (sname, dep, " ".join(needed[dep])))
Esempio n. 19
0
def build_symbol_sets(bld, tgt_list):
    '''build the public_symbols and undefined_symbols attributes for each target'''

    if bld.env.public_symbols:
        return

    objlist = []  # list of object file
    objmap = {}   # map from object filename to target (subsystem) name

    for t in tgt_list:
        t.public_symbols = set()
        t.undefined_symbols = set()
        t.used_symbols = set()
        for tsk in getattr(t, 'compiled_tasks', []):
            for output in tsk.outputs:
                objpath = output.abspath(bld.env)
                objlist.append(objpath)
                objmap[objpath] = t

    symbols = symbols_extract(bld, objlist)
    for obj in objlist:
        t = objmap[obj]
        t.public_symbols = t.public_symbols.union(symbols[obj]["PUBLIC"])
        t.undefined_symbols = t.undefined_symbols.union(symbols[obj]["UNDEFINED"])
        t.used_symbols = t.used_symbols.union(symbols[obj]["UNDEFINED"])

    t.undefined_symbols = t.undefined_symbols.difference(t.public_symbols)

    # and the reverse map of public symbols to subsystem name
    bld.env.symbol_map = {}

    for t in tgt_list:
        for s in t.public_symbols:
            if not s in bld.env.symbol_map:
                bld.env.symbol_map[s] = []
            bld.env.symbol_map[s].append(real_name(t.sname))

    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

    bld.env.public_symbols = {}
    for t in tgt_list:
        name = real_name(t.sname)
        if name in bld.env.public_symbols:
            bld.env.public_symbols[name] = bld.env.public_symbols[name].union(t.public_symbols)
        else:
            bld.env.public_symbols[name] = t.public_symbols
        if t.samba_type == 'LIBRARY':
            for dep in t.add_objects:
                t2 = bld.get_tgen_by_name(dep)
                bld.ASSERT(t2 is not None, "Library '%s' has unknown dependency '%s'" % (name, dep))
                bld.env.public_symbols[name] = bld.env.public_symbols[name].union(t2.public_symbols)

    bld.env.used_symbols = {}
    for t in tgt_list:
        name = real_name(t.sname)
        if name in bld.env.used_symbols:
            bld.env.used_symbols[name] = bld.env.used_symbols[name].union(t.used_symbols)
        else:
            bld.env.used_symbols[name] = t.used_symbols
        if t.samba_type == 'LIBRARY':
            for dep in t.add_objects:
                t2 = bld.get_tgen_by_name(dep)
                bld.ASSERT(t2 is not None, "Library '%s' has unknown dependency '%s'" % (name, dep))
                bld.env.used_symbols[name] = bld.env.used_symbols[name].union(t2.used_symbols)
Esempio n. 20
0
def calculate_final_deps(bld, tgt_list, loops):
    '''calculate the final library and object dependencies'''
    for t in tgt_list:
        # start with the maximum possible list
        t.final_libs    = t.direct_libs.union(indirect_libs(bld, t, set(), loops))
        t.final_objects = t.direct_objects.union(indirect_objects(bld, t, set(), loops))

    for t in tgt_list:
        # don't depend on ourselves
        if t.sname in t.final_libs:
            t.final_libs.remove(t.sname)
        if t.sname in t.final_objects:
            t.final_objects.remove(t.sname)

    # handle any non-shared binaries
    for t in tgt_list:
        if t.samba_type == 'BINARY' and bld.NONSHARED_BINARY(t.sname):
            subsystem_list = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')
            targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

            # replace lib deps with objlist deps
            for l in t.final_libs:
                objname = l + '.objlist'
                t2 = bld.get_tgen_by_name(objname)
                if t2 is None:
                    Logs.error('ERROR: subsystem %s not found' % objname)
                    sys.exit(1)
                t.final_objects.add(objname)
                t.final_objects = t.final_objects.union(extended_objects(bld, t2, set()))
                if l in subsystem_list:
                    # its a subsystem - we also need the contents of any modules
                    for d in subsystem_list[l]:
                        module_name = d['TARGET']
                        if targets[module_name] == 'LIBRARY':
                            objname = module_name + '.objlist'
                        elif targets[module_name] == 'SUBSYSTEM':
                            objname = module_name
                        else:
                            continue
                        t2 = bld.get_tgen_by_name(objname)
                        if t2 is None:
                            Logs.error('ERROR: subsystem %s not found' % objname)
                            sys.exit(1)
                        t.final_objects.add(objname)
                        t.final_objects = t.final_objects.union(extended_objects(bld, t2, set()))
            t.final_libs = set()

    # find any library loops
    for t in tgt_list:
        if t.samba_type in ['LIBRARY', 'PYTHON']:
            for l in t.final_libs.copy():
                t2 = bld.get_tgen_by_name(l)
                if t.sname in t2.final_libs:
                    if getattr(bld.env, "ALLOW_CIRCULAR_LIB_DEPENDENCIES", False):
                        # we could break this in either direction. If one of the libraries
                        # has a version number, and will this be distributed publicly, then
                        # we should make it the lower level library in the DAG
                        Logs.warn('deps: removing library loop %s from %s' % (t.sname, t2.sname))
                        dependency_loop(loops, t, t2.sname)
                        t2.final_libs.remove(t.sname)
                    else:
                        Logs.error('ERROR: circular library dependency between %s and %s'
                            % (t.sname, t2.sname))
                        show_library_loop(bld, t.sname, t2.sname, t.sname, set())
                        show_library_loop(bld, t2.sname, t.sname, t2.sname, set())
                        sys.exit(1)

    for loop in loops:
        debug('deps: Found dependency loops for target %s : %s', loop, loops[loop])

    # we now need to make corrections for any library loops we broke up
    # any target that depended on the target of the loop and doesn't
    # depend on the source of the loop needs to get the loop source added
    for type in ['BINARY','PYTHON','LIBRARY','BINARY']:
        for t in tgt_list:
            if t.samba_type != type: continue
            for loop in loops:
                if loop in t.final_libs:
                    diff = loops[loop].difference(t.final_libs)
                    if t.sname in diff:
                        diff.remove(t.sname)
                    if t.sname in diff:
                        diff.remove(t.sname)
                    # make sure we don't recreate the loop again!
                    for d in diff.copy():
                        t2 = bld.get_tgen_by_name(d)
                        if t2.samba_type == 'LIBRARY':
                            if t.sname in t2.final_libs:
                                debug('deps: removing expansion %s from %s', d, t.sname)
                                diff.remove(d)
                    if diff:
                        debug('deps: Expanded target %s by loop %s libraries (loop %s) %s', t.sname, loop,
                              loops[loop], diff)
                        t.final_libs = t.final_libs.union(diff)

    # remove objects that are also available in linked libs
    count = 0
    while reduce_objects(bld, tgt_list):
        count += 1
        if count > 100:
            Logs.warn("WARNING: Unable to remove all inter-target object duplicates")
            break
    debug('deps: Object reduction took %u iterations', count)

    # add in any syslib dependencies
    for t in tgt_list:
        if not t.samba_type in ['BINARY','PYTHON','LIBRARY','SUBSYSTEM']:
            continue
        syslibs = set()
        for d in t.final_objects:
            t2 = bld.get_tgen_by_name(d)
            syslibs = syslibs.union(t2.direct_syslibs)
        # this adds the indirect syslibs as well, which may not be needed
        # depending on the linker flags
        for d in t.final_libs:
            t2 = bld.get_tgen_by_name(d)
            syslibs = syslibs.union(t2.direct_syslibs)
        t.final_syslibs = syslibs


    # find any unresolved library loops
    lib_loop_error = False
    for t in tgt_list:
        if t.samba_type in ['LIBRARY', 'PYTHON']:
            for l in t.final_libs.copy():
                t2 = bld.get_tgen_by_name(l)
                if t.sname in t2.final_libs:
                    Logs.error('ERROR: Unresolved library loop %s from %s' % (t.sname, t2.sname))
                    lib_loop_error = True
    if lib_loop_error:
        sys.exit(1)

    debug('deps: removed duplicate dependencies')
Esempio n. 21
0
def SAMBA_PIDL(bld,
               pname,
               source,
               options='',
               output_dir='.',
               generate_tables=True):
    '''Build a IDL file using pidl.
       This will produce up to 13 output files depending on the options used'''

    bname = source[0:-4]
    # strip off the .idl suffix
    bname = os.path.basename(bname)
    name = "%s_%s" % (pname, bname.upper())

    if not SET_TARGET_TYPE(bld, name, 'PIDL'):
        return

    bld.SET_BUILD_GROUP('build_source')

    # the output files depend on the options used. Use this dictionary
    # to map between the options and the resulting file names
    options_map = {
        '--header': '%s.h',
        '--ndr-parser': 'ndr_%s.c ndr_%s.h',
        '--samba3-ndr-server': 'srv_%s.c srv_%s.h',
        '--samba3-ndr-client': 'cli_%s.c cli_%s.h',
        '--server': 'ndr_%s_s.c',
        '--client': 'ndr_%s_c.c ndr_%s_c.h',
        '--python': 'py_%s.c',
        '--tdr-parser': 'tdr_%s.c tdr_%s.h',
        '--dcom-proxy': '%s_p.c',
        '--com-header': 'com_%s.h'
    }

    table_header_idx = None
    out_files = []
    options_list = TO_LIST(options)

    for o in options_list:
        if o in options_map:
            ofiles = TO_LIST(options_map[o])
            for f in ofiles:
                out_files.append(os.path.join(output_dir, f % bname))
                if f == 'ndr_%s.h':
                    # remember this one for the tables generation
                    table_header_idx = len(out_files) - 1

    # depend on the full pidl sources
    source = TO_LIST(source)
    try:
        pidl_src_nodes = bld.pidl_files_cache
    except AttributeError:
        bld.pidl_files_cache = bld.srcnode.ant_glob('pidl/lib/Parse/**/*.pm',
                                                    flat=False)
        bld.pidl_files_cache.extend(bld.srcnode.ant_glob('pidl', flat=False))
        pidl_src_nodes = bld.pidl_files_cache

    # the cd .. is needed because pidl currently is sensitive to the directory it is run in
    cpp = ""
    cc = ""
    if bld.CONFIG_SET("CPP") and bld.CONFIG_GET("CPP") != "":
        if isinstance(bld.CONFIG_GET("CPP"), list):
            cpp = 'CPP="%s"' % " ".join(bld.CONFIG_GET("CPP"))
        else:
            cpp = 'CPP="%s"' % bld.CONFIG_GET("CPP")

    if cpp == "CPP=xlc_r":
        cpp = ""

    if bld.env['PIDL_DEVELOPER_MODE']:
        pidl_dev = 'PIDL_DEVELOPER=1 '
    else:
        pidl_dev = ''

    if bld.CONFIG_SET("CC"):
        if isinstance(bld.CONFIG_GET("CC"), list):
            cc = 'CC="%s"' % " ".join(bld.CONFIG_GET("CC"))
        else:
            cc = 'CC="%s"' % bld.CONFIG_GET("CC")

    t = bld(
        rule=
        'cd ${PIDL_LAUNCH_DIR} && %s%s %s ${PERL} ${PIDL} --quiet ${OPTIONS} --outputdir ${OUTPUTDIR} -- "${IDLSRC}"'
        % (pidl_dev, cpp, cc),
        ext_out='.c',
        before='c',
        update_outputs=True,
        shell=True,
        source=source,
        target=out_files,
        name=name,
        samba_type='PIDL')

    t.env.PIDL_LAUNCH_DIR = bld.srcnode.path_from(bld.bldnode)
    pnode = bld.srcnode.find_resource('pidl/pidl')
    t.env.PIDL = pnode.path_from(bld.srcnode)
    t.env.OPTIONS = TO_LIST(options)
    snode = t.path.find_resource(source[0])
    t.env.IDLSRC = snode.path_from(bld.srcnode)
    t.env.OUTPUTDIR = bld.bldnode.path_from(
        bld.srcnode) + '/' + bld.path.find_dir(output_dir).path_from(
            bld.srcnode)

    bld.add_manual_dependency(snode, pidl_src_nodes)

    if generate_tables and table_header_idx is not None:
        pidl_headers = LOCAL_CACHE(bld, 'PIDL_HEADERS')
        pidl_headers[name] = [
            bld.path.find_or_declare(out_files[table_header_idx])
        ]

    t.more_includes = '#' + bld.path.path_from(bld.srcnode)
Esempio n. 22
0
def reduce_objects(bld, tgt_list):
    '''reduce objects by looking for indirect object dependencies'''
    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

    rely_on = {}

    for t in tgt_list:
        t.extended_objects = None

    changed = False

    for type in ['BINARY', 'PYTHON', 'LIBRARY', 'PLUGIN']:
        for t in tgt_list:
            if t.samba_type != type: continue
            # if we will indirectly link to a target then we don't need it
            new = t.final_objects.copy()
            for l in t.final_libs:
                t2 = bld.get_tgen_by_name(l)
                t2_obj = extended_objects(bld, t2, set())
                dup = new.intersection(t2_obj)
                if t.sname in rely_on:
                    dup = dup.difference(rely_on[t.sname])
                if dup:
                    # Do not remove duplicates of BUILTINS
                    for d in iter(dup.copy()):
                        dtype = targets[d]
                        if dtype == 'BUILTIN':
                            debug(
                                'deps: BUILTIN SKIP: removing dups from %s of type %s: %s also in %s %s',
                                t.sname, t.samba_type, d, t2.samba_type, l)
                            dup.remove(d)
                    if len(dup) == 0:
                        continue

                    debug(
                        'deps: removing dups from %s of type %s: %s also in %s %s',
                        t.sname, t.samba_type, dup, t2.samba_type, l)
                    new = new.difference(dup)
                    changed = True
                    if not l in rely_on:
                        rely_on[l] = set()
                    rely_on[l] = rely_on[l].union(dup)
            for n in iter(new.copy()):
                # if we got the builtin version as well
                # as the native one, we keep using the
                # builtin one and remove the rest.
                # Otherwise our check_duplicate_sources()
                # checks would trigger!
                if n.endswith('.builtin.objlist'):
                    unused = n.replace('.builtin.objlist', '.objlist')
                    if unused in new:
                        new.remove(unused)
                    unused = n.replace('.builtin.objlist', '')
                    if unused in new:
                        new.remove(unused)
            t.final_objects = new

    if not changed:
        return False

    # add back in any objects that were relied upon by the reduction rules
    for r in rely_on:
        t = bld.get_tgen_by_name(r)
        t.final_objects = t.final_objects.union(rely_on[r])

    return True
Esempio n. 23
0
def add_init_functions(self):
    '''This builds the right set of init functions'''

    bld = self.bld

    subsystems = LOCAL_CACHE(bld, 'INIT_FUNCTIONS')

    # cope with the separated object lists from BINARY and LIBRARY targets
    sname = self.sname
    if sname.endswith('.objlist'):
        sname = sname[0:-8]

    modules = []
    if sname in subsystems:
        modules.append(sname)

    m = getattr(self, 'samba_modules', None)
    if m is not None:
        modules.extend(TO_LIST(m))

    m = getattr(self, 'samba_subsystem', None)
    if m is not None:
        modules.append(m)

    if 'pyembed' in self.features:
        return

    sentinel = getattr(self, 'init_function_sentinel', 'NULL')

    targets    = LOCAL_CACHE(bld, 'TARGET_TYPE')
    cflags = getattr(self, 'samba_cflags', [])[:]

    if modules == []:
        sname = sname.replace('-','_')
        sname = sname.replace('.','_')
        sname = sname.replace('/','_')
        cflags.append('-DSTATIC_%s_MODULES=%s' % (sname, sentinel))
        if sentinel == 'NULL':
            proto = "extern void __%s_dummy_module_proto(void)" % (sname)
            cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (sname, proto))
        self.cflags = cflags
        return

    for m in modules:
        bld.ASSERT(m in subsystems,
                   "No init_function defined for module '%s' in target '%s'" % (m, self.sname))
        init_fn_list = []
        for d in subsystems[m]:
            if targets[d['TARGET']] != 'DISABLED':
                init_fn_list.append(d['INIT_FUNCTION'])
        if init_fn_list == []:
            cflags.append('-DSTATIC_%s_MODULES=%s' % (m, sentinel))
            if sentinel == 'NULL':
                proto = "extern void __%s_dummy_module_proto(void)" % (m)
                cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (m, proto))
        else:
            cflags.append('-DSTATIC_%s_MODULES=%s' % (m, ','.join(init_fn_list) + ',' + sentinel))
            proto=''
            for f in init_fn_list:
                proto += '_MODULE_PROTO(%s)' % f
            proto += "extern void __%s_dummy_module_proto(void)" % (m)
            cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (m, proto))
    self.cflags = cflags
Esempio n. 24
0
def SET_SYSLIB_DEPS(conf, target, deps):
    '''setup some implied dependencies for a SYSLIB'''
    cache = LOCAL_CACHE(conf, 'SYSLIB_DEPS')
    cache[target] = deps
Esempio n. 25
0
def load_samba_deps(bld, tgt_list):
    '''load a previous set of build dependencies if possible'''
    depsfile = os.path.join(bld.bldnode.abspath(), "sambadeps")
    denv = ConfigSet.ConfigSet()
    try:
        debug('deps: checking saved dependencies')
        denv.load_fast(depsfile)
        if (denv.version != savedeps_version or
            denv.savedeps_inputs != savedeps_inputs or
            denv.savedeps_outputs != savedeps_outputs):
            return False
    except Exception:
        return False

    # check if critical files have changed
    for f in savedeps_files:
        if f not in denv.files:
            return False
        if denv.files[f] != os.stat(os.path.join(bld.srcnode.abspath(), f)).st_mtime:
            return False

    # check if caches are the same
    for c in savedeps_caches:
        if c not in denv.caches or denv.caches[c] != LOCAL_CACHE(bld, c):
            return False

    # check if caches are the same
    for e in savedeps_envvars:
        if e not in denv.envvar or denv.envvar[e] != bld.env[e]:
            return False

    # check inputs are the same
    for t in tgt_list:
        tdeps = {}
        for attr in savedeps_inputs:
            v = getattr(t, attr, None)
            if v is not None:
                tdeps[attr] = v
        if t.sname in denv.input:
            olddeps = denv.input[t.sname]
        else:
            olddeps = {}
        if tdeps != olddeps:
            #print '%s: \ntdeps=%s \nodeps=%s' % (t.sname, tdeps, olddeps)
            return False

    # put outputs in place
    for t in tgt_list:
        if not t.sname in denv.output: continue
        tdeps = denv.output[t.sname]
        for a in tdeps:
            setattr(t, a, tdeps[a])

    # put output env vars in place
    for t in tgt_list:
        if not t.sname in denv.outenv: continue
        tdeps = denv.outenv[t.sname]
        for a in tdeps:
            t.env[a] = tdeps[a]

    debug('deps: loaded saved dependencies')
    return True
Esempio n. 26
0
def replace_builtin_subsystem_deps(bld, tgt_list):
    '''replace dependencies based on builtin subsystems/libraries

    '''

    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')

    # If either the target or the dependency require builtin linking
    # we should replace the dependency
    for t in tgt_list:
        t_require_builtin_deps = getattr(t, 'samba_require_builtin_deps',
                                         False)
        if t_require_builtin_deps:
            debug("deps: target %s: requires builtin dependencies..." %
                  (t.sname))
        else:
            debug("deps: target %s: does not require builtin dependencies..." %
                  (t.sname))

        replacing = {}

        for dep in t.samba_deps_extended:
            bld.ASSERT(
                dep in targets,
                "target %s: dependency target %s not declared" %
                (t.sname, dep))
            dtype = targets[dep]
            bld.ASSERT(
                dtype != 'BUILTIN',
                "target %s: dependency target %s is BUILTIN" % (t.sname, dep))
            bld.ASSERT(
                dtype != 'PLUGIN',
                "target %s: dependency target %s is PLUGIN" % (t.sname, dep))
            if dtype not in ['SUBSYSTEM', 'LIBRARY']:
                debug("deps: target %s: keep %s dependency %s" %
                      (t.sname, dtype, dep))
                continue
            dt = bld.get_tgen_by_name(dep)
            bld.ASSERT(
                dt is not None,
                "target %s: dependency target %s not found by name" %
                (t.sname, dep))
            dt_require_builtin_deps = getattr(dt, 'samba_require_builtin_deps',
                                              False)
            if not dt_require_builtin_deps and not t_require_builtin_deps:
                # both target and dependency don't require builtin linking
                continue
            sdt = getattr(dt, 'samba_builtin_subsystem', None)
            if not t_require_builtin_deps:
                if sdt is None:
                    debug(
                        "deps: target %s: dependency %s requires builtin deps only"
                        % (t.sname, dep))
                    continue
                debug(
                    "deps: target %s: dependency %s requires builtin linking" %
                    (t.sname, dep))
            bld.ASSERT(
                sdt is not None,
                "target %s: dependency target %s is missing samba_builtin_subsystem"
                % (t.sname, dep))
            sdep = sdt.sname
            bld.ASSERT(
                sdep in targets,
                "target %s: builtin dependency target %s (from %s) not declared"
                % (t.sname, sdep, dep))
            sdt = targets[sdep]
            bld.ASSERT(
                sdt == 'BUILTIN',
                "target %s: builtin dependency target %s (from %s) is not BUILTIN"
                % (t.sname, sdep, dep))
            replacing[dep] = sdep

        for i in range(len(t.samba_deps_extended)):
            dep = t.samba_deps_extended[i]
            if dep in replacing:
                sdep = replacing[dep]
                debug(
                    "deps: target %s: replacing dependency %s with builtin subsystem %s"
                    % (t.sname, dep, sdep))
                t.samba_deps_extended[i] = sdep