13

I've been on a crusade lately to eliminate warnings from our code and have become more familiar with GCC warning flags (such as -Wall, -Wno-<warning to disable>, -fdiagnostics-show-option, etc.). However I haven't been able to figure out how to disable (or even control) linker warnings. The most common linker warning that I was getting is of the following form:

ld: warning: <some symbol> has different visibility (default) in 
<path/to/library.a> and (hidden) in <path/to/my/class.o>

The reason I was getting this was because the library I was using was built using the default visibility while my application is built with hidden visibility. I've fixed this by rebuilding the library with hidden visibility.

My question though is: how would I suppress that warning if I wanted to? It's not something that I need to do now that I've figured out how to fix it but I'm still curious as to how you'd suppress that particular warning — or any linker warnings in general?

Using the -fdiagnostics-show-option for any of the C/C++/linker flags doesn't say where that warning comes from like with other compiler warnings.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Cutterpillow
  • 1,717
  • 13
  • 32

2 Answers2

12

Actually, you can't disable a GCC linker warning, as it's stored in a specific section of the binary library you're linking with. (The section is called .gnu.warning.symbol)

You can however mute it, like this (this is extracted from libc-symbols.h):

Without it:

#include <sys/stat.h>

int main()
{
    lchmod("/path/to/whatever", 0666);
    return 0;
}

Gives:

$ gcc a.c
/tmp/cc0TGjC8.o: in function « main »:
a.c:(.text+0xf): WARNING: lchmod is not implemented and will always fail

With disabling:

#include <sys/stat.h>

/* We want the .gnu.warning.SYMBOL section to be unallocated.  */
#define __make_section_unallocated(section_string)    \
  __asm__ (".section " section_string "\n\t.previous");

/* When a reference to SYMBOL is encountered, the linker will emit a
   warning message MSG.  */
#define silent_warning(symbol) \
  __make_section_unallocated (".gnu.warning." #symbol) 

silent_warning(lchmod)

int main()
{
    lchmod("/path/to/whatever", 0666);
    return 0;
}

gives:

$ gcc a.c
/tmp/cc195eKj.o: in function « main »:
a.c:(.text+0xf): WARNING:

With hiding:

#include <sys/stat.h>

#define __hide_section_warning(section_string)    \
    __asm__ (".section " section_string "\n.string \"\rHello world!                      \"\n\t.previous");

/* If you want to hide the linker's output */
#define hide_warning(symbol) \
  __hide_section_warning (".gnu.warning." #symbol) 


hide_warning(lchmod)

int main()
{
    lchmod("/path/to/whatever", 0666);
    return 0;
}

gives:

$ gcc a.c
/tmp/cc195eKj.o: in function « main »:
Hello world!

Obviously, in that case, replace Hello world! either by multiple space or some advertisement for your wonderful project.

xryl669
  • 3,376
  • 24
  • 47
  • "you can't... as it's stored in ... the binary library " - but, so what? Why can't we just tell ld to ignore warnings matching some criteria (at worst, with message text matching a certain substring)? – einpoklum May 14 '23 at 15:15
  • The linker is not a compiler. It's not parsing user text and diagnosing errors and warning. It's main role is to merge, drop and fix offset in perfectly valid binary object. There's no mechanism for warning in there, so they hacked a way for the linker to produce messages (via specific sections) and they didn't think you would want to ignore them. You can probably drop with objcopy them before invoking ld, but it's not in the usual build step . – xryl669 May 17 '23 at 10:53
  • Ah, but it is not merely a hack on the compiled object's side - there must be the mechanism in the linker for emitting warnings from those sections. And that mechanism must be configurable, just like a compiler's - even if the linker doesn't know what the warning really means. – einpoklum May 17 '23 at 16:57
3

Unfortunately ld does not appear to have any intrinsic way of suppressing specific options. One thing that I found useful was limiting the number of duplicate warnings by passing -Wl,--warn-once to g++ (or you can pass --warn-once directly to ld).

Riot
  • 15,723
  • 4
  • 60
  • 67