How to compile the demo example of SoLoud library in C? - c

I planned to use the SoLoud library (https://sol.gfxile.net/soloud/index.html) for my C project. I can't understand how to compile the C demo file contained in
/demos/c_test/
to make it executable.
Can someone help me to understand how to compile it using gcc?

in the demos/c_test/main.c,
I changed:
#include "soloud_c.h"
to
#include "../../include/soloud_c.h"
and it compiled. However, the compiler output the following warnings:
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "main.c" -o "main.o" main.c:
In function ‘generate_sample’:
main.c:72:38: warning: conversion from ‘int’ to ‘float’ may change value [-Wconversion]
72 | buf[i] += (((rand() % 1024) - 512) / 512.0f) *
| ^
main.c:75:36: warning: conversion from ‘int’ to ‘float’ may change value [-Wconversion]
75 | float fade = (44100 * 10 - base) / (44100 * 10.0f);
| ^
main.c: In function ‘main’:
main.c:129:14: warning: unused parameter ‘parc’ [-Wunused-parameter]
129 | int main(int parc, char ** pars)
| ~~~~^~~~
main.c:129:28: warning: unused parameter ‘pars’ [-Wunused-parameter]
129 | int main(int parc, char ** pars)
| ~~~~~~~~^~~~
Compilation finished successfully.
Note: I did not bother to link the executable, however, I did note a few items of interest.
the available libraries are *.dll files, so this is expecting to be compiled/linked under the windows OS.
under the 'bin' directory are the libraries: soloud_x64.dll, soloud_x86.dll and SDL2.dll. I don't know which of these libraries your specific computer will need to include

Related

make CC=other_cc in windows

maybe this question is stupid but i really am not able to get a way to fix this i am trying to make a file in Cygwin64 i have all the dependency files installed, but when i make the file it throws me this
$ make
x86_64-w64-mingw32-gcc -D OS_WINDOWS_NT -ansi -Wall -O2 -Wno-long-long -I /usr/include -c -o main.o main.c
In file included from /usr/include/sys/_pthreadtypes.h:12,
from /usr/include/sys/types.h:223,
from /usr/include/stdio.h:61,
from main.c:5:
/usr/include/sys/cpuset.h:17:30: error: expected expression before ‘/’ token
17 | #define __CPU_SETSIZE 1024 // maximum number of logical processors tracked
| ^
/usr/include/sys/cpuset.h:19:25: note: in expansion of macro ‘__CPU_SETSIZE’
19 | #define __CPU_GROUPMAX (__CPU_SETSIZE / __NCPUBITS) // maximum group number
| ^~~~~~~~~~~~~
/usr/include/sys/cpuset.h:26:21: note: in expansion of macro ‘__CPU_GROUPMAX’
26 | __cpu_mask __bits[__CPU_GROUPMAX];
| ^~~~~~~~~~~~~~
/usr/include/sys/cpuset.h:19:55: error: expected expression before ‘/’ token
19 | #define __CPU_GROUPMAX (__CPU_SETSIZE / __NCPUBITS) // maximum group number
| ^
/usr/include/sys/cpuset.h:26:21: note: in expansion of macro ‘__CPU_GROUPMAX’
26 | __cpu_mask __bits[__CPU_GROUPMAX];
| ^~~~~~~~~~~~~~
/usr/include/sys/cpuset.h:27:1: warning: no semicolon at end of struct or union
27 | } cpu_set_t;
| ^
In file included from /usr/include/errno.h:9,
from main.c:8:
/usr/include/sys/errno.h:14: warning: "errno" redefined
14 | #define errno (*__errno())
|
In file included from /usr/lib/gcc/x86_64-w64-mingw32/10/include/stddef.h:1,
from /usr/include/sys/cdefs.h:47,
from /usr/include/stdio.h:35,
from main.c:5:
/usr/x86_64-w64-mingw32/sys-root/mingw/include/stddef.h:19: note: this is the location of the previous definition
19 | #define errno (*_errno())
|
make: *** [<builtin>: main.o] Error 1
Your problem is that you've added the -ansi option to your compile line:
x86_64-w64-mingw32-gcc -D OS_WINDOWS_NT -ansi ...
The -ansi option tells the compiler to compile your code as if it were ANSI C 89 standard code. That version of the standard did not support the // single-line comment delimiter: it only supports the traditional /* ... */ comments.
However the header file you're including clearly expects to be able to use // comments. So you cannot use the -ansi flag when you compile with these header files.

how to generate hex files from c code and assembly code RISCV

I have some C Codes/ assembly codes and I want to compile it and generate hex files for RISCV pulppissimo. Can anyone help me with the steps for this.
Currently running the hello code
#include <stdio.h>
int main()
{
printf("Hello !\n");
return 0;
}
while compiling using riscv32 using the command riscv32-unknown-elf-gcc hello.c
getting error like this
RISCV/lib/gcc/riscv32-unknown-elf/7.1.1/../../../../riscv32-unknown-elf/bin/ld: cannot open linker script file riscv.ld: No such file or directory
collect2: error: ld returned 1 exit status
There is a perfect example in the git repository for the pulp platform boot code that can be used for answering your question. Since I do not have the toolchain you are using, I am using a toolchain I downloaded from the bootlin web site.
wget https://toolchains.bootlin.com/downloads/releases/toolchains/riscv32-ilp32d/tarballs/riscv32-ilp32d--glibc--bleeding-edge-2020.02-2.tar.bz2
mkdir -p /opt/bootlin
tar jxvf riscv32-ilp32d--glibc--bleeding-edge-2020.02-2.tar.bz2 -C /opt/bootlin
git clone git clone https://github.com/pulp-platform/boot-code
cd boot-code
edit the Makefile, and adjust the following lines in order to reflect the location for the toolchain you are using:
PULP_CC = riscv32-unknown-elf-gcc
PULP_LD = riscv32-unknown-elf-gcc
When using the bootlin toolchain, this would result in the two following lines:
PULP_CC = /opt/bootlin/riscv32-ilp32d--glibc--bleeding-edge-2020.02-2/bin/riscv32-buildroot-linux-gnu-gcc
PULP_LD = /opt/bootlin/riscv32-ilp32d--glibc--bleeding-edge-2020.02-2/bin/riscv32-buildroot-linux-gnu-gcc
The the same Makefile, replace the following line - the code does not compile as is I think:
CFLAGS += -Os -g -fno-jump-tables -I$(CURDIR)/include
by:
CFLAGS += -Os -g -fno-jump-tables -I$(CURDIR)/include -DMCHAN_CMD_ILE_BIT=21 -DMCHAN_CMD_ELE_BIT=20
You can now build the build/bootcode executable:
make
CC boot_code.c
In file included from /home/frant/mnt/git/boot-code/include/hal/chips/pulp/pulp.h:20,
from /home/frant/mnt/git/boot-code/include/hal/pulp.h:27,
from boot_code.c:18:
/home/frant/mnt/git/boot-code/include/hal/riscv/riscv_v5.h: In function ‘hal_cluster_id’:
/home/frant/mnt/git/boot-code/include/hal/riscv/riscv_v5.h:172:10: warning: implicit declaration of function ‘__builtin_pulp_ClusterId’ [-Wimplicit-function-declaration]
172 | return __builtin_pulp_ClusterId();
| ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/frant/mnt/git/boot-code/include/hal/chips/pulp/pulp.h:21,
from /home/frant/mnt/git/boot-code/include/hal/pulp.h:27,
from boot_code.c:18:
/home/frant/mnt/git/boot-code/include/hal/eu/eu_v3.h: In function ‘evt_read32’:
/home/frant/mnt/git/boot-code/include/hal/eu/eu_v3.h:43:11: warning: implicit declaration of function ‘__builtin_pulp_event_unit_read’ [-Wimplicit-function-declaration]
43 | value = __builtin_pulp_event_unit_read((int *)base, offset);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CC crt0.S
LD /home/frant/mnt/git/boot-code/build/bootcode
./stim_utils.py \
--binary=/home/frant/mnt/git/boot-code/build/bootcode \
--stim-bin=rom.bin \
--area=0x1a000000:0x01000000
Created stimuli generator
Added binary: /home/frant/mnt/git/boot-code/build/bootcode
Added target area: [0x1a000000 -> 0x1b000000]
Handling section (base: 0x1a000000, size: 0x57c)
Bypassing section (base:make
CC boot_code.c
In file included from /home/frant/mnt/git/boot-code/include/hal/chips/pulp/pulp.h:20,
from /home/frant/mnt/git/boot-code/include/hal/pulp.h:27,
from boot_code.c:18:
/home/frant/mnt/git/boot-code/include/hal/riscv/riscv_v5.h: In function ‘hal_cluster_id’:
/home/frant/mnt/git/boot-code/include/hal/riscv/riscv_v5.h:172:10: warning: implicit declaration of function ‘__builtin_pulp_ClusterId’ [-Wimplicit-function-declaration]
172 | return __builtin_pulp_ClusterId();
| ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/frant/mnt/git/boot-code/include/hal/chips/pulp/pulp.h:21,
from /home/frant/mnt/git/boot-code/include/hal/pulp.h:27,
from boot_code.c:18:
/home/frant/mnt/git/boot-code/include/hal/eu/eu_v3.h: In function ‘evt_read32’:
/home/frant/mnt/git/boot-code/include/hal/eu/eu_v3.h:43:11: warning: implicit declaration of function ‘__builtin_pulp_event_unit_read’ [-Wimplicit-function-declaration]
43 | value = __builtin_pulp_event_unit_read((int *)base, offset);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CC crt0.S
LD /home/frant/mnt/git/boot-code/build/bootcode
./stim_utils.py \
--binary=/home/frant/mnt/git/boot-code/build/bootcode \
--stim-bin=rom.bin \
--area=0x1a000000:0x01000000
Created stimuli generator
Added binary: /home/frant/mnt/git/boot-code/build/bootcode
Added target area: [0x1a000000 -> 0x1b000000]
Handling section (base: 0x1a000000, size: 0x57c)
Bypassing section (base: 0x1c000000, size: 0x1928)
objcopy --srec-len 1 --output-target=srec /home/frant/mnt/git/boot-code/build/bootcode /home/frant/mnt/git/boot-code/build/bootcode.s19
./s19toboot.py /home/frant/mnt/git/boot-code/build/bootcode.s19 boot_code.cde pulp 0x1c000000, size: 0x1928)
objcopy --srec-len 1 --output-target=srec /home/frant/mnt/git/boot-code/build/bootcode /home/frant/mnt/git/boot-code/build/bootcode.s19
./s19toboot.py /home/frant/mnt/git/boot-code/build/bootcode.s19 boot_code.cde pulp
And convert it into Intel Hex format:
/opt/bootlin/riscv32-ilp32d--glibc--bleeding-edge-2020.02-2/bin/riscv32-buildroot-linux-gnu-objcopy --output-target=ihex build/bootcode bootcode.ihex
cat bootcode.ihex
:020000041A00E0
:100000006F0080086F0040086F0000086F00C00795
:100010006F0080076F0040076F0000076F00C00689
../...
:081920000000000000000000BF
:040000051A000000DD
:00000001FF
Now that you have a working example for the pulp platform I think is your target, you should be able to adapt it to your needs.

"Static declaration of ‘memfd_create’ follows non-static declaration" Error while building Linux image using Yocto

I am building Linux Image using Yoctobuild system on Ubuntu 18.04 host machine. I am following steps provided over here. I am building for Colibri iMX6ULL computer-on-module. However, my build has failed and it is showing errors given below
declaration of ‘memfd_create’ follows non-static declaration
| static int memfd_create(const char *name, unsigned int flags)
| ^~~~~~~~~~~~
| In file included from /usr/include/x86_64-linux-gnu/bits/mman-linux.h:115:0,
| from /usr/include/x86_64-linux-gnu/bits/mman.h:45,
| from /usr/include/x86_64-linux-gnu/sys/mman.h:41,
| from /home/abhiarora/iohertz/gateway_os/yocto/build/tmp-glibc/work/x86_64-linux/qemu-native/2.10.0-r0/qemu-2.10.0/include/sysemu/os-posix.h:29,
| from /home/abhiarora/iohertz/gateway_os/yocto/build/tmp-glibc/work/x86_64-linux/qemu-native/2.10.0-r0/qemu-2.10.0/include/qemu/osdep.h:104,
| from /home/abhiarora/iohertz/gateway_os/yocto/build/tmp-glibc/work/x86_64-linux/qemu-native/2.10.0-r0/qemu-2.10.0/util/memfd.c:28:
| /usr/include/x86_64-linux-gnu/bits/mman-shared.h:46:5: note: previous declaration of ‘memfd_create’ was here
| int memfd_create (const char *__name, unsigned int __flags) __THROW;
| ^~~~~~~~~~~~
| /home/abhiarora/iohertz/gateway_os/yocto/build/tmp-glibc/work/x86_64-linux/qemu-native/2.10.0-r0/qemu-2.10.0/rules.mak:66: recipe for target 'util/memfd.o' failed
And this error:
| gcc -c -I. -I../lib -I../../git/lib -isystem/home/abhiarora/iohertz/gateway_os/yocto/build/tmp-glibc/work/x86_64-linux/e2fsprogs-native/1.43.5-r0/recipe-sysroot-native/usr/include -isystem/home/abhiarora/iohertz/gateway_os/yocto/build/tmp-glibc/work/x86_64-linux/e2fsprogs-native/1.43.5-r0/recipe-sysroot-native/usr/include -O2 -pipe -DHAVE_CONFIG_H -I../../git/debugfs/../e2fsck -DDEBUGFS ../../git/debugfs/quota.c -o quota.o
| ../../git/debugfs/../misc/create_inode.c:406:18: error: conflicting types for ‘copy_file_range’
| static errcode_t copy_file_range(ext2_filsys fs, int fd, ext2_file_t e2_file,
| ^~~~~~~~~~~~~~~
| In file included from ../../git/debugfs/../misc/create_inode.c:19:0:
| /usr/include/unistd.h:1110:9: note: previous declaration of ‘copy_file_range’ was here
| ssize_t copy_file_range (int __infd, __off64_t *__pinoff,
| ^~~~~~~~~~~~~~~
| gcc -c -I. -I../lib -I../../git/lib -isystem/home/abhiarora/iohertz/gateway_os/yocto/build/tmp-glibc/work/x86_64-linux/e2fsprogs-native/1.43.5-r0/recipe-sysroot-native/usr/include -isystem/home/abhiarora/iohertz/gateway_os/yocto/build/tmp-glibc/work/x86_64-linux/e2fsprogs-native/1.43.5-r0/recipe-sysroot-native/usr/include -O2 -pipe -DHAVE_CONFIG_H -I../../git/debugfs/../e2fsck -DDEBUGFS ../../git/debugfs/xattrs.c -o xattrs.o
| Makefile:422: recipe for target 'create_inode.o' failed
| make[2]: *** [create_inode.o] Error 1
| make[2]: *** Waiting for unfinished jobs....
The packages/tasks that were failed:
e2fsprogs_1.43.5
qemu_2.10.0
Can someone help me? I can't switch to ubuntu 16.04 but I think it should be working with my system as well.
This is a known issue at Toradex and is on the Roadmap, see issue #36657.
Fixes are already in the upstream layers, and we have updated our BSP repo. You can try this branch by using the LinuxImageV2.7-integration branch.

No warnings for headers included by headers in non-current directories

How can I let gcc and clang generate warnings for header files included by header files in non-current directories?
I'm using gcc 4.9.2 and clang 3.6.0.
For example, assume that ./include_a.c includes ./dir/a.h, ./dir/a.h includes ./b.h, and ./b.h is expected to generate a warning for -Wconversion; then, gcc and clang with -Wconversion DO NOT generate the expected warning when they compile include_a.c. With -Wconversion -Wsystem-headers, the expected warning is generated, but it often comes with many useless warnings for system headers. When ./b.h is directly included from a source file in the current directory (such as ./include_b.c), the expected warning is generated without -Wsystem-headers.
The following shell script reproduces this example (the case of clang is omitted):
#!/bin/sh
mkdir dir
echo '#include "b.h"' >dir/a.h
echo 'void f() {int a = 0; char b = a;}' >b.h
echo '#include "dir/a.h"' >include_a.c
echo '#include "b.h"' >include_b.c
set -x
gcc -c include_a.c -Wconversion # DOES NOT generate a warning
gcc -c include_a.c -Wconversion -Wsystem-headers # generate a warning
gcc -c include_b.c -Wconversion # generate a warning
Output:
+ gcc -c include_a.c -Wconversion
+ gcc -c include_a.c -Wconversion -Wsystem-headers
In file included from dir/a.h:1:0,
from include_a.c:1:
./b.h: In function ‘f’:
./b.h:1:31: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
void f() {int a = 0; char b = a;}
^
+ gcc -c include_b.c -Wconversion
In file included from include_b.c:1:0:
b.h: In function ‘f’:
b.h:1:31: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
void f() {int a = 0; char b = a;}
^
This behavior seems not to be a bug because gcc and clang perform in the same way, but how can I obtain warnings from all the my source files?

gcc4.9, disable include files trace, from warnings

I just moved to gcc4.9 . Now when I run make to compile my program, I noticed the verbosity of messages is much increased. In particular in the warnings, I receive a lot more of info I don't need, mainly such messages:
myfile.c: In function 'myfunc':
myfile.c:4677:10: warning: passing argument 1 of 'sprintf' from incompatible pointer type
sprintf(str1,"file.txt");
^
In file included from /usr/include/features.h:374:0,
from /usr/include/stdio.h:27,
from myfile.c:28:
/usr/include/i386-linux-gnu/bits/stdio2.h:31:1: note: expected 'char * __restrict__' but argument is of type 'char **'
__NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
^
My compilation parameters are always the same "-g -O3".
I tried -g0 and -g1, but verbosity doesn't lower.
So wanted to ask, how can I set gcc to suppress all those excessive compile-time messages in the warnings, everything starting from "In file included..." and after?
EDIT:
I guess I have to elaborate more what I want to achieve.
I want the warnings, so I don't need -w option.
I do want to see:
myfile.c: In function 'myfunc':
myfile.c:4677:10: warning: passing argument 1 of 'sprintf' from incompatible pointer type
sprintf(str1,"file.txt");
^
I do NOT want to see:
In file included from /usr/include/features.h:374:0,
from /usr/include/stdio.h:27,
from myfile.c:28:
/usr/include/i386-linux-gnu/bits/stdio2.h:31:1: note: expected 'char * __restrict__' but argument is of type 'char **'
__NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
I'm not interested that primitive sprintf is declared in a,called by b (...who actually could be interested in that...?!?)
The previous gcc version didn't have that issue, so my best guess, there must be some new option in gcc4.9 to remove that (but I couldn't find it)
Does anybody know how to remove everything starting from "In file included..." further(in the warning)?
Thanks
I strongly recommend you don't do this, but if you insist:
gcc -w inhibits all warnings. This is something you could have discovered from googling 'gcc suppress warnings'. . .
That said, the warnings are valid - you appear to be doing wrong things in your code. If you want to get rid of the warnings, why not fix the code? Then you have better code and no warnings.
What you suggest is a workaround, but I can still try it. Could you please write here that filter you talk about?
OK; I'd create a shell script to do the hard work. There are two ways to handle it. One is to call the script gcc-filter and then instead of running:
gcc -g -O3 -Wall -Wextra -Werror -I/where/ever -c source.c
you would run:
gcc-filter gcc -g -O3 -Wall -Wextra -Werror -I/where/ever -c source.c
Using make, you can achieve that by specifying CC="gcc-filter gcc" or equivalent.
The alternative is to run the script after redirecting output:
gcc -g -O3 -Wall -Wextra -Werror -I/where/ever -c source.c 2>&1 | gcc-filter
I'm going to assume the first technique.
gcc-filter.sh
"$#" 2>&1 |
sed '/^In file /,/^ *^/d' >&2
The first line runs gcc (or whatever command is specified by the arguments; it doesn't have to be gcc) with the arguments as specified on the command line. It redirects both standard output and standard error to a pipe (I'll come back to this), which goes to sed.
The sed line looks for the pattern In file at the start of a line, and deletes from there up to the first line that starts with a caret after optional spaces. The redirection sends the information that it passes through to standard error.
There are two prime defects with the script as it stands:
It assumes that standard output and standard error can be merged (or, more succinctly, that gcc doesn't write much to standard output).
It works off one pattern of error reporting. If there are other sequences that should be filtered, you will need to add to the sed script.
You can deal with the standard output vs standard error issue, but it is mildly mind blowing (maybe 'mind puffing').
(
"$#" 2>&1 1>&3 |
sed '/^In file /,/^ *^/d' >&2
) 3>&1
The sub-shell ( ... ) 3>&1 sends data written to file descriptor 3 so it goes to standard output.
Inside the sub-shell 2>&1 1>&3 | arranges for:
Standard output to go to the pipe.
Standard error to go where standard output is going (the pipe).
Standard output to go to file descriptor 3 (without changing where standard error is going, the pipe).
The sed command therefore gets the standard error output from gcc as its standard input, filters it, and the >&2 sends its standard output to standard error.
The net result is that standard error is filtered while standard output is not. However, be aware that you can end up with different interleaving of output from the two streams as a result of the buffering going on.
One other problem: exit status. The exit status of the script as written is the exit status of the sed command, which will be 0 under most circumstances. If we need to relay the exit status from gcc, we have to work with the Bash set -o pipefail, I think. Or you can poke at the PIPESTATUS array; exit ${PIPESTATUS[0]} should exit with the same exit status that gcc exited with.
Demonstrating the code working on Linux
The system is running an Ubuntu 14.04 LTS derivative with GCC 4.9.2.
Test code b.c
(I'd used up x.c, y.c, z.c, and a.c on other programs.)
#include <stdio.h>
int main(void)
{
char array[512];
char *buffer = array;
sprintf(&buffer, "file.txt");
printf("%s\n", buffer);
return 0;
}
Compilation without gcc-filter.sh:
$ make b.o WFLAG3= WFLAG4= WFLAG5= WFLAG6= IFLAGS= LDFLAGS= LDLIBS= cc -g -O3 -std=c11 -Wall -Wextra -Werror -c -o b.o b.c
b.c: In function ‘main’:
b.c:8:3: error: passing argument 1 of ‘sprintf’ from incompatible pointer type [-Werror]
sprintf(&buffer, "file.txt");
^
In file included from /usr/include/features.h:374:0,
from /usr/include/stdio.h:27,
from b.c:1:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:31:1: note: expected ‘char * restrict’ but argument is of type ‘char **’
__NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
^
cc1: all warnings being treated as errors
<builtin>: recipe for target 'b.o' failed
make: *** [b.o] Error 1
$
Compilation with gcc-filter.sh
$ make b.o CC="./gcc-filter.sh gcc"
./gcc-filter.sh gcc -g -O3 -std=c11 -Wall -Wextra -Werror -c -o b.o b.c
b.c: In function ‘main’:
b.c:8:11: error: passing argument 1 of ‘sprintf’ from incompatible pointer type [-Werror]
sprintf(&buffer, "file.txt");
^
cc1: all warnings being treated as errors
<builtin>: recipe for target 'b.o' failed
make: *** [b.o] Error 1
$
gcc-filter.sh
#!/bin/bash
set -o pipefail
(
"$#" 2>&1 1>&3 |
sed '/^In file /,/^ *^/d' >&2
) 3>&1
exit ${PIPESTATUS[0]}
And another test
I also created c.c which contained three sprintf() lines and three printf() lines, and the filtered output was:
$ ./gcc-filter.sh gcc -g -O3 -std=c11 -Wall -Wextra -Werror -c c.c
c.c: In function ‘main’:
c.c:8:11: error: passing argument 1 of ‘sprintf’ from incompatible pointer type [-Werror]
sprintf(&buffer, "file1.txt");
^
c.c:10:11: error: passing argument 1 of ‘sprintf’ from incompatible pointer type [-Werror]
sprintf(&buffer, "file2.txt");
^
c.c:12:11: error: passing argument 1 of ‘sprintf’ from incompatible pointer type [-Werror]
sprintf(&buffer, "file3.txt");
^
cc1: all warnings being treated as errors
$
So multiple errors are handled properly (but in times past, more than one similar script has appeared to work on a single instance of an error message but when tested on multiple error messages, it was too enthusiastic about discarding output).

Resources