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 @@ + + + + Library + netstandard@NETSTANDARD_VERSION@ + + + + 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 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 . /// /// But as is abstract, whis realized class will allow us to create C# instances of it. +[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.') -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() + + 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()) + + 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 @@ + + + + Exe + netcoreapp@NETCOREAPP_VERSION@ + + + + 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 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