From 7bc6ef873438d09918ac2e469d84a8a61f3ebe83 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sat, 18 Sep 2021 13:45:57 +0100 Subject: [PATCH] Do not generate C resources for all possible toolchains The resources data is generated for both GCC and MSVC toolchains, even though we know beforehand which toolchain we're going to compile it for. By dropping the data duplication we make the generated resources file faster to compile, especially when dealing with large embedded data, instead of relying on the C pre-processor to walk the whole file and discard the branch we're not using. --- docs/reference/gio/glib-compile-resources.xml | 10 ++ gio/glib-compile-resources.c | 146 ++++++++++++++---- 2 files changed, 126 insertions(+), 30 deletions(-) diff --git a/docs/reference/gio/glib-compile-resources.xml b/docs/reference/gio/glib-compile-resources.xml index a85f6003c..7ab36f5a9 100644 --- a/docs/reference/gio/glib-compile-resources.xml +++ b/docs/reference/gio/glib-compile-resources.xml @@ -200,6 +200,16 @@ be used with make. + + + +Generate code that is going to target the given compiler NAME. +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 CC environment variable. + + + diff --git a/gio/glib-compile-resources.c b/gio/glib-compile-resources.c index ac95801f4..306809a18 100644 --- a/gio/glib-compile-resources.c +++ b/gio/glib-compile-resources.c @@ -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_("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 }, + { "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,