mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-02 09:16:17 +01:00
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:
parent
c33a98f42f
commit
d04b9c371d
@ -170,6 +170,16 @@ which is what <option>--internal</option> does.
|
|||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--external-data</option></term>
|
||||||
|
<listitem><para>
|
||||||
|
By default code generated by <option>--generate-source</option> embeds the
|
||||||
|
resource data as a string literal. When <option>--external-data</option>
|
||||||
|
is given, the data is only declared in the generated C file, and the data
|
||||||
|
has to be linked externally.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--dependency-file=<replaceable>FILE</replaceable></option></term>
|
<term><option>--dependency-file=<replaceable>FILE</replaceable></option></term>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
|
@ -725,6 +725,7 @@ main (int argc, char **argv)
|
|||||||
gboolean generate_header = FALSE;
|
gboolean generate_header = FALSE;
|
||||||
gboolean manual_register = FALSE;
|
gboolean manual_register = FALSE;
|
||||||
gboolean internal = FALSE;
|
gboolean internal = FALSE;
|
||||||
|
gboolean external_data = FALSE;
|
||||||
gboolean generate_dependencies = FALSE;
|
gboolean generate_dependencies = FALSE;
|
||||||
gboolean generate_phony_targets = FALSE;
|
gboolean generate_phony_targets = FALSE;
|
||||||
char *dependency_file = NULL;
|
char *dependency_file = NULL;
|
||||||
@ -744,6 +745,7 @@ main (int argc, char **argv)
|
|||||||
{ "generate-phony-targets", 0, 0, G_OPTION_ARG_NONE, &generate_phony_targets, N_("Include phony targets in the generated dependency file"), NULL },
|
{ "generate-phony-targets", 0, 0, G_OPTION_ARG_NONE, &generate_phony_targets, N_("Include phony targets in the generated dependency file"), NULL },
|
||||||
{ "manual-register", 0, 0, G_OPTION_ARG_NONE, &manual_register, N_("Don’t automatically create and register resource"), NULL },
|
{ "manual-register", 0, 0, G_OPTION_ARG_NONE, &manual_register, N_("Don’t automatically create and register resource"), NULL },
|
||||||
{ "internal", 0, 0, G_OPTION_ARG_NONE, &internal, N_("Don’t export functions; declare them G_GNUC_INTERNAL"), NULL },
|
{ "internal", 0, 0, G_OPTION_ARG_NONE, &internal, N_("Don’t export functions; declare them G_GNUC_INTERNAL"), NULL },
|
||||||
|
{ "external-data", 0, 0, G_OPTION_ARG_NONE, &external_data, N_("Don’t embed resource data in the C file; assume it's linked externally instead"), NULL },
|
||||||
{ "c-name", 0, 0, G_OPTION_ARG_STRING, &c_name, N_("C identifier name used for the generated source code"), NULL },
|
{ "c-name", 0, 0, G_OPTION_ARG_STRING, &c_name, N_("C identifier name used for the generated source code"), NULL },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
@ -1089,49 +1091,60 @@ main (int argc, char **argv)
|
|||||||
"\n",
|
"\n",
|
||||||
c_name_no_underscores);
|
c_name_no_underscores);
|
||||||
|
|
||||||
/* For Visual Studio builds: Avoid surpassing the 65535-character limit for a string, GitLab issue #1580 */
|
if (external_data)
|
||||||
g_fprintf (file, "#ifdef _MSC_VER\n");
|
|
||||||
g_fprintf (file,
|
|
||||||
"static const SECTION union { const guint8 data[%"G_GSIZE_FORMAT"]; const double alignment; void * const ptr;} %s_resource_data = { {\n",
|
|
||||||
data_size + 1 /* nul terminator */, c_name);
|
|
||||||
|
|
||||||
for (i = 0; i < data_size; i++)
|
|
||||||
{
|
{
|
||||||
if (i % 16 == 0)
|
g_fprintf (file,
|
||||||
g_fprintf (file, " ");
|
"extern const SECTION union { const guint8 data[%"G_GSIZE_FORMAT"]; const double alignment; void * const ptr;} %s_resource_data;"
|
||||||
g_fprintf (file, "0%3.3o", (int)data[i]);
|
"\n",
|
||||||
if (i != data_size - 1)
|
data_size, c_name);
|
||||||
g_fprintf (file, ", ");
|
|
||||||
if (i % 16 == 15 || i == data_size - 1)
|
|
||||||
g_fprintf (file, "\n");
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For Visual Studio builds: Avoid surpassing the 65535-character limit for a string, GitLab issue #1580 */
|
||||||
|
g_fprintf (file, "#ifdef _MSC_VER\n");
|
||||||
|
g_fprintf (file,
|
||||||
|
"static const SECTION union { const guint8 data[%"G_GSIZE_FORMAT"]; const double alignment; void * const ptr;} %s_resource_data = { {\n",
|
||||||
|
data_size + 1 /* nul terminator */, c_name);
|
||||||
|
|
||||||
g_fprintf (file, "} };\n");
|
for (i = 0; i < data_size; i++)
|
||||||
|
{
|
||||||
|
if (i % 16 == 0)
|
||||||
|
g_fprintf (file, " ");
|
||||||
|
g_fprintf (file, "0%3.3o", (int)data[i]);
|
||||||
|
if (i != data_size - 1)
|
||||||
|
g_fprintf (file, ", ");
|
||||||
|
if (i % 16 == 15 || i == data_size - 1)
|
||||||
|
g_fprintf (file, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* For other compilers, use the long string approach */
|
g_fprintf (file, "} };\n");
|
||||||
g_fprintf (file, "#else /* _MSC_VER */\n");
|
|
||||||
g_fprintf (file,
|
|
||||||
"static const SECTION union { const guint8 data[%"G_GSIZE_FORMAT"]; const double alignment; void * const ptr;} %s_resource_data = {\n \"",
|
|
||||||
data_size + 1 /* nul terminator */, c_name);
|
|
||||||
|
|
||||||
for (i = 0; i < data_size; i++) {
|
/* For other compilers, use the long string approach */
|
||||||
g_fprintf (file, "\\%3.3o", (int)data[i]);
|
g_fprintf (file, "#else /* _MSC_VER */\n");
|
||||||
if (i % 16 == 15)
|
g_fprintf (file,
|
||||||
g_fprintf (file, "\"\n \"");
|
"static const SECTION union { const guint8 data[%"G_GSIZE_FORMAT"]; const double alignment; void * const ptr;} %s_resource_data = {\n \"",
|
||||||
}
|
data_size + 1 /* nul terminator */, c_name);
|
||||||
|
|
||||||
g_fprintf (file, "\" };\n");
|
for (i = 0; i < data_size; i++)
|
||||||
g_fprintf (file, "#endif /* !_MSC_VER */\n");
|
{
|
||||||
|
g_fprintf (file, "\\%3.3o", (int)data[i]);
|
||||||
|
if (i % 16 == 15)
|
||||||
|
g_fprintf (file, "\"\n \"");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_fprintf (file, "\" };\n");
|
||||||
|
g_fprintf (file, "#endif /* !_MSC_VER */\n");
|
||||||
|
}
|
||||||
|
|
||||||
g_fprintf (file,
|
g_fprintf (file,
|
||||||
"\n"
|
"\n"
|
||||||
"static GStaticResource static_resource = { %s_resource_data.data, sizeof (%s_resource_data.data) - 1 /* nul terminator */, NULL, NULL, NULL };\n"
|
"static GStaticResource static_resource = { %s_resource_data.data, sizeof (%s_resource_data.data)%s, NULL, NULL, NULL };\n"
|
||||||
"%s GResource *%s_get_resource (void);\n"
|
"%s GResource *%s_get_resource (void);\n"
|
||||||
"GResource *%s_get_resource (void)\n"
|
"GResource *%s_get_resource (void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return g_static_resource_get_resource (&static_resource);\n"
|
" return g_static_resource_get_resource (&static_resource);\n"
|
||||||
"}\n",
|
"}\n",
|
||||||
c_name, c_name, linkage, c_name, c_name);
|
c_name, c_name, (external_data ? "" : " - 1 /* nul terminator */"), linkage, c_name, c_name);
|
||||||
|
|
||||||
|
|
||||||
if (manual_register)
|
if (manual_register)
|
||||||
|
@ -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)
|
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) $<
|
$(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
|
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
|
endif # !CROSS_COMPILING
|
||||||
|
|
||||||
BUILT_SOURCES += giotypefuncs.inc
|
BUILT_SOURCES += giotypefuncs.inc
|
||||||
|
@ -524,12 +524,67 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
|
|||||||
copy : true,
|
copy : true,
|
||||||
install : false)
|
install : false)
|
||||||
|
|
||||||
gio_tests += {
|
# Create object file containing resource data
|
||||||
'resources' : {
|
# for testing the external data option
|
||||||
'extra_sources' : [test_gresource, test_resources_c, test_resources2_c,
|
if build_machine.system() == 'linux'
|
||||||
test_resources2_h],
|
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
|
endif
|
||||||
|
|
||||||
foreach test_name, extra_args : gio_tests
|
foreach test_name, extra_args : gio_tests
|
||||||
|
@ -558,6 +558,43 @@ test_resource_manual2 (void)
|
|||||||
g_resource_unref (resource);
|
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
|
static void
|
||||||
test_resource_module (void)
|
test_resource_module (void)
|
||||||
{
|
{
|
||||||
@ -877,6 +914,7 @@ main (int argc,
|
|||||||
g_test_add_func ("/resource/automatic", test_resource_automatic);
|
g_test_add_func ("/resource/automatic", test_resource_automatic);
|
||||||
/* This only uses automatic resources too, so it tests the constructors and destructors */
|
/* 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/module", test_resource_module);
|
||||||
|
g_test_add_func ("/resource/binary-linked", test_resource_binary_linked);
|
||||||
#endif
|
#endif
|
||||||
g_test_add_func ("/resource/uri/query-info", test_uri_query_info);
|
g_test_add_func ("/resource/uri/query-info", test_uri_query_info);
|
||||||
g_test_add_func ("/resource/uri/file", test_uri_file);
|
g_test_add_func ("/resource/uri/file", test_uri_file);
|
||||||
|
6
gio/tests/test5.gresource.xml
Normal file
6
gio/tests/test5.gresource.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<gresources>
|
||||||
|
<gresource prefix="/binary_linked">
|
||||||
|
<file>test1.txt</file>
|
||||||
|
</gresource>
|
||||||
|
</gresources>
|
Loading…
Reference in New Issue
Block a user