lauromoura pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=17a81bee4a53891e44a165a14ca20027f9aa0824

commit 17a81bee4a53891e44a165a14ca20027f9aa0824
Author: Lauro Moura <[email protected]>
Date:   Tue Nov 5 17:59:01 2019 -0300

    csharp: Revamp dotnet support
    
    Summary:
    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] https://github.com/mesonbuild/meson/issues/2320
    
    Fixes T8168
    
    Reviewers: bu5hm4n, woohyun, Jaehyun_Cho
    
    Reviewed By: Jaehyun_Cho
    
    Subscribers: cedric, brunobelo, felipealmeida, segfaultxavi
    
    Tags: #efl, #do_not_merge
    
    Maniphest Tasks: T8168
    
    Differential Revision: https://phab.enlightenment.org/D9717
---
 meson_options.txt                                 |   6 +
 src/bindings/mono/efl_mono/meson.build            |   7 +-
 src/bindings/mono/efl_sharp.csproj.in             |  39 ++++++
 src/bindings/mono/eo_mono/EoWrapper.cs            |   1 +
 src/bindings/mono/meson.build                     | 113 +++++++++++-----
 src/tests/efl_mono/efl_sharp_test_suite.csproj.in |  36 +++++
 src/tests/efl_mono/meson.build                    | 152 +++++++++++++---------
 7 files changed, 257 insertions(+), 97 deletions(-)

diff --git a/meson_options.txt b/meson_options.txt
index 66ef0257f4..42a7397ac4 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -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'],
diff --git a/src/bindings/mono/efl_mono/meson.build 
b/src/bindings/mono/efl_mono/meson.build
index 6542f5124a..8bfba319c1 100644
--- a/src/bindings/mono/efl_mono/meson.build
+++ b/src/bindings/mono/efl_mono/meson.build
@@ -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
diff --git a/src/bindings/mono/efl_sharp.csproj.in 
b/src/bindings/mono/efl_sharp.csproj.in
new file mode 100644
index 0000000000..d44aa5a8e5
--- /dev/null
+++ b/src/bindings/mono/efl_sharp.csproj.in
@@ -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>
diff --git a/src/bindings/mono/eo_mono/EoWrapper.cs 
b/src/bindings/mono/eo_mono/EoWrapper.cs
index 621a8bca68..4209fa7978 100644
--- a/src/bindings/mono/eo_mono/EoWrapper.cs
+++ b/src/bindings/mono/eo_mono/EoWrapper.cs
@@ -483,6 +483,7 @@ public abstract class EoWrapper : IWrapper, IDisposable
 /// 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) { }
diff --git a/src/bindings/mono/meson.build b/src/bindings/mono/meson.build
index 9545aa1cd2..86cef4d089 100644
--- a/src/bindings/mono/meson.build
+++ b/src/bindings/mono/meson.build
@@ -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, ], #
@@ -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())
 
diff --git a/src/tests/efl_mono/efl_sharp_test_suite.csproj.in 
b/src/tests/efl_mono/efl_sharp_test_suite.csproj.in
new file mode 100644
index 0000000000..c23636345c
--- /dev/null
+++ b/src/tests/efl_mono/efl_sharp_test_suite.csproj.in
@@ -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>
+
diff --git a/src/tests/efl_mono/meson.build b/src/tests/efl_mono/meson.build
index d7cd6bbff7..9b58563516 100644
--- a/src/tests/efl_mono/meson.build
+++ b/src/tests/efl_mono/meson.build
@@ -1,3 +1,4 @@
+# Generation of .eo.cs files and test library common to dotnet and mono
 eo_files = [
     'dummy_child.eo',
     'dummy_numberwrapper.eo',
@@ -56,68 +57,88 @@ foreach mono_gen_file : eo_files
                                 '@INPUT@'])
 endforeach
 
-efl_mono_test = library('efl_mono_test',
-    eo_file_targets,
-    link_with : [efl_mono],
+if get_option('dotnet')
+
+  dotnet_test_conf_data = configuration_data()
+
+  dotnet_test_conf_data.set('EFL_VERSION', meson.project_version())
+  dotnet_test_conf_data.set('BINDING_BUILD', 
join_paths(meson.current_build_dir(),
+                                                        '..', '..', 
'bindings', 'mono'))
+  dotnet_test_conf_data.set('BINDING_TEST_SRC', meson.current_source_dir())
+
+  dotnet_test_conf_data.set('NETCOREAPP_VERSION', dotnet_core_app_version)
+
+  if get_option('mono-beta')
+    dotnet_test_conf_data.set('EFL_BETA', 'EFL_BETA')
+  else
+    dotnet_test_conf_data.set('EFL_BETA', '')
+  endif
+
+  dotnet_test_csproj = configure_file(input: 'efl_sharp_test_suite.csproj.in',
+                                      output: 'efl_sharp_test_suite.csproj',
+                                      configuration: dotnet_test_conf_data,
+  )
+
+  efl_mono_suite = custom_target('efl_mono_test',
+    input: eo_file_targets + [dotnet_test_csproj],
+    output: 'efl_sharp_test_suite.dll',
+    depends: [efl_mono],
+    build_by_default: true,
+    command: [dotnet,
+              'build',
+              '-o',
+              meson.current_build_dir(),
+              '--framework',
+              'netcoreapp' + dotnet_core_app_version,
+              dotnet_test_csproj],
+  )
+
+else
+  efl_mono_test = library('efl_mono_test',
+      eo_file_targets,
+      link_with : [efl_mono],
+      cs_args : extra_cs_args
+  )
+
+  efl_mono_src = [
+       'Main.cs',
+       'TestUtils.cs',
+       'EinaTestData.cs',
+       'StructHelpers.cs',
+       'BasicDirection.cs',
+       'Eina.cs',
+       'Eldbus.cs',
+       'Eo.cs',
+       'EoPromises.cs',
+       'EoConstruction.cs',
+       'Errors.cs',
+       'Events.cs',
+       'FunctionPointers.cs',
+       'FunctionPointerMarshalling.cs',
+       'Model.cs',
+       'Parts.cs',
+       'Promises.cs',
+       'Strbuf.cs',
+       'Strings.cs',
+       'Structs.cs',
+       'Value.cs',
+       'ValueEolian.cs',
+       'Inheritance.cs',
+       'Hash.cs'
+  ]
+
+  efl_mono_suite = executable('efl-mono-suite',
+    efl_mono_src,
+    link_with : [efl_mono, efl_mono_test],
     cs_args : extra_cs_args
-)
-
-efl_mono_src = [
-     'Main.cs',
-     'TestUtils.cs',
-     'EinaTestData.cs',
-     'StructHelpers.cs',
-     'BasicDirection.cs',
-     'Eina.cs',
-     'Eldbus.cs',
-     'Eo.cs',
-     'EoPromises.cs',
-     'EoConstruction.cs',
-     'Errors.cs',
-     'Events.cs',
-     'FunctionPointers.cs',
-     'FunctionPointerMarshalling.cs',
-     'Model.cs',
-     'Parts.cs',
-     'Promises.cs',
-     'Strbuf.cs',
-     'Strings.cs',
-     'Structs.cs',
-     'Value.cs',
-     'ValueEolian.cs',
-     'Inheritance.cs',
-     'Hash.cs'
-]
-
-efl_mono_suite = executable('efl-mono-suite',
-  efl_mono_src,
-  link_with : [efl_mono, efl_mono_test],
-  cs_args : extra_cs_args
-)
+  )
+endif
 
+# Common environment shared by both dotnet and mono
 env_mono = environment()
 env_mono.set('MONO_PATH', efl_mono_test_suite_path )
 env_mono.set('EFL_RUN_IN_TREE', '1')
 
-if (cs_is_dotnet)
-copy_prog = find_program(['cp', 'copy'])
-
-configure_file(input : 'efl-mono-suite.runtimeconfig.json',
-               output : 'efl-mono-suite.runtimeconfig.json',
-               copy : true)
-
-custom_target('copy_efl_mono_dll',
-              build_by_default : true,
-              input : efl_mono,
-              output : efl_mono.full_path().split('/')[-1],
-              command : [copy_prog, '@INPUT@', '@OUTPUT@'])
-
-custom_target('copy_efl_mono_lib_dll',
-              build_by_default : true,
-              input : efl_mono_lib,
-              output : efl_mono_lib.full_path().split('/')[-1],
-              command : [copy_prog, '@INPUT@', '@OUTPUT@'])
-endif
 
 config_libs = ['eina', 'ecore', 'eo', 'efl', 'evas', 'eldbus', 'elementary', 
'efl_mono']
 load_lib = efl_mono_test_suite_path + ':'
@@ -136,9 +157,20 @@ foreach config : config_libs
   load_lib += repaired_path+':'
 endforeach
 
+load_lib += ':' + meson.current_build_dir()
+
 env_mono.set('LD_LIBRARY_PATH', load_lib)
 
-test('efl-mono-suite',
-  efl_mono_suite,
-  env : env_mono
-)
+
+if get_option('dotnet')
+  test('efl-mono-suite',
+    dotnet,
+    args: [join_paths(meson.current_build_dir(), 'efl_sharp_test_suite.dll')],
+    env: env_mono,
+  )
+else
+  test('efl-mono-suite',
+    efl_mono_suite,
+    env : env_mono
+  )
+endif

-- 


Reply via email to