Merge branch 'ebassi/compile-resource-split' into 'main'

Do not generate C resources for all possible toolchains

Closes #2492

See merge request GNOME/glib!2250
This commit is contained in:
Philip Withnall 2022-02-14 13:47:42 +00:00
commit 1f75ca6ebd
3 changed files with 137 additions and 30 deletions

View File

@ -200,6 +200,16 @@ be used with <literal>make</literal>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--compiler=<replaceable>NAME</replaceable></option></term>
<listitem><para>
Generate code that is going to target the given compiler <replaceable>NAME</replaceable>.
The current two compiler modes are "gcc", for all GCC-compatible toolchains; and "msvc",
for the Microsoft Visual C Compiler. If this option isn't set, then the default will be
taken from the <envar>CC</envar> environment variable.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -710,6 +710,86 @@ escape_makefile_string (const char *string)
return g_string_free (str, FALSE);
}
typedef enum {
COMPILER_GCC,
COMPILER_CLANG,
COMPILER_MSVC,
COMPILER_UNKNOWN
} CompilerType;
/* Get the compiler id from the platform, environment, or command line
*
* Keep compiler IDs consistent with https://mesonbuild.com/Reference-tables.html#compiler-ids
* for simplicity
*/
static CompilerType
get_compiler_id (const char *compiler)
{
char *base, *ext_p;
CompilerType compiler_type;
if (compiler == NULL)
{
#ifdef G_OS_UNIX
const char *compiler_env = g_getenv ("CC");
# ifdef __APPLE__
if (compiler_env == NULL || *compiler_env == '\0')
compiler = "clang";
else
compiler = compiler_env;
# elif __linux__
if (compiler_env == NULL || *compiler_env == '\0')
compiler = "gcc";
else
compiler = compiler_env;
# else
if (compiler_env == NULL || *compiler_env == '\0')
compiler = "unknown";
else
compiler = compiler_env;
# endif
#endif
#ifdef G_OS_WIN32
if (g_getenv ("MSYSTEM") != NULL)
{
const char *compiler_env = g_getenv ("CC");
if (compiler_env == NULL || *compiler_env == '\0')
compiler = "gcc";
else
compiler = compiler_env;
}
else
compiler = "msvc";
#endif
}
base = g_path_get_basename (compiler);
ext_p = strrchr (base, '.');
if (ext_p != NULL)
{
gsize offset = ext_p - base;
base[offset] = '\0';
}
compiler = base;
if (g_strcmp0 (compiler, "gcc") == 0)
compiler_type = COMPILER_GCC;
else if (g_strcmp0 (compiler, "clang") == 0)
compiler_type = COMPILER_CLANG;
else if (g_strcmp0 (compiler, "msvc") == 0)
compiler_type = COMPILER_MSVC;
else
compiler_type = COMPILER_UNKNOWN;
g_free (base);
return compiler_type;
}
int
main (int argc, char **argv)
{
@ -732,6 +812,8 @@ main (int argc, char **argv)
char *c_name = NULL;
char *c_name_no_underscores;
const char *linkage = "extern";
const char *compiler = NULL;
CompilerType compiler_type = COMPILER_GCC;
GOptionContext *context;
GOptionEntry entries[] = {
{ "version", 0, 0, G_OPTION_ARG_NONE, &show_version_and_exit, N_("Show program version and exit"), NULL },
@ -747,6 +829,7 @@ main (int argc, char **argv)
{ "internal", 0, 0, G_OPTION_ARG_NONE, &internal, N_("Dont export functions; declare them G_GNUC_INTERNAL"), NULL },
{ "external-data", 0, 0, G_OPTION_ARG_NONE, &external_data, N_("Dont 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 },
{ "compiler", 'C', 0, G_OPTION_ARG_STRING, &compiler, N_("The target C compiler (default: the CC environment variable)"), NULL },
G_OPTION_ENTRY_NULL
};
@ -802,6 +885,8 @@ main (int argc, char **argv)
if (internal)
linkage = "G_GNUC_INTERNAL";
compiler_type = get_compiler_id (compiler);
srcfile = argv[1];
xmllint = g_strdup (g_getenv ("XMLLINT"));
@ -1105,40 +1190,41 @@ main (int argc, char **argv)
}
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);
for (i = 0; i < data_size; i++)
if (compiler_type == COMPILER_MSVC || compiler_type == COMPILER_UNKNOWN)
{
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 Visual Studio builds: Avoid surpassing the 65535-character limit for a string, GitLab issue #1580 */
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, "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");
}
g_fprintf (file, "} };\n");
}
g_fprintf (file, "} };\n");
/* For other compilers, use the long string approach */
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++)
else
{
g_fprintf (file, "\\%3.3o", (int)data[i]);
if (i % 16 == 15)
g_fprintf (file, "\"\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");
g_fprintf (file, "#endif /* !_MSC_VER */\n");
for (i = 0; i < data_size; i++)
{
g_fprintf (file, "\\%3.3o", (int)data[i]);
if (i % 16 == 15)
g_fprintf (file, "\"\n \"");
}
g_fprintf (file, "\" };\n");
}
}
g_fprintf (file,

View File

@ -575,10 +575,13 @@ endif
if not meson.is_cross_build() or meson.has_exe_wrapper()
compiler_type = '--compiler=@0@'.format(cc.get_id())
plugin_resources_c = custom_target('plugin-resources.c',
input : 'test4.gresource.xml',
output : 'plugin-resources.c',
command : [glib_compile_resources,
compiler_type,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--internal',
@ -604,6 +607,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
input : 'test.gresource.xml',
output : 'test.gresource',
command : [glib_compile_resources,
compiler_type,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),
@ -616,6 +620,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
input : 'test3.gresource.xml',
output : 'test_resources2.c',
command : [glib_compile_resources,
compiler_type,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--internal',
@ -628,6 +633,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
input : 'test3.gresource.xml',
output : 'test_resources2.h',
command : [glib_compile_resources,
compiler_type,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--internal',
@ -641,6 +647,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
depends : big_test_resource,
output : 'test_resources.c',
command : [glib_compile_resources,
compiler_type,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),
@ -653,6 +660,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
input : '111_digit_test.gresource.xml',
output : 'digit_test_resources.c',
command : [glib_compile_resources,
compiler_type,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),
@ -665,6 +673,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
input : '111_digit_test.gresource.xml',
output : 'digit_test_resources.h',
command : [glib_compile_resources,
compiler_type,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--internal',
@ -710,6 +719,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
input : 'test5.gresource.xml',
output : 'test5.gresource',
command : [glib_compile_resources,
compiler_type,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),
@ -723,6 +733,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
input : 'test5.gresource.xml',
output : 'test_resources_binary.c',
command : [glib_compile_resources,
compiler_type,
'--target=@OUTPUT@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),