C
C#•4d ago
Olsson

Create MSBuild custom task to modify C# files before compilation

Hi, I need to rewrite some properties and function calls for interop, and would love to do that in a MSBuild Task. How can I overwrite the Compile item group with my modified files?
19 Replies
ero
ero•4d ago
you should absolutely not even try to do this. what is your concrete use case, can you share a little bit more about it? in theory there are source generators, which you should prefer for adding source files to your compilation automatically, but this doesn't involve modifying files
Olsson
OlssonOP•4d ago
I'm integrating C# into a game engine, and need the user written C# properties to fetch the value in memory from C++. I could use Mono.Cecil to weave the instructions, but it's very cumbersome Source generators would not work for my use case
ero
ero•4d ago
why not? that sounds like exactly the perfect use case for source generators
Olsson
OlssonOP•4d ago
You can't modify the code in place, as you said. I need to modify the file
ero
ero•4d ago
you do not need to modify the file. why would you? what i believe you're looking for here is partial properties, yes?
Olsson
OlssonOP•4d ago
For functions it wouldn't work, RPC calls needs to be rewritten
ero
ero•4d ago
user code:
partial class C
{
[CppFetch]
public partial int Foo { get; }
}
partial class C
{
[CppFetch]
public partial int Foo { get; }
}
generated code:
partial class C
{
public partial int Foo
{
get
{
// your generated code...
}
}
}
partial class C
{
public partial int Foo
{
get
{
// your generated code...
}
}
}
would this not be viable for you? (same thing can be done for methods)
Olsson
OlssonOP•4d ago
// User facing
[ServerCall]
public void MyServerCall()
{
// User code logic
}

// Compiled
{
[ServerCall]
public void MyServerCall()
{
// RPC logic to send the event to the server
}

public void MyServerCall_ActualImplementation()
{
// User code logic
}
}
// User facing
[ServerCall]
public void MyServerCall()
{
// User code logic
}

// Compiled
{
[ServerCall]
public void MyServerCall()
{
// RPC logic to send the event to the server
}

public void MyServerCall_ActualImplementation()
{
// User code logic
}
}
I don't see how this can be achieved with source generators
ero
ero•4d ago
interceptors would be a better fit, but unfortunately i don't know the current state of them i can't think of a good solution here that doesn't make some kind of compromise which is one kind of compromise i would seriously highly recommend against modifying source files, it feels like asking for trouble
Olsson
OlssonOP•4d ago
I'm not modifying the original source file
ero
ero•4d ago
i understand what you're doing, it's still bad you can for example do
partial class C
{
[ServerCall(impl: nameof(MyServerCallImpl))]
public partial void MyServerCall();

private void MyServerCallImpl()
{
// User code logic
}
}
partial class C
{
[ServerCall(impl: nameof(MyServerCallImpl))]
public partial void MyServerCall();

private void MyServerCallImpl()
{
// User code logic
}
}
Olsson
OlssonOP•4d ago
That's not gonna cut it. I'll research further
ero
ero•4d ago
how so?
Olsson
OlssonOP•4d ago
Not how I want the syntax to be for this scripting layer of the engine
ero
ero•4d ago
that's a pretty arbitrary barrier
Olsson
OlssonOP•4d ago
It's still not how I want it 😅 So I'll research further, thank you guys for the help though! 😄 Yea, been thinking of something similar like this.
Unknown User
Unknown User•4d ago
Message Not Public
Sign In & Join Server To View
MODiX
MODiX•4d ago
If you want to make an incremental source generator, please make sure to read through both the design document and the cookbook before starting.
Olsson
OlssonOP•4d ago
another partial?

Did you find this page helpful?