This is a continuation of trying to compile a license-free GPL version of the Microchip XC32 microcontroller g++ XC32 v4.35 cross-compiler from source.
See my Q&A here, and my repo here: https://github.com/ElectricRCAircraftGuy/Microchip_XC32_Compiler.
Note that this builds perfectly to completion on Linux Ubuntu 22.04 with gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
.
However, when compiling on Windows in the MSYS2 UCRT64 environment (set up per my instructions here) with gcc --version
gcc.exe (Rev2, Built by MSYS2 project) 13.2.0
, I now get the following error in gcc/gcc/system.h
:
./../../pic32m-source/gcc/gcc/prefix.c
../../../pic32m-source/gcc/gcc/system.h:737:30: error: expected identifier before string constant
737 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
| ^~~~~~~~
../../../pic32m-source/gcc/gcc/system.h:737:30: error: expected ',' or '...' before string constant
../../../pic32m-source/gcc/gcc/system.h:737:30: error: expected identifier before string constant
737 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
| ^~~~~~~~
../../../pic32m-source/gcc/gcc/system.h:737:30: error: expected ',' or '...' before string constant
make[1]: *** [Makefile:1112: prefix.o] Error 1
make[1]: Leaving directory '/c/Users/gabriel/GS/dev/Microchip_XC32_Compiler/xc32-v4.35-src/pic32m-build/gcc/gcc'
make: *** [Makefile:4290: all-gcc] Error 2
Here is the system.h
file I am using, at line 737:
/* Redefine abort to report an internal error w/o coredump, and
reporting the location of the error in the source file. */
extern void fancy_abort (const char *, int, const char *)
ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
This definition of abort()
is getting called, for instance, inside a C++ template class in fibonacci_heap.h
line 460, here:
template<class K, class V>
V*
fibonacci_heap<K,V>::delete_node (fibonacci_node<K,V> *node, bool release)
{
V *ret = node->m_data;
/* To perform delete, we just make it the min key, and extract. */
replace_key (node, m_global_min_key);
if (node != m_min)
{
fprintf (stderr, "Can't force minimum on fibheap.\n");
abort (); // <=========== HERE ===========
}
extract_min (release);
return ret;
}
How do I resolve this build error?
And, why is it occurring on Windows, but not on Linux?
Useful Google search: msys gcc abort fancy_abort error: expected identifier before string constant
Possible bug: https://sourceforge.net/p/mingw-w64/bugs/974/
Possible fix: https://github.com/yosshin4004/xdev68k/blob/main/build_m68k-toolchain.sh#L199-L210
#
# 新しい mingw 環境では以下のようなエラーとなる。
# ../../../src/gcc-10.2.0/gcc/system.h:743:30: error: expected identifier before string constant
# 743 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
# 応急処置として、問題を起こす行を除去する。
# abort() は stdlib.h 内で宣言された実装のままの挙動となる。
#
if [ "$(expr substr $(uname -s) 1 5)" == "MINGW" ]; then
cat ${SRC_DIR}/${GCC_DIR}/gcc/system.h |\
perl -e 'my $before="#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)";my $after="/* $before */";$before=quotemeta($before);while(<>){$_=~s/$before/$after/g;print $_;}' > ${SRC_DIR}/${GCC_DIR}/gcc/system.h.tmp;
mv ${SRC_DIR}/${GCC_DIR}/gcc/system.h.tmp ${SRC_DIR}/${GCC_DIR}/gcc/system.h
fi
Translation of the comments from Japanese to English:
#
# In the new mingw environment, the following error will occur.
# ../../../src/gcc-10.2.0/gcc/system.h:743:30: error: expected identifier before string constant
# 743 | #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
# As a workaround, remove the offending line.
# abort() behaves as the implementation declared in stdlib.h.
The code above simply finds #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
in gcc/system.h
, and comments it out as /* #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__) */
, thereby removing it.
Just commenting out this offending macro define seems really hacky. I don't fully understand the repercussions of this change.
Big thanks to @Tim Roberts and "@n. m. could be an AI" for their help and comments under the question which contributed to this answer.
Solution:
Comment out #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
in system.h
to make gcc compile.
Simply commenting out the abort()
define, as done here and as documented at the bottom of my question, worked.
There seems to be a bug in MSYS2 in Windows stopping the build from working with it defined, so simply open up xc32-v4.35-src/pic32m-source/gcc/gcc/system.h
, find this on line 737:
#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
...and comment it out like this:
/* #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__) */
The build now goes to completion when I run time Microchip_XC32_Compiler/build-xc32-v4.35m.sh
, and the MSYS2 UCRT64 gcc toolchain is able to build the PIC32 mcu gcc cross-compiler to completion!
Yes, we think so.
There are 3 layers here: I'm using the MSYS2 UCRT GCC compiler on Windows (layer 1) to compile the Microchip XC32 PIC32 gcc microcontroller cross-compiler (layer 2), which will cross-compile programs (on Windows in this Q&A, though I have it built on Linux Ubuntu too) for PIC32 microcontrollers (layer 3).
Per the discussion with @Tim Roberts under my question (for example, this comment, and others), we think this change is pretty benign and should only affect the layer 2 XC32 cross-compiler (which is what is being compiled in this Q&A), by making it produce less-useful runtime error messages (missing the __FILE__, __LINE__, __FUNCTION__
content) if it crashes while running and compiling for a layer 3 target. So, not a big deal. Layer 3 (the target mcu) remains unaffected. Layer 2 will just have less-useful error messages if it crashes. But, that's unlikely. I can't recall the gcc compiler ever crashing on me. It has produced tons of compilation errors while compiling, of course, but I can't recall having seen it ever produce a run-time crash and output its own internal error. This is what we are talking about. That's the part my change has affected.
Tony Yu on SourceForge has what looks like a good alternative fix too, here.
Basically, just comment out #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
in system.h
, like I did, but then also replace all calls to abort()
in gcc/gcc.c
with fancy_abort (__FILE__, __LINE__, __FUNCTION__)
instead. The challenge here is replacing all of the correct abort()
calls, not just here, but anywhere they may be calling fancy_abort()
. So...that seems hard. I think just commenting it out is fine instead. 👍
I opened this bug report. Feel free to leave a comment: https://github.com/msys2/MSYS2-packages/issues/4142
Apply this patch to a bunch of gcc files: https://gcc.gnu.org/pipermail/gcc-patches/2023-January/609514.html. This link comes from a reply to my bug report above.
Basically, you should always #define WIN32_LEAN_AND_MEAN
before calling #include <windows.h>
. This, apparently, is the proper fix.
Reason: from here: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=902c755930326cb4405672aa3ea13c35c653cbff (emphasis added):
Always define
WIN32_LEAN_AND_MEAN
before<windows.h>
Recently, mingw-w64 has got updated
<msxml.h>
from Wine which is included indirectly by<windows.h>
ifWIN32_LEAN_AND_MEAN
is not defined. TheIXMLDOMDocument
class has a member function namedabort()
, which gets affected by ourabort()
macro in "system.h".
WIN32_LEAN_AND_MEAN
should, nevertheless, always be defined. This can exclude 'APIs such as Cryptography, DDE, RPC, Shell, and Windows Sockets' [1], and speed up compilation of these files a bit.
So, I plan to manually do the fix, produce a git diff
-based patch file, commit the patch file, and then make the patch via git apply
(see my answer here) as part of the build script process.