I am unable to figure this out. I am trying to build the Microchip XC32 PIC32 microcontroller GCC cross-compiler.
To try it yourself (this is how I got to my error I'm stuck on):
On Windows 10 or Windows 11: enable "developer mode" to allow symlinks. Windows key --> search for "Use developer features", click the button (now blue in the image below) to turn it on:
Clone my repo here: https://github.com/ElectricRCAircraftGuy/Microchip_XC32_Compiler
Install MSYS2, and open the MSYS2 UCRT64 shell. Optionally, follow my full MSYS2 setup instructions here.
Install dependencies via pacman, like this: copy and paste this whole blob all at once, into the terminal:
# ============= DO THIS TO INSTALL ALL DEPENDENCIES AT ONCE! ============= # UCRT64 if [ "$MSYSTEM" != "UCRT64" ]; then echo "ERROR: You must run this script in an MSYS2 ucrt64 terminal!" exit 1 fi package_list=( "mingw-w64-ucrt-x86_64-gcc" # specific version for MSYS2 ucrt64 "make" "binutils" "autoconf" "autogen" "bison" "dejagnu" "flex" "gawk" "gperf" "gzip" # "nsis" # generic; must be specific; hence the line below "mingw-w64-ucrt-x86_64-nsis" # specific version for MSYS2 ucrt64 "perl" "scons" "tcl" "texinfo" "wget" "zip" # "texlive" # generic; must be specific; hence the line below "mingw-w64-ucrt-x86_64-texlive-core" # specific version for MSYS2 ucrt64 # "texlive-extra-utils" # generic; must be specific; hence the line below "mingw-w64-ucrt-x86_64-texlive-extra-utils" # specific version for MSYS2 ucrt64 ) # Only install packages if tHey are NOT already installed. for package in "${package_list[@]}"; do if ! pacman -Qs $package > /dev/null; then echo -e "\n=== $package is not installed. Installing... ===" pacman -S --noconfirm $package else echo -e "\n=== $package is already installed. ===" fi done echo -e "\n=== Done installing packages! ===\n"
Run the build script:
build-xc32-v4.35m.sh
:time ./build-xc32-v4.35m.sh
About 20 minutes into it, it fails when compiling gcc, while configuring GMP. Note that to get clean errors you must modify the build script to use
-j1
instead of-j$(nproc)
, here in the first line, or else you'll get multi-threaded output garbled on top of each other in the terminal:time make -j$(nproc) all-gcc \ STAGE1_LIBS="-lexpat -lmchp -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic" \ CPPFLAGS="-I${hostinstalldir}/include -imacros host-defs.h" \ LDFLAGS=-L${hostinstalldir}/lib make install-gcc
Here's my failure. Configuring GMP seems to fail when it's looking for mp_limb_t
. I've marked some notes/lines with <====
below:
checking for sysctl... no
checking for sysctlbyname... no
checking for times... no
checking for library containing clock_gettime... none required
checking for vsnprintf... yes
checking whether vsnprintf works... probably
configure: WARNING: cannot check for properly working vsnprintf when cross compiling, will assume it's ok
checking whether sscanf needs writable input... no
checking for struct pst_processor.psp_iticksperclktick... no
checking size of void *... 8
checking size of unsigned short... 2
checking size of unsigned... 4
checking size of unsigned long... 4
checking size of mp_limb_t... 0 <===== SIZE SHOULD BE 8
configure: error: Oops, mp_limb_t doesn't seem to work <===== ERROR
make: *** [Makefile:4701: configure-gmp] Error 1
real 3m27.324s
user 0m1.373s
sys 0m30.921s
Error: [gcc] failed to build!
real 3m27.510s
user 0m1.373s
Note that the build script runs perfectly to completion on Ubuntu 22.04, once I install the dependencies. It's Windows in MSYS2 that I am unable to get it to work in. Any help is greatly appreciated. This will help the PIC32 community build with GCC without having to buy a license from Microchip. The cross-compiler is GPL-licensed.
I've left a comment here too with a little more detail: https://github.com/JuliaLang/julia/issues/13206#issuecomment-1791823912. I no longer think symlinks are the issue, as I've tried copying the data directly over them with no change.
I have provided the autogenerated Makefile
and gcc/gmp/config.log
files here: https://github.com/ElectricRCAircraftGuy/Microchip_XC32_Compiler/tree/main/temp_debug_files. I've described them in the README.md file in that directory.
Been stuck on this for days. Could use some community support.
If anyone wants to try it in the MSYS2 MINGW64 environment instead, here is how to install those dependencies in that terminal:
# ============= DO THIS TO INSTALL ALL DEPENDENCIES AT ONCE! =============
# mingw64
if [ "$MSYSTEM" != "MINGW64" ]; then
echo "ERROR: You must run this script in an MSYS2 mingw64 terminal!"
exit 1
fi
package_list=(
"mingw-w64-x86_64-gcc" # specific version for MSYS2 mingw64
"make"
"binutils"
"autoconf"
"autogen"
"bison"
"dejagnu"
"flex"
"gawk"
"gperf"
"gzip"
# "nsis" # generic; must be specific; hence the line below
"mingw-w64-x86_64-nsis" # specific version for MSYS2 mingw64
"perl"
"scons"
"tcl"
"texinfo"
"wget"
"zip"
# "texlive" # generic; must be specific; hence the line below
"mingw-w64-x86_64-texlive-core" # specific version for MSYS2 mingw64
# "texlive-extra-utils" # generic; must be specific; hence the line below
"mingw-w64-x86_64-texlive-extra-utils" # specific version for MSYS2 mingw64
)
# Only install packages if tHey are NOT already installed.
for package in "${package_list[@]}"; do
if ! pacman -Qs $package > /dev/null; then
echo -e "\n=== $package is not installed. Installing... ==="
pacman -S --noconfirm $package
else
echo -e "\n=== $package is already installed. ==="
fi
done
echo -e "\n=== Done installing packages! ===\n"
Here's the autogenerated Makefile chunk of interest: C:\Users\gabriel\GS\dev\Microchip_XC32_Compiler\xc32-v4.35-src\pic32m-build\gcc\Makefile
:
.PHONY: configure-gmp maybe-configure-gmp
maybe-configure-gmp:
maybe-configure-gmp: configure-gmp
configure-gmp:
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
test ! -f $(HOST_SUBDIR)/gmp/Makefile || exit 0; \
$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/gmp; \
$(HOST_EXPORTS) \
echo Configuring in $(HOST_SUBDIR)/gmp; \
cd "$(HOST_SUBDIR)/gmp" || exit 1; \
case $(srcdir) in \
/* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
*) topdir=`echo $(HOST_SUBDIR)/gmp/ | \
sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
esac; \
module_srcdir=gmp; \
$(SHELL) \
$$s/$$module_srcdir/configure \
--srcdir=$${topdir}/$$module_srcdir \
$(HOST_CONFIGARGS) --build=${build_alias} --host=none-${host_vendor}-${host_os} \
--target=none-${host_vendor}-${host_os} --disable-shared LEX="touch lex.yy.c" \
|| exit 1
More leads to follow up on:
- https://www.google.com/search?q=bug%3A+msys2+doesnt+accept+absolute+paths+in+gcc&oq=bug%3A+msys2+doesnt+accept+absolute+paths+in+gcc&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIGCAEQRRg60gEJMTQ5NDNqMGo0qAIAsAIA&client=ms-android-google&sourceid=chrome-mobile&ie=UTF-8
- https://mcmap.net/q/13185/-gcc-and-clang-under-msys2-cannot-resolve-includes-with-absolute-paths
- https://github.com/msys2/MINGW-packages/issues/6711#issuecomment-662982274
Note to self: I think a leading /
in an include may be interpreted by MSYS GCC as C:\
, which means that /c/my/path
is seen as C:\c\my\path
instead of as C:\my\path
. This is contrary to how the MSYS terminal handles it, however. What a PITA. Study the sources above.
Convert to relative paths in the build script, using realpath --relative-to
. Update my Stack Overflow answer on this too: https://mcmap.net/q/12865/-how-do-i-get-the-directory-where-a-bash-script-is-located-from-within-the-script-itself
#include "/c/Users/<...>/gcc/gmp/gmp-h.in"
is suspicious, since I think MinGW GCC (other than the Cygwin-ish/usr/bin/gcc
, which you don't and shouldn't use) doesn't understand Linux-style paths. The configure script might need to be patched to not generate absolute paths, or to convert them to Windows style. – Soybeanbash
does the path conversion magic every time you call a non-msys (non-Cygwin-based) app. The compiler isn't going to do that by itself. "please try to clone and build" I don't have a Windows machine, and it would probably take ages in a VM. I also don't know what generates that path... – SoybeanC:\Users\gabriel\GS\dev\Microchip_XC32_Compiler\xc32-v4.35-src\pic32m-source\gcc\gmp\configure
:#include "$srcdir/gmp-h.in"
. This makes the path, I think from the configure script. Theconftest.c
file is generated within thatconfigure
file. And from the autogenerated masterpic32m-build\gcc\Makefile
:--srcdir=$${topdir}/$$module_srcdir
– Postmistresstopdir
a relative path... – Soybean.../configure
with no options and no weird environment variables)? If that works, try to find out what differs in what the script is doing. If it doesn't, you are more likely to find people to help you with that. Also, msys2 has a GMP package, you could just tweak your script to use that one instead of trying to build another version. – Lylycd
'ed into thepic32m-build/gcc/gmp
build dir and then manually run../../../pic32m-source/gcc/gmp/configure
, and it ran just fine! It really bewildered me. Turns out it's a stinking MSYS2 gcc absolute path issue. You cannot call theconfigure
script with an absolute path since it uses the call path to generate a C include in the build process. See my answer. – Postmistress