Closed lukaspirkl closed 4 months ago
Both timeBeginPeriod and timeEndPeriod use Winmm.lib. My path to these are "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\WinMM.Lib". Not sure if this would help but it looks like Visual Studio uses macros for paths to the Windows SDK. Looking at the path for the DLLs you are importing $(WindowsSDK_LibraryPath_x64) seems like its the right one.
I tried it on Linux and it works.
<ItemGroup>
<DirectPInvoke Include="raylib" Visible="false" />
<NativeLibrary Include="libraylib.a" />
</ItemGroup>
I didn't know that it was possible to link statically with native AOT. That's great, thank you.
I haven't tried it on Windows.
@nickyMcDonald Thank you! It is working now. And it doesn't look that terrible with the $(WindowsSDK_LibraryPath_x64). I found out that even this is not necessary and using just the file name is enough.
So for Windows, the complete ItemGroup for static linking looks like this:
<ItemGroup>
<DirectPInvoke Include="raylib" />
<NativeLibrary Include="raylib.lib" />
<NativeLibrary Include="Gdi32.lib" />
<NativeLibrary Include="shell32.lib" />
<NativeLibrary Include="WinMM.Lib" />
</ItemGroup>
The dotnet publish
is now returning only the warning and it is producing a nice single executable with everything inside.
c:\Dev\Raylib_AOT>dotnet publish
Determining projects to restore...
Restored c:\Dev\Raylib_AOT\Raylib_AOT.csproj (in 215 ms).
Raylib_AOT -> c:\Dev\Raylib_AOT\bin\Release\net8.0\win-x64\Raylib_AOT.dll
Generating native code
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library [c:\Dev\Raylib_
AOT\Raylib_AOT.csproj]
Raylib_AOT -> c:\Dev\Raylib_AOT\bin\Release\net8.0\win-x64\publish\
I am still curious about the warning message. I found these two pieces of information:
Using <LinkerArg Include="/VERBOSE:LIB" />
writes to output a lot of lib files that it is searching for. And there is indeed LIBCMT.lib together with MSVCRT.lib.
When I include <LinkerArg Include="/NODEFAULTLIB:msvcrt.lib" />
, the warning disappears. However, as mentioned in the StackOverflow answer, this doesn't actually fix the problem. If I understand it correctly, Raylib and AOT are using different C++ runtime libraries. I'm looking for information on how to switch it, but I would appreciate some help or direction as this is quite new to me.
Ok.. so for as far as I know the nativeaot /MD, /MT, /LD (Use Run-Time Library) compiler option is not accessable. If they were accessable then the correct compiler option would be /MD I think since the release version of raylib is built with that option.
Fortunatly a workaround is to just build raylib itself with the compiler option /MT set. That seemed to work for me because the dotnet publish warning dissapeared.
To build it I used the raylib solution file provided in the source code file:
"
Then for "Release" you want to set the runtime library to /MT not /MD:
Im not sure if it was neccisary to build the dll but I built both the dll and lib versions of release:
The dll build location is "
Btw when building raylib with /MT set there probably will be a lot of linker errors such as: LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library Those are fine since they are just the example projects which are set with /MD and not the raylib.dll itself.
@nickyMcDonald Thank you so much! I was so focused on CMake and console when building C++ stuff that I forgot I could build Raylib directly in Visual Studio. :laughing: Everything is working flawlessly without any warning.
Issue description
When C# is used with the raylib the resulting binaries are huge. Usually, there is a whole runtime packed and a lot of DLLs are just laying around. It is possible to publish the project as a single file, but it is not really a "single" as the raylib.dll is still laying next to it. And the executable is still huge. With the latest dotnet features like native ahead-of-time compilation, it could/should be possible to generate just one small executable like when C/C++ is used.
Current state
Right now, with the latest raylib-cs library, it is possible to add
<PublishAot>true</PublishAot>
into the csproj and it will create native executable (~2MB) and raylib.dll. But it would be nice if the DLL would be linked statically and the whole program would be just a single executable. It would also trim the unused functions from the raylib library so the result would be even smaller.Experiment
So I tried it. 😊 To minimize all side effects, I started from scratch without any library whatsoever. This is what I did:
dotnet publish
And to my surprise, everything was working. Inside the output directory, there were raylib.dll (1.8 MB), Raylib-AOT.exe (1.5 MB), and debug symbols. I continued and added the following text into the csproj as described in the documentation:
This time the
dotnet publish
failed.I tried some random things as I had no idea what I am doing. I ended up with the following text in the csproj:
And most of the errors disappeared:
Not great, not terrible. But my gut feeling is telling me that I am on the wrong way and there should be some other solution than adding paths to random system libraries.
The minimal project: Raylib_AOT.zip
BTW, I tried the same approach with Lua library and it worked without any error or warning. Dotnet executable compiled to native code with lua linked statically just worked.