C
C#13mo ago
Logan M.

Packaging a non-C# binary into a NuGet package.

So I've been optimizing this logging library of mine to try to get it as fast as I can. with the main bottleneck appearing to be as fast as it can be I just wrote the main functions of it in Rust and decided to interop it in. this showed to give a rough ~50ms improvement on benchmarking but now I don't know how to package this thing really... In the C# section it roughly looks as so:
[DllImport("print.dll", CharSet = CharSet.Ansi)]
static extern void print(IntPtr input, IntPtr filePath, bool isInfo, uint lineNum);
[DllImport("print.dll", CharSet = CharSet.Ansi)]
static extern IntPtr formattedLog(IntPtr input, bool isInfo, IntPtr filePath, uint lineNum);
[DllImport("print.dll", CharSet = CharSet.Ansi)]
static extern void print(IntPtr input, IntPtr filePath, bool isInfo, uint lineNum);
[DllImport("print.dll", CharSet = CharSet.Ansi)]
static extern IntPtr formattedLog(IntPtr input, bool isInfo, IntPtr filePath, uint lineNum);
but since the DllImport is directly just the dll, I'm pretty sure I have to have print.dll in the same path as the library right? which brings the question of how do I do that..? Closest I've gotten is managing to package print.dll in there but not in the right path causing an exception when you try to print something. Currently what I have so far is as so
<!--rust dll-->
<ItemGroup>
<None Update="bin\Release\net7.0\print.dll" Pack="true" PackagePath="runtimes/win/lib/net7.0">
<files>
<file src="bin\Release\net7.0\print.dll" target="runtimes\win\lib\net7.0\print.dll" />
</files>
</None>
</ItemGroup>
<!--rust dll-->
<ItemGroup>
<None Update="bin\Release\net7.0\print.dll" Pack="true" PackagePath="runtimes/win/lib/net7.0">
<files>
<file src="bin\Release\net7.0\print.dll" target="runtimes\win\lib\net7.0\print.dll" />
</files>
</None>
</ItemGroup>
which for some reason doesn't even pack print.dll into the package. Any help would be appreciated!
No description
No description
29 Replies
wasabi
wasabi13mo ago
Well, there's a lot of weird stuff in your example MSBuild code. Like, what is the nested <files> thing supposed to even be? For .NET Core projects, all you need to do is get it packed into the right path. Which would be runtimes/{rid}/native
Logan M.
Logan M.OP13mo ago
If I had it somewhere else it gave me a build error, so I just eventually shoved <files> into <None>.
wasabi
wasabi13mo ago
Why would you need it anywhere at all?
Logan M.
Logan M.OP13mo ago
Isn't <files> entire purpose this..?
wasabi
wasabi13mo ago
No. There is no such <files> element in MSBuild.
Logan M.
Logan M.OP13mo ago
wait what
wasabi
wasabi13mo ago
PackagePath is a MSBuild metadata property. So that's correct.
Logan M.
Logan M.OP13mo ago
Im confused though if thats the case wouldnt msbuild have given me an error of somekind about that?
wasabi
wasabi13mo ago
No, because <files> is interpreted as a metadata property named 'files' set on the items in the itemgroup. Which has no effect, because nothing cares about it.
Logan M.
Logan M.OP13mo ago
oh
Logan M.
Logan M.OP13mo ago
but with packagePath though? is there a reason why that fails to package the dll?
<None Update="bin\Release\net7.0\print.dll" Pack="true" PackagePath="runtimes/win/lib/net7.0"/>
<None Update="bin\Release\net7.0\print.dll" Pack="true" PackagePath="runtimes/win/lib/net7.0"/>
No description
wasabi
wasabi13mo ago
Is there an item in the None ItemGroup which you are updating? If not, then the None Update line has no effect either.
Logan M.
Logan M.OP13mo ago
No there shouldnt be.. but wouldn't still have worked here with the paths provided? oh
wasabi
wasabi13mo ago
Update means to update an existing item in the ItemsGroup. But if there is no such item in the Itemgroup.... there is nothing to Update.
Logan M.
Logan M.OP13mo ago
oh
wasabi
wasabi13mo ago
Chances are you want Include. But, you also should not package items from the bin directory outside of Targets.
Logan M.
Logan M.OP13mo ago
why shouldn't I exactly? its the dll file that matters here right?
wasabi
wasabi13mo ago
You'll get incorrect metadata reads.
Logan M.
Logan M.OP13mo ago
oh in that case what should I do here then?
wasabi
wasabi13mo ago
Properties and Items outside of Targets get processed when the project loads. At which time bin/ is unlikely to exist. Thus, the file won't exist at the time of loading, and thus the item in the None ItemGroup will have no timestamp metadata. And incremental builds will be wonky. Assuming the file is produced externally, put it somewhere else.
Logan M.
Logan M.OP13mo ago
so I imagine just keep it in strc/rust/target/
wasabi
wasabi13mo ago
Then `<None Include="..that filewhereever" PackagePath="etc" Pack="true" />
Logan M.
Logan M.OP13mo ago
instead of shoving it in bin on build
wasabi
wasabi13mo ago
Yes.
Logan M.
Logan M.OP13mo ago
alr i'll try that
wasabi
wasabi13mo ago
if you want it to be present in bin/ during build of the project, you let the build itself copy it to bin/ By setting CopyToOutputDirectory
Logan M.
Logan M.OP13mo ago
would that be in <None>?
wasabi
wasabi13mo ago
Yup. So when you execute the Clean or Rebuild target, the copy in bin/ gets deleted. And then Build copies it back. And a second run of Build compares timestamps, and only copies if out of date. CopyToOutputDirectory should probably be set to PreserveNewest
Logan M.
Logan M.OP13mo ago
ok, thanks so kinda like so?
<!--rust dll-->
<ItemGroup>
<None Update="src\rust\target\debug\print.dll" Pack="true" PackagePath="runtimes/win/lib/net7.0">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<!--rust dll-->
<ItemGroup>
<None Update="src\rust\target\debug\print.dll" Pack="true" PackagePath="runtimes/win/lib/net7.0">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
alr yeah that worked blep
Want results from more Discord servers?
Add your server