Reputation: 132138
My project code links against some libraries whose source I don't have. During linking I get:
/usr/x86_64-suse-linux/bin/ld:libfoo.a(foo.o): in function `flush':
source/readcfg.c:1234:(.text+0xabc): warning: the use of `tmpnam' is dangerous, better use `mkstemp'
/usr/x86_64-suse-linux/bin/libbar.a(.o): in function `getErmes':
source/bar.c:123:(.text+0x1238): warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead
Can I suppress these messages (or these kinds of messages), without having edited the source files for foo and bar?
(Note: for compiler errors, we can set -Wsomething
and -Wno-something
to enable or suppress. This is even true for some GNU ld warnings, as its man ld
describes several --warn
/--nowarn
options.)
Related: warning: the use of `tmpnam' is dangerous, better use `mkstemp' discusses how to avoid the error from the get-go.
Upvotes: 1
Views: 116
Reputation: 27324
These diagnostics come from special .gnu.warning
sections in the standard library's .o files. (Thanks to this question for giving the hint.) That is, "tmpnam.o" contains a special section named .gnu.warning.tmpnam
. When GNU ld
sees that section (and a use of tmpnam
), it prints the warning.
According to fcambus/gwcheck, the .gnu.warning
logic is implemented in GNU ld and gold, but not in LLVM lld nor on Solaris.
Someone in the 2006 OSDev thread suggests that you could do something "clever" involving objcopy --remove-section
: basically "preprocess" libc.a or libc.so for use with your project, then link against the preprocessed/stripped libc.
Similarly, objcopy --rename-section
.
A partial solution might involve gcc -Wl,--wrap,tmpnam *.o
. This causes ld
to treat every unresolved reference to tmpnam
as if it were an unresolved reference to __wrap_tmpnam
instead. But then you still have to write your own implementation of __wrap_tmpnam
— and you can't implement it by just calling __real_tmpnam
, because that'll trigger the warning again.
Of course if you're willing to reimplement tmpnam
, then you could just add your own tmpnam.o
to your project; you don't need to involve --wrap
.
The simplest solution might actually be "use an alternative to GNU ld," such as mold
or lld
. (But not GNU gold
, which has the same behavior as ld
.)
Or, set your CC
/CXX
environment variable to point not to /usr/bin/gcc
but to a simple shell script like (thanks to this question for explaining how to filter stderr only):
cat >gcc.sh <<EOF
#!/bin/bash
gcc "$@" 2> >(sed -n -e "/tmpnam' is dangerous/{s/.*//;x;d};x;p" >&2)
EOF
CC=./gcc.sh
(Sorry, my sed
-fu is bad. The intent here is to eliminate the line containing tmpnam' is dangerous
and also the immediately preceding line.)
One thing that does not work (as of 2024) is to just add your own empty warning message for tmpnam
, like this:
cat >dummy.c <<EOF
static const char msg[0] __attribute__((section(".gnu.warning.tmpnam")));
EOF
cat >main.c <<EOF
#include <stdio.h>
int main() { char s[100]; tmpnam(s); }
EOF
gcc -c main.c dummy.c
This does "override" the message from libc.so, but it doesn't cause the warning to disappear — it just causes the warning message to become empty, like this:
$ gcc dummy.o main.o
/usr/bin/ld: main.o: in function `main':
main.c:(.text+0x10): warning:
It certainly seems like (as of 2024) there is no simple or one-line solution to this problem.
Upvotes: 1