Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it easier to build a working mono-enabled Godot from scons #76542

Closed

Conversation

shana
Copy link
Contributor

@shana shana commented Apr 28, 2023

Building a mono-enabled Godot from source currently requires a bunch of manual steps , including having a separate Godot installation available to bootstrap the build. The current multi-step bootstrap+build process makes it harder for new users to do their own builds. It would be nice to be able to just do scons target=editor module_mono_enabled=yes and end up with a fully working Godot+Mono build, without extra steps.

This PR adds generate_mono_glue and build_assemblies options to scons.

Having these as part of the build means that building a mono-enabled godot will create all the necessary bits to run it without having to do extra manual steps. It also means that changes to the native code that might change scripting API will automatically trigger regenerating the C# glue bindings and a rebuild of the assemblies, as part of the normal build process. The build_assemblies.py can still be run manually from the command line as before.

Notes

The one thing this PR doesn't do is pass in the --push-nupkgs-local flag to build_assemblies, because that assumes that a dotnet nuget source has already been configured. Which teeeechnically means that game projects will not be fully buildable and users still need to do extra steps for a fully working installation.

In this scenario, my personal preference would be for the build to also configure a nuget source pointing to the #bin/GodotSharp/Tools/nupkgs build output folder, so the packages get consumed directly from the build and not pushed to somewhere else. Users can then optionally push their nupkgs if they want to distribute them/once they're happy with them, but by default they don't have to do anything, and all binaries and packages are consumed from the bin folder directly. Thoughts?

@shana shana requested a review from a team as a code owner April 28, 2023 12:17
@akien-mga akien-mga added this to the 4.x milestone Apr 28, 2023
@shana shana force-pushed the shana/csharp-build-improvements branch 2 times, most recently from e12084a to b451d29 Compare April 28, 2023 13:48
@shana shana force-pushed the shana/csharp-build-improvements branch from b451d29 to 5588cd0 Compare April 28, 2023 15:00
Copy link
Member

@RedworkDE RedworkDE left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

including having a separate Godot installation available to bootstrap the build

Not sure where this comes from. scons build -> gen glue -> build assemblies, should work just fine (except that during the first time build you have to close a message box #75152)

but by default they don't have to do anything, and all binaries and packages are consumed from the bin folder directly. Thoughts?

Passing the --push-nupkgs-local also causes the nuget cache to be cleared of the relevant package version to avoid some caching issues, this should be activated anyways if the new standard build process no longer uses that option.


IMO simplifying the build like this is a good idea, esp if this caches the generated glue and packages.

Did not actually test running this yet; will need updated documentation.

modules/mono/editor/bindings_generator.cpp Outdated Show resolved Hide resolved
modules/mono/mono_gd/gd_mono.cpp Outdated Show resolved Hide resolved
modules/mono/mono_gd/gd_mono.cpp Outdated Show resolved Hide resolved
modules/mono/build_scripts/build_assemblies.py Outdated Show resolved Hide resolved
@neikeq neikeq self-requested a review April 29, 2023 16:46
@shana
Copy link
Contributor Author

shana commented May 1, 2023

including having a separate Godot installation available to bootstrap the build

Not sure where this comes from. scons build -> gen glue -> build assemblies, should work just fine (except that during the first time build you have to close a message box #75152)

The steps work fine, yes, but they have to be run one by one manually in order to get a complete build. I've also had issues with the exceptions that are thrown on the first run, with godot aborting instead of displaying the popup mentioned on #75152, so I've had to download a usable godot in order to bootstrap the process (Edit: this happens on macos ARM, where it crashes instead of just complaining about the missing runtime)

Since these steps are required in order to have a working build, having to lookup/remember a bunch of different command line things is an extra burden that makes things unnecessarily complex for users. If they were optional steps, having them as separate manual steps would make sense, but they're not optional, so incorporating them into the general scons build system makes more sense to me - hence this PR.

As someone that does a lot of godot+mono local builds and keeps having to go lookup random commands in the docs (because my memory for these things is bleh), this PR is scratching a personal itch 😆
This also helps me not forget to run things in the proper order, because I don't have to remember - scons knows what files depend on what, so it knows to run the generate and assembly building in the proper order, and only when it's needed.

but by default they don't have to do anything, and all binaries and packages are consumed from the bin folder directly. Thoughts?

Passing the --push-nupkgs-local also causes the nuget cache to be cleared of the relevant package version to avoid some caching issues, this should be activated anyways if the new standard build process no longer uses that option.

Ah, good point, yes, the clearing needs to be done even when consuming from the bin/ dir, I'll fix that.

IMO simplifying the build like this is a good idea, esp if this caches the generated glue and packages.

Did not actually test running this yet; will need updated documentation.

I'll get a PR going for the docs repo.

@shana shana force-pushed the shana/csharp-build-improvements branch 2 times, most recently from a6f8f4f to efa3558 Compare May 1, 2023 23:14
@shana shana requested a review from a team as a code owner May 1, 2023 23:14
@shana shana requested a review from RedworkDE May 1, 2023 23:19
@shana
Copy link
Contributor Author

shana commented May 2, 2023

Draft PR with updated docs based on these changes is at godotengine/godot-docs#7265
Should I mark that PR as ready for review now, or only once this one is merge?

On this one, I've done a bit more rearranging of the build_assemblies.py script to set the relevant build parameters according to what the build environment has, make sure the NuGet cache is cleaned up, and set up/update the NuGet source for the local build. I cleaned up a bunch of duped code in the process.

shana added a commit to shana/godot-docs that referenced this pull request May 2, 2023
shana added a commit to shana/godot-docs that referenced this pull request May 2, 2023
Copy link
Member

@RedworkDE RedworkDE left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This still includes the changes from Skip initializing the C# runtime when generating glue bindings #76659 please removed them from this PR. (You can include the other PR as a separate commit if the changes are required, but as far I can tell this PR should work just fine without them)
  2. Nit: The rebase based workflow godot uses doesn't really like mentioning issues or PRs in the commit message as that ends up spamming the issue with useless links to various commits.
  3. Looks ok otherwise, but I didn't test the current version so far.

@shana shana force-pushed the shana/csharp-build-improvements branch from efa3558 to d86b1dd Compare May 2, 2023 19:56
@shana
Copy link
Contributor Author

shana commented May 2, 2023

  1. This still includes the changes from Skip initializing the C# runtime when generating glue bindings #76659 please removed them from this PR. (You can include the other PR as a separate commit if the changes are required, but as far I can tell this PR should work just fine without them)

Ooops, I'm sorry, I was testing both locally and must have added the native changes by mistake. This PR doesn't need the other one, it was just me doing things really late at night 🙈

2. Nit: The rebase based workflow godot uses doesn't really like mentioning issues or PRs in the commit message as that ends up spamming the issue with useless links to various commits.

Ah, yes, good point. I'll avoid those in the future 👍

@neikeq
Copy link
Contributor

neikeq commented May 3, 2023

Is this intended for one-time builds rather than for development? Because that's the only scenario I would find this helpful. During development, you're going to want to use 3 separate commands for building the engine, generating the glue and building the assemblies. Otherwise, each step would be much slower than necessary, specially if you're iterating a lot.

I'm not sure the extra build logic is worth it for a single use-case, but if enough people want it.

Some comments on the current implementation:

  1. It's missing push-nupkgs-local which is essential if you want Godot to use the assemblies you're building.
  2. The options should be opt-in. The C# module will be enabled by default at some point in the future, so this would be an annoyance for non-C# users who don't want to build C# code and may not even have .NET installed.
  3. You can simplify this by replacing generate_mono_glue and build_assemblies with a single build_csharp option. I don't see anyone wanting to use these two separately with SCons, as this is meant for one-time builds, right?

@shana
Copy link
Contributor Author

shana commented May 3, 2023

Is this intended for one-time builds rather than for development? Because that's the only scenario I would find this helpful. During development, you're going to want to use 3 separate commands for building the engine, generating the glue and building the assemblies. Otherwise, each step would be much slower than necessary, specially if you're iterating a lot.

This isn't meant for one-time builds - any time a user updates their local clone of Godot, these steps might need to run again; any time they change the precision, they'll need to run again. There's a lot of times when these steps need to run, even for users not doing anything special, and it's very easy to forget to run those steps.

scons knows how to track changed files and build dependencies, so it only runs the steps if it needs to, there's no extra overhead with having the build system handle these extra build commands. In the majority of cases, it will only run these steps once, and never again, unless you do meaningful changes to either the generated source or to the built artifacts.

I'm not sure the extra build logic is worth it for a single use-case, but if enough people want it.

Some comments on the current implementation:

1. It's missing `push-nupkgs-local` which is essential if you want Godot to use the assemblies you're building.

I updated the PR description to note that this no longer needs to push nuget packages. Instead, it's configuring a nuget source pointing to the location of the nupkgs in the bin/ folder, so they're always up to date and we skip a copy step entirely, also removing the need for manually configuring a nuget source. It does clear the nuget cache whenever it rebuilds the nuget packages.

2. The options should be opt-in. The C# module will be enabled by default at some point in the future, so this would be an annoyance for non-C# users who don't want to build C# code and may not even have .NET installed.

If the C# module is enabled but these options aren't, the build will not be functional. I don't think that's a good default UX for normal users.

If and when the C# module becomes enabled by default, you/we/someone should probably consider providing users with some sort of pre-configured build profiles, or change the default flags, or something, so that they can make builds out of the box with their preferred language, instead of breaking the C# build by default unless they run additional magic commands. Should also make sure that the C# module is only enabled if the user has the right prerequisites, for example. There's probably a bit of user experience work that should be done as a part of enabling the C# module by default, to make sure that it's not a broken experience out of the box.

Given that the C# module is not enabled by default right now, if a user enables it, it's because they want to use it, so they should have a working build in the end, as smoothly as possible. These options are required for that.

3. You can simplify this by replacing `generate_mono_glue` and `build_assemblies` with a single `build_csharp` option. I don't see anyone wanting to use these two separately with SCons, as this is meant for one-time builds, right?

We can have one build_csharp option to make it easy to disable both of these steps at once - that could be a nice shortcut, in an edge case where you don't want scons to make decisions about whether to run the steps or not, or you want to do it all manually and don't want to pass in both flags. The steps still need to be separate targets, because scons tracks them differently and their sources are different, so having both flags available to control them separately is still important.

@shana
Copy link
Contributor Author

shana commented May 18, 2023

@neikeq @RedworkDE I was busy moving countries so I couldn't get back to this before now. I've turned the glue generation and assembly build off by default when mono is enabled, and added a build_csharp flag to enable both of the steps on the command line. I'll update the docs PR with the new flags.

@shana shana requested a review from RedworkDE May 22, 2023 15:24
@shana
Copy link
Contributor Author

shana commented May 31, 2023

Any updates on this?

Copy link
Member

@RedworkDE RedworkDE left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the CI doesn't like the formatting, not an expert for Python or SCons tho, so I can't really comment on the code.

In general neikeq and raulsntos (the dotnet maintainers) currently have no to very limited time to work on godot so C# development is basically paused right now, except for small bug fixes (and even then I have several such PRs that are waiting on reviews for months)

I am not sure how effective this currently is at avoiding unnecessary rebuilds of the dotnet part, tho I don't think it is impossible to make it better than knowing when the glue needs to be rebuilt and (un-) commenting to relevant bits in my build script.

modules/mono/build_scripts/build_assemblies.py Outdated Show resolved Hide resolved
@akien-mga akien-mga self-requested a review May 31, 2023 22:44
@shana
Copy link
Contributor Author

shana commented Jun 1, 2023

In general neikeq and raulsntos (the dotnet maintainers) currently have no to very limited time to work on godot so C# development is basically paused right now, except for small bug fixes (and even then I have several such PRs that are waiting on reviews for months)

Ah, that is important information, I had no idea, thank you.

@akien-mga
Copy link
Member

akien-mga commented Jun 9, 2023

I fully support the idea to make it easier to build C# support out of the box 👍
I haven't reviewed the buildsystem changes in depth yet, but overall the changes seem sensible. I'll review more in depth once we reach a consensus on what the default behavior should be.

I gave this PR a try locally on Linux, it works well. To be clear in the current iteration it requires passing scons module_mono_enabled=yes build_csharp=yes, following discussions above asking to make this opt-in.

Regarding @neikeq's concerns on making this enabled by default, I'd like to clarify the use cases we need to cover:

  • Godot users do occasional custom builds of Godot with C# support, e.g. to add a C++ module or some custom patches in their fork. Those would benefit from everything being enabled out of the box as they do builds rarely.
  • Godot users who are tracking a development branch and compiling it daily, or even several times per day. Those would also still benefit from C# support being enabled out of the box if they enable the mono module.
  • Engine contributors who work on the codebase and compile it multiple times per day (for some dozens of time if iterating quickly on some changes), and for the most part not working directly on updating C# bindings.

This last use case is what @neikeq is concerned about I believe, and as of the current state of this PR, building with scons module_mono_enabled=yes build_csharp=yes does seem to imply generating the mono glue for each incremental build, even if it doesn't need to change. @shana mentioned:

scons knows how to track changed files and build dependencies, so it only runs the steps if it needs to, there's no extra overhead with having the build system handle these extra build commands. In the majority of cases, it will only run these steps once, and never again, unless you do meaningful changes to either the generated source or to the built artifacts.

But for the mono glue generation, this doesn't seem to work full as I would expect it currently.

Here's an example:

  • I build Godot from scratch with scons module_mono_enabled=yes build_csharp=yes, everything is properly generated and the resulting binaries work well 👍
  • I make a change in code that doesn't impact the Mono glue and bindings, e.g. adding a comment to main/main.cpp. When building with scons module_mono_enabled=yes build_csharp=yes again, building main.o and relinking the Godot binary is fast, but then the mono glue generation step still runs.

This means that my incremental build takes 18s instead of the 13s it takes for the same code change without the Mono module. (Generating the Mono glue seems to take ~5s on my system. For comparison, a "null" rebuild with no changes takes 5s, and does not re-generate the mono glue, so that's working fine.)

The mono glue generation seems to take the Godot binary as its dependency, so whenever Godot changes (i.e. any non no-op compilation) will trigger a generation of the mono glue. The workflow contributors might currently be used to when working with the Mono module is that they first do the relevant engine changes (which might involve multiple incremental compilations until they get things to compile to what they want), and then do the next steps to test their changes.

That being said, 5s extra isn't terrible. Ideally it would only generate the glue when it's really needed, but I'm not sure what the dependencies should be for that.

I haven't checked how long the build_assemblies option takes but it doesn't seem to take long? So even if it runs more than strictly needed it might be ok.

Overall, I'd be in favor of enabling build_csharp by default, and leave it to power users to use build_csharp=no if they know they often want to do multiple compilations of the Godot binary before triggering a generation of the Mono glue (or in general, know that the changes they're doing would not impact the Mono glue and thus don't need to do this extra step at all while developing).


As a side note, fixing the Python style issues would be great so we can get the proper compilation CI going. After installing black, you can install the hooks from misc/hooks/* to .git/hooks/ to get the pre-commit hook running. Or run black with black -l 120 path/to/py.

modules/mono/SCsub Outdated Show resolved Hide resolved
@shana
Copy link
Contributor Author

shana commented Jun 14, 2023

Ooops, totally missed your comments here @akien-mga, thanks for taking a look!

  • I make a change in code that doesn't impact the Mono glue and bindings, e.g. adding a comment to main/main.cpp. When building with scons module_mono_enabled=yes build_csharp=yes again, building sprite_2d.o and relinking the Godot binary is fast, but then the mono glue generation step still runs.

Ok, so, yes, I've gone through a couple of iterations on the bindings dependencies, and this version is setting the binary itself as a dependency of the bindings - this is because the list of files that contribute to bindings is not available to scons, it's a database that's built in to the binary itself, and so it is hard to accurately tell scons exactly what should trigger a rebuild. I'm not particularly happy with this, it's too trigger happy. I was experimenting with alternate ways of setting a dependency list, so I'll do some tweaks on this to make it less eager, I think.

@shana shana force-pushed the shana/csharp-build-improvements branch from b2a7e26 to e64cb0f Compare September 13, 2023 13:19
This adds the `generate_mono_glue=[no,yes]` and
`build_assemblies=[no,yes]` flags to scons, which calls the godot
binary with `--generate-mono-glue` and the `build_assemblies.py`
script, respectively.

Having these as part of the build means that building a mono-enabled
godot will create all the necessary bits to run it without having to
do extra manual steps. It also means that changes to the native code
that might change scripting API will automatically trigger regenerating
the C# glue bindings and a rebuild of the assemblies, as part of the
normal build process.

Relevant flags like `precision` and `platform` are passed into the
build assemblies step, so the C# libraries match the godot build.

Add build_csharp flag to build C# bindings when mono is enabled
@shana shana force-pushed the shana/csharp-build-improvements branch from e64cb0f to ca866a8 Compare September 13, 2023 13:30
@akien-mga
Copy link
Member

Looks good to me from a very cursory overview, I'll do some more in depth review and testing hopefully tomorrow.

@scgm0
Copy link
Contributor

scgm0 commented Sep 13, 2023

Works fine on my linux!👍

@shana
Copy link
Contributor Author

shana commented Sep 13, 2023

@akien-mga Ok! So, this new cleanup incorporates all the feedback, except for "if I touch something in an unrelated class, bindings will get regenerated". The command line flags can stop that from happening, but having scons accurately track that automatically is going to be a real pain, as I noted before. If we're ok with that and ok with addressing that later, this should be good to go 😄

Copy link
Member

@raulsntos raulsntos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, this new cleanup incorporates all the feedback, except for "if I touch something in an unrelated class, bindings will get regenerated" [...] If we're ok with that and ok with addressing that later, this should be good to go

I think this is important, but as long as the old workflow is still available (the multi-step building) I'm fine with it.

nupkgs_dir = os.path.abspath("bin/GodotSharp/Tools/nupkgs")
tools = find_any_msbuild_tool("")

# configure a default nuget source pointing to the bin/GodotSharp/Tools/nupkgs dir, so packages can be picked up automatically
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel hesitant about changing user configuration by default, I'd rather it be explicitly opt-in.

Copy link
Contributor Author

@shana shana Sep 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, it's a reasonable hesitation. However, without this, C# projects just won't work, which means it is a mandatory step to the whole pipeline - you have to configure a nuget source in order to pick up the packages. Having this opt-in means 99% of users having to run this manually anyways, which defeats the purpose somewhat.

I agree that it's happening too quietly, and with no way to opt-out of it if you have your own custom setup. I don't think it should be opt-in - we should be aiming for the 80/20 rule in user experience (making the 80% most common workflows easier) - but it should be controllable by a flag, so you can disable the behaviour in your own setup and not disrupt thing for very advanced users. I'll add a thing for that - a configure_nuget_source=yes|no flag is probably a thing we want here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've been bitten in the past by making changes to user configuration. In 4.0 we had a GodotNuGetFallbackFolder and changed the user configuration so NuGet would use it. The problem is that, if that folder is removed, then NuGet doesn't work at all. This means we essentially broke all their .NET projects (not just Godot projects), because they could no longer restore packages.

Configuring a NuGet source is a step that only needs to be done once though, so I don't think it's that much to ask. It's the same thing as installing the .NET SDK or setting up other prerequisites before building Godot, and we don't automate those either.

Copy link
Member

@akien-mga akien-mga Sep 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've actually experienced this issue last time I tested this PR (and the issue of course happens if following the current manual steps, but it's more explicit to the user that they're adding a local source).

I compiled Godot with Mono support, it generated the local nuget source and everything worked great out of the box 👍

Then some days later I ran git clean -fxd as I often do, it removed the folder from bin, and next time I tried to used an official build of Godot, my .NET setup was broken. I had to ask on chat and be told to check whether my ~/.nuget/NuGet/NuGet.config was referring to something missing.

Is there no way to add a packageSource in that config that wouldn't break dotnet if it's missing? Like with a conditional so it's only added if the folder exists?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no way to add a packageSource in that config that wouldn't break dotnet if it's missing? Like with a conditional so it's only added if the folder exists?

I don't think so, I remember looking at a way to do this in the context of GodotNuGetFallbackFolder but I couldn't find anything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm :\

I don't know if it's easy to do with scons, but maybe we could make the option output information after the build (the first time the package source needs to be added only) that tells the user about what was done, and how to remove the package source if they need?

I feel like just making the behavior opt-in wouldn't help much because if it's a SCons options, most users won't know what it does and how to undo it anyway.

Another option could be to install the packageSource stuff in the user's NuGet folder (~/.nuget), so that they won't easily delete it by mistake (and I guess it's not too harmful to their other non-Godot stuff, it just has Godot related packages).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right, I also hit this right after commenting, completely forgot that nuget is the worst. Urgh.
There are three "ways" of avoiding the system nuget failing miserably when a local source path doesn't exist:

  • Nuget supports a --ignore-failed-sources flag on restore to not fail in these situations. You have to pass it in manually, though, so that doesn't help anything, as users (and VS) won't pass this flag in normally.

  • Pushing local build packages to a location that is known to always exist: I was trying to avoid pushing packages to another place in the filesystem and instead consume them directly from the bin folder, because that would avoid stale/forgotten local build packages being picked up accidentally, but that's indeed a safe option.

  • Generating nuget.config files: The only way to have nuget sources that don't affect every project is to have a nuget.config file next to the csproj, with the local source, so only that project is affected if a source goes away. We could generate this config file in the project folder when a project is opened with a local build of godot-dotnet. Since the csproj in these cases would already referencing a -dev version of the Sdk, it would fail to restore with non-local builds of godot, a failure to restore if the local source path is missing would make it obvious what the failure is, without being confusing to other .net projects.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think NuGet is the worst, it's just probably not designed for this use case. I think it's weird for a project to add a local source, if you let the user choose the source then it can be whatever they want (it could be a remote source).

Since your intention is to make this "just work", I agree that the first option is not a solution.

The second option is what @akien-mga suggested. I don't really like it, we're still modifying the user's configuration and now we're storing packages somewhere in their computer that they may not be aware of. It feels rude.

I like the third option, but we have to keep in mind that the user may already have a nuget.config file in their project. Not sure how difficult it would be to manage this situation, but it feels like it'd be overkill to implement all this if it's not the most common case.

My opinion is that we're overcomplicating this. Setting up a local source is a step you only have to do once, are there really users complaining about this step or is it a theoretical problem that we're trying to solve here?

Comment on lines +44 to +45
# the only generated files with fixed names are these
glue_targets = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to explicitly list these files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A scons build rule requires a list of sources and a list of targets. This is so that the build system can figure out what build targets need to run when files are changed. In the bindings generation case, we have a problem: we don't exactly know what files contribute to bindings classes, because the binding generation data is calculated while it's running, and there's no metadata information that scons can read that says "this .h/.cpp file is going to generate a .cs file", short of literally regexing every file in the codebase looking for binding information (which, btw, can be done). Therefore we don't have an accurate list of target files to give to scons. We have to give it something, and there are files that are always a part of the code generation, so we can give scons this list. This list doesn't have to be super accurate, because no other build rules rely on this rule for their dependency tracking.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, my concerns are that this list may get outdated so it's one more thing we'll have to keep track of.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm hoping at least the NativeFuncs.cs file will always exist? We only really need one file to give to scons here, so whatever file we are very unlikely to rename will do. It needs to be a file that is generated by the generator, so that if it's missing scons knows it needs to rerun this rule.

We could record the filenames that are generated into a text file, commit that to the repo, and use that as the initial source of files to track, instead of hardcoding a file list here. That way it would be more accurate and wouldn't go stale.

The ideal ideal solution, I think, would be to have a dry-run generator pass that would output the list of .h/.cpp sources and the list of .cs targets relevant to the bindings generator, without doing anything else. We would run that as build step right after the c++ build, and then this rule would have exactly the right list of sources and targets to know when it would need to run.

Copy link
Member

@akien-mga akien-mga Sep 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we use a globbing pattern here, even if may encompass more files than absolutely necessary?

As a first step we probably want to be conservative and it's better to match more files than needed, than to miss some. And with something like *.cs we don't have to maintain a hardcoded list.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant NativeCalls.cs. NativeFuncs.cs is not generated.

I think the file that is least likely to ever be renamed/moved/removed is probably GeneratedIncludes.props, but to be honest I think it's not very likely that any of the files you list here will be.

What you describe as the ideal solution makes sense to me, but maybe we don't need to make it that complicated. Every generated file is always re-generated when generating the glue (even if the generated file would have the same content), so I'm assuming that means SCons will think the file changed. So I don't really see the benefits of this over the current implementation, but maybe I'm missing something.

from SCons.Variables import BoolVariable

return [
BoolVariable("generate_mono_glue", "Generate C# glue", False),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should move away from the mono naming, it's already confusing to users that the module is still named mono (but it will be renamed to dotnet in the future). I think generate_csharp_glue or generate_dotnet_glue would be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree that we should have renamed it to dotnet from the start, keeping it as mono is all kinds of confusing!
In this case, though, the command line argument for the generator is generate-mono-glue, and this is meant to be an alias to that. Do we want to diverge this flag name? I don't have a super strong opinion either way, really.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added further comments on this below - lookin at all the flags, yeah I agree it would be better to make them more consistent and dotnet-ish.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should rename the generate-mono-glue argument too. The plan is to rename the module with the Editor unification, at that time we can rename these options too. I was trying to anticipate the rename so we don't have to change the SCons arguments later, but I guess it may be better to be consistent with the current names.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point, yeah, it would be nice to have the right names now. We can add an alias to the generate-mono-glue argument in preparation for that, and deprecate it later (so it doesn't break everyone's scripts)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should do the mono -> dotnet rename before 4.2, and thus now-ish. I put it on the agenda for Thursday's meeting.

return [
BoolVariable("generate_mono_glue", "Generate C# glue", False),
BoolVariable("build_assemblies", "Build C# assemblies", False),
BoolVariable("build_csharp", "Generate and build C# bindings", False),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the name build_csharp is confusing with build_assemblies. Maybe we can call this option generate_and_build_csharp or generate_and_build_dotnet.

And, to be honest, build_assemblies being a SCons option, it should probably include csharp or dotnet in the name to be explicit that this option is related to the .NET module.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build_csharp flag should be kept short imo, as it is an aggregate flag you use to turn on or off other features and therefore you're likely typing them more often. The other ones can be more verbose, they're going to be used less on average.

If we're tweaking flag names, maybe generate_dotnet and compile_dotnet for the two individual build steps? Maybe with a configure_nuget_source=yes|no option as well, for the nuget step? And then build_dotnet for the aggregate flag, that would make things more consistent.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, generate_and_build_dotnet=yes is still shorter than generate_mono_glue=yes build_assemblies=yes, but I see your point. I don't feel like the verb build implies also generating, but I guess it's a matter of perspective.

To be honest, I don't expect many users to type the SCons commands manually. I've seen users write scripts that execute all the steps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants