예제 #1
0
def build(
        BENCHMARKS_CSPROJ: dotnet.CSharpProject,
        configuration: str,
        target_framework_monikers: list,
        incremental: str,
        verbose: bool) -> None:
    '''Restores and builds the benchmarks'''

    packages = get_packages_directory()

    if incremental == 'no':
        __log_script_header("Removing packages, bin and obj folders.")
        binary_folders = [
            packages,
            path.join(BENCHMARKS_CSPROJ.bin_path),
        ]
        for binary_folder in binary_folders:
            remove_directory(path=binary_folder)

    # dotnet restore
    __log_script_header("Restoring .NET micro benchmarks")
    BENCHMARKS_CSPROJ.restore(packages_path=packages, verbose=verbose)

    # dotnet build
    build_title = "Building .NET micro benchmarks for '{}'".format(
        ' '.join(target_framework_monikers))
    __log_script_header(build_title)
    BENCHMARKS_CSPROJ.build(
        configuration=configuration,
        target_framework_monikers=target_framework_monikers,
        verbose=verbose,
        packages_path=packages)
예제 #2
0
 def existing(self, projectdir: str, projectfile: str):
     'create a project from existing project file'
     self._backup(projectdir)
     csproj = CSharpProjFile(os.path.join(const.APPDIR, projectfile),
                             sys.path[0])
     self.project = CSharpProject(csproj, const.BINDIR)
     self._updateframework(csproj.file_name)
예제 #3
0
def run(BENCHMARKS_CSPROJ: dotnet.CSharpProject, configuration: str,
        framework: str, verbose: bool, *args) -> None:
    '''Runs the benchmarks'''
    __log_script_header(
        "Running .NET micro benchmarks for '{}'".format(framework))
    # dotnet run
    run_args = __get_benchmarkdotnet_arguments(framework, *args)
    target_framework_moniker = FrameworkAction.get_target_framework_moniker(
        framework)
    BENCHMARKS_CSPROJ.run(configuration, target_framework_moniker, verbose,
                          *run_args)
예제 #4
0
 def new(self, template: str, output_dir: str, bin_dir: str, exename: str,
         working_directory: str):
     'makes a new app with the given template'
     self.project = CSharpProject.new(template=template,
                                      output_dir=output_dir,
                                      bin_dir=bin_dir,
                                      exename=exename,
                                      working_directory=working_directory,
                                      force=True,
                                      verbose=True)
     return self
예제 #5
0
def run(BENCHMARKS_CSPROJ: dotnet.CSharpProject, configuration: str,
        framework: str, run_isolated: bool, verbose: bool, *args) -> None:
    '''Runs the benchmarks'''
    __log_script_header(
        "Running .NET micro benchmarks for '{}'".format(framework))

    # dotnet exec
    run_args = __get_benchmarkdotnet_arguments(framework, *args)
    target_framework_moniker = dotnet.FrameworkAction.get_target_framework_moniker(
        framework)

    if run_isolated:
        runDir = BENCHMARKS_CSPROJ.bin_path
        asm_path = dotnet.get_main_assembly_path(
            runDir, BENCHMARKS_CSPROJ.project_name)
        dotnet.exec(asm_path, verbose, *run_args)
    else:
        # This is needed for `dotnet run`, but not for `dotnet exec`
        run_args = ['--'] + run_args
        BENCHMARKS_CSPROJ.run(configuration, target_framework_moniker, verbose,
                              *run_args)
예제 #6
0
파일: sod.py 프로젝트: dotnet/performance
 def __init__(self):
     if helixpayload() and os.path.exists(os.path.join(helixpayload(), 'SOD')):
         self._setsodpath(os.path.join(helixpayload(), 'SOD'))
     elif helixworkitempayload() and os.path.exists(os.path.join(helixworkitempayload(), 'SOD')):
         self._setsodpath(os.path.join(helixworkitempayload(), 'SOD'))
     else:
         relpath = os.path.join(get_artifacts_directory(), 'SOD')
         sodproj = os.path.join('..',
                                    '..',
                                    'tools',
                                    'ScenarioMeasurement',
                                    'SizeOnDisk',
                                    'SizeOnDisk.csproj')
         sod = CSharpProject(CSharpProjFile(sodproj,
                                                sys.path[0]),
                                                os.path.join(os.path.dirname(sodproj),
                                 os.path.join(get_artifacts_directory(), 'SOD')))
         if not os.path.exists(relpath):
             sod.restore(get_packages_directory(),
                             True,
                             getruntimeidentifier())
             sod.publish('Release',
                             relpath,
                             True,
                             get_packages_directory(),
                             None,
                             getruntimeidentifier(),
                             None, 
                             '--no-restore'
                             )
         self._setsodpath(sod.bin_path)
예제 #7
0
 def __init__(self):
     startupdir = 'startup'
     self.reportjson = os.path.join(TRACEDIR, 'perf-lab-report.json')
     if helixpayload() and os.path.exists(os.path.join(helixpayload(), startupdir)):
         self._setstartuppath(os.path.join(helixpayload(), startupdir))
     elif helixworkitempayload() and os.path.exists(os.path.join(helixworkitempayload(), startupdir)):
         self._setstartuppath(os.path.join(helixworkitempayload(), startupdir))
     else:
         relpath = os.path.join(get_artifacts_directory(), startupdir)
         startupproj = os.path.join('..',
                                    '..',
                                    'tools',
                                    'ScenarioMeasurement',
                                    'Startup',
                                    'Startup.csproj')
         startup = CSharpProject(CSharpProjFile(startupproj,
                                                sys.path[0]),
                                                os.path.join(os.path.dirname(startupproj),
                                                os.path.join(get_artifacts_directory(), startupdir)))
         if not os.path.exists(relpath):
             startup.restore(get_packages_directory(),
                             True,
                             getruntimeidentifier())
             startup.publish('Release',
                             relpath,
                             True,
                             get_packages_directory(),
                             None,
                             getruntimeidentifier(),
                             None,
                             '--no-restore'
                             )
         self._setstartuppath(startup.bin_path)
예제 #8
0
def build(BENCHMARKS_CSPROJ: dotnet.CSharpProject, configuration: str,
          target_framework_monikers: list, incremental: str,
          run_isolated: bool, verbose: bool) -> None:
    '''Restores and builds the benchmarks'''

    packages = get_packages_directory()

    if incremental == 'no':
        __log_script_header("Removing packages, bin and obj folders.")
        binary_folders = [
            packages,
            path.join(BENCHMARKS_CSPROJ.bin_path),
        ]
        for binary_folder in binary_folders:
            remove_directory(path=binary_folder)

    # dotnet restore
    __log_script_header("Restoring .NET micro benchmarks")
    BENCHMARKS_CSPROJ.restore(packages_path=packages, verbose=verbose)

    # dotnet build
    build_title = "Building .NET micro benchmarks for '{}'".format(
        ' '.join(target_framework_monikers))
    __log_script_header(build_title)
    BENCHMARKS_CSPROJ.build(
        configuration=configuration,
        target_framework_monikers=target_framework_monikers,
        output_to_bindir=run_isolated,
        verbose=verbose,
        packages_path=packages)

    # When running isolated, artifacts/obj/{project_name} will still be
    # there, and would interfere with any subsequent builds. So, remove
    # that
    if run_isolated:
        objDir = path.join(get_artifacts_directory(), 'obj',
                           BENCHMARKS_CSPROJ.project_name)
        remove_directory(objDir)
예제 #9
0
 def new(self,
         template: str,
         output_dir: str,
         bin_dir: str,
         exename: str,
         working_directory: str,
         language: str = None):
     'makes a new app with the given template'
     self.project = CSharpProject.new(template=template,
                                      output_dir=output_dir,
                                      bin_dir=bin_dir,
                                      exename=exename,
                                      working_directory=working_directory,
                                      force=True,
                                      verbose=True,
                                      language=language)
     self._updateframework(self.project.csproj_file)
예제 #10
0
 def new(self,
         template: str,
         output_dir: str,
         bin_dir: str,
         exename: str,
         working_directory: str,
         language: str = None):
     'makes a new app with the given template'
     self.project = CSharpProject.new(
         template=template,
         output_dir=output_dir,
         bin_dir=bin_dir,
         exename=exename,
         working_directory=working_directory,
         force=True,
         verbose=True,
         target_framework_moniker=self.framework,
         language=language)
예제 #11
0
 def new(self,
         template: str,
         output_dir: str,
         bin_dir: str,
         exename: str,
         working_directory: str,
         language: str = None,
         no_https: bool = False):
     'makes a new app with the given template'
     self.project = CSharpProject.new(template=template,
                                      output_dir=output_dir,
                                      bin_dir=bin_dir,
                                      exename=exename,
                                      working_directory=working_directory,
                                      force=True,
                                      verbose=True,
                                      language=language,
                                      no_https=no_https)
     self._updateframework(self.project.csproj_file)
     self._addstaticmsbuildproperty(self.project.csproj_file)
예제 #12
0
 def __init__(self):
     payload = helixpayload()
     if payload:
         self._setstartuppath(os.path.join(payload, 'Startup'))
     else:
         startupproj = os.path.join('..', '..', 'tools',
                                    'ScenarioMeasurement', 'Startup',
                                    'Startup.csproj')
         startup = CSharpProject(
             CSharpProjFile(startupproj, sys.path[0]),
             os.path.join(
                 os.path.dirname(startupproj),
                 os.path.join(get_artifacts_directory(), 'startup')))
         startup.restore(get_packages_directory(), True)
         startup.build(configuration='Release',
                       verbose=True,
                       packages_path=get_packages_directory(),
                       output_to_bindir=True)
         self._setstartuppath(startup.bin_path)
예제 #13
0
    def __init__(self):
        payload = helixpayload()
        if payload:
            self._setstartuppath(os.path.join(payload, 'Startup'))
        else:
            startupproj = os.path.join('..', '..', 'tools',
                                       'ScenarioMeasurement', 'Startup',
                                       'Startup.csproj')
            startup = CSharpProject(
                CSharpProjFile(startupproj, sys.path[0]),
                os.path.join(
                    os.path.dirname(startupproj),
                    os.path.join(get_artifacts_directory(), 'startup')))

            startup.restore(get_packages_directory(), True,
                            getruntimeidentifier())
            startup.publish('Release',
                            os.path.join(get_artifacts_directory(), 'startup'),
                            True, get_packages_directory(), None,
                            getruntimeidentifier(), '--no-restore')
            self._setstartuppath(startup.bin_path)
예제 #14
0
 def __init__(self):
     payload_startup = os.path.join(helixpayload(), 'Startup')
     workitem_startup = os.path.join(helixworkitempayload(), 'Startup')
     if os.path.exists(payload_startup):
         self._setstartuppath(payload_startup)
     elif os.path.exists(workitem_startup):
         self._setstartuppath(workitem_startup)
     else:
         relpath = os.path.join(get_artifacts_directory(), 'startup')
         startupproj = os.path.join('..', '..', 'tools',
                                    'ScenarioMeasurement', 'Startup',
                                    'Startup.csproj')
         startup = CSharpProject(
             CSharpProjFile(startupproj, sys.path[0]),
             os.path.join(
                 os.path.dirname(startupproj),
                 os.path.join(get_artifacts_directory(), 'startup')))
         if not os.path.exists(relpath):
             startup.restore(get_packages_directory(), True,
                             getruntimeidentifier())
             startup.publish('Release', relpath, True,
                             get_packages_directory(), None,
                             getruntimeidentifier(), '--no-restore')
         self._setstartuppath(startup.bin_path)
예제 #15
0
class PreCommands:
    '''
    Handles building and publishing
    '''

    def __init__(self):
        self.project: CSharpProject
        self.projectfile: CSharpProjFile
        parser = ArgumentParser()

        subparsers = parser.add_subparsers(title='Operations', 
                                           description='Common preperation steps for perf tests.',
                                           dest='operation')

        default_parser = subparsers.add_parser(DEFAULT, help='Default operation' )
        self.add_common_arguments(default_parser)

        build_parser = subparsers.add_parser(BUILD, help='Builds the project')
        self.add_common_arguments(build_parser)

        publish_parser = subparsers.add_parser(PUBLISH, help='Publishes the project')
        self.add_common_arguments(publish_parser)

        args = parser.parse_args()

        if not args.operation:
            getLogger().error("Please specify an operation: %s" % list(OPERATIONS))
            sys.exit(1)

        self.configuration = args.configuration 
        self.operation = args.operation
        self.framework = args.framework
        self.runtime_identifier = args.runtime
        self.msbuild = args.msbuild
        self.msbuildstatic = args.msbuildstatic

    def new(self,
            template: str,
            output_dir: str,
            bin_dir: str,
            exename: str,
            working_directory: str,
            language: str = None):
        'makes a new app with the given template'
        self.project = CSharpProject.new(template=template,
                                 output_dir=output_dir,
                                 bin_dir=bin_dir,
                                 exename=exename,
                                 working_directory=working_directory,
                                 force=True,
                                 verbose=True,
                                 language=language)
        self._updateframework(self.project.csproj_file)
        self._addstaticmsbuildproperty(self.project.csproj_file)

    def add_common_arguments(self, parser: ArgumentParser):
        "Options that are common across many 'dotnet' commands"
        parser.add_argument('-c', '--configuration',
                            dest='configuration',
                            choices=[DEBUG, RELEASE],
                            metavar='config')
        parser.add_argument('-f', '--framework',
                            dest='framework',
                            metavar='framework')
        parser.add_argument('-r', '--runtime',
                            dest='runtime',
                            metavar='runtime')
        parser.add_argument('--msbuild',
                            help='Flags passed through to msbuild',
                            dest='msbuild',
                            metavar='/p:Foo=Bar;/p:Baz=Blee;...')
        parser.add_argument('--msbuild-static',
                            help='Properties added to csproj',
                            dest='msbuildstatic',
                            metavar='Foo=Bar;Bas=Blee;...'
                           )
        parser.set_defaults(configuration=RELEASE)

    def existing(self, projectdir: str, projectfile: str):
        'create a project from existing project file'
        self._backup(projectdir)
        csproj = CSharpProjFile(os.path.join(const.APPDIR, projectfile), sys.path[0])
        self.project = CSharpProject(csproj, const.BINDIR)
        self._updateframework(csproj.file_name)

    def execute(self):
        'Parses args and runs precommands'
        if self.operation == DEFAULT:
            pass
        if self.operation == BUILD:
            self._restore()
            self._build(configuration=self.configuration, framework=self.framework)
        if self.operation == PUBLISH:
            self._restore()
            self._publish(configuration=self.configuration,
                          runtime_identifier=self.runtime_identifier)

    def add_startup_logging(self, file: str, line: str):
        self.add_event_source(file, line, "PerfLabGenericEventSource.Log.Startup();")

    def add_event_source(self, file: str, line: str, trace_statement: str):
        '''
        Adds a copy of the event source to the project and inserts the correct call
        file: relative path to the root of the project (where the project file lives)
        line: Exact line to insert trace statement after
        trace_statement: Statement to insert
        '''

        projpath = os.path.dirname(self.project.csproj_file)
        staticpath = os.path.join(get_repo_root_path(), "src", "scenarios", "staticdeps")
        if helixpayload():
            staticpath = os.path.join(helixpayload(), "staticdeps")
        shutil.copyfile(os.path.join(staticpath, "PerfLab.cs"), os.path.join(projpath, "PerfLab.cs"))
        filepath = os.path.join(projpath, file)
        insert_after(filepath, line, trace_statement)

    def _addstaticmsbuildproperty(self, projectfile: str):
        if self.msbuildstatic:
          for propertyarg in self.msbuildstatic.split(';'):
            propertyname, propertyvalue = propertyarg.split('=')
            propertystring = f'\n  <PropertyGroup>\n    <{propertyname}>{propertyvalue}</{propertyname}>\n  </PropertyGroup>'
            insert_after(projectfile, r'</PropertyGroup>', propertystring )

    def _updateframework(self, projectfile: str):
        if self.framework:
            replace_line(projectfile, r'<TargetFramework>.*?</TargetFramework>', f'<TargetFramework>{self.framework}</TargetFramework>')

    def _publish(self, configuration: str, framework: str = None, runtime_identifier: str = None):
        self.project.publish(configuration=configuration,
                             output_dir=const.PUBDIR, 
                             verbose=True,
                             packages_path=os.path.join(get_packages_directory(), ''), # blazor publish targets require the trailing slash for joining the paths
                             target_framework_moniker=framework,
                             runtime_identifier=runtime_identifier
                             )

    def _restore(self):
        self.project.restore(packages_path=get_packages_directory(), verbose=True)

    def _build(self, configuration: str, framework: str = None):
        self.project.build(configuration=configuration,
                               verbose=True,
                               packages_path=get_packages_directory(),
                               target_framework_monikers=[framework],
                               output_to_bindir=True)

    def _backup(self, projectdir:str):
        # copy from projectdir to appdir
        if os.path.isdir(const.APPDIR):
            shutil.rmtree(const.APPDIR)
        shutil.copytree(projectdir, const.APPDIR)
예제 #16
0
class PreCommands:
    '''
    Handles building and publishing
    '''
    def __init__(self):
        self.project: CSharpProject
        self.projectfile: CSharpProjFile
        parser = ArgumentParser()
        subparsers = parser.add_subparsers(
            title='Operations',
            description='Common preperation steps for perf tests.',
            required=True,
            dest='operation')
        restore_parser = subparsers.add_parser(RESTORE,
                                               help='Restores the project')

        build_parser = subparsers.add_parser(BUILD, help='Builds the project')
        self.add_common_arguments(build_parser)

        publish_parser = subparsers.add_parser(PUBLISH,
                                               help='Publishes the project')
        self.add_common_arguments(publish_parser)

        args = parser.parse_args()
        self.configuration = args.configuration
        self.operation = args.operation

    def new(self, template: str, output_dir: str, bin_dir: str, exename: str,
            working_directory: str):
        'makes a new app with the given template'
        self.project = CSharpProject.new(template=template,
                                         output_dir=output_dir,
                                         bin_dir=bin_dir,
                                         exename=exename,
                                         working_directory=working_directory,
                                         force=True,
                                         verbose=True)
        return self

    def add_common_arguments(self, parser: ArgumentParser):
        "Options that are common across many 'dotnet' commands"
        parser.add_argument('-c',
                            '--configuration',
                            dest='configuration',
                            choices=[DEBUG, RELEASE],
                            metavar='config')
        parser.add_argument('-f',
                            '--framework',
                            dest='framework',
                            metavar='framework')
        parser.add_argument('-r',
                            '--runtime',
                            dest='runtime',
                            metavar='runtime')
        parser.add_argument('--msbuild',
                            help='Flags passed through to msbuild',
                            dest='msbuild',
                            metavar='/p:Foo=Bar;/p:Baz=Blee;...')
        parser.set_defaults(configuration=RELEASE)

    def existing(self, projectfile: str):
        'create a project from existing project file'
        csproj = CSharpProjFile(projectfile, sys.path[0])
        self.project = CSharpProject(csproj, const.BINDIR)
        return self

    def execute(self):
        'Parses args and runs precommands'
        if self.operation == BUILD:
            self._restore()
            self._build(self.configuration)
        if self.operation == RESTORE:
            self._restore()
        if self.operation == PUBLISH:
            self._restore()
            self._publish(self.configuration)

    def _publish(self, configuration: str):
        self.project.publish(configuration=configuration,
                             output_dir=const.PUBDIR,
                             verbose=True,
                             packages_path=get_packages_directory())

    def _restore(self):
        self.project.restore(packages_path=get_packages_directory(),
                             verbose=True)

    def _build(self, configuration: str):
        self.project.build(configuration=configuration,
                           verbose=True,
                           packages_path=get_packages_directory(),
                           target_framework_monikers=None,
                           output_to_bindir=True)
예제 #17
0
 def existing(self, projectfile: str):
     'create a project from existing project file'
     csproj = CSharpProjFile(projectfile, sys.path[0])
     self.project = CSharpProject(csproj, const.BINDIR)
     return self
예제 #18
0
class PreCommands:
    '''
    Handles building and publishing
    '''
    def __init__(self):
        self.project: CSharpProject
        self.projectfile: CSharpProjFile
        self.crossgen_arguments = CrossgenArguments()
        parser = ArgumentParser()

        subparsers = parser.add_subparsers(
            title='Operations',
            description=
            'Common preperation steps for perf tests. Should run under src\scenarios\<test asset folder>',
            dest='operation')

        default_parser = subparsers.add_parser(
            DEFAULT,
            help=
            'Default operation (placeholder command and no specific operation will be executed)'
        )
        self.add_common_arguments(default_parser)

        build_parser = subparsers.add_parser(BUILD, help='Builds the project')
        self.add_common_arguments(build_parser)

        publish_parser = subparsers.add_parser(PUBLISH,
                                               help='Publishes the project')
        self.add_common_arguments(publish_parser)

        crossgen_parser = subparsers.add_parser(
            CROSSGEN, help='Runs crossgen on a particular file')
        self.add_common_arguments(crossgen_parser)
        self.crossgen_arguments.add_crossgen_arguments(crossgen_parser)

        crossgen2_parser = subparsers.add_parser(
            CROSSGEN2, help='Runs crossgen2 on a particular file')
        self.add_common_arguments(crossgen2_parser)
        self.crossgen_arguments.add_crossgen2_arguments(crossgen2_parser)

        args = parser.parse_args()

        if not args.operation:
            getLogger().error("Please specify an operation: %s" %
                              list(OPERATIONS))
            sys.exit(1)

        self.configuration = args.configuration
        self.operation = args.operation
        self.framework = args.framework
        self.runtime_identifier = args.runtime
        self.msbuild = args.msbuild
        self.msbuildstatic = args.msbuildstatic
        self.binlog = args.binlog

        if self.operation == CROSSGEN:
            self.crossgen_arguments.parse_crossgen_args(args)
        if self.operation == CROSSGEN2:
            self.crossgen_arguments.parse_crossgen2_args(args)

    def new(self,
            template: str,
            output_dir: str,
            bin_dir: str,
            exename: str,
            working_directory: str,
            language: str = None):
        'makes a new app with the given template'
        self.project = CSharpProject.new(template=template,
                                         output_dir=output_dir,
                                         bin_dir=bin_dir,
                                         exename=exename,
                                         working_directory=working_directory,
                                         force=True,
                                         verbose=True,
                                         language=language)
        self._updateframework(self.project.csproj_file)
        self._addstaticmsbuildproperty(self.project.csproj_file)

    def add_common_arguments(self, parser: ArgumentParser):
        "Options that are common across many 'dotnet' commands"
        parser.add_argument(
            '-c',
            '--configuration',
            dest='configuration',
            choices=[DEBUG, RELEASE],
            metavar='config',
            help='configuration for build or publish - ex: Release or Debug')
        parser.add_argument(
            '-f',
            '--framework',
            dest='framework',
            metavar='framework',
            help='framework for build or publish - ex: netcoreapp3.0')
        parser.add_argument('-r',
                            '--runtime',
                            dest='runtime',
                            metavar='runtime',
                            help='runtime for build or publish - ex: win-x64')
        parser.add_argument(
            '--msbuild',
            dest='msbuild',
            metavar='msbuild',
            help=
            'a list of msbuild flags passed to build or publish command separated by semicolons - ex: /p:Foo=Bar;/p:Baz=Blee;...'
        )
        parser.add_argument(
            '--msbuild-static',
            dest='msbuildstatic',
            metavar='msbuildstatic',
            help=
            'a list of msbuild properties inserted into .csproj file of the project - ex: Foo=Bar;Bas=Blee;'
        )
        parser.add_argument(
            '--binlog',
            dest='binlog',
            metavar='<file-name>.binlog',
            help=
            'flag to turn on binlog for build or publish; ex: <file-name>.binlog'
        )
        parser.set_defaults(configuration=RELEASE)

    def existing(self, projectdir: str, projectfile: str):
        'create a project from existing project file'
        self._backup(projectdir)
        csproj = CSharpProjFile(os.path.join(const.APPDIR, projectfile),
                                sys.path[0])
        self.project = CSharpProject(csproj, const.BINDIR)
        self._updateframework(csproj.file_name)

    def execute(self):
        'Parses args and runs precommands'
        if self.operation == DEFAULT:
            pass
        if self.operation == BUILD:
            self._restore()
            self._build(configuration=self.configuration,
                        framework=self.framework)
        if self.operation == PUBLISH:
            self._restore()
            self._publish(configuration=self.configuration,
                          runtime_identifier=self.runtime_identifier)
        if self.operation == CROSSGEN:
            startup_args = [
                os.path.join(self.crossgen_arguments.coreroot,
                             'crossgen%s' % extension()),
            ]
            startup_args += self.crossgen_arguments.get_crossgen_command_line()
            RunCommand(startup_args,
                       verbose=True).run(self.crossgen_arguments.coreroot)
        if self.operation == CROSSGEN2:
            startup_args = [
                os.path.join(self.crossgen_arguments.coreroot,
                             'corerun%s' % extension()),
                os.path.join(self.crossgen_arguments.coreroot, 'crossgen2',
                             'crossgen2.dll'),
            ]
            startup_args += self.crossgen_arguments.get_crossgen2_command_line(
            )
            RunCommand(startup_args,
                       verbose=True).run(self.crossgen_arguments.coreroot)

    def add_startup_logging(self, file: str, line: str):
        self.add_event_source(file, line,
                              "PerfLabGenericEventSource.Log.Startup();")

    def add_event_source(self, file: str, line: str, trace_statement: str):
        '''
        Adds a copy of the event source to the project and inserts the correct call
        file: relative path to the root of the project (where the project file lives)
        line: Exact line to insert trace statement after
        trace_statement: Statement to insert
        '''

        projpath = os.path.dirname(self.project.csproj_file)
        staticpath = os.path.join(get_repo_root_path(), "src", "scenarios",
                                  "staticdeps")
        if helixpayload():
            staticpath = os.path.join(helixpayload(), "staticdeps")
        shutil.copyfile(os.path.join(staticpath, "PerfLab.cs"),
                        os.path.join(projpath, "PerfLab.cs"))
        filepath = os.path.join(projpath, file)
        insert_after(filepath, line, trace_statement)

    def _addstaticmsbuildproperty(self, projectfile: str):
        'Insert static msbuild property in the specified project file'
        if self.msbuildstatic:
            for propertyarg in self.msbuildstatic.split(';'):
                propertyname, propertyvalue = propertyarg.split('=')
                propertystring = f'\n  <PropertyGroup>\n    <{propertyname}>{propertyvalue}</{propertyname}>\n  </PropertyGroup>'
                insert_after(projectfile, r'</PropertyGroup>', propertystring)

    def _updateframework(self, projectfile: str):
        'Update the <TargetFramework> property so we can re-use the template'
        if self.framework:
            replace_line(
                projectfile, r'<TargetFramework>.*?</TargetFramework>',
                f'<TargetFramework>{self.framework}</TargetFramework>')

    def _publish(self,
                 configuration: str,
                 framework: str = None,
                 runtime_identifier: str = None):
        self.project.publish(
            configuration,
            const.PUBDIR,
            True,
            os.path.join(
                get_packages_directory(), ''
            ),  # blazor publish targets require the trailing slash for joining the paths
            framework,
            runtime_identifier,
            self.msbuild or "",
            '-bl:%s' % self.binlog if self.binlog else "")

    def _restore(self):
        self.project.restore(packages_path=get_packages_directory(),
                             verbose=True)

    def _build(self, configuration: str, framework: str = None):
        self.project.build(configuration=configuration,
                           verbose=True,
                           packages_path=get_packages_directory(),
                           target_framework_monikers=[framework],
                           output_to_bindir=True)

    def _backup(self, projectdir: str):
        'Copy from projectdir to appdir so we do not modify the source code'
        if os.path.isdir(const.APPDIR):
            shutil.rmtree(const.APPDIR)
        shutil.copytree(projectdir, const.APPDIR)