Example #1
0
def manifest_emitter(target, source, env):
    if 'mainclass' in env:
        Depends(target, SCons.Node.Python.Value(env['mainclass']))
    if 'classpath' in env:
        Depends(target, SCons.Node.Python.Value(env['classpath']))
    else:
        Depends(target, SCons.Node.Python.Value(env['JAVACLASSPATH']))
    source = []
    return target, source
Example #2
0
def infusion_emitter(target, source, env):
    if len(target) != 1:
        env.Error("Infusion needs exactly one output directory!")
        exit(1)
    target[0].must_be_same(SCons.Node.FS.Dir)

    # derrive infusion path and name
    infusion_path = str(target[0])
    infusion_name = os.path.basename(infusion_path)

    # check source files
    for s in source:
        file_name = str(s)
        if not os.path.splitext(file_name)[1] in ['.class', '.dih', '.jar']:
            env.Error(
                "Infusion source `{}` is neither *.class nor *.dih nor *.jar".
                format(file_name))
            exit(1)

    # create file targets
    output_templates = [
        '{}.dih', '{}.di', 'jlib_{}.c', 'jlib_{}.h', 'jlib_{}.hpp'
    ]
    target = []
    for templ in output_templates:
        path = os.path.join(infusion_path, templ.format(infusion_name))
        file_target = File(path)
        Depends(file_target, env['INFUSER_JAR'])
        target.append(file_target)

    return target, source
Example #3
0
def main(env,
         analysiss,
         processes,
         plot_together,
         configs,
         lo_nlo_lines_and_nlo_band,
         descriptions,
         do_controls=False):
    analysis = env.Analysis("RivetAnalysis", analysiss)
    make_plot_dir = lambda d: d + '/index.html'
    control_plots = map(make_plot_dir, processes)
    plot_targets = [pt['target'] for pt in plot_together]
    plot_targets = map(make_plot_dir, plot_targets)
    for idx, pd in enumerate(plot_together):
        plot_together[idx]['target'] = make_plot_dir(pd['target'])

    print 'processes: ', processes
    yodas = build_yodas_from_hepmcs(env, processes)
    Depends(yodas, analysis)
    small_yoda_names = su.get_yodas_from_proc_list(processes)
    print 'small_yoda_names: ', small_yoda_names
    n_yodas = len(sum(small_yoda_names, []))
    if n_yodas > 0:
        do_yodas(env, small_yoda_names, make_plot_dir, control_plots, configs,
                 lo_nlo_lines_and_nlo_band, plot_targets, plot_together,
                 descriptions, do_controls)
Example #4
0
def do_small_yodas(env, small_yodas, configs, control_plot):
    # TODO: (bcn 2016-05-26) Use all given configs
    try:
        if len(small_yodas) == 0:
            raise IndexError
        plot = env.Plot(target=control_plot,
                        source=small_yodas,
                        CONFIG=configs[0])
        Depends(plot, configs[0])
    except IndexError:
        print 'Could not build', control_plot, 'from', small_yodas
Example #5
0
 def subst_emitter(target, source, env):
     """Add dependency from substituted SUBST_DICT to target.
     Returns original target, source tuple unchanged.
     """
     d = env['SUBST_DICT'].copy()  # copy it
     for (k, v) in d.items():
         if callable(v):
             d[k] = env.subst(v())
         elif SCons.Util.is_String(v):
             d[k] = env.subst(v)
     Depends(target, SCons.Node.Python.Value(d))
     return target, source
Example #6
0
def ostfriesentee_library_method(env, name, source, **kwargs):
    """ This is a pseudo builder that tells scons how to generate a
	    `OstfriesenteeLibrary`:
	    * may consist of Java and C sources
	    * may depend on other libraries (specify with env['OFT_LIBS'])
	    * needs to be linked into the executable containing the Ostfriesentee jvm
	    * other libraries as well as apps may depend on it
	    * _input_: *.java, *.c
	    * _output_: *.a, *.di, *.dih, *.jar
	"""
    # parse variable keyword args
    libs_dep = list(env['OFT_LIBS'])
    if 'OFT_LIBS' in kwargs:
        libs_dep += list(kwargs['OFT_LIBS'])
    is_app = False
    if 'is_app' in kwargs:
        is_app = bool(kwargs['is_app'])

    # check if name is valid and determine buildpath
    if not re.match('[a-zA-Z][a-zA-Z0-9_]*', name):
        env.Error(
            "Invalid name `{}`. Please use C identifier conventions.".format(
                name))
        exit(1)
    if is_app:
        build_path = os.path.join(env['OFT_BUILDPATH'], 'app', name)
    else:
        build_path = os.path.join(env['OFT_BUILDPATH'], 'lib', name)

    # check if jar file and this library was already specified:
    jar_name = os.path.join(build_path, name + '.jar')
    target = [File(jar_name)]
    target.append(File(os.path.join(build_path, name + '.di')))
    (c_src, c_src_dir) = env.FindFiles(source, ".c")
    if not is_app:
        target.append(File(os.path.join(build_path, name + '.dih')))
    if not is_app and len(c_src) > 0:
        target.append(File(os.path.join(build_path, 'lib' + name + '.a')))
    already_specified = reduce(operator.and_,
                               [t.has_builder() for t in target])
    if already_specified:
        return target

    # build java sources
    java_src = env.FindFiles(source, ".java")[0]
    env_java = env.Clone()
    for lib in libs_dep:
        jar_dep = os.path.join(env['OFT_BUILDPATH'], 'lib', lib, lib + '.jar')
        env_java.AppendUnique(JAVACLASSPATH=jar_dep)
        Depends(jar_name, jar_dep)

    # do not depend on system jars but on lib base, however: only if this is not libbase
    if name != 'base':
        env_java['JAVABOOTCLASSPATH'] = [
            os.path.join(env['OFT_BUILDPATH'], 'lib', 'base', 'base.jar')
        ]
    else:
        env_java['JAVABOOTCLASSPATH'] = []
    jar = env_java.JavaToJar(os.path.join(build_path, name + '.jar'), java_src)
    target = [jar]

    # make infusion
    infusion_src = list(target)
    for lib in libs_dep:
        infusion_src.append(
            os.path.join(env['OFT_BUILDPATH'], 'lib', lib, lib + '.dih'))
    infusion = env.Infusion(build_path, infusion_src)

    def find_suffix(files, suffix):
        return [
            os.path.abspath(str(ff)) for ff in files
            if str(ff).endswith(suffix)
        ]

    infusion_dih = find_suffix(infusion, '.dih')
    infusion_di = find_suffix(infusion, '.di')
    infusion_c = find_suffix(infusion, '.c')

    # if this is an app, there is no c code and no dih file to emit, because
    # no dependency on an app is allowed
    if is_app:
        return target + infusion_di

    target += infusion_di + infusion_dih

    # compile native code
    if len(c_src) > 0:
        c_env = env.Clone()
        # place object files in buildpath
        c_env.VariantDir(variant_dir=build_path, src_dir=c_src_dir)
        c_var_src = []
        for cc in c_src:
            abs_path = os.path.abspath(str(cc))
            rel = os.path.relpath(abs_path, c_src_dir)
            c_var_src.append(os.path.join(build_path, rel))
        # for infusion_h file
        c_env.AppendUnique(CPPPATH=[build_path])
        # library header files
        for lib in libs_dep:
            c_env.AppendUnique(
                CPPPATH=[os.path.join(env['OFT_BUILDPATH'], 'lib', lib)])
        # tell scons how to build static lib
        target += c_env.StaticLibrary(os.path.join(build_path, name),
                                      infusion_c + c_var_src)

    return target
Example #7
0
def build_program(tile, elfname, chip, patch=True, objcopy_flags=""):
    """
    Build an ARM cortex executable
    """

    dirs = chip.build_dirs()

    output_name = '%s_%s.elf' % (
        elfname,
        chip.arch_name(),
    )
    output_binname = '%s_%s.bin' % (
        elfname,
        chip.arch_name(),
    )
    patched_name = '%s_%s_patched.elf' % (
        elfname,
        chip.arch_name(),
    )
    patchfile_name = '%s_%s_patchcommand.txt' % (
        elfname,
        chip.arch_name(),
    )
    map_name = '%s_%s.map' % (
        elfname,
        chip.arch_name(),
    )

    VariantDir(dirs['build'], os.path.join('firmware', 'src'), duplicate=0)

    args_file = os.path.join('.', dirs['build'], 'gcc_args.txt')
    prog_env = setup_environment(chip, args_file=args_file)

    prog_env['OUTPUT'] = output_name
    prog_env['BUILD_DIR'] = dirs['build']
    prog_env['OUTPUT_PATH'] = os.path.join(dirs['build'], output_name)
    prog_env['OUTPUTBIN'] = os.path.join(dirs['build'], output_binname)
    prog_env['PATCHED'] = os.path.join(dirs['build'], patched_name)
    prog_env['PATCH_FILE'] = os.path.join(dirs['build'], patchfile_name)
    prog_env['PATCH_FILENAME'] = patchfile_name
    prog_env['MODULE'] = elfname

    # Setup all of our dependencies and make sure our output depends on them being built
    tilebus_defs = setup_dependencies(tile, prog_env)

    # Setup specific linker flags for building a program
    # Specify the linker script
    # We can find a linker script in one of two places, either in a dependency or in an explicit 'linker' property
    # First check for a linker script in our dependencies
    ldscripts = list(
        itertools.chain(*[
            x.find_products('linker_script') for x in prog_env['DEPENDENCIES']
        ]))

    # Make sure we don't have multiple linker scripts coming in from dependencies
    if len(ldscripts) > 1:
        raise BuildError(
            "Multiple linker scripts included from dependencies, at most one may be included",
            linker_scripts=ldscripts)

    # Make sure we don't have a linker script from a dependency and explicity specified
    if len(ldscripts) == 1 and chip.property('linker', None) is not None:
        raise BuildError(
            "Linker script specified in dependency and explicitly in module_settings",
            explicit_script=chip.property('linker'),
            dependency_script=ldscripts[0])

    if len(ldscripts) == 1:
        ldscript = ldscripts[0]
    else:
        ldscript = utilities.join_path(chip.property('linker'))

    # Find the linker script directory in case it includes other linker scripts in the same directory
    lddir = os.path.abspath(os.path.dirname(ldscript))
    prog_env['LIBPATH'] += [lddir]

    prog_env['LINKFLAGS'].append('-T"%s"' % ldscript)

    # Specify the output map file
    prog_env['LINKFLAGS'].extend(
        ['-Xlinker',
         '-Map="%s"' % os.path.join(dirs['build'], map_name)])
    Clean(os.path.join(dirs['build'], output_name),
          [os.path.join(dirs['build'], map_name)])

    # Compile the TileBus command and config variable definitions
    # Try to use the modern 'tilebus' directory or the old 'cdb' directory
    tbname = os.path.join('firmware', 'src', 'tilebus',
                          prog_env["MODULE"] + ".bus")
    if not os.path.exists(tbname):
        tbname = os.path.join('firmware', 'src', 'cdb',
                              prog_env["MODULE"] + ".cdb")

    compile_tilebus(tilebus_defs + [tbname], prog_env)

    # Ensure that our argument file to gcc is created
    args_node = prog_env.Command([args_file], [],
                                 action=prog_env.Action(
                                     create_arg_file,
                                     "Creating GCC Arguments"))
    prog_env.AlwaysBuild(args_node)

    # Compile an elf for the firmware image
    objs = SConscript(os.path.join(dirs['build'], 'SConscript'),
                      exports='prog_env')
    for obj in objs:
        Depends(obj, args_file)

    outfile = prog_env.Program(os.path.join(dirs['build'], prog_env['OUTPUT']),
                               objs)

    if patch:
        # Create a patched ELF including a proper checksum
        # First create a binary dump of the program flash
        outbin = prog_env.Command(
            prog_env['OUTPUTBIN'],
            os.path.join(dirs['build'], prog_env['OUTPUT']),
            "arm-none-eabi-objcopy -O binary {} $SOURCES $TARGET".format(
                objcopy_flags))

        # Now create a command file containing the linker command needed to patch the elf
        outhex = prog_env.Command(prog_env['PATCH_FILE'],
                                  outbin,
                                  action=prog_env.Action(
                                      checksum_creation_action,
                                      "Generating checksum file"))

        # Next relink a new version of the binary using that patch file to define the image checksum
        patch_env = prog_env.Clone()
        patch_env['LINKFLAGS'].append(
            ['-Xlinker', '@%s' % patch_env['PATCH_FILE']])

        patched_file = patch_env.Program(prog_env['PATCHED'], objs)
        patch_env.Depends(patched_file, [
            os.path.join(dirs['build'], output_name), patch_env['PATCH_FILE']
        ])

        prog_env.Depends(os.path.join(dirs['build'], output_name), [ldscript])

        prog_env.InstallAs(os.path.join(dirs['output'], output_name),
                           os.path.join(dirs['build'], patched_name))
    else:
        prog_env.InstallAs(os.path.join(dirs['output'], output_name), outfile)

    prog_env.InstallAs(os.path.join(dirs['output'], map_name),
                       os.path.join(dirs['build'], map_name))

    return os.path.join(dirs['output'], output_name)