From 4467b57dc97f4a009ecd2438ff03b3051dc82e84 Mon Sep 17 00:00:00 2001 From: Lauro Moura Date: Wed, 2 Oct 2019 16:12:44 -0300 Subject: [PATCH] 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 (/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_sharp.csproj.in | 39 +++++ src/bindings/mono/eo_mono/EoWrapper.cs | 1 + src/bindings/mono/meson.build | 96 +++++++---- .../efl_mono/efl_sharp_test_suite.csproj.in | 36 +++++ src/tests/efl_mono/meson.build | 150 +++++++++++------- 6 files changed, 233 insertions(+), 95 deletions(-) create mode 100644 src/bindings/mono/efl_sharp.csproj.in create mode 100644 src/tests/efl_mono/efl_sharp_test_suite.csproj.in diff --git a/meson_options.txt b/meson_options.txt index 33e74dedbbb..6d74ced2930 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -330,6 +330,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_sharp.csproj.in b/src/bindings/mono/efl_sharp.csproj.in new file mode 100644 index 00000000000..4286c5666db --- /dev/null +++ b/src/bindings/mono/efl_sharp.csproj.in @@ -0,0 +1,39 @@ + + + + Library + netstandard2.0 + + + + Efl.Csharp + @EFL_VERSION@ + EFL Team + Apache-2.0 + + + + + + + @EFL_BETA@ + + + + + + + + + + + + + + + + + + diff --git a/src/bindings/mono/eo_mono/EoWrapper.cs b/src/bindings/mono/eo_mono/EoWrapper.cs index 79d597c7b65..37f4a9c2182 100644 --- a/src/bindings/mono/eo_mono/EoWrapper.cs +++ b/src/bindings/mono/eo_mono/EoWrapper.cs @@ -419,6 +419,7 @@ private static IntPtr Constructor(IntPtr obj, IntPtr pd) /// allow minimal interaction with them through . /// /// But as is abstract, whis realized class will allow us to create C# instances of it. +[Efl.Object.NativeMethods] internal class ObjectRealized : Efl.Object { protected ObjectRealized(Efl.Eo.Globals.WrappingHandle ch) : base(ch) { } diff --git a/src/bindings/mono/meson.build b/src/bindings/mono/meson.build index dbdacd88c85..f768e341000 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, ], # @@ -154,16 +132,64 @@ 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.') -meson.add_install_script(join_paths(meson.source_root(), 'meson', 'meson_csharp_docs.sh'), - efl_mono_xml_doc, - efl_mono_install_dir) + lib_csproj_conf_data = configuration_data() + + lib_csproj_conf_data.set('BINDING_SRC', meson.current_source_dir()) + lib_csproj_conf_data.set('EFL_VERSION', meson.project_version()) + + 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 00000000000..38fdc50a013 --- /dev/null +++ b/src/tests/efl_mono/efl_sharp_test_suite.csproj.in @@ -0,0 +1,36 @@ + + + + Exe + netcoreapp2.0 + + + + Efl.Csharp.Test.Suite + @EFL_VERSION@ + EFL Team + Apache-2.0 + + + + @EFL_BETA@ + + + + + + + + + + + + + + diff --git a/src/tests/efl_mono/meson.build b/src/tests/efl_mono/meson.build index d7cd6bbff70..dcad80bd173 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,86 @@ 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()) + + 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', + 'netcoreapp2.0', + 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 +155,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