Skip to content

Commit

Permalink
csharp: Revamp dotnet support
Browse files Browse the repository at this point in the history
Instead of building with a patched meson version, make use of custom
targets and generated csproj files so we can used upstream meson
normally.

This avoids digging into "non official" dotnet stuff like calling
the CSC.dll directly that the patched meson tried to do.

To enable, run meson with `-Ddotnet=true`.

Regarding source file dependencies, Meson has a limitation[1]
about generated artifacts being placed in subdirectories.

In order to correctly track these generated artifacts for dotnet, we
generated them in the same folder as the csproj file through
`dotnet build -o`.

Instead of installing the dll like we do for mono, a nupkg is generated
and installed in the same folder as the dll would be
(<prefix>/lib/x86_64-linux-gnu/efl-mono-1)

To avoid messing around with Nupkg caches, we reference the source
project for the library directly instead of the nupkg when building the
test suite.

[1] mesonbuild/meson#2320

Fixes T8168
Differential Revision: https://phab.enlightenment.org/D9717
  • Loading branch information
lauromoura authored and marcelhollerbach committed Nov 5, 2019
1 parent 6108ea0 commit f7f616c
Show file tree
Hide file tree
Showing 7 changed files with 257 additions and 97 deletions.
6 changes: 6 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,12 @@ option('mono-examples-dir',
description: 'Where eolian_mono will search for examples to embed into the documentation'
)

option('dotnet',
type: 'boolean',
value: false,
description: 'Enable building C# bindings with dotnet instead of mono'
)

option('lua-interpreter',
type: 'combo',
choices: ['luajit', 'lua'],
Expand Down
7 changes: 5 additions & 2 deletions src/bindings/mono/efl_mono/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ efl_src = configure_file(
friend_assemblies = ''
mono_friend_assemblies = get_option('mono-friend-assemblies')
if get_option('build-tests')
mono_friend_assemblies += 'efl-mono-suite'
mono_friend_assemblies += 'efl_mono_test'
if get_option('dotnet')
mono_friend_assemblies += 'efl_sharp_test_suite'
else
mono_friend_assemblies += 'efl_mono_test'
endif
endif

foreach f : mono_friend_assemblies
Expand Down
39 changes: 39 additions & 0 deletions src/bindings/mono/efl_sharp.csproj.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>netstandard@NETSTANDARD_VERSION@</TargetFramework>
</PropertyGroup>

<PropertyGroup>
<PackageId>Efl.Csharp</PackageId>
<Version>@EFL_VERSION@</Version>
<Authors>EFL Team</Authors>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
</PropertyGroup>

<!-- <PropertyGroup Condition="'$(BuildType)'=='Beta'"> -->
<!-- <DefineConstants>EFL_BETA</DefineConstants> -->
<!-- </PropertyGroup> -->
<PropertyGroup>
<DefineConstants>@EFL_BETA@</DefineConstants>
</PropertyGroup>

<ItemGroup>
<Compile Include="@BINDING_SRC@/efl_mono/*.cs" />
<!-- FIXME Windows support -->
<Compile Include="@BINDING_SRC@/eo_mono/*.cs" Exclude="@BINDING_SRC@/eo_mono/*Windows.cs" />
<Compile Include="@BINDING_SRC@/eina_mono/*.cs" />
<Compile Include="@BINDING_SRC@/eolian_mono/*.cs" />
<Compile Include="@BINDING_SRC@/eldbus_mono/*.cs" />
</ItemGroup>

<!-- Calling `dotnet build` from a different folder seems to mess up the automatic source file discovery.
But we want them to be included only when building the lib itself.
-->
<ItemGroup Condition="'$(BuildingLib)'=='Yes'">
<Compile Include="./efl_mono/*.cs" />
<Compile Include="./*.cs" />
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions src/bindings/mono/eo_mono/EoWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ private static IntPtr Constructor(IntPtr obj, IntPtr pd)
/// allow minimal interaction with them through <see cref="Efl.Object" />.
///
/// But as <see cref="Efl.Object" /> is abstract, whis realized class will allow us to create C# instances of it.</summary>
[Efl.Object.NativeMethods]
internal class ObjectRealized : Efl.Object
{
internal ObjectRealized(Efl.Eo.WrappingHandle ch) : base(ch) { }
Expand Down
113 changes: 78 additions & 35 deletions src/bindings/mono/meson.build
Original file line number Diff line number Diff line change
@@ -1,33 +1,11 @@
add_languages('cs')
# dotnet supports cs files indirectly through custom_targets
if not get_option('dotnet')
add_languages('cs')
endif


runtime_assemblies = []

# Check if we should use dotnet options
cs_is_dotnet = meson.get_compiler('cs').get_id().contains('dotnet')

if (cs_is_dotnet)

warning('Dotnet support is still not upstream in meson.')

runtime_assemblies += [
'-r:System.Console.dll',
'-r:Microsoft.CSharp.dll',
'-r:System.Collections.dll',
'-r:System.Collections.Concurrent.dll',
'-r:System.ComponentModel.Primitives.dll',
'-r:System.ComponentModel.Primitives.dll',
'-r:System.Diagnostics.Debug.dll',
'-r:System.Diagnostics.TraceSource.dll',
'-r:System.Dynamic.Runtime.dll',
'-r:System.Linq.dll',
'-r:System.Runtime.dll',
'-r:System.Runtime.Extensions.dll',
'-r:System.Security.dll',
]

endif

mono_sublibs = [
['Eina', true, ], #
['Eolian', true, ], #
Expand Down Expand Up @@ -158,16 +136,81 @@ endif
efl_mono_install_dir = join_paths(dir_lib, 'efl-mono-'+version_major)
efl_mono_xml_doc = join_paths(meson.current_build_dir(), 'efl_mono.xml')

efl_mono = library('efl_mono',
mono_generator_target + mono_files + [efl_src],
install : true,
install_dir : efl_mono_install_dir,
cs_args : extra_cs_args + ['-doc:' + efl_mono_xml_doc, '-warnaserror+']
)
if (get_option('dotnet'))
dotnet = find_program('dotnet')
warning('Dotnet support is still experimental.')

lib_csproj_conf_data = configuration_data()

dotnet_version = run_command(dotnet, ['--version'], check: true)
message('Found dotnet core version ' + dotnet_version.stdout().strip())

# The major version should be enough for now while we don't have to deal
# with minor differences and dotnet core is far from version 10
dotnet_major_version = dotnet_version.stdout().strip()[0].to_int()
if dotnet_major_version == 3
dotnet_core_app_version = '3.0'
dotnet_standard_version = '2.1'
elif dotnet_major_version == 2
dotnet_core_app_version = '2.0'
dotnet_standard_version = '2.0'
else
error('Unsupported dotnet version. Must be at least 2.2')
endif

lib_csproj_conf_data.set('NETSTANDARD_VERSION', dotnet_standard_version)
lib_csproj_conf_data.set('BINDING_SRC', meson.current_source_dir())
lib_csproj_conf_data.set('EFL_VERSION', meson.project_version())

meson.add_install_script(join_paths(meson.source_root(), 'meson', 'meson_csharp_docs.sh'),
efl_mono_xml_doc,
efl_mono_install_dir)
if get_option('mono-beta')
lib_csproj_conf_data.set('EFL_BETA', 'EFL_BETA')
else
lib_csproj_conf_data.set('EFL_BETA', '')
endif

lib_csproj = configure_file(input: 'efl_sharp.csproj.in',
output: 'efl_sharp.csproj',
configuration: lib_csproj_conf_data)

efl_mono = custom_target('efl_mono',
input: mono_generator_target + mono_files + [efl_src] + [lib_csproj],
output: 'efl_sharp.dll',
build_by_default: true,
command: [dotnet,
'build',
'-o', meson.current_build_dir(),
'-p:BuildingLib=Yes',
lib_csproj],
install: true,
install_dir: efl_mono_install_dir,
)

efl_mono_pack = custom_target('efl_mono_nuget',
input: lib_csproj,
output: 'Efl.Csharp.' + meson.project_version() + '.nupkg',
depends: [efl_mono],
command: [dotnet,
'pack',
'-o', meson.current_build_dir(),
'-p:BuildingLib=No',
lib_csproj],
install: true,
install_dir: efl_mono_install_dir,
)

else

efl_mono = library('efl_mono',
mono_generator_target + mono_files + [efl_src],
install : true,
install_dir : efl_mono_install_dir,
cs_args : extra_cs_args + ['-doc:' + efl_mono_xml_doc, '-warnaserror+']
)

meson.add_install_script(join_paths(meson.source_root(), 'meson', 'meson_csharp_docs.sh'),
efl_mono_xml_doc,
efl_mono_install_dir)
endif

efl_mono_test_suite_path=join_paths(meson.current_build_dir())

Expand Down
36 changes: 36 additions & 0 deletions src/tests/efl_mono/efl_sharp_test_suite.csproj.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp@NETCOREAPP_VERSION@</TargetFramework>
</PropertyGroup>

<PropertyGroup>
<PackageId>Efl.Csharp.Test.Suite</PackageId>
<Version>@EFL_VERSION@</Version>
<Authors>EFL Team</Authors>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
</PropertyGroup>

<PropertyGroup>
<DefineConstants>@EFL_BETA@</DefineConstants>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="../../bindings/mono/efl_sharp.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Include="@BINDING_TEST_SRC@/*.cs" />
<!-- Somehow dotnet build -o DIR seems to miss the genenerated files despite
them being in the same folder as the csproj file. The line below makes
sure we include them.

The side effect is that invoking directly `dotnet build` will raise "source file FOO
already included" warnings.
-->
<Compile Include="./*.cs" />
</ItemGroup>

</Project>

Loading

0 comments on commit f7f616c

Please sign in to comment.