Sharpmake icon indicating copy to clipboard operation
Sharpmake copied to clipboard

Exception when processing command line

Open Teknogrebo opened this issue 5 years ago • 5 comments

I have been trying to add a command line option to my script parsing using the example set out in the documentation, but when I call ExecuteOnObject the script throws an exception. The details are below:

Object reference not set to an instance of an object.
        While running c:\dev\kestrel\demo\tools\sharpmake\0.8.0\bin\release\Sharpmake.Application.exe
        @15/05/2019 10:17:15: Exception message (level 0):
        Unhandled exception in thread pool
        Inner exception message (level 1):
        Cannot create instances of type: DemoProject, make sure it's public
        Inner exception message (level 2):
        Exception has been thrown by the target of an invocation.
        Inner exception message (level 3):
        Object reference not set to an instance of an object.

        Stack trace:
        Inner exception stack trace (level 3):
   at Sharpmake.Assembler.Build(IBuilderContext builderContext, String libraryFile, String[] sources) in C:\dev\Sharpmake-master\Sharpmake\Assembler.cs:line 439
   at Sharpmake.Assembler.BuildDelegate[TDelegate](String functionBody, String functionNamespace, String[] usingNamespaces, Assembly[] assemblies) in C:\dev\Sharpmake-master\Sharpmake\Assembler.cs:line 223
   at Sharpmake.CommandLine.Execute(Type type, Object instance, String commandLine, String[] namespaces) in C:\dev\Sharpmake-master\Sharpmake\CommandLine.cs:line 235
   at Sharpmake.CommandLine.ExecuteOnObject(Object obj, String commandLine) in C:\dev\Sharpmake-master\Sharpmake\CommandLine.cs:line 53
   at BaseProject..ctor(String name) in c:\dev\scripts\BaseProject.sharpmake.cs:line 32
   at DemoProject..ctor() in c:\dev\scripts\demo.sharpmake.cs:line 14
        Inner exception stack trace (level 2):
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.Activator.CreateInstance(Type type)
   at Sharpmake.Project.CreateProject(Type projectType, List`1 fragmentMasks) in C:\dev\Sharpmake-master\Sharpmake\Project.cs:line 1371
        Inner exception stack trace (level 1):
   at Sharpmake.Project.CreateProject(Type projectType, List`1 fragmentMasks) in C:\dev\Sharpmake-master\Sharpmake\Project.cs:line 1378
   at Sharpmake.Builder.LoadProjectType(Type type) in C:\dev\Sharpmake-master\Sharpmake\Builder.cs:line 470
   at Sharpmake.Builder.BuildProjectAndSolutionTask(Object parameter) in C:\dev\Sharpmake-master\Sharpmake\Builder.cs:line 304
   at Sharpmake.ThreadPool.ThreadWork(Object obj) in C:\dev\Sharpmake-master\Sharpmake\ThreadPool.cs:line 208
        Root stack trace (level 0):
   at Sharpmake.ThreadPool.Wait() in C:\dev\Sharpmake-master\Sharpmake\ThreadPool.cs:line 174
   at Sharpmake.Builder.BuildProjectAndSolution() in C:\dev\Sharpmake-master\Sharpmake\Builder.cs:line 292
   at Sharpmake.Application.Program.CreateBuilder(BaseBuildContext context, Argument parameters, Boolean allowCleanBlobs, Boolean generateDebugSolution) in C:\dev\Sharpmake-master\Sharpmake.Application\Program.cs:line 585
   at Sharpmake.Application.Program.CreateBuilderAndGenerate(BaseBuildContext buildContext, Argument parameters, Boolean generateDebugSolution) in C:\dev\Sharpmake-master\Sharpmake.Application\Program.cs:line 382
   at Sharpmake.Application.Program.Main() in C:\dev\Sharpmake-master\Sharpmake.Application\Program.cs:line 292

The object I pass in isn't null, so I'm not exactly sure what isn't initialised here

Teknogrebo avatar May 15 '19 09:05 Teknogrebo

Could you check that your project DemoProject has a public constructor ? It is mandatory to have one, even if empty (not sure why...).

belkiss avatar May 15 '19 10:05 belkiss

DemoProject is a public class and has a public constructor. It actually derives from a public BaseProject() class that has public constructor taking a single parameter. Would that make a difference?

Teknogrebo avatar May 15 '19 10:05 Teknogrebo

Hum it shouldn't. Here's a quick example base on the HelloWorld:

using Sharpmake;

namespace HelloWorld
{
    public class CmdLineArguments
    {
        public int DefaultVersion = 5;

        [CommandLine.Option("randomArg", "")]
        public void DisableDebugInfoFct()
        {
            DefaultVersion = 10;
        }
    }


    public class BaseProject : Project
    {
        protected int Version = 0;
        public BaseProject(int version)
        {
            Version = version;
        }
    }


    [Sharpmake.Generate]
    public class HelloWorldProject : BaseProject
    {
        public HelloWorldProject()
            : base(Main.Arguments.DefaultVersion)
        {
            Name = "HelloWorld";

            AddTargets(new Target(
                    Platform.win32 | Platform.win64,
                    DevEnv.vs2017,
                    Optimization.Debug // | Optimization.Release
            ));

            SourceRootPath = @"[project.SharpmakeCsPath]\codebase";
        }

        [Configure()]
        public void ConfigureAll(Configuration conf, Target target)
        {
            conf.ProjectFileName = "[project.Name]_[target.DevEnv]_[target.Platform]_" + Version;
            conf.ProjectPath = @"[project.SharpmakeCsPath]\projects";

            // if not set, no precompile option will be used.
            conf.PrecompHeader = "stdafx.h";
            conf.PrecompSource = "stdafx.cpp";
        }
    }

    [Sharpmake.Generate]
    public class HelloWorldSolution : Sharpmake.Solution
    {
        public HelloWorldSolution()
        {
            Name = "HelloWorld";

            AddTargets(new Target(
                    Platform.win32 | Platform.win64,
                    DevEnv.vs2017,
                    Optimization.Debug // | Optimization.Release
            ));
        }

        [Configure()]
        public void ConfigureAll(Configuration conf, Target target)
        {
            conf.SolutionFileName = "[solution.Name]_[target.DevEnv]_[target.Platform]";
            conf.SolutionPath = @"[solution.SharpmakeCsPath]\projects";
            conf.AddProject<HelloWorldProject>(target);
        }
    }

    public static class Main
    {
        public static CmdLineArguments Arguments = new CmdLineArguments();

        [Sharpmake.Main]
        public static void SharpmakeMain(Sharpmake.Arguments arguments)
        {
            CommandLine.ExecuteOnObject(Arguments);
            arguments.Generate<HelloWorldSolution>();
        }
    }
}

belkiss avatar May 15 '19 10:05 belkiss

Yeah. I appreciate that it shouldn't. I'm not sure now what I was doing that was any different from your example. I've found a hacky way around it now by parsing the command line myself using Environment.GetCommandLineArgs() which isn't ideal, but I needed to make some progress

Teknogrebo avatar May 17 '19 10:05 Teknogrebo

Could you post your sharpmake files?

belkiss avatar May 17 '19 12:05 belkiss