libretro / RetroArch

Cross-platform, sophisticated frontend for the libretro API. Licensed GPLv3.
http://www.libretro.com
GNU General Public License v3.0
10.31k stars 1.83k forks source link

Minor warnings during compilation (GCC 6.3.0 on standard Raspbian Stretch) #8191

Closed hhromic closed 5 years ago

hhromic commented 5 years ago

Description

Summary: Minor warnings during compilation (GCC 6.3.0 on standard Raspbian Stretch).

The build goes fine and runs very well however there are couple of warnings is a warning in three files one file. All the rest compiles absolutely cleanly. This is not critical nor priority, just perfectionism.

The first two warnings are for the same problem: using %lu format to print a size_t type that is not necessarily a long unsigned int. This could be fixed portably (C99) by using the %zu modifier as suggested here. [fix merged]

The third warning is because gl2_renderchain_init_pbo is always defined but populated conditionally using compiler flags. Then it's usage is conditioned. Therefore when these flags are not active, the function is left defined but not used as the warning indicates correctly. This doesn't happen with other similar functions in the same file because their calls aren't conditioned. A possible solution could be to move the definition inside the pre-processor conditional, however it will break the code style compared to the other functions.

For now I didn't want to make a PR because this sort of changes require senior developer reviewing. If you prefer I can also send a PR and further review/discuss there.


Expected behavior

Compilation of RetroArch without any warnings from the compiler or linker.

Actual behavior

Getting 3 minor warnings during compilation.

Steps to reproduce the bug

  1. Compile the source using GCC 6.3.0 and observe the output log

Version/Commit

You can find this information under Information/System Information

Environment information

hhromic commented 5 years ago

A bit further on the topic of warnings, the deps/discord-rpc dependency codease is using #pragma warning pre-processor macros that are not supported by GCC, but by Microsoft compilers. Making these pragmas portable seems to be a hard problem so I would ignore that for now.

hhromic commented 5 years ago

Okay, the warnings seem to be because PRI_SIZET is not being defined portably in deps/libretro-common/include/retro_miscellaneous.h:

https://github.com/libretro/RetroArch/blob/69d89bc991be2a73b09ea6e4755a05a95f9cc31b/libretro-common/include/retro_miscellaneous.h#L158-L170

As suggested here, probably defining zu instead of lu in the last define would be the correct solution.

orbea commented 5 years ago

I saw similar warnings as in the OP with 32-bit linux too.

hhromic commented 5 years ago

Thinking more about it, probably the issue doesn't manifest in 64 bits OSs because size_t probably matches long unsigned int and the warning is then not triggered.

As you noted, 32-bit linuxs such as armv7 devices (e.g. the RPI) probably always manifest the warnings.

What C std is RetroArch aiming for? %zu should be available from c99 onwards.

orbea commented 5 years ago

It needs to be c89 compatible, unfortunately while %zu silences the warnings here with 32-bit linux, it causes new warnings with C89_BUILD=1.

Try: ./configure && make C89_BUILD=1

hhromic commented 5 years ago

Just tested compiling in 64 bits linux and the format warnings are not there as expected, so they are being triggered in 32 bits machines only (probably).

Um I see, the easy solution using %zu is unavailable then. Maybe a selective define to set lu or li depending on bitness should be c89-compatible. Similar to what is done in the windows defines.

hhromic commented 5 years ago

Thanks for the C89_BUILD pointer, if you are interested on silencing these warnings, I can think of a suitable solution and make sure it's c89 compliant.

orbea commented 5 years ago

Yes, silencing warnings is always desirable if it doesn't cause regressions. :)

orbea commented 5 years ago

I tried %li and got these warnings still with 32-bit linux.

setting_list.c: In function 'setting_get_string_representation_size':
setting_list.c:179:24: warning: format '%li' expects argument of type 'long int', but argument 4 has type 'size_t {aka unsigned int}' [-Wformat=]
       snprintf(s, len, "%" PRI_SIZET,
                        ^
setting_list.c:179:24: warning: format '%li' expects argument of type 'long int', but argument 4 has type 'size_t {aka unsigned int}' [-Wformat=]
setting_list.c: In function 'setting_get_string_representation_size_in_mb':
setting_list.c:187:24: warning: format '%li' expects argument of type 'long int', but argument 4 has type 'size_t {aka unsigned int}' [-Wformat=]
       snprintf(s, len, "%" PRI_SIZET,
                        ^
setting_list.c:187:24: warning: format '%li' expects argument of type 'long int', but argument 4 has type 'size_t {aka unsigned int}' [-Wformat=]
setting_list.c: In function 'setting_set_with_string_representation':
setting_list.c:511:24: warning: format '%li' expects argument of type 'long int *', but argument 3 has type 'size_t * {aka unsigned int *}' [-Wformat=]
          sscanf(value, "%" PRI_SIZET, setting->value.target.sizet);
                        ^
libretro-common/file/config_file.c: In function 'config_get_size_t':
libretro-common/file/config_file.c:694:32: warning: format '%li' expects argument of type 'long int *', but argument 3 has type 'size_t * {aka unsigned int *}' [-Wformat=]
       if (sscanf(entry->value, "%" PRI_SIZET, &val) == 1)
                                ^
hhromic commented 5 years ago

I think for 32 bits should be just %u (for unsigned int as it's complaining) and for 64 bits should be the curent %lu (for long unsigned int), mirroring the windows defines above. The problem is how to reliably detect the bitness for the non-windows case and set the define accordingly. The best I could find so far is this:

#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif

However it's GCC-dependent. If RetroArch is required to be built using gcc compilers, then that should work reliably for all the platforms supported. What do you think?

Edit: the retroarch build system doesn't already provide a bitness flag, right?

hhromic commented 5 years ago

Also, care must be taken to also consider defines such as __aarch64__ in that check.

orbea commented 5 years ago

Yes, %u works for 32-bit linux, I might have something that works, but I need to fix some c89 build failures with 32-bit linux first...

hhromic commented 5 years ago

Great! Looking forward to see your idea, take your time.

Also, let's not forget about the other puzzle:

The third warning is because gl2_renderchain_init_pbo is always defined but populated conditionally using compiler flags. Then it's usage is conditioned. Therefore when these flags are not active, the function is left defined but not used as the warning indicates correctly. This doesn't happen with other similar functions in the same file because their calls aren't conditioned. A possible solution could be to move the definition inside the pre-processor conditional, however it will break the code style compared to the other functions.

It's fun to hunt warnings :)

inactive123 commented 5 years ago

However it's GCC-dependent. If RetroArch is required to be built using gcc compilers, then that should work reliably for all the platforms supported. What do you think?

Nah, we try to be compiler-agnostic. Clang/GCC/MSVC should all be viable options for compiling RetroArch.

hhromic commented 5 years ago

That means these conditionals are a no-no as well. I found other methods but I'm not sure of their robustness, for example comparing sizeof(void *) == 8 to detect pointer size. But nothing is safe in cross-platform. Let's wait for what orbea has in mind.

orbea commented 5 years ago

@hhromic This works for 64/32-bit linux, can you test it too?

diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h
index bdb41f7bba..9114357675 100644
--- a/libretro-common/include/retro_miscellaneous.h
+++ b/libretro-common/include/retro_miscellaneous.h
@@ -159,14 +159,18 @@ typedef struct
 #  ifdef _WIN64
 #    define PRI_SIZET PRIu64
 #  else
-#if _MSC_VER == 1800
-#    define PRI_SIZET PRIu32
+#    if _MSC_VER == 1800
+#      define PRI_SIZET PRIu32
+#    else
+#      define PRI_SIZET "u"
+#    endif
+#  endif
 #else
+#  ifdef __x86_64__
+#    define PRI_SIZET "lu"
+#  else
 #    define PRI_SIZET "u"
-#endif
 #  endif
-#else
-#  define PRI_SIZET "lu"
 #endif

 #endif
hhromic commented 5 years ago

That probably works on x86/64 machines but I don't think it will work for example in ARM/ARM64 devices where there is no __x86_64__ define and will fall-back to u for example in ARM64 where it should be lu.

I saw there are many bitness-related conditionals in retroarch files such as config.def.h, perhaps a collation can be performed to safely cover most of the supported platforms. I would think creating a more abstract ENV32BITS / ENV64BITS set of defines would be beneficial as well.

hhromic commented 5 years ago

Actually, this whole thing can be simpler. In the end we are trying to condition the formatting for size_t, which by definition is always an unsigned integer. So we just need to figure out if it's unsigned int, unsigned long or unsigned long long (rare but possible!), and define the format accordingly: u, lu or llu. I will investigate later how this can be determined in the pre-processor, maybe in limits.h there is a clue, and come back with an idea.

orbea commented 5 years ago

Yea, I only have access to linux 64/32 bit build environments so testing arm or other platforms is hard for me...

hhromic commented 5 years ago

I can test on RPI (ARM32), Win32/64 and Linux64. Once we found a suitable solution I will test on these and report back.

orbea commented 5 years ago

Thanks! The biggest worry are consoles, but the buildbot should find hopefully find those issues where they can then be fixed...

hhromic commented 5 years ago

@orbea so, I put the idea from https://github.com/libretro/RetroArch/issues/8191#issuecomment-461138089 in practice and came up with the following define logic for non-windows platforms:

#include <stdint.h>
#include <stdio.h>

#if (SIZE_MAX == 0xFFFF)
#define PRI_SIZET "hu"
#elif (SIZE_MAX == 0xFFFFFFFF)
#define PRI_SIZET "u"
#elif (SIZE_MAX == 0xFFFFFFFFFFFFFFFF)
#define PRI_SIZET "lu"
#else
#error PRI_SIZET: unknown SIZE_MAX
#endif

int main() {
  size_t test = 123456;
  printf("PRI_SIZET = %s\n", PRI_SIZET);
  printf("size_t test = %" PRI_SIZET "\n", test);
  return 0;
}

I got the idea from here and basically it compares SIZE_MAX (from stdint.h) which is the size of size_t against known sizes and consequently defines the format specification accodingly. It recognises three very common sizes for 16, 32 and 64 bits.

When compiled using c89 mode it produces no warnings in 32 nor 64 bits platforms:

gcc -std=c89 -pedantic -Wall pri_sizet.c -o pri_sizet

Please note that stdint.h is not strictly part of c89, however it is used all around the RetroArch codebase, so should be fine. I tested this using a Linux64 and ARM32 platforms. How does it look?

orbea commented 5 years ago

I tried this.

-#ifdef _WIN32
-#  ifdef _WIN64
-#    define PRI_SIZET PRIu64
-#  else
-#if _MSC_VER == 1800
-#    define PRI_SIZET PRIu32
+#if (SIZE_MAX == 0xFFFF)
+#define PRI_SIZET "hu"
+#elif (SIZE_MAX == 0xFFFFFFFF)
+#define PRI_SIZET "u"
+#elif (SIZE_MAX == 0xFFFFFFFFFFFFFFFF)
+#define PRI_SIZET "lu"
 #else
-#    define PRI_SIZET "u"
-#endif
-#  endif
-#else
-#  define PRI_SIZET "lu"
+#error PRI_SIZET: unknown SIZE_MAX
 #endif

Bluntly I am not an experienced programmer so my feedback on correctness is not worth that much, but I ran it with 64/32-bit linux without any new warnings and it did solve the already relevant warnings. :)

That said I next tried it with travis which found these new warnings with the 64-bit mingw build.

setting_list.c: In function ‘setting_set_with_string_representation’:
setting_list.c:511:10: warning: format ‘%lu’ expects argument of type ‘long unsigned int *’, but argument 3 has type ‘size_t *’ [-Wformat=]
          sscanf(value, "%" PRI_SIZET, setting->value.target.sizet);
          ^
libretro-common/file/config_file.c: In function ‘config_get_size_t’:
libretro-common/file/config_file.c:694:7: warning: format ‘%lu’ expects argument of type ‘long unsigned int *’, but argument 3 has type ‘size_t *’ [-Wformat=]
       if (sscanf(entry->value, "%" PRI_SIZET, &val) == 1)
       ^

So I next tried which seems to work, what do you think? Maybe you have a better idea?

diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h
index bdb41f7bba..13364c8859 100644
--- a/libretro-common/include/retro_miscellaneous.h
+++ b/libretro-common/include/retro_miscellaneous.h
@@ -159,14 +159,22 @@ typedef struct
 #  ifdef _WIN64
 #    define PRI_SIZET PRIu64
 #  else
-#if _MSC_VER == 1800
-#    define PRI_SIZET PRIu32
+#    if _MSC_VER == 1800
+#      define PRI_SIZET PRIu32
+#    else
+#      define PRI_SIZET "u"
+#    endif
+#  endif
 #else
+#  if (SIZE_MAX == 0xFFFF)
+#    define PRI_SIZET "hu"
+#  elif (SIZE_MAX == 0xFFFFFFFF)
 #    define PRI_SIZET "u"
-#endif
+#  elif (SIZE_MAX == 0xFFFFFFFFFFFFFFFF)
+#    define PRI_SIZET "lu"
+#  else
+#    error PRI_SIZET: unknown SIZE_MAX
 #  endif
-#else
-#  define PRI_SIZET "lu"
 #endif

 #endif
hhromic commented 5 years ago

Yes, as I stated in my post, the example alone I posted was meant for non-windows platforms only, and should been integrated with the existing windows-based defines, as you correctly did. So, it should look like this in its final form:

#ifdef _WIN32
#  ifdef _WIN64
#    define PRI_SIZET PRIu64
#  else
#    if _MSC_VER == 1800
#      define PRI_SIZET PRIu32
#    else
#      define PRI_SIZET "u"
#    endif
#  endif
#else
#  if (SIZE_MAX == 0xFFFF)
#    define PRI_SIZET "hu"
#  elif (SIZE_MAX == 0xFFFFFFFF)
#    define PRI_SIZET "u"
#  elif (SIZE_MAX == 0xFFFFFFFFFFFFFFFF)
#    define PRI_SIZET "lu"
#  else
#    error PRI_SIZET: unknown SIZE_MAX
#  endif
#endif

That is working fine for me in Linux64, Windows64 and ARM32. If it works for you in Travis without any warnings, then I think it should be the correct way to handle PRI_SIZET cross-platform.

Do you want me to send a PR for this?

orbea commented 5 years ago

I misunderstood/misread inititially and yes, if you can send a PR that would be great. :)

orbea commented 5 years ago

So what are the remaining warnings in our code? Lets not consider stuff in deps and similar for now which ideally should be fixed upstream.

Here with gcc-8.2.0 I only see.

gfx/display_servers/dispserv_x11.c: In function ‘x11_display_server_set_resolution’:
gfx/display_servers/dispserv_x11.c:136:12: warning: variable ‘scrn’ set but not used [-Wunused-but-set-variable]
    Screen *scrn             = NULL;
            ^~~~

This will probably be fixed soon, see: https://github.com/libretro/RetroArch/pull/8132#issuecomment-459861231

With clang-7.0.1 I see.

ui/drivers/qt/qt_playlist.cpp:268:20: warning: unused function 'comp_hash_label_key_lower' [-Wunused-function]
inline static bool comp_hash_label_key_lower(const QHash<QString, QString> &lhs, const QHash<QString, QString> &rhs)
                   ^
1 warning generated.
cores/libretro-gong/gong.c:121:20: warning: unused function 'pressed' [-Wunused-function]
static INLINE bool pressed(Game_Button_State state)
                   ^
1 warning generated.

(And in libchdr which is not our code.)

It seems clang will warn on unused inline functions while gcc won't.

With C89_BUILD this one still remains with both gcc and clang.

menu/menu_driver.c: In function ‘menu_subsystem_populate’:
menu/menu_driver.c:2698:65: warning: universal character names are only valid in C++ and C99
    snprintf(star_char, sizeof(star_char), "%s", is_rgui ? "*" : "★");
                                                                 ^~~~~~~~

With CXX_BUILD=1 using either gcc or clang.

runahead/secondary_core.c: In function ‘char* get_temp_directory_alloc()’:
runahead/secondary_core.c:84:11: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
    path = "/tmp";
           ^~~~~~

Do you see any others?

orbea commented 5 years ago

Here is a potential fix for the CXX_BUILD warning, I'm not sure its ideal though...

diff --git a/runahead/secondary_core.c b/runahead/secondary_core.c
index f597c1afaa..606b36c1cf 100644
--- a/runahead/secondary_core.c
+++ b/runahead/secondary_core.c
@@ -51,7 +51,7 @@ void clear_controller_port_map(void);

 static char *get_temp_directory_alloc(void)
 {
-   char *path             = NULL;
+   const char *path       = NULL;
 #ifdef _WIN32
 #ifdef LEGACY_WIN32
    DWORD pathLength       = GetTempPath(0, NULL) + 1;
@@ -87,7 +87,7 @@ static char *get_temp_directory_alloc(void)

    path = strcpy_alloc_force(path);
 #endif
-   return path;
+   return (char*)path;
 }

 static bool write_file_with_random_name(char **tempDllPath,
hhromic commented 5 years ago

So what are the remaining warnings in our code? Lets not consider stuff in deps and similar for now which ideally should be fixed upstream.

I have to check but last time the third warning mentioned in the OP. By the way, what is your invocation for configure? Is there any configure option to "enable everything"? Otherwise we won't be covering all the code for testing.

Here with gcc-8.2.0 I only see.

gfx/display_servers/dispserv_x11.c: In function ‘x11_display_server_set_resolution’:
gfx/display_servers/dispserv_x11.c:136:12: warning: variable ‘scrn’ set but not used [-Wunused-but-set-variable]
    Screen *scrn             = NULL;
            ^~~~

This will probably be fixed soon, see: #8132 (comment)

I guess we have to wait for that issue/PR to be completed first.

With clang-7.0.1 I see.

ui/drivers/qt/qt_playlist.cpp:268:20: warning: unused function 'comp_hash_label_key_lower' [-Wunused-function]
inline static bool comp_hash_label_key_lower(const QHash<QString, QString> &lhs, const QHash<QString, QString> &rhs)
                   ^
1 warning generated.
cores/libretro-gong/gong.c:121:20: warning: unused function 'pressed' [-Wunused-function]
static INLINE bool pressed(Game_Button_State state)
                   ^
1 warning generated.

(And in libchdr which is not our code.)

It seems clang will warn on unused inline functions while gcc won't.

Yes I think that is known. Most of the unused warnings can be fixed by better ifdef handling. Will take a look later when I get a bit more time.

With C89_BUILD this one still remains with both gcc and clang.

menu/menu_driver.c: In function ‘menu_subsystem_populate’:
menu/menu_driver.c:2698:65: warning: universal character names are only valid in C++ and C99
    snprintf(star_char, sizeof(star_char), "%s", is_rgui ? "*" : "★");
                                                                 ^~~~~~~~

Ah I mentioned that one before, it's tricky because it's a unicode character. We could replace it with the raw bytes but the "star" character might not display correctly in some platforms, it requires testing. Another alternative is to use the ICU library, but might be overkill.

With CXX_BUILD=1 using either gcc or clang.

runahead/secondary_core.c: In function ‘char* get_temp_directory_alloc()’:
runahead/secondary_core.c:84:11: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
    path = "/tmp";
           ^~~~~~

(will answer your other message about this)

Do you see any others?

I haven't check again, but will soon. Let me know your configure arguments!

hhromic commented 5 years ago

Here is a potential fix for the CXX_BUILD warning, I'm not sure its ideal though...

diff --git a/runahead/secondary_core.c b/runahead/secondary_core.c
index f597c1afaa..606b36c1cf 100644
--- a/runahead/secondary_core.c
+++ b/runahead/secondary_core.c
@@ -51,7 +51,7 @@ void clear_controller_port_map(void);

 static char *get_temp_directory_alloc(void)
 {
-   char *path             = NULL;
+   const char *path       = NULL;
 #ifdef _WIN32
 #ifdef LEGACY_WIN32
    DWORD pathLength       = GetTempPath(0, NULL) + 1;
@@ -87,7 +87,7 @@ static char *get_temp_directory_alloc(void)

    path = strcpy_alloc_force(path);
 #endif
-   return path;
+   return (char*)path;
 }

 static bool write_file_with_random_name(char **tempDllPath,

That fix is not appropiate as path needs to be modifiable, i.e. not a constant const. The problem is the direct assignment of a string literal (const) to the char pointer. As you can see a little below that point in the code, what you need to do is to "copy" the string literal into the path variable:

path = strcpy_alloc_force("/tmp");

That should be safe and should silence the warning.

hhromic commented 5 years ago

Actually, that block of code is a bit convoluted:

   path = "/tmp";
   if (getenv("TMPDIR"))
      path = getenv("TMPDIR");

   path = strcpy_alloc_force(path);

A better/simpler code block would be:

   if (getenv("TMPDIR"))
      path = strcpy_alloc_force(getenv("TMPDIR"));
   else
      path = strcpy_alloc_force("/tmp");
orbea commented 5 years ago

I am just doing ./configure && make, ./configure && make C89_BUILD=1 and ./configure && make CXX_BUILD=1 with most possible optional dependencies installed. Its hard to find all the warnings because of the sheer volume of features and supported platforms, the configure script still has a few issues left to handle... For example try setting set -eu... I am better with shell than C so I have been slowly working on that, hopefully in the future it will be easier to figure these things out... However I can't test some of the supported options like HAVE_VIDEOCORE which certainly need improvement...

hhromic commented 5 years ago

with most possible optional dependencies installed

ahh that is what I'm not doing in my build environment. do you have list of these handy?

orbea commented 5 years ago

I don't have a complete list, but from my own list of optional dependencies for slackbuilds.org I have.

  ffmpeg jack-audio-connection-kit libsixel libxkbcommon mbedtls
  miniupnpc nvidia-cg-toolkit OpenAL python3 qt5 SDL2 vulkansdk
  wayland-egl wayland-protocols

I haven't checked the build with jack-audio-connection-kit, nvidia-cg-toolkit (Deprecated by nvidia in 2012) or wayland. Some of them like mbedtls or miniupnpc require to use the related --disable-builtinmbedtls or --disable-builtinminiupnpc options to actually use the system lib.

Also this list doesn't include dependencies already in the Slackware main tree like flac or v4l2-utils which I don't have a complete list of...

This would be hard for me to document well except for with Slackware unfortunately where the packages aren't split up like in debian or ubuntu meaning it wouldn't be helpful for a lot of users.

There are also more warnings with --enable-sixel, @bparker06 might have a better idea since he implemented this driver.

gfx/drivers_font/sixel_font.c: In function ‘sixel_render_msg’:
gfx/drivers_font/sixel_font.c:83:19: warning: variable ‘newY’ set but not used [-Wunused-but-set-variable]
    unsigned newX, newY;
                   ^~~~
gfx/drivers_font/sixel_font.c:83:13: warning: variable ‘newX’ set but not used [-Wunused-but-set-variable]
    unsigned newX, newY;
             ^~~~
gfx/drivers_font/sixel_font.c: At top level:
gfx/drivers_font/sixel_font.c:133:4: warning: initialization of ‘void (*)(video_frame_info_t *, void *, const char *, const struct font_params *)’ {aka ‘void (*)(struct video_frame_info *, void *, const char *, const struct font_params *)’} from incompatible pointer type ‘void (*)(video_frame_info_t *, void *, const char *, const void *)’ {aka ‘void (*)(struct video_frame_info *, void *, const char *, const void *)’} [-Wincompatible-pointer-types]
    sixel_render_msg,
    ^~~~~~~~~~~~~~~~
gfx/drivers_font/sixel_font.c:133:4: note: (near initialization for ‘sixel_font.render_msg’)
CC gfx/drivers_context/sixel_ctx.c
CC menu/drivers_display/menu_display_sixel.c
menu/drivers_display/menu_display_sixel.c:93:4: warning: initialization of ‘void (*)(menu_display_ctx_draw_t *, video_frame_info_t *)’ {aka ‘void (*)(struct menu_display_ctx_draw *, struct video_frame_info *)’} from incompatible pointer type ‘void (*)(void *)’ [-Wincompatible-pointer-types]
    menu_display_sixel_draw,
    ^~~~~~~~~~~~~~~~~~~~~~~
menu/drivers_display/menu_display_sixel.c:93:4: note: (near initialization for ‘menu_display_ctx_sixel.draw’)
menu/drivers_display/menu_display_sixel.c:94:4: warning: initialization of ‘void (*)(menu_display_ctx_draw_t *, video_frame_info_t *)’ {aka ‘void (*)(struct menu_display_ctx_draw *, struct video_frame_info *)’} from incompatible pointer type ‘void (*)(void *)’ [-Wincompatible-pointer-types]
    menu_display_sixel_draw_pipeline,
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
menu/drivers_display/menu_display_sixel.c:94:4: note: (near initialization for ‘menu_display_ctx_sixel.draw_pipeline’)
menu/drivers_display/menu_display_sixel.c:95:4: warning: initialization of ‘void (*)(menu_display_ctx_draw_t *, video_frame_info_t *)’ {aka ‘void (*)(struct menu_display_ctx_draw *, struct video_frame_info *)’} from incompatible pointer type ‘void (*)(void *)’ [-Wincompatible-pointer-types]
    menu_display_sixel_viewport,
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~
menu/drivers_display/menu_display_sixel.c:95:4: note: (near initialization for ‘menu_display_ctx_sixel.viewport’)
menu/drivers_display/menu_display_sixel.c:96:4: warning: initialization of ‘void (*)(video_frame_info_t *)’ {aka ‘void (*)(struct video_frame_info *)’} from incompatible pointer type ‘void (*)(void)’ [-Wincompatible-pointer-types]
    menu_display_sixel_blend_begin,
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
menu/drivers_display/menu_display_sixel.c:96:4: note: (near initialization for ‘menu_display_ctx_sixel.blend_begin’)
menu/drivers_display/menu_display_sixel.c:97:4: warning: initialization of ‘void (*)(video_frame_info_t *)’ {aka ‘void (*)(struct video_frame_info *)’} from incompatible pointer type ‘void (*)(void)’ [-Wincompatible-pointer-types]
    menu_display_sixel_blend_end,
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
menu/drivers_display/menu_display_sixel.c:97:4: note: (near initialization for ‘menu_display_ctx_sixel.blend_end’)
menu/drivers_display/menu_display_sixel.c:99:4: warning: initialization of ‘void (*)(menu_display_ctx_clearcolor_t *, video_frame_info_t *)’ {aka ‘void (*)(struct menu_display_ctx_clearcolor *, struct video_frame_info *)’} from incompatible pointer type ‘void (*)(menu_display_ctx_clearcolor_t *)’ {aka ‘void (*)(struct menu_display_ctx_clearcolor *)’} [-Wincompatible-pointer-types]
    menu_display_sixel_clear_color,
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
menu/drivers_display/menu_display_sixel.c:99:4: note: (near initialization for ‘menu_display_ctx_sixel.clear_color’)
menu/drivers_display/menu_display_sixel.c:100:4: warning: initialization of ‘void * (*)(video_frame_info_t *)’ {aka ‘void * (*)(struct video_frame_info *)’} from incompatible pointer type ‘void * (*)(void)’ [-Wincompatible-pointer-types]
    menu_display_sixel_get_default_mvp,
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
menu/drivers_display/menu_display_sixel.c:100:4: note: (near initialization for ‘menu_display_ctx_sixel.get_default_mvp’)
hhromic commented 5 years ago

@orbea - wayland is not building for me in Debian 9 (with backports). Unfortunately wayland-protocols is at version 1.13 there and RetroArch seems to require 1.15 minimum. This makes RetroArch+Wayland unbuildable in standard Debian 9 even with backports enabled.

Is this a desirable situation? Debian is a very widely used Linux OS :(

hhromic commented 5 years ago

Regarding the warnings hunting, I'm only getting the following types of warnings with CXX_BUILD=1:

menu/menu_displaylist.c: In function ‘bool menu_displaylist_ctl(menu_displaylist_ctl_state, menu_displaylist_info_t*)’:
menu/menu_displaylist.c:8495:60: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                                  if (!checked_found && val == orig_value)
                                                        ~~~~^~~~~~~~~~~~~
menu/menu_displaylist.c:8521:60: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                                  if (!checked_found && val == orig_value)
                                                        ~~~~^~~~~~~~~~~~~
menu/menu_displaylist.c:8846:57: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                               if (!checked_found && val == orig_value)
                                                     ~~~~^~~~~~~~~~~~~
menu/menu_displaylist.c:8872:57: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                               if (!checked_found && val == orig_value)
                                                     ~~~~^~~~~~~~~~~~~

There are other source files with exactly the same warning.

The problem is simple, there are comparisons in if statements that are being done between signed/unsigned types. For example in menu/menu_displaylist.c, line 8495:

if (!checked_found && val == orig_value)

The type of val is int and the type of orig_value is unsigned. It seems to me that a bit earlier, the line:

int val = (int)i;

Should be:

unsigned val = (unsigned)i;

The same rationale is for all the other warnings of this type.

I don't have time this weekend to help with this, but I will have later during the week if you wish for me to provide a PR.

orbea commented 5 years ago

It would be nice to add support for older versions of wayland-protocols like was done with the wayland-scanner, but I use x11 and have very little knowledge of wayland so I am not sure how it should be done.

The problem would need to be addressed in this script.

https://github.com/libretro/RetroArch/blob/master/gfx/common/wayland/generate_wayland_protos.sh

Also see commits https://github.com/libretro/RetroArch/commit/63c7abef067704d8ece0a8b6563c48880a156134 and https://github.com/libretro/RetroArch/commit/677395f05e71f3090c7de9f7bd8c05cbc5ec4229.

@Sunderland93 Would you have any ideas about this? Is it even possible?

Fwiw with Slackware I just asked the wayland-protocols maintainer to update his SlackBuild and this was done immediately, it should be an easy and painless upgrade for the debian maintainers. Its also very easy to build from source even inside travis as some projects have been forced to do...

Regarding the warnings hunting, I'm only getting the following types of warnings with CXX_BUILD=1

I haven't seen these warnings yet, but I'll try and look harder to see if I can reproduce them. Otherwise I think it might be better if you could fix them when time permits. :)

Sunderland93 commented 5 years ago

We support xdg-decoration-unstable-v1 protocol, which was introduced in wayland-protocols 1.15. That's why the minimum required version is 1.15. Actually, RetroArch needs four protocols: xdg-shell stable, xdg-shell-unstable-v6, xdg-decoration-unstable-v1 and idle-inhibit-unstable-v1. We may bundle them with RetroArch, and not depend on full wayland-protocols set.

orbea commented 5 years ago

Do the generated files differ at all between systems? I wonder if files generated on Slackware would work on Debian or vica versa?

From a package management point of perspective bundling libraries or generated files is sometimes frowned upon and if this is done it would be good to retain both paths so that users could still use their own wayland-protocols packages.

Sunderland93 commented 5 years ago

I wonder if files generated on Slackware would work on Debian or vica versa?

Of course

From a package management point of perspective bundling libraries or generated files is sometimes frowned upon and if this is done it would be good to retain both paths so that users could still use their own wayland-protocols packages.

Many apps contains build-time dependencies (as submodules or in "externals" dir) and provide build options to choose between system libraries and external (such as -DUSE_SYSTEM_LIBS=On). Maybe we could do something like that?

Sunderland93 commented 5 years ago

On the other hand, wayland-protocols is just set of .xml's, it doesn't break anything in system...

Sunderland93 commented 5 years ago

I have one idea for that. I'll make PR later today.

hhromic commented 5 years ago

@Sunderland93 , I was thinking exactly the same about wayland-protocols being just a set of xml descriptors, so I think I know what your idea is :) looking forward for your PR then. Thanks!

Debian 9 (stretch) comes with wayland 1.12.0-1, which should be good enough. The Debian 9 backports come with wayland 1.16.0-1, which is what I'm using for building.

For the record, the next Debian version (buster) is set to include wayland-protocols 1.17-1, so Debian should be soon supported with RetroArch as-is: https://packages.debian.org/search?keywords=wayland-protocols

Debian 10 is set to be released mid-2019, which is quite soon. However, eliminating the current dependency on wayland-protocols 1.15 would be a great thing for compatibility due to current Debian 9 being very widely used nowadays.

orbea commented 5 years ago

Many apps contains build-time dependencies (as submodules or in "externals" dir) and provide build options to choose between system libraries and external (such as -DUSE_SYSTEM_LIBS=On). Maybe we could do something like that?

Well, I suppose if the correct wayland-scanner version is found we could use the system version or fallback to bundled versions when its missing?

hhromic commented 5 years ago

@orbea @Sunderland93 How about bundling just the wayland protocols files, i.e. not the main wayland packages? I mean that is not necessary to bundle wayland-scanner, etc. This wouldn't even require a configure flag for it.

For example SDL2 does only bundle their own copy of wayland protocols (not even the complete set, just the specific files they need), which is just a set of xml files (see: https://github.com/SDL-mirror/SDL).

Moreover, as the wayland protocols should be pretty fixed/static/stable for the project, probably they won't change at all for RetroArch even if wayland gets updated, right? Only when things related to the protocols are changed, then the xml files would require updating. In the end these xml files are a type of source code more than a functional library dependency.

Sunderland93 commented 5 years ago

@hhromic Yes, I like SDL2-way for that thing.

Sunderland93 commented 5 years ago

How about bundling just the wayland protocols files, i.e. not the main wayland packages? I mean that is not necessary to bundle wayland-scanner, etc. This wouldn't even require a configure flag for it.

I think this is the only one, best solution. Also MATE folks did the same https://github.com/mate-desktop/mate-panel/tree/master/mate-panel/wayland-protocols

hhromic commented 5 years ago

I think this is the only one, best solution.

So if you agree it's a sensible solution then maybe we should follow the example of these projects :)

I have zero experience on the RetroArch build system, would you or @orbea be able to create a PR for integrating the necessary wayland-protocols files into this repository and update the build system to use these instead of trying to look for the package in the system? All the other wayland packages should be left as they are, being looked in the system.

Maybe gfx/common/wayland-protocols is a good place to put the protocol files so they don't polute the repository main directory? You know best guys :)

Edit: sorry I meant gfx/common/wayland-protocols alongside wayland

orbea commented 5 years ago

Its still not ideal to force bundling the generated files, there may be cases where newer versions of wayland-protocols would be preferred by specific distributions.

hhromic commented 5 years ago

@orbea the idea is not to bundle the generated files, but the source protocol xml files. This way the generation is done exactly as it is now but with the bundled xml files. Also the bundled version in RetroArch can be kept always up-to-date (newer), so they never depend on the distribution (if installed). I'm no expert on wayland but that's what I understood from @Sunderland93 on how the protocol xml files work.

Edit: I understand that the generator takes the xml protocol descriptor files and generate header files to be compiled. These xml protocol descriptors can be bundled (in an always known updated version) but still be generated on build. This is how SDL2/MATE seem to do it.

Edit2: the xml files are not system-dependent but used by the system-installed wayland-scanner to generate the final code (which is system-dependant). This is how the generated code is guaranteed to work on the system being built for, no matter where the xml files come from. @Sunderland93 could you confirm this?

orbea commented 5 years ago

I see I misunderstood, so the idea would be to bundle parts of wayland-protocols into the code base and use those to generate the files?

I don't have a problem with this as a fallback, but I still think it would be preferable to use the system version when available.