I was trying to compile libpng as static library in MinGW for capture support in DOSBox. Following DOSBox's build Wiki, running configure(--disable-shared --prefix=mingw) and then make results in following error:
libtool: compile: gcc -DHAVE_CONFIG_H -I. -g -O2 -MT png.lo -MD -MP -MF .deps/png.Tpo -c png.c -o png.o In file included from pngpriv.h:72:0, from png.c:14: pnglibconf.h:205:54: error: expected identifier or '(' before '-' token #define PNG_TEXT_Z_DEFAULT_STRATEGY 0 ^ In file included from png.h:366:0, from pngpriv.h:377, from png.c:14: pngconf.h:522:9: error: unknown type name 'ptrdiff_t' typedef ptrdiff_t png_ptrdiff_t; ^~~~~~~~~ In file included from png.c:14:0: pngpriv.h:910:21: error: operator '!=' has no left operand #if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM ^~ make[1]: *** [png.lo] Error 1 make[1]: Leaving directory `/home/Administrator/BUILD/DOSBOX/libpng-1.6.32' make: *** [all] Error 2
The above error doesn't happen while compiling in Linux.
After digging in, following are the observations:
a) MinGW's GCC preprocessor output(pnglibconf.tf1) splits all the PNG_DFN settings that have a substitution(@"...."@) into 3 lines.
for e.g.,
PNG_DFN "#define PNG_Z_DEFAULT_STRATEGY @"
1
"@"
However native linux GCC preprocessor output is perfect, i.e., PNG_DFN "#define PNG_Z_DEFAULT_STRATEGY @" 1 "@"
b) As mentioned in dfn.awk, the above splitting was supposed to be taken care off automatically by the code in line 176 : sub(/^M$/, "", line), but it doesn't, most likely due to CR incompatibility with MinGW msys environment. If I edit the above code as " sub(/\r/, "", line) ", then the 'setting' with substitutions is output in a single line albeit with a lot of white spaces between setting name and the value. Compilation is successful, however.
c) Instead of the above code edit, inserting the above substitution, i.e., sub(/\r/, "", line) just before code in line 131 also takes care of the extra white spaces.
Or else, am I doing something wrong w.r.t CR? I'm somewhat new to this awk & scripting things.
I think this is handled in scripts/options.awk which is a little difficult for me to follow.
I wonder if the problem goes away if you add some parentheses in pngpriv.h line 910
so it reads
#if (PNG_ZLIB_VERNUM != 0) && (PNG_ZLIB_VERNUM != ZLIB_VERNUM)
Thanks for the reply.
Same error after adding parantheses too,
As per my understanding, execution of 'options.awk' script on 'pnglibconf.dfa' works as expected in both MinGW and native Linux, i.e. the contents of the output files(pnglibconf.tf4 & pnglibconf.tf5) from STEPS-1 & 2(indicated below) are the same in both. It is only after the preprocessing of pnglibconf.c in STEP-3, the output file(pnglibconf.tf1) contents vary w.r.t MinGW and native Linux, which ultimately results in the error during compilation under MinGW. As mentioned in my initial post, the issue is only with the PNG_DFN settings whose value gets substituted with those from header file(zlib.h) of zlib package during compilation/runtime, most likely due to the 'CR'. I tried with various switches on the preprocessing command (gcc -E ...) to try and fix the issue at the source itself, without sucess. Maybe it's undefined behaviour due to the implementation differences of GCC preprocessing under MinGW in comparison to that of Linux.
'make' sequence marked with compilation STEPS:
Coming to STEP-4, dfn.awk is supposed to take care of this discrepancy of 'split' lines, but it does not. A quick fix was to insert code " sub(/\r/, "", line) " before line 131 in dfn.awk, which takes care of the discrepancy, then the final auto-generated "pnglibconf.h" in MinGW is same as that of Linux.
Most likely there is a better fix than the one above, but, that's my knowledge limit.
Another thing I observed is the 'sub' string function in line 176 of dfn.awk is split to next line due to CR or ^M in the matching regexp argument. As per my understanding, this function is supposed to remove trailing CR and thus avoid the discrepancy, but it doesn't. Maybe the regexp pattern needs to be modified accordingly in which case the code insert in line 131 may not be required at all.
I've faced the same problem with compiling libpng with MinGW (the only difference is that I build shared library). My research showed me the source of problem:
create the same file 'pnglibconf.tf1' as on Linux but with CRLF line endings
2. In file 'srcipts/dfn.awk' which is executed with command
rule to remove extra CR symbol is lower than other processing rules so after main processing CR symbol is left in #define string like this:
and will not be deleted after.
My fix for such problem is pretty simple and doesn't break anything. I just move rule to clean up line ending at the beginning of while loop in 'srcipts/dfn.awk':
Unfortunately I don't know where to send this fix to merge it in libpng code.
Last edit: Alexander Ushakov 2018-04-17
Hi,
By any chance, could you join the full modified dfn.awk to your message, instead of just the patched file ? It seems the whole 1.6 branch cannot be compiled on mingw-msys2 because of that bug. 1.5 works fine.
This is a very annoying bug; I've tried with my limited knowledge to solve it, but have failed to do so...
Thanks!
LCH
Last edit: LCH 2018-04-19
Attached, is the patched version of "dfn.awk" from the libpng 1.6.35 source