Open vadimkantorov opened 3 months ago
I wrote down a primer of a minimalistic workflow file I meant above, looking to generate C API bindings to https://github.com/triton-inference-server/core/blob/main/include/triton/core/tritonserver.h
Does CppSharp absolutely need to have access to CppSharp compiled libtritonserver.so
? (module.LibraryDirs
/ module.Libraries
)
How could
name: tritonservercppsharp
on: workflow_dispatch
env:
PLATFORM: x64
jobs:
tritonservercppsharp:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- name: Write down the bindings code
run: |
tee tritonservercppsharp.cs <<EOF
namespace CppSharpTransformer { class DllDemoGenerator : CppSharp.ILibrary {
public static void Main(string[] args) { CppSharp.ConsoleDriver.Run(new DllDemoGenerator()); }
public void SetupPasses(CppSharp.Driver driver) { }
public void Preprocess(CppSharp.Driver driver, ASTContext ctx) { }
public void Postprocess(CppSharp.Driver driver, ASTContext ctx) { }
void ILibrary.Setup(CppSharp.Driver driver) { }
void Setup(CppSharp.Driver driver) {
var options = driver.Options;
options.GeneratorKind = GeneratorKind.CSharp;
var module = options.AddModule("TritonServerCppSharp");
module.IncludeDirs.Add("core/include");
module.Headers.Add("triton/core/tritonserver.h");
//module.LibraryDirs.Add("/path/to/triton/which/containslibtritonserver.so/");
//module.Libraries.Add("libtritonserver.so");
}
} }
EOF
- name: Clone and build CppSharp
run: |
#wget https://dot.net/v1/dotnet-install.sh && bash dotnet-install.sh --channel 9.0
git clone --single-branch --depth 1 --branch v1.1 https://github.com/mono/CppSharp
cd CppSharp
bash build/build.sh generate -configuration Release -platform $PLATFORM
bash build/build.sh download_llvm -platform $PLATFORM
bash build/build.sh restore -platform $PLATFORM
bash build/build.sh -platform $PLATFORM -build_only
find bin
dotnet --version
- name: Generating bindings
run: |
git clone --single-branch --depth 1 --branch r23.03 https://github.com/triton-inference-server/core
#"$HOME/.dotnet"
DOTNET_ROOT=/usr/share/dotnet
DOTNETSDKVER=$(dotnet --version)
DOTNETFWKVER=$(dotnet --list-runtimes | grep Microsoft.NETCore.App | tail -n 1 | cut -d " " -f2)
DOTNETLIBDIR="$DOTNET_ROOT/shared/Microsoft.NETCore.App/$DOTNETFWKVER"
LD_LIBRARY_PATH=CppSharp/bin/Release_x64/ dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" -r:CppSharp/bin/Release_x64/CppSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.AST.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.dll $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') -target:library -out:tritonservercppsharp.exe tritonservercppsharp.cs
dotnet tritonservercppsharp.exe
# - uses: actions/upload-artifact@v4
# with:
# path: CppSharp/bin/Release_x64/
Could it be considered a base for such a workflow file producing a fully functioning llvm+CppSharp install?
Sure, though this way will compile CppSharp from source (which I personally like, though takes a bit more time). Another valid approach would be to re-use the Nuget packages published by CppSharp's own CI step.
Does CppSharp absolutely need to have access to CppSharp compiled
libtritonserver.so
? (module.LibraryDirs
/module.Libraries
)
IIRC it does not need it, it's only used to find which symbols are provided by the compiled libraries. Especially for C libraries this is not a concern, because header-only inline symbols are usually not present. For C++, it might be a concern depending on the library.
Also to note, for some applications, the CppSharp CLI might be useful since it does not need a custom C# code setup: https://github.com/mono/CppSharp/blob/main/src/CLI/CLI.cs
Customization is harder in that case, but does not have to be the case. I would be very helpful to provide a declarative customization model for simple cases (YAML or even C# script based).
Also to note, for some applications, the CppSharp CLI might be useful since it does not need a custom C# code setup
Is there an example of using this tool anywhere? For simple things (and as a baseline), it should indeed be sufficient! I think it's worth advertising a complete example of using this option in the CppSharp's README directly (to have a complete example with dotnet add package
and dotnet tool ...
or similar) :)
Another valid approach would be to re-use the Nuget packages published by CppSharp's own CI step.
For this case, do I need to do dotnet add package CppSharp
? And in both cases, which assemblies do I need to reference for csc.dll
to get the basic CppSharp.ILibrary
and CppSharp.Driver
?
Thanks!
Is there an example of using this tool anywhere? For simple things (and as a baseline), it should indeed be sufficient!
The test suite is using it, but I would check out the CLI tool directly, as it provides help and description for the parameters: https://github.com/mono/CppSharp/blob/main/tests/napi/test.sh#L13
For this case, do I need to do
dotnet add package CppSharp
? And in both cases, which assemblies do I need to reference forcsc.dll
to get the basicCppSharp.ILibrary
andCppSharp.Driver
?
I think these are the main ones:
I am not the best person to ask about Nuget as I rarely use it in my workflows.
But development versions are pushed to GitHub packages:
dotnet nuget push "*.nupkg" --api-key ${{ secrets.GITHUB_TOKEN }} --source "https://nuget.pkg.github.com/mono/index.json" --skip-duplicate
https://github.com/mono/CppSharp/pkgs/nuget/CppSharp
The last version says it was published 4 months ago, so maybe publishing for ongoing development commits is not working correctly after all.
For some reason I'm getting problems loading the generated exe
(depsite that I copy all the .dll
s and .so
s in the current dir:
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'CppSharp.Generator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
File name: 'CppSharp.Generator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
/home/runner/work/_temp/388ed1a4-2143-4a23-bfad-d50c5b136892.sh: line 25: 2764 Aborted (core dumped) dotnet
name: tritonservercppsharp
on: workflow_dispatch
env:
PLATFORM: x64
jobs:
tritonservercppsharp:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- name: Write down the bindings code
run: |
tee tritonservercppsharp.cs <<EOF
namespace CppSharpTransformer { public class DllDemoGenerator : CppSharp.ILibrary {
public static void Main(string[] args) { CppSharp.ConsoleDriver.Run(new DllDemoGenerator()); }
public void SetupPasses(CppSharp.Driver driver) { }
public void Preprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
public void Postprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
public void Setup(CppSharp.Driver driver) {
var options = driver.Options;
options.GeneratorKind = CppSharp.Generators.GeneratorKind.CSharp;
var module = options.AddModule("TritonServerCppSharp");
module.IncludeDirs.Add("core/include");
module.Headers.Add("triton/core/tritonserver.h");
module.Headers.Add("triton/core/tritonbackend.h");
module.Headers.Add("triton/core/tritoncache.h");
module.Headers.Add("triton/core/tritonrepoagent.h");
//module.LibraryDirs.Add("/path/to/triton/server.so");
//module.Libraries.Add("tritonserver.so");
} } }
EOF
- name: Clone and build CppSharp
run: |
#wget https://dot.net/v1/dotnet-install.sh && bash dotnet-install.sh --channel 9.0
git clone --single-branch --depth 1 https://github.com/mono/CppSharp
cd CppSharp
bash build/build.sh generate -configuration Release -platform $PLATFORM
bash build/build.sh download_llvm -platform $PLATFORM
bash build/build.sh restore -platform $PLATFORM
bash build/build.sh -platform $PLATFORM -build_only
find bin
- name: Generating bindings
run: |
git clone --single-branch --depth 1 https://github.com/triton-inference-server/core
#"$HOME/.dotnet"
DOTNET_ROOT=/usr/share/dotnet
DOTNETSDKVER=$(dotnet --version)
DOTNETFWKVER=$(dotnet --list-runtimes | grep Microsoft.NETCore.App | tail -n 1 | cut -d " " -f2)
DOTNETLIBDIR="$DOTNET_ROOT/shared/Microsoft.NETCore.App/$DOTNETFWKVER"
dotnet --version
dotnet --list-runtimes
echo $DOTNETSDKVER $DOTNETFWKVER
# -r:CppSharp/bin/Release_x64/CppSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.AST.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.dll
#echo 'namespace ProgramNamespace { public static class Program { public static void Main(string[] args) { System.Console.WriteLine("Hello world!"); } } }' > footest.cs
#dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') -target:exe -out:footest.exe footest.cs
#echo '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":"'$DOTNETFWKVER'"}}}' > footest.runtimeconfig.json
#dotnet footest.exe
find CppSharp/bin/Release_x64 -name 'CppSharp*.dll'
# -r:CppSharp/bin/Release_x64/CppSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.AST.dll -r:CppSharp/bin/Release_x64/CppSharp.Runtime.dll -r:CppSharp/bin/Release_x64/CppSharp.CLI.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.CSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.Bootstrap.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.Gen.dll
dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') $(find CppSharp/bin -name "*.dll" -printf '-r:"%p" ') -target:exe -out:tritonservercppsharp.exe tritonservercppsharp.cs
echo '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":"'$DOTNETFWKVER'"}}}' > tritonservercppsharp.runtimeconfig.json
echo BEFORE
find CppSharp/bin -name "*.dll" -o -name "*.so" -exec cp {} . ';'
dotnet tritonservercppsharp.exe
Have you tried this locally or are you running only on CI?
Only on CI. It appears that dotnet does not like the libSystem.Native.so
which is found successfully on system path and so it proceeds checking the local directory, it cannot find it and then aborts (after loading 10 various unicode libraries to maybe localize the error message :) ):
2024-08-19T17:11:59.5137891Z [pid 2844] openat(AT_FDCWD, "/home/runner/work/tritonservercppsharp/tritonservercppsharp/libSystem.Native.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
2024-08-19T17:11:59.5140546Z [pid 2844] openat(AT_FDCWD, "/usr/share/dotnet/shared/Microsoft.NETCore.App/8.0.7/libSystem.Native.so", O_RDONLY|O_CLOEXEC) = 15
2024-08-19T17:11:59.5142439Z [pid 2844] read(15, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
2024-08-19T17:11:59.5144051Z [pid 2844] newfstatat(15, "", {st_mode=S_IFREG|0777, st_size=90488, ...}, AT_EMPTY_PATH) = 0
2024-08-19T17:11:59.5145178Z [pid 2844] close(15) = 0
2024-08-19T17:11:59.5146687Z [pid 2844] access("", F_OK) = -1 ENOENT (No such file or directory)
2024-08-19T17:11:59.5148223Z [pid 2844] access("opt/corebreadcrumbs", F_OK) = -1 ENOENT (No such file or directory)
2024-08-19T17:11:59.5149673Z [pid 2844] readlink("/home", 0x7fff9273a7e0, 1023) = -1 EINVAL (Invalid argument)
2024-08-19T17:11:59.5151334Z [pid 2844] readlink("/home/runner", 0x7fff9273a7e0, 1023) = -1 EINVAL (Invalid argument)
2024-08-19T17:11:59.5152984Z [pid 2844] readlink("/home/runner/work", 0x7fff9273a7e0, 1023) = -1 EINVAL (Invalid argument)
2024-08-19T17:11:59.5154785Z [pid 2844] readlink("/home/runner/work/tritonservercppsharp", 0x7fff9273a7e0, 1023) = -1 EINVAL (Invalid argument)
2024-08-19T17:11:59.5157228Z [pid 2844] readlink("/home/runner/work/tritonservercppsharp/tritonservercppsharp", 0x7fff9273a7e0, 1023) = -1 EINVAL (Invalid argument)
2024-08-19T17:11:59.5159757Z [pid 2844] stat("/home/runner/work/tritonservercppsharp/tritonservercppsharp/tritonservercppsharp.exe", {st_mode=S_IFREG|0644, st_size=4608, ...}) = 0
2024-08-19T17:11:59.5162486Z [pid 2844] openat(AT_FDCWD, "/home/runner/work/tritonservercppsharp/tritonservercppsharp/tritonservercppsharp.exe", O_RDONLY) = 15
2024-08-19T17:11:59.5179454Z [pid 2844] openat(AT_FDCWD, "/proc/self/status", O_RDONLY) = 19
2024-08-19T17:11:59.5180713Z [pid 2844] read(19, "Name:\tdotnet\nUmask:\t0022\nState:\t"..., 2047) = 1442
2024-08-19T17:11:59.5181800Z [pid 2844] close(19) = 0
2024-08-19T17:11:59.5240540Z Unhandled exception. [pid 2844] openat(AT_FDCWD, "/home/runner/work/tritonservercppsharp/tritonservercppsharp/libSystem.Native.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
2024-08-19T17:11:59.5242833Z [pid 2844] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 19
With the similar command:
echo 'namespace ProgramNamespace { public static class Program { public static void Main(string[] args) { System.Console.WriteLine("Hello world!"); } } }' > footest.cs
dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') -target:exe -out:footest.exe footest.cs
echo '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":"'$DOTNETFWKVER'"}}}' > footest.runtimeconfig.json
dotnet footest.exe
this runs with success
but maybe the problem is that the build command uses a different dotnet / runtime and hence incompat with the runtime I use for running the compiled app?
DOTNET_ROOT=/usr/share/dotnet
DOTNETSDKVER=$(dotnet --version)
DOTNETFWKVER=$(dotnet --list-runtimes | grep Microsoft.NETCore.App | tail -n 1 | cut -d " " -f2)
DOTNETLIBDIR="$DOTNET_ROOT/shared/Microsoft.NETCore.App/$DOTNETFWKVER"
dotnet --version
dotnet --list-runtimes
echo $DOTNETSDKVER $DOTNETFWKVER
2024-08-19T17:11:57.7465811Z 8.0.303
2024-08-19T17:11:57.7524923Z Microsoft.AspNetCore.App 6.0.32 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
2024-08-19T17:11:57.7526906Z Microsoft.AspNetCore.App 7.0.20 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
2024-08-19T17:11:57.7528649Z Microsoft.AspNetCore.App 8.0.7 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
2024-08-19T17:11:57.7531310Z Microsoft.NETCore.App 6.0.32 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
2024-08-19T17:11:57.7532927Z Microsoft.NETCore.App 7.0.20 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
2024-08-19T17:11:57.7534428Z Microsoft.NETCore.App 8.0.7 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
2024-08-19T17:11:57.7535843Z 8.0.303 8.0.7
Seems likely, any reason you are installing a separate .NET version instead of using the system one?
any reason you are installing a separate .NET version instead of using the system one?
I am not installing any separate .NET. This line is commented out #wget https://dot.net/v1/dotnet-install.sh && bash dotnet-install.sh --channel 9.0
. I was not sure if Ubuntu comes with the system one or not
Ok, have you tried without this tritonservercppsharp.runtimeconfig.json
? Why are you generating it?
It appears in CppSharp.Generator.dll
the following. So it seems that build script use the 6.0 version of .NET despite that default (and latest) version is 8.0 (as reported by dotnet --version
).
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v6.0",
"signature": ""
},
Why are you generating it?
Because otherwise dotnet
command cannot run the executables built directly with csc
:(
Ok, must be a new .NET feature, previously I don't remember that being necessary.
https://github.com/mono/CppSharp/commit/8cf6e3f2805babe78b1b30b1d719d6c62c0cbaac
Maybe this can help, you can pass -target-framework
to the build script.
I've tried that. This indeed makes "runtimeTarget": {"name": ".NETCoreApp,Version=v8.0", "signature": ""},
into the deps.json, but still same error at the end :(
name: tritonservercppsharp
on: workflow_dispatch
env:
PLATFORM: x64
FRAMEWORK: net80
DOTNET_ROOT: /usr/share/dotnet
DOTNETSDKVER: 8.0.303
DOTNETFWKVER: 8.0.7
jobs:
tritonservercppsharp:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- name: Write down the bindings code
run: |
tee tritonservercppsharp.cs <<EOF
namespace CppSharpTransformer { public class DllDemoGenerator : CppSharp.ILibrary {
public static void Main(string[] args) { CppSharp.ConsoleDriver.Run(new DllDemoGenerator()); }
public void SetupPasses(CppSharp.Driver driver) { }
public void Preprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
public void Postprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
public void Setup(CppSharp.Driver driver) {
var options = driver.Options;
options.GeneratorKind = CppSharp.Generators.GeneratorKind.CSharp;
var module = options.AddModule("TritonServerCppSharp");
module.IncludeDirs.Add("core/include");
module.Headers.Add("triton/core/tritonserver.h");
module.Headers.Add("triton/core/tritonbackend.h");
module.Headers.Add("triton/core/tritoncache.h");
module.Headers.Add("triton/core/tritonrepoagent.h");
//module.LibraryDirs.Add("/path/to/triton/server.so");
//module.Libraries.Add("tritonserver.so");
} } }
EOF
- name: Clone and build CppSharp
run: |
git clone --single-branch --depth 1 https://github.com/mono/CppSharp
cd CppSharp
bash build/build.sh generate -configuration Release -platform $PLATFORM -target-framework $FRAMEWORK
bash build/build.sh download_llvm -platform $PLATFORM -target-framework $FRAMEWORK
bash build/build.sh restore -platform $PLATFORM -target-framework $FRAMEWORK
bash build/build.sh -platform $PLATFORM -build_only -target-framework $FRAMEWORK
find bin
- name: Generating bindings
run: |
git clone --single-branch --depth 1 https://github.com/triton-inference-server/core
dotnet --version
dotnet --list-runtimes
DOTNETLIBDIR="$DOTNET_ROOT/shared/Microsoft.NETCore.App/$DOTNETFWKVER"
#DOTNETSDKVER=$(dotnet --version)
#DOTNETFWKVER=$(dotnet --list-runtimes | grep Microsoft.NETCore.App | tail -n 1 | cut -d " " -f2)
echo 'namespace ProgramNamespace { public static class Program { public static void Main(string[] args) { System.Console.WriteLine("Hello world!"); } } }' > footest.cs
dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') -target:exe -out:footest.exe footest.cs
echo '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":"'$DOTNETFWKVER'"}}}' > footest.runtimeconfig.json
dotnet footest.exe
# -r:CppSharp/bin/Release_x64/CppSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.AST.dll -r:CppSharp/bin/Release_x64/CppSharp.Runtime.dll -r:CppSharp/bin/Release_x64/CppSharp.CLI.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.CSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.Bootstrap.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.Gen.dll
dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') $(find CppSharp/bin -name "*.dll" -printf '-r:"%p" ') -target:exe -out:tritonservercppsharp.exe tritonservercppsharp.cs
echo '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":"'$DOTNETFWKVER'"}}}' > tritonservercppsharp.runtimeconfig.json
find CppSharp/bin -name "*.dll" -o -name "*.so" -exec cp {} . ';'
dotnet tritonservercppsharp.exe || true
- uses: actions/upload-artifact@v4
with:
path: |
CppSharp/bin/
tritonservercppsharp.cs
tritonservercppsharp.runtimeconfig.json
tritonservercppsharp.exe
Ha-ha, it seems that running a csc-compiled file referencing assemblies obtained from dotnet build
is somehow incompatible. I guess I need somehow a csproj/sln files examples (that are known to work) referencing the compiled cppsharp assemblies... Very unfortunate that .NET makes it super-hard to just run a C# file without all the ceremonies of csharpproj and runtimeconfig...
I've tried also using CSharp.Gen
:
cp ./CppSharp/bin/Release_x64/libCppSharp.CppParser.so ./CppSharp/bin/Release_x64/libStd-symbols.so .
mkdir output && ./CppSharp/bin/Release_x64/CSharp.Gen -I core/include/triton/core -o ./output/
More errors:
Generating bindings for CSharp (CSharp)
Unable to translate macro 'MY_MACRO_TEST2_0' to en enum value: Variable [_invalid] unknown in expression : [0_invalid]
Linking library libStd-symbols.so...
Linking success.
Linking library libCSharp-symbols.so...
Linking success.
Symbol not found: _ZNSpecializationOfClassWithNonTypeTemplateArgumentD2Ev
Symbol not found: _ZN48SpecializationOfClassWithNonTypeTemplateArgumentC2Ev
Symbol not found: HasPureVirtualWithDefaultArg_HasPureVirtualWithDefaultArg
Symbol not found: ProtectedConstructorDestructor_ProtectedConstructorDestructor
But I couldn't figure out where the symbols _ZNSpecializationOfClassWithNonTypeTemplateArgumentD2Ev
, _ZN48SpecializationOfClassWithNonTypeTemplateArgumentC2Ev
, HasPureVirtualWithDefaultArg_HasPureVirtualWithDefaultArg
, ProtectedConstructorDestructor_ProtectedConstructorDestructor
are supposed to be coming from? from some CLR shared lib?
So somehow these are some test functions from CppSharp itself: https://github.com/mono/CppSharp/blob/b658ff32f126ecde6fb56d36558d42af7a518c04/tests/dotnet/CSharp/CSharpTemplates.h#L936
why is it searching for these symbols? Is it trying to run some tests?
And the Driver path gives this error. How do I make this Clang resource file findable?
Unhandled exception. System.Exception: Clang resource folder 'lib/clang/18/include' was not found.
at CppSharp.Parser.ParserOptions.SetupIncludes(TargetPlatform targetPlatform) in /home/runner/work/tritonservercppsharp/tritonservercppsharp/CppSharp/src/Parser/ParserOptions.cs:line 405
at CppSharp.Parser.ParserOptions.Setup(TargetPlatform targetPlatform) in /home/runner/work/tritonservercppsharp/tritonservercppsharp/CppSharp/src/Parser/ParserOptions.cs:line 293
at CppSharp.Driver.Setup() in /home/runner/work/tritonservercppsharp/tritonservercppsharp/CppSharp/src/Generator/Driver.cs:line [57](https://github.com/vadimkantorov/tritonservercppsharp/actions/runs/10461058179/job/28968586864#step:5:58)
at CppSharp.ConsoleDriver.Run(ILibrary library) in /home/runner/work/tritonservercppsharp/tritonservercppsharp/CppSharp/src/Generator/Driver.cs:line 399
at CppSharpTransformer.DllDemoGenerator.Main(String[] args) in /home/runner/work/tritonservercppsharp/tritonservercppsharp/tritonservercppsharp.cs:line 2
I've tried also using
CSharp.Gen
:cp ./CppSharp/bin/Release_x64/libCppSharp.CppParser.so ./CppSharp/bin/Release_x64/libStd-symbols.so . mkdir output && ./CppSharp/bin/Release_x64/CSharp.Gen -I core/include/triton/core -o ./output/
More errors:
Generating bindings for CSharp (CSharp) Unable to translate macro 'MY_MACRO_TEST2_0' to en enum value: Variable [_invalid] unknown in expression : [0_invalid] Linking library libStd-symbols.so... Linking success. Linking library libCSharp-symbols.so... Linking success. Symbol not found: _ZNSpecializationOfClassWithNonTypeTemplateArgumentD2Ev Symbol not found: _ZN48SpecializationOfClassWithNonTypeTemplateArgumentC2Ev Symbol not found: HasPureVirtualWithDefaultArg_HasPureVirtualWithDefaultArg Symbol not found: ProtectedConstructorDestructor_ProtectedConstructorDestructor
But I couldn't figure out where the symbols
_ZNSpecializationOfClassWithNonTypeTemplateArgumentD2Ev
,_ZN48SpecializationOfClassWithNonTypeTemplateArgumentC2Ev
,HasPureVirtualWithDefaultArg_HasPureVirtualWithDefaultArg
,ProtectedConstructorDestructor_ProtectedConstructorDestructor
are supposed to be coming from? from some CLR shared lib?So somehow these are some test functions from CppSharp itself:
why is it searching for these symbols? Is it trying to run some tests?
I think CSharp.Gen is just an artifact built for generating the tests bindings.
And the Driver path gives this error. How do I make this Clang resource file findable?
Sure, there should be a lib/clang
folder which should be copied into your bin folder.
Okay, I managed to build two variants. Some notes:
dotnet run
, this is a temp directory and certainly not the current directorydotnet ....exe
, but otherwise I could not make it work correctly with CppSharp built using dotnet
commandI guess I'll try now to bind the C++ headers at https://github.com/triton-inference-server/developer_tools/tree/main/server/include/triton/developer_tools
My overall impression: complete, fully self-contained examples are desperately needed (and especially of the ./CppSharp/bin/Release_x64/CppSharp.CLI
command usage), especially for someone un-versed in msbuild/dotnet command over-complicated madness.
name: tritonservercppsharp
on: workflow_dispatch
env:
PLATFORM: x64
FRAMEWORK: net80
FRAMEWORKDOT: net8.0
jobs:
tritonservercppsharp:
runs-on: ubuntu-22.04
steps:
- name: Clone tritonserver
run: |
git clone --single-branch --depth 1 --branch r24.08 https://github.com/triton-inference-server/core
git clone --single-branch --depth 1 --branch r24.08 https://github.com/triton-inference-server/developer_tools
- name: Clone and build CppSharp
run: |
git clone --single-branch --depth 1 https://github.com/mono/CppSharp
cd CppSharp
bash build/build.sh generate -configuration Release -platform $PLATFORM -target-framework $FRAMEWORK
bash build/build.sh download_llvm -platform $PLATFORM -target-framework $FRAMEWORK
bash build/build.sh restore -platform $PLATFORM -target-framework $FRAMEWORK
bash build/build.sh -platform $PLATFORM -build_only -target-framework $FRAMEWORK
- name: Variant 1
run: ./CppSharp/bin/Release_x64/CppSharp.CLI -m tritonserver -g csharp -p linux -a x64 -o ./variant1/ -I=core/include core/include/triton/core/tritonserver.h core/include/triton/core/tritonbackend.h core/include/triton/core/tritoncache.h core/include/triton/core/tritonrepoagent.h
- name: Variant 2
run: |
echo '<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory><OutputType>Exe</OutputType><TargetFramework>net8.0</TargetFramework><EnableDefaultItems>false</EnableDefaultItems></PropertyGroup><ItemGroup><Compile Remove="**/*.cs"/><Compile Include="tritonservercppsharp.cs"/><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Runtime.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.AST.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Generator.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.CLI.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Parser.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Parser.CSharp.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Parser.Bootstrap.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Parser.Gen.dll</HintPath></Reference></ItemGroup></Project>' > tritonservercppsharp.csproj
tee tritonservercppsharp.cs <<EOF
namespace CppSharpTransformer { public class DllDemoGenerator : CppSharp.ILibrary {
public static void Main(string[] args) { CppSharp.ConsoleDriver.Run(new DllDemoGenerator()); }
public void SetupPasses(CppSharp.Driver driver) { }
public void Preprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
public void Postprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
public void Setup(CppSharp.Driver driver) {
var options = driver.Options;
options.GeneratorKind = CppSharp.Generators.GeneratorKind.CSharp;
var module = options.AddModule("tritonserver");
options.OutputDir = "variant2";
module.IncludeDirs.Add(".");
module.IncludeDirs.Add("core/include");
module.Headers.Add("core/include/triton/core/tritonserver.h");
module.Headers.Add("core/include/triton/core/tritonbackend.h");
module.Headers.Add("core/include/triton/core/tritoncache.h");
module.Headers.Add("core/include/triton/core/tritonrepoagent.h");
//module.LibraryDirs.Add("/path/to/triton/server.so");
//module.Libraries.Add("tritonserver.so");
} } }
EOF
mkdir -p bin/x64/Release/$FRAMEWORKDOT && cp -r ./CppSharp/bin/Release_x64/lib bin/x64/Release/$FRAMEWORKDOT/lib
LD_PRELOAD=$PWD/CppSharp/bin/Release_x64/libCppSharp.CppParser.so:$PWD/CppSharp/bin/Release_x64/libStd-symbols.so dotnet run -c Release
- uses: actions/upload-artifact@v4
with:
path: |
variant1/
variant2/
Tried adding ./CppSharp/bin/Release_x64/CppSharp.CLI -m tritondevelopertoolsserver -g csharp -p linux -a x64 -o ./variant3/ -I=developer_tools/server/include -I=core/include -I=developer_tools/server/include/triton/developer_tools developer_tools/server/include/triton/developer_tools/server_wrapper.h developer_tools/server/include/triton/developer_tools/generic_server_wrapper.h developer_tools/server/include/triton/developer_tools/common.h
to wrap https://github.com/triton-inference-server/developer_tools/blob/main/server/include/triton/developer_tools/server_wrapper.h - getting an error error: no template named 'shared_ptr' in namespace 'std'
trying to wrap https://github.com/triton-inference-server/developer_tools/blob/main/server/include/triton/developer_tools/common.h. Does CppSharp support std::shared_ptr
? Could it be TypeMap'd? This seems quite a fundamental and a frequent type (especially in modern C++), probably worth supporting it for APIs in core CppSharp...
ServerOptions(
const std::vector<std::string>& model_repository_paths,
const LoggingOptions& logging, const MetricsOptions& metrics,
const std::vector<BackendConfig>& be_config, const std::string& server_id,
const std::string& backend_dir, const std::string& repo_agent_dir,
const bool disable_auto_complete_config,
const ModelControlMode& model_control_mode,
const int32_t repository_poll_secs,
const std::set<std::string>& startup_models,
const std::vector<RateLimitResource>& rate_limit_resource,
const int64_t pinned_memory_pool_byte_size,
const std::vector<CUDAMemoryPoolByteSize>& cuda_memory_pool_byte_size,
const uint64_t response_cache_byte_size,
const double& min_cuda_compute_capability, const bool exit_on_error,
const int32_t exit_timeout_secs,
const int32_t buffer_manager_thread_count,
const uint32_t model_load_thread_count,
const std::vector<ModelLoadGPULimit>& model_load_gpu_limit,
const std::vector<HostPolicy>& host_policy, std::shared_ptr<Trace> trace);
InferOptions(
const std::string& model_name, const int64_t model_version,
const std::string& request_id, const uint64_t correlation_id,
const std::string& correlation_id_str, const bool sequence_start,
const bool sequence_end, const uint64_t priority,
const uint64_t request_timeout,
std::shared_ptr<Allocator> custom_allocator,
std::shared_ptr<Trace> trace);
For this case, do I need to do
dotnet add package CppSharp
? And in both cases, which assemblies do I need to reference forcsc.dll
to get the basicCppSharp.ILibrary
andCppSharp.Driver
?I think these are the main ones:
* CppSharp * CppSharp.AST * CppSharp.Generator * CppSharp.Parser * CppSharp.Parser.CppSharp
I am not the best person to ask about Nuget as I rarely use it in my workflows.
But development versions are pushed to GitHub packages:
dotnet nuget push "*.nupkg" --api-key ${{ secrets.GITHUB_TOKEN }} --source "https://nuget.pkg.github.com/mono/index.json" --skip-duplicate
https://github.com/mono/CppSharp/pkgs/nuget/CppSharp
The last version says it was published 4 months ago, so maybe publishing for ongoing development commits is not working correctly after all.
I was not able build package via scripts on windows so I made nuspec file which works to get some context... although I'm pretty sure it is dropping lib files at the moment.
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>CppSharp</id>
<version>x.y.z</version>
<authors>CppSharp Devs</authors>
<owners>Mono</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>YOU!</description>
<dependencies>
<dependency id="Microsoft.Win32.Registry" version="5.0.0"/>
</dependencies>
<contentFiles>
<files include="any/any/**/*.h" buildAction="Content" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src="bin\Release_x64\CppSharp.dll" target="lib\netstandard2.1" />
<file src="bin\Release_x64\CppSharp.AST.dll" target="lib\netstandard2.1" />
<file src="bin\Release_x64\CppSharp.Generator.dll" target="lib\netstandard2.1" />
<file src="bin\Release_x64\CppSharp.Parser.dll" target="lib\netstandard2.1" />
<file src="bin\Release_x64\CppSharp.CppParser.dll" target="lib\netstandard2.1" />
<file src="bin\Release_x64\CppSharp.CppParser.lib" target="lib\netstandard2.1" />
<file src="bin\Release_x64\CppSharp.Parser.CLI.dll" target="lib\netstandard2.1" />
<file src="bin\Release_x64\CppSharp.Parser.CLI.lib" target="lib\netstandard2.1" />
<file src="bin\Release_x64\Std-symbols.dll" target="lib\netstandard2.1" />
<file src="bin\Release_x64\Std-symbols.lib" target="lib\netstandard2.1" />
<file src="bin\Release_x64\Ijwhost.dll" target="lib\netstandard2.1" />
<!-- Clang headers which path changes depend upon what version of Clang is downloaded -->
<!-- Are needed see "Parser/ParserOptions.cs" -->
<file src="build\llvm\llvm-6eb36a-windows-vs2022-x64-RelWithDebInfo\lib\**\include\**\*.h" target="contentFiles\any\any\lib\" />
</files>
</package>
What is CppSharp behavior for binding C++ classes destructors? Does it generate Dispose
methods calling the destructor? Does it generate C# finalizers calling Dispose/destructors?
Regarding binding std::shared_ptr<T>
- maybe System.Nullable<T>
could be somewhat abused to represent std::shared_ptr<T>
(might be good as it's a system type always present, so "copies" of this type in bindings of several separately generated bindings are not needed)? Or maybe some new Box<T>
or similar could be produced
In modern C++, plenty of various pointer wrappers could now be used in APIs like std::unique_ptr<T>
and others... So it's important to have some binding of them (even if not fully performant or requiring additional user's manual intervention to trigger garbage collection / call destructors)
Otherwise, in C# classes have reference/shared_ptr-like semantics anyway, so maybe no wrappers are needed...
Tried adding
./CppSharp/bin/Release_x64/CppSharp.CLI -m tritondevelopertoolsserver -g csharp -p linux -a x64 -o ./variant3/ -I=developer_tools/server/include -I=core/include -I=developer_tools/server/include/triton/developer_tools developer_tools/server/include/triton/developer_tools/server_wrapper.h developer_tools/server/include/triton/developer_tools/generic_server_wrapper.h developer_tools/server/include/triton/developer_tools/common.h
to wrap https://github.com/triton-inference-server/developer_tools/blob/main/server/include/triton/developer_tools/server_wrapper.h - getting an error
error: no template named 'shared_ptr' in namespace 'std'
trying to wrap https://github.com/triton-inference-server/developer_tools/blob/main/server/include/triton/developer_tools/common.h. Does CppSharp supportstd::shared_ptr
?
We do not support shared_ptr
, but this error is actually just a general parsing error. That header is not designed to be included on its own, and does not include all its own dependencies, so in this case its just a general C++ issue, would happen with a regular compiler too.
What is CppSharp behavior for binding C++ classes destructors? Does it generate
Dispose
methods calling the destructor? Does it generate C# finalizers calling Dispose/destructors?
Yes, see the GenerateFinalizers
option: https://github.com/mono/CppSharp/blob/345de8b/src/Generator/Options.cs#L125
Regarding binding
std::shared_ptr<T>
- maybeSystem.Nullable<T>
could be somewhat abused to representstd::shared_ptr<T>
(might be good as it's a system type always present, so "copies" of this type in bindings of several separately generated bindings are not needed)? Or maybe some newBox<T>
or similar could be produced
We could start by just allowing for manual reference count increase and decrease, which at least would already allow supporting those objects. But the main reason I did not spend too much time with standard library constructs is that it leads to non portable bindings, where you need generated C# bindings code for each ABI, which complicates packaging and distribution on the C# side.
Hence I always recommend modifying the original C++ code, or creating a portable wrapper on top of it. You can check out the Cpp
generator type in CppSharp for this task, I have used it before to create a pure C++ wrapper of a complicated C++ library. That in turns was used to generate C# bindings with CppSharp.
Thanks for explaining! Deleting common.h
from the command gives and succeeds. How does it succeed without shared_ptr support? :)
./CppSharp/bin/Release_x64/CppSharp.CLI -m tritondevelopertoolsserver -g csharp -p linux -a x64 -o ./variant3/ -I=developer_tools/server/include -I=core/include -I=developer_tools/server/include/triton/developer_tools developer_tools/server/include/triton/developer_tools/server_wrapper.h developer_tools/server/include/triton/developer_tools/generic_server_wrapper.h
Generating C# bindings for Linux x64...
Parsing libraries...
Parsing code...
Parsed '/home/runner/work/tritonservercppsharp/tritonservercppsharp/developer_tools/server/include/triton/developer_tools/server_wrapper.h, /home/runner/work/tritonservercppsharp/tritonservercppsharp/developer_tools/server/include/triton/developer_tools/generic_server_wrapper.h'
Processing code...
Generating code...
Generated 'Std.cs'
Generated 'developer_tools.cs'
I think for bindings not distributed publicly but generated, compiled and consumed on the target platform, it is okay to support non-ABI-portable things like shared_ptr
. For reference, https://github.com/triton-inference-server/server/blob/main/docs/customization_guide/inference_protocols.md#java-bindings-for-in-process-triton-server-api also distribute these Java bindings (although do not recommend using them) to these same C++ code: https://github.com/bytedeco/javacpp-presets/tree/master/tritonserver/src/gen/java/org/bytedeco/tritonserver/tritondevelopertoolsserver
So overall, JavaCpp seems to support shared_ptr: https://github.com/bytedeco/javacpp/discussions/623
Maybe for CppSharp, the model of a single repo with GitHub Actions - i.e. JavaCpp presets repo: https://github.com/bytedeco/javacpp-presets, reproducbile bindings generation could also be very useful: https://github.com/bytedeco/javacpp-presets
Thanks for explaining! Deleting
common.h
from the command gives and succeeds. How does it succeed without shared_ptr support? :)
It will ignore any methods and fields that are not supported, so the binding can still be generated.
I think for bindings not distributed publicly but generated, compiled and consumed on the target platform, it is okay to support non-ABI-portable things like
shared_ptr
. For reference, https://github.com/triton-inference-server/server/blob/main/docs/customization_guide/inference_protocols.md#java-bindings-for-in-process-triton-server-api also distribute these Java bindings (although do not recommend using them) to these same C++ code: https://github.com/bytedeco/javacpp-presets/tree/master/tritonserver/src/gen/java/org/bytedeco/tritonserver/tritondevelopertoolsserverSo overall, JavaCpp seems to support shared_ptr: bytedeco/javacpp#623
They support it by generating C++ code (with JNI) which is a lot more doable for C++ standard library constructs. And somewhat equivalent to what I said before about generating pure C++ bindings with the Cpp generator in CppSharp.
With the regular CppSharp approach, it only generates C++ code for inline symbols for which there is absolute no other way. We currently support std::string by drilling down into the templates from the standard library implementation and having specific code for that: https://github.com/mono/CppSharp/blob/main/src/Generator/Types/Std/Stdlib.CSharp.cs#L304
Its doable to do the same for other C++ std lib types, but overall its somewhat complicated and error prone.
I'd probably switch to the approach of generating supporting C++ code, helper functions to wrap std::
types, which would make it much easier to extend and support all of C++ more easily.
Maybe for CppSharp, the model of a single repo with GitHub Actions - i.e. JavaCpp presets repo: https://github.com/bytedeco/javacpp-presets, reproducbile bindings generation could also be very useful: https://github.com/bytedeco/javacpp-presets
No doubt, this would be great, was always on my mind, but its a lot of work to setup and maintain, so unless someone else is willing to do the dirty work, its not going to happen from my side.
We currently support std::string by drilling down into the templates from the standard library implementation and having specific code for that:
Maybe then an example/recipe in the docs for adding non-portable support for shared_ptr
via some hacks (since C# reference types already have some sort of shared_ptr
semantics already) and showcase TypeMap... For the user's particular platform/compiler/libstdc++.
No doubt, this would be great, was always on my mind, but its a lot of work to setup and maintain
Maybe if it's not to support a high-quality bar and just be a place where people contribute single-file, self-contained GitHub Actions workflow files as examples, then the maintenance bar would be lower and some reproducibility would be preserved. And also might be nice if https://github.com/dotnet org or https://dotnetfoundation.org/ sponsored/supported this effort...
They support it by generating C++ code (with JNI) which is a lot more doable for C++ standard library constructs. And somewhat equivalent to what I said before about generating pure C++ bindings with the Cpp generator in CppSharp. With the regular CppSharp approach, it only generates C++ code for inline symbols for which there is absolute no other way.
But yeah, I see what you mean...
UPD: the missing
std::shared_ptr<T>
support context is in the message https://github.com/mono/CppSharp/issues/1860#issuecomment-2297731111. Currently this support seems missing, andshared_ptr
/unique_ptr
are quite common types in modern C++ APIs to be processedJavaCpp seems to support binding
std::shared_ptr<T>
: https://github.com/bytedeco/javacpp/discussions/623Below is a very long thread where we ended up rolling a fully complete GitHub Actions Workflow file.
GitHub Actions allow for a reproducible environment, so pulling in-tree a collection of GitHub Actions workflow files for popular libraries from https://github.com/mono/CppSharp?tab=readme-ov-file#users (like ffmpeg or dearimgui) could be a great start for new users showcasing the install procedures.
And sometimes it would be possible to just copy the filly self-contained workflow-file and modify it to create a command for binding-generation for a new library. Then users could send PRs with such workflows/scripts, and they could be tested easily (and especially - tested against new versions of the libraries). Currently https://github.com/mono/CppSharp/tree/main/tests doesn't have many real-world library examples.
I found https://github.com/mono/CppSharp/blob/main/.github/workflows/main.yml. Could it be considered a base for such a workflow file producing a fully functioning llvm+CppSharp install?