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

Complex project setup with plugins and git submodules, need help building very specific output #10046

Open
just-ero opened this issue Apr 20, 2024 · 2 comments
Assignees

Comments

@just-ero
Copy link

Hello everyone. I have some questions about getting my build to work the way I want. The issue appears fairly complex and I have been unable to receive any help from anywhere else. Please keep in mind that this project is over 10 years old and riddled with some bad design choices.

Let me explain.

The App

MyApp/
├─ plugins/
│  └─ Directory.Build.props
├─ lib/
├─ src/
│  ├─ MyApp/
│  ├─ MyApp.Core/
│  ├─ MyApp.Register/
│  ├─ MyApp.View/
│  ├─ MyApp.UpdateManager/
│  └─ Directory.Build.props
├─ test
│  ├─ MyApp.*.UnitTests/
│  └─ Directory.Build.props
├─ Directory.Build.props
└─ MyApp.sln

Firstly I need to mention one extremely important point: every sub-directory in MyApp/plugins/ and MyApp/lib/ is a git submodule. This means that they all need to exist and require the ability to be built on their very own.

  1. A connection to the parent MyApp repository or directory must still be given, because all of the plugins reference MyApp.Core and MyApp.UpdateManager. I was planning on handling this via a Directory.Build.props file in MyApp/plugins/ which sets a property like $(MyAppSrcDirectory).
  2. MyApp/src/MyApp/ must remain the startup project of the solution.
  3. Building and running (I am willing to accept publishing here as well) MyApp/src/MyApp/ must build the following projects as well (they are required for MyApp to run with all functionality):
    • MyApp/src/MyApp.Register
    • MyApp/src/MyApp.UpdateManager as OutputType=WinExe (it's Library by default, which is required for the other projects)
    • all projects in MyApp/plugins/, placed in a Plugins/ sub-directory in the output directory.
  4. Duplicate assemblies which are already present in the output directory should be omitted from the Plugins/ sub-directory.

The Plugins

MyApp.SomePlugin/
├─ src/
│  └─ MyApp.SomePlugin/
├─ test
│  └─ MyApp.SomePlugin.UnitTests/
├─ Directory.Build.props
└─ MyApp.SomePlugin.sln

As mentioned, all plugins are git submodules. That means when only the plugin is cloned on its own, there must be a way to build it even then. A requirement for this, of course, is that MyApp must also be cloned, but this can be a shallow, non-recursive clone. When building the plugin, the user then merely passes the path to the required directories: dotnet build -p:MyAppSrcDirectory=....

Directory.Build.props

Since Directory.Build.props files help me apply a lot of properties all at once on relevant projects, I use them everywhere. That means I am also using them in the plugin projects. This obviously causes some problems:

  1. If I can, I don't want to conditionally import a Directory.Build.props from the directory above in the plugins. The Import needs to be conditional, because the plugin may be cloned not as a submodule of MyApp, which means the Directory.Build.props file in a directory above would not exist.
    I am currently doing this to include MyApp/plugins/Directory.Build.props, which sets the aforementioned $(MyAppSrcDirectory), which is in turn used in the ProjectReferences of the plugins.
  2. I set UseArtifactsOutput to true in all top-level Directory.Build.props files. I want the artifacts to be placed in the same directory for all projects, including the plugins. This is hindered because the plugins' top-level Directory.Build.props file overwrites the ArtifactsPath from MyApp/Directory.Build.props.

MyApp.sln

This might be the most frustrating part. I personally work exclusively on the command line. But most users will want to clone the repository (recursively), open the solution file, press F6, and have a complete running app. This is difficult to fulfill due to the fairly complex output structure.

Additionally, the MyApp/ solution file includes the plugin projects themselves as well, which probably causes issues when building the entire solution.


That's the gist of it.

I'm looking for some help on what I need to do to get this to work the way I need. I'm desperate at this point. Please ask any clarifying questions and I'll be happy to provide more information.

@KalleOlaviNiemitalo
Copy link

KalleOlaviNiemitalo commented Apr 20, 2024

Perhaps the SolutionDir property can be useful for conditions in the plugin projects. IIRC, it is set by Visual Studio; not sure about command-line MSBuild, but if not, then Directory.Solution.props could set it — this might have to be done via an ItemDefinitionGroup that adds AdditionalProperties metadata to ProjectReference items.

@just-ero
Copy link
Author

I'm so confused about what any of that means. Please include examples.

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

No branches or pull requests

3 participants