ubisoft / Sharpmake

Sharpmake is an open-source C#-based solution for generating project definition files, such as Visual Studio projects and solutions, GNU makefiles, Xcode projects, etc.
Apache License 2.0
922 stars 168 forks source link

Platform and Optimization extensibility #308

Closed cmello closed 9 months ago

cmello commented 9 months ago

Hi,

I'm currently working on a project where I need to add more platforms and optimizations. However, I'd like to do this without requiring code changes to Sharpmake.Platform and Sharpmake.Optimization.

Please do you have any suggestions or best practices for achieving this? Any advice would be greatly appreciated.

Thank you!

Best regards, Cesar

jspelletier commented 9 months ago

Hi, Which platforms do you want to add? If this is for consoles support, you will need to get platforms code from their respective console makers forums.

As for optimization for your project, what you need to do is define an optimization fragment

namespace MyEngine
{
    [Fragment, Flags]
    public enum Optimization
    {
        Debug = 0x01,
        SuperAwesomeDebug = 0x02,
        Release = 0x04,
        Profile = 0x08,
        QCFinal = 0x10,
        Final = 0x20
    }
    public class Target : ITarget
    {
            public Platform Platform;
            public Optimization Optimization;
            public BuildSystem BuildSystem;
            public DevEnv DevEnv;
            // Plus any other fragments/properties            
    }

}

And then you use your Target type in your projects. See this: https://github.com/ubisoft/Sharpmake/wiki/Custom-Targets

cmello commented 9 months ago

Thank you very much for the prompt response and the suggestion to define our own optimization fragment and reference it from a custom target.

Is it possible to do something similar to extend Sharpmake.Platform? I'm afraid it is not possible because the 'Sharpmake.Platform' type is referenced by Sharpmake.Configuration.

The platform I would like to add is XBox Series X. But I would be more interested in being able to add more platforms in general without requiring code changes in the Sharpmake codebase. Either through some plugin DLL or other form of extension that could be included outside the Sharpmake codebase. Is that currently possible?

Thanks a lot for your kind attention!

Best regards, Cesar

jspelletier commented 9 months ago

If you want to add XBox, I guess you got the sharpmake code for the XBox platform from the forums? Each non public platform use a _reservedXX value from Platform enum. Public platforms use the real value defined in that enum.

I am curious about what platform you want to add.

cmello commented 9 months ago

Interesting, thanks again for the prompt response!

But then let's say, if I wanted to keep adding support for new reserved platforms, should I manually copy and paste each one from the forums and merge into my own custom version of Sharpmake\Target.cs? If that's the case, I wonder if we could help implement an extensibility approach that is more pluggable? Maybe some helpers to provide a custom enum from outside the Sharpmake codebase?

Thanks!

Best regards, Cesar

jspelletier commented 9 months ago

If you need some platform support, you should get those platform code modules from the forums and include them into your SharpmakeExtended solution.

There is some doc regarding platforms here: https://github.com/ubisoft/Sharpmake/blob/main/docs/Platforms.md

There is some doc regarding how to setup a SharpmakeExtended solution here: https://github.com/ubisoft/Sharpmake/blob/main/README.md

I will paste some code here to show you how to integrate those platforms in your code but will obfuscate the platform name as the platform owners don't let us put their platform in Sharpmake public code.

We have a platform class for all consoles(XBox, PSX, switch). This is annoying but each of those platform code is only available in forums. This is not our choices. Ideally all platforms support would be in github. Sharpmake is after all only a glorified xml/json generator.

Here are some example on how we are using some of those platforms. I just renamed the real platform name. Apart from the name change, this is pasted from our actual production code.

Here is some code for a platform called "SomeAnonymous". Each non public platform defines a SharpPlatform constant borrowing one of the reserved values(each using a unique value).

    public static partial class SomeAnonymousPlatform
    {
        public const Platform SharpmakePlatform = Platform._reserved7;
....
    }

Then in our code we are doing things like

public static Target[] GetEngineTargets()
{
      var result = new List<Target>();
      result.Add(new Target(
                        SomeAnonymousPlatform.SharpmakePlatform,
                        GetDefaultDevEnv(),
                        GetDefaultEngineOptimization(),
                        OutputType.Lib,
                        Blob.Blob,
                        Mode.Engine,
                        BuildSystem.FastBuild));
      return result;
}                        

We can use in in Configure methods in Configure attribute also do in our projects:

class SomeProject : CommonProject
{
     [Configure(SomeAnonymousPlatform.SharpmakePlatform)]
     public void ConfigureAnonymousPlatform(Configuration conf, Target target)
     {
     //....
     }
}

I hope this clears everything out.

cmello commented 9 months ago

Yes, those resources solve my needs completely. Thank you very much for your extensive help and congrats for the great work!

Best regards, Cesar