diff --git a/.travis.yml b/.travis.yml
index 7247a0c10..872d7ba2c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,4 +9,4 @@ before_install:
- sudo pip3 install git+https://github.com/mesonbuild/meson/
script:
- - meson build/ && ninja -C build/
+ - meson build/ && ninja -C build/ test
diff --git a/Source/atk/generated/meson.build b/Source/atk/generated/meson.build
index e62cb9f62..7da249fc6 100644
--- a/Source/atk/generated/meson.build
+++ b/Source/atk/generated/meson.build
@@ -109,13 +109,28 @@ source_gen = custom_target('atk_generated',
'--extra-includes', glib_api_includes,
'--out', meson.current_build_dir(),
'--files', ';'.join(generated_sources),
- '--assembly-name', meson.project_name()
+ '--assembly-name', assembly_name,
+ '--glue-includes', 'atk/atk.h',
+ '--abi-cs-usings', 'Atk,GLib',
],
depends: [gapi_codegen, gapi_fixup],
input: raw_api_fname,
output: generated_sources,
)
+c_abi = custom_target(assembly_name + '_c_abi',
+ input: raw_api_fname,
+ output: assembly_name + '-abi.c',
+ command: [generate_api, '--fakeglue'],
+ depends: [source_gen])
+
+cs_abi = custom_target(assembly_name + '_cs_abi',
+ input: raw_api_fname,
+ output: assembly_name + '-abi.cs',
+ command: [generate_api, '--fakeglue'],
+ depends: [source_gen])
+
+
api_xml = custom_target(pkg + '_api_xml',
input: raw_api_fname,
output: pkg + '-api.xml',
diff --git a/Source/atk/meson.build b/Source/atk/meson.build
index 8298dd306..2fd72f9b1 100644
--- a/Source/atk/meson.build
+++ b/Source/atk/meson.build
@@ -31,3 +31,14 @@ atk_sharp = library(assembly_name, source_gen, sources, assemblyinfo,
nuget_infos += [['AtkSharp', atk_sharp, ['GlibSharp', 'GioSharp']]]
install_infos += [assembly_name, atk_sharp.full_path()]
atk_sharp_dep = declare_dependency(link_with: [glib_sharp, atk_sharp])
+
+if add_languages('c', required: false)
+ c_abi_exe = executable(assembly_name + '_c_abi', c_abi,
+ dependencies: [glib_dep, atk_dep])
+
+ cs_abi_exe = executable(assembly_name + '_cs_abi', cs_abi,
+ cs_args: ['-nowarn:169', '-nowarn:108', '-nowarn:114', '-nowarn:0618', '-unsafe'],
+ dependencies: [atk_sharp_dep])
+
+ test(assembly_name + 'abi', diff, args: [c_abi_exe.full_path(), cs_abi_exe.full_path()])
+endif
diff --git a/Source/audit/test_abi.py b/Source/audit/test_abi.py
new file mode 100755
index 000000000..838801cab
--- /dev/null
+++ b/Source/audit/test_abi.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+
+import difflib
+import sys
+import shutil
+import subprocess
+
+reference_abi = subprocess.check_output(sys.argv[1]).decode().split("\n")
+launcher = []
+if shutil.which("mono"):
+ launcher = ["mono", "--debug"]
+csharp_abi = subprocess.check_output(launcher + [sys.argv[2]]).decode().split("\n")
+print("Comparing output of %s and %s" % (sys.argv[1], sys.argv[2]))
+
+res = 0
+for line in difflib.unified_diff(reference_abi, csharp_abi):
+ res = 1
+ print(line)
+
+if res:
+ files = [(sys.argv[1] + ".res", reference_abi),
+ (sys.argv[2] + 'res', csharp_abi)]
+
+ for f, vals in files:
+ with open(f, "w") as _f:
+ print("Outputing results in " + f)
+ _f.write("\n".join(vals))
+sys.exit(res)
diff --git a/Source/gio/generated/generate_code.py b/Source/gio/generated/generate_code.py
index 3c36254da..fa8b9da65 100644
--- a/Source/gio/generated/generate_code.py
+++ b/Source/gio/generated/generate_code.py
@@ -16,6 +16,7 @@ if __name__ == "__main__":
parser.add_argument("--gapi-codegen")
parser.add_argument("--glue-file", default="")
parser.add_argument("--glue-includes", default="")
+ parser.add_argument("--abi-cs-usings", default="")
parser.add_argument("--glue-libname", default="")
parser.add_argument("--assembly-name")
parser.add_argument("--extra-includes", action='append', default=[])
@@ -38,7 +39,7 @@ if __name__ == "__main__":
shutil.copyfile(opts.api_raw, api_xml)
if shutil.which('mono'):
- launcher = ['mono']
+ launcher = ['mono', '--debug']
else:
launcher = []
@@ -55,11 +56,17 @@ if __name__ == "__main__":
'--glue-filename=' + opts.glue_file,
'--gluelib-name=' + opts.glue_libname,
'--glue-includes=' + opts.glue_includes,
- '--assembly-name=' + opts.assembly_name,]
+ '--assembly-name=' + opts.assembly_name,
+ '--abi-c-filename=' + os.path.join(opts.out, opts.assembly_name + "-abi.c"),
+ '--abi-cs-filename=' + os.path.join(opts.out, opts.assembly_name + "-abi.cs"),
+ ]
if opts.schema:
cmd += ['--schema=' + opts.schema]
+ if opts.abi_cs_usings:
+ cmd += ['--abi-cs-usings=' + opts.abi_cs_usings]
+
cmd += ['-I' + i for i in opts.extra_includes]
subprocess.check_call(launcher + cmd)
diff --git a/Source/gtk/Gtk.metadata b/Source/gtk/Gtk.metadata
index a1aa3276a..e8c1db5d8 100644
--- a/Source/gtk/Gtk.metadata
+++ b/Source/gtk/Gtk.metadata
@@ -907,10 +907,36 @@
Maximized
DefaultActivated
FocusActivated
- slider_detail
- gchar*
- stepper_detail
- gchar*
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+
+ SliderDetail
+ gchar*
+ slider_detail
+
+ StepperDetail
+ gchar*
+ stepper_detail
+
1
1
1
@@ -936,6 +962,7 @@
1
1
n_targets
+ true
PangoUnderline
1
1
diff --git a/Source/gtk/generated/meson.build b/Source/gtk/generated/meson.build
index fae017237..cce834ff4 100644
--- a/Source/gtk/generated/meson.build
+++ b/Source/gtk/generated/meson.build
@@ -1065,7 +1065,7 @@ source_gen = custom_target(assembly_name + 'codegen',
generate_api,
'--api-raw', '@INPUT@',
'--gapi-fixup', gapi_fixup.full_path(),
- '--metadata', metadata_fname,
+ '--metadata', metadata,
'--symbols', symbols,
'--gapi-codegen', gapi_codegen.full_path(),
'--extra-includes', glib_api_includes,
@@ -1078,10 +1078,23 @@ source_gen = custom_target(assembly_name + 'codegen',
'--out', meson.current_build_dir(),
'--files', ';'.join(generated_sources),
'--assembly-name', assembly_name,
+ '--abi-cs-usings', 'Gtk,GLib',
'--schema', schema,
],
depends: [gapi_codegen, gapi_fixup])
+c_abi = custom_target(assembly_name + '_c_abi',
+ input: raw_api_fname,
+ output: assembly_name + '-abi.c',
+ command: [generate_api, '--fakeglue'],
+ depends: [source_gen])
+
+cs_abi = custom_target(assembly_name + '_cs_abi',
+ input: raw_api_fname,
+ output: assembly_name + '-abi.cs',
+ command: [generate_api, '--fakeglue'],
+ depends: [source_gen])
+
api_xml = custom_target(pkg + '_api_xml',
input: raw_api_fname,
output: pkg + '-api.xml',
diff --git a/Source/gtk/meson.build b/Source/gtk/meson.build
index 8a0c9de81..a14766bb5 100644
--- a/Source/gtk/meson.build
+++ b/Source/gtk/meson.build
@@ -3,7 +3,7 @@ assembly_name = pkg + '-sharp'
symbols = join_paths(meson.current_source_dir(), pkg + '-symbols.xml')
raw_api_fname = join_paths(meson.current_source_dir(), pkg + '-api.raw')
-metadata_fname = join_paths(meson.current_source_dir(), 'Gtk.metadata')
+metadata = files('Gtk.metadata')
glueincludes = 'gtk/gtk.h'
gluefile = join_paths(meson.current_build_dir(), 'generate.c')
@@ -144,3 +144,15 @@ nuget_infos += [['GtkSharp', gtk_sharp, ['GlibSharp', 'GioSharp',
'AtkSharp', 'GdkSharp']]]
install_infos += [assembly_name, gtk_sharp.full_path()]
gtk_sharp_dep = declare_dependency(link_with: deps + [gtk_sharp])
+
+if add_languages('c', required: false)
+ c_abi_exe = executable(assembly_name + '_c_abi', c_abi,
+ c_args: ['-Wno-deprecated', '-Wno-deprecated-declarations'],
+ dependencies: [glib_dep, gio_dep, atk_dep, gdk_dep, gtk_dep])
+
+ cs_abi_exe = executable(assembly_name + '_cs_abi', cs_abi,
+ cs_args: ['-nowarn:169', '-nowarn:108', '-nowarn:114', '-nowarn:0618', '-unsafe'],
+ dependencies: [gtk_sharp_dep])
+
+ test(assembly_name + 'abi', diff, args: [c_abi_exe.full_path(), cs_abi_exe.full_path()])
+endif
diff --git a/Source/meson.build b/Source/meson.build
index b33b3b867..59884baff 100644
--- a/Source/meson.build
+++ b/Source/meson.build
@@ -38,6 +38,7 @@ assemblyinfo='/AssemblyInfo.cs'
gacutil = find_program('gacutil')
al = find_program('al')
+diff = find_program('audit/test_abi.py')
glib_dep = dependency('glib-2.0', version: glib_required_version,
fallback: ['glib', 'libglib_dep'])