glib-compile-resources: Add external data option

Add option to not encode resource data into the C source file
in order to embed the data using `ld -b binary`. This improves compilation
times, but can only be done on Linux or other platforms with a
supporting linker.

(Rebased by Philip Withnall, fixing minor rebase conflicts.)

Fixes #1489
This commit is contained in:
Ninja-Koala
2018-09-09 18:31:38 +02:00
committed by Philip Withnall
parent c33a98f42f
commit d04b9c371d
6 changed files with 171 additions and 36 deletions

View File

@@ -670,8 +670,21 @@ plugin_resources.c: test4.gresource.xml Makefile $(shell $(glib_compile_resource
test.gresource: test.gresource.xml Makefile $(shell $(glib_compile_resources) --sourcedir=. --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/test.gresource.xml)
$(AM_V_GEN) $(glib_compile_resources) --target=$@ --sourcedir=. --sourcedir=$(srcdir) $<
EXTRA_DIST += test.gresource.xml test1.txt test2.gresource.xml test2.txt test3.gresource.xml test3.txt test4.gresource.xml gen-big-test-resource.py
EXTRA_DIST += test.gresource.xml test1.txt test2.gresource.xml test2.txt test3.gresource.xml test3.txt test4.gresource.xml test5.gresource.xml gen-big-test-resource.py
CLEANFILES += test-generated.txt test_resources.c test_resources2.[ch] plugin_resources.c test.gresource gresource-big-test.txt
if OS_LINUX
test5.gresource: test5.gresource.xml Makefile $(shell $(glib_compile_resources) --sourcedir=. --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/test5.gresource.xml)
$(AM_V_GEN) $(glib_compile_resources) --target=$@ --sourcedir=. --sourcedir=$(srcdir) $<
test_resources_binary.c: test5.gresource.xml Makefile $(shell $(glib_compile_resources) --sourcedir=. --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/test5.gresource.xml)
$(AM_V_GEN) $(glib_compile_resources) --target=$@ --sourcedir=$(srcdir) --generate-source --c-name _g_binary_test1 $<
test_resources_binary_data.o: test5.gresource
$(AM_V_GEN) ld -r -b binary $< -o $@
test_resources_binary_data2.o: test_resources_binary.o
$(AM_V_GEN) objcopy --add-symbol _g_binary_test1_resource_data=.data:0 -N _binary_test5_gresource_start -N _binary_test5_gresource_size -N _binary_test5_gresource_end $< $@
nodist_resources_SOURCES += test_resources_binary_data2.o test_resources_binary.c
endif
endif # !CROSS_COMPILING
BUILT_SOURCES += giotypefuncs.inc

View File

@@ -524,12 +524,67 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
copy : true,
install : false)
gio_tests += {
'resources' : {
'extra_sources' : [test_gresource, test_resources_c, test_resources2_c,
test_resources2_h],
},
}
# Create object file containing resource data
# for testing the external data option
if build_machine.system() == 'linux'
test_gresource_binary = custom_target('test5.gresource',
input : 'test5.gresource.xml',
output : 'test5.gresource',
command : [glib_compile_resources,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),
'@INPUT@'],
install_dir : installed_tests_execdir,
install : installed_tests_enabled)
# Create resource data file
test_resources_binary_c = custom_target('test_resources_binary.c',
input : 'test5.gresource.xml',
output : 'test_resources_binary.c',
command : [glib_compile_resources,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),
'--generate-source',
'--external-data',
'--c-name', '_g_binary_test1',
'@INPUT@'])
# Create object file containing resource data
test_resources_binary = custom_target('test_resources.o',
input : test_gresource_binary,
output : 'test_resources.o',
command : ['ld',
'-r',
'-b','binary',
'@INPUT@',
'-o','@OUTPUT@'])
# Rename symbol to match the one in the C file
test_resources_binary2 = custom_target('test_resources2.o',
input : test_resources_binary,
output : 'test_resources2.o',
command : ['objcopy',
'--add-symbol','_g_binary_test1_resource_data=.data:0',
'@INPUT@',
'@OUTPUT@'])
gio_tests += {
'resources' : {
'extra_sources' : [test_gresource, test_resources_c, test_resources2_c,
test_resources2_h, test_resources_binary_c,
test_resources_binary2],
},
}
else
gio_tests += {
'resources' : {
'extra_sources' : [test_gresource, test_resources_c, test_resources2_c,
test_resources2_h],
},
}
endif
endif
foreach test_name, extra_args : gio_tests

View File

@@ -558,6 +558,43 @@ test_resource_manual2 (void)
g_resource_unref (resource);
}
/* Test building resources with external data option,
* where data is linked in as binary instead of compiled in.
* Checks if resources are automatically registered and
* data can be found and read. */
static void
test_resource_binary_linked (void)
{
#ifndef __linux__
g_test_skip ("--external-data test only works on Linux");
return;
#else /* if __linux__ */
GError *error = NULL;
gboolean found;
gsize size;
guint32 flags;
GBytes *data;
found = g_resources_get_info ("/binary_linked/test1.txt",
G_RESOURCE_LOOKUP_FLAGS_NONE,
&size, &flags, &error);
g_assert_true (found);
g_assert_no_error (error);
g_assert_cmpint (size, ==, 6);
g_assert_cmpuint (flags, ==, 0);
data = g_resources_lookup_data ("/binary_linked/test1.txt",
G_RESOURCE_LOOKUP_FLAGS_NONE,
&error);
g_assert_nonnull (data);
g_assert_no_error (error);
size = g_bytes_get_size (data);
g_assert_cmpint (size, ==, 6);
g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test1\n");
g_bytes_unref (data);
#endif /* if __linux__ */
}
static void
test_resource_module (void)
{
@@ -877,6 +914,7 @@ main (int argc,
g_test_add_func ("/resource/automatic", test_resource_automatic);
/* This only uses automatic resources too, so it tests the constructors and destructors */
g_test_add_func ("/resource/module", test_resource_module);
g_test_add_func ("/resource/binary-linked", test_resource_binary_linked);
#endif
g_test_add_func ("/resource/uri/query-info", test_uri_query_info);
g_test_add_func ("/resource/uri/file", test_uri_file);

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/binary_linked">
<file>test1.txt</file>
</gresource>
</gresources>