编译Microchip XC32编译器源代码时,当检查mp_limb_t的大小时,返回0,并且出现"configure: error: Oops, mp_limb_t doesn't seem to work"的错误提示。

3
我无法弄清楚这个问题。我正在尝试构建Microchip XC32 PIC32微控制器GCC交叉编译器。
要自己尝试(这是我遇到的错误):
在Windows 10或Windows 11上:启用“开发人员模式”以允许符号链接。按下Windows键-->搜索“使用开发人员功能”,点击按钮(如下图中的蓝色按钮)将其打开:enter image description here 克隆我的存储库:https://github.com/ElectricRCAircraftGuy/Microchip_XC32_Compiler 安装MSYS2,并打开MSYS2 UCRT64 shell。可选择按照我的完整MSYS2设置说明进行操作。
通过pacman安装依赖项,如下所示: 将整个代码块一次性复制粘贴到终端中:
# ============= 一次性安装所有依赖项! ============= # UCRT64 if [ "$MSYSTEM" != "UCRT64" ]; then echo "错误:您必须在MSYS2 ucrt64终端中运行此脚本!" exit 1 fi package_list=( "mingw-w64-ucrt-x86_64-gcc" # MSYS2 ucrt64的特定版本 "make" "binutils" "autoconf" "autogen" "bison" "dejagnu" "flex" "gawk" "gperf" "gzip" # "nsis" # 通用版本;必须是特定版本;因此以下行 "mingw-w64-ucrt-x86_64-nsis" # MSYS2 ucrt64的特定版本 "perl" "scons" "tcl" "texinfo" "wget" "zip" # "texlive" # 通用版本;必须是特定版本;因此以下行 "mingw-w64-ucrt-x86_64-texlive-core" # MSYS2 ucrt64的特定版本 # "texlive-extra-utils" # 通用版本;必须是特定版本;因此以下行 "mingw-w64-ucrt-x86_64-texlive-extra-utils" # MSYS2 ucrt64的特定版本 )
# 仅在尚未安装时安装软件包。 for package in "${package_list[@]}"; do if ! pacman -Qs $package > /dev/null; then echo -e "\n=== 未安装$package。正在安装... ===" pacman -S --noconfirm $package else echo -e "\n=== 已安装$package。 ===" fi done echo -e "\n=== 完成安装软件包! ===\n"
运行构建脚本:build-xc32-v4.35m.sh
time ./build-xc32-v4.35m.sh
大约进行到20分钟时,在编译gcc时失败,同时配置GMP。请注意,为了获得清晰的错误信息,您必须修改构建脚本,将第一行中的-j$(nproc)改为-j1,否则终端中会出现多线程输出混乱的情况:
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
这是我的失败。当GMP在寻找mp_limb_t时,配置似乎失败了。我在下面用<====标记了一些注释/行:
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

请注意,构建脚本在安装依赖项后在Ubuntu 22.04上完美运行,但在MSYS2中的Windows上无法正常工作。非常感谢任何帮助。这将帮助PIC32社区在不购买Microchip许可证的情况下使用GCC进行构建。交叉编译器采用GPL许可证。
我在这里留下了一条评论,提供了更多详细信息:https://github.com/JuliaLang/julia/issues/13206#issuecomment-1791823912。我不再认为符号链接是问题所在,因为我已经尝试直接复制数据到它们上面,但没有任何变化。
我在这里提供了自动生成的Makefilegcc/gmp/config.log文件:https://github.com/ElectricRCAircraftGuy/Microchip_XC32_Compiler/tree/main/temp_debug_files。我在该目录的README.md文件中对它们进行了描述。
我已经被困在这个问题上好几天了。希望能得到社区的支持。
如果有人想在MSYS2 MINGW64环境中尝试,以下是如何在该终端中安装这些依赖项的方法:
# ============= 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"

这是自动生成的Makefile代码块感兴趣的部分: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

更多待跟进的潜在客户:

  1. 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
  2. https://stackoverflow.com/a/39256699/4561887
  3. https://github.com/msys2/MINGW-packages/issues/6711#issuecomment-662982274
自己注意:我觉得在include中的一个前导/可能会被MSYS GCC解释为C:\,这意味着/c/my/path会被视为C:\c\my\path而不是C:\my\path。然而,这与MSYS终端的处理方式相反。真是个让人头疼的问题。研究一下上面的资源。
在构建脚本中转换为相对路径,使用realpath --relative-to。同时更新我在Stack Overflow上的答案:https://dev59.com/yXVD5IYBdhLWcg3wL4cA#60157372

1
那个 #include "/c/Users/<...>/gcc/gmp/gmp-h.in" 看起来有点可疑,因为我认为 MinGW GCC(除了 Cygwin-ish 的 /usr/bin/gcc,你不应该使用)不理解 Linux 风格的路径。配置脚本可能需要修补,以避免生成绝对路径,或者将其转换为 Windows 风格的路径。 - undefined
1
在终端中,每次调用非msys(非Cygwin基于)应用程序时,bash都会进行路径转换的魔法。编译器本身不会自动完成这个任务。 "请尝试克隆和构建" 我没有Windows机器,而且在虚拟机中可能需要很长时间。我也不知道是什么生成了那个路径... - undefined
C:\Users\gabriel\GS\dev\Microchip_XC32_Compiler\xc32-v4.35-src\pic32m-source\gcc\gmp\configure#include "$srcdir/gmp-h.in"。我认为这是从配置脚本中生成的路径。conftest.c文件是在configure文件中生成的。并且从自动生成的主pic32m-build\gcc\Makefile--srcdir=$${topdir}/$$module_srcdir - undefined
现在我想知道你是否可以将topdir设置为相对路径... - undefined
你试过只是构建最新的GMP(纯粹的.../configure,没有选项和奇怪的环境变量)吗?如果这样可以工作,试着找出脚本在做什么方面有所不同。如果不行,你更有可能找到人来帮助你。另外,msys2有一个GMP包,你可以调整你的脚本来使用那个版本,而不是尝试构建另一个版本。 - undefined
显示剩余5条评论
1个回答

2
解决了。非常感谢@HolyBlackCat的评论和帮助,包括这个评论,让我开始找到解决办法。
修复方法:在Windows的MSYS2终端中编译时,C和C++中不允许使用绝对路径的#include!
原来这是一个MSYS2 gcc绝对路径问题/bug。由于调用路径用于生成构建过程中的C include,所以不能使用绝对路径来调用configure脚本。而且,在Windows上的MSYS2中,C或C++中的绝对路径是无效的。
所以,在build-xc32-v4.35m.sh中更改这部分内容:
# Finally, GCC.
PS4="[gcc] "
(
    set -ex

    rm -rf ${gcc_builddir}
    mkdir -p ${gcc_builddir}
    cd ${gcc_builddir}

    ${gcc_srcdir}/configure \
    # ...

到这里。唯一的变化是创建和使用gcc_srcdir_RELATIVE以相对路径而不是绝对路径调用configure脚本!
# Finally, GCC.
PS4="[gcc] "
(
    set -ex

    rm -rf ${gcc_builddir}
    mkdir -p ${gcc_builddir}
    cd ${gcc_builddir}

    # Obtain relative paths, since Windows doesn't like absolute paths due to Windows/Linux path
    # differences in gcc includes.
    gcc_srcdir_RELATIVE=$(realpath --relative-to="." "${gcc_srcdir}")

    ${gcc_srcdir_RELATIVE}/configure \
    # ...

不起作用的是什么

如果您获取到这些相对路径:

    INSTALLDIR_RELATIVE=$(realpath --relative-to="." "${INSTALLDIR}")
    hostinstalldir_RELATIVE=$(realpath --relative-to="." "${hostinstalldir}")

...然后在构建脚本中像这样使用它们:
    INSTALLDIR_RELATIVE=$(realpath --relative-to="." "${INSTALLDIR}")
    hostinstalldir_RELATIVE=$(realpath --relative-to="." "${hostinstalldir}")

    ${gcc_srcdir}/configure \
                 --target=pic32mx \
                 --prefix=${INSTALLDIR_RELATIVE} \
                 --program-prefix=pic32m- \
                 --with-sysroot=${INSTALLDIR_RELATIVE}/pic32mx \
                 --with-bugurl=http://example.com \
                 --with-pkgversion="Microchip XC32 Compiler v4.35 custom" \
                 --bindir=${INSTALLDIR_RELATIVE}/bin/bin \
                 --infodir=${INSTALLDIR_RELATIVE}/share/doc/xc32-pic32m-gcc/info \
                 --mandir=${INSTALLDIR_RELATIVE}/share/doc/xc32-pic32m-gcc/man \
                 --libdir=${INSTALLDIR_RELATIVE}/lib \
                 --libexecdir=${INSTALLDIR_RELATIVE}/bin/bin \
                 --with-build-sysroot=${INSTALLDIR_RELATIVE}/pic32mx \
                 --enable-stage1-languages=c \
                 --enable-languages=c,c++ \
                 --enable-target-optspace \
                 --disable-comdat \
                 --disable-libstdcxx-pch \
                 --disable-libstdcxx-verbose \
                 --disable-libssp \
                 --disable-libmudflap \
                 --disable-libffi \
                 --disable-libfortran \
                 --disable-bootstrap \
                 --disable-shared \
                 --disable-nls \
                 --disable-gdb \
                 --disable-libgomp \
                 --disable-threads \
                 --disable-tls \
                 --disable-sim \
                 --disable-decimal-float \
                 --disable-libquadmath \
                 --disable-shared \
                 --disable-checking \
                 --disable-maintainer-mode \
                 --enable-lto \
                 --enable-fixed-point \
                 --enable-gofast \
                 --enable-static \
                 --enable-sgxx-sde-multilibs \
                 --enable-sjlj-exceptions \
                 --enable-poison-system-directories \
                 --enable-obsolete \
                 --without-isl \
                 --without-cloog \
                 --without-headers \
                 --with-musl \
                 --with-dwarf2 \
                 --with-gnu-as \
                 --with-gnu-ld \
                 '--with-host-libstdcxx=-static-libgcc -static-libstdc++ -Wl,-lstdc++ -lm' \
                 CPPFLAGS="-I${hostinstalldir_RELATIVE}/include -imacros host-defs.h" \
                 LDFLAGS=-L${hostinstalldir_RELATIVE}/lib

    time make -j$(nproc) all-gcc \
         STAGE1_LIBS="-lexpat -lmchp -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic" \
         CPPFLAGS="-I${hostinstalldir_RELATIVE}/include -imacros host-defs.h" \
         LDFLAGS=-L${hostinstalldir_RELATIVE}/lib

...这只是破坏了构建过程。它不起作用。构建系统抱怨所有(或几乎所有)这些路径都需要是绝对路径。因此,唯一需要修复的是对configure脚本的相对调用,像这样:${gcc_srcdir_RELATIVE}/configure

关于${gcc_srcdir_RELATIVE}/configure相对路径修复的解释

快速总结:

使用相对路径调用gcc的configure脚本会导致该相对路径被插入到主要的gcc Makefile中,然后传递给gmp的configure脚本,在那里它被注入到一个自动生成的conftest.c C文件中作为一个包含语句。因此,使用绝对路径调用gcc的configure脚本会在conftest.c中的#include语句中放置一个绝对路径,而使用相对路径调用gcc的configure脚本会将一个相对路径放入该#include语句中。然而,在MSYS2 UCRT64 gcc编译器中,只允许使用相对路径,这是由于路径转换问题,其中包括绝对路径的开头部分是C:\(在Windows风格的路径中)或/c/(在Windows上的Unix风格路径中)。
通过这样做,Microchip_XC32_Compiler/xc32-v4.35-src/pic32m-build/gcc/Makefile文件顶部的srcdir变量会发生变化,从这个绝对路径改变为:
srcdir = /c/Users/gbriel/GS/dev/Microchip_XC32_Compiler/xc32-v4.35-src/pic32m-source/gcc

到这个相对路径:
srcdir = ../../pic32m-source/gcc

以下是相同的Makefile。请注意,topdir=$(srcdir),并且--srcdir=$${topdir}/$$module_srcdir被传递给对gmp库的configure调用。
.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

嗯,gmp的configure脚本使用了--srcdir参数来设置这个include,如下所示在Microchip_XC32_Compiler/xc32-v4.35-src/pic32m-build/gcc/gmp/config.log中
configure:27432: gcc -c -g -O2 -D__USE_MINGW_ACCESS -DNO_ASM -I/c/Users/gabriel/GS/dev/Microchip_XC32_Compiler/xc32-v4.35-src/pic32m-build/opt/include -imacros host-defs.h conftest.c >&5
conftest.c:80:10: fatal error: /c/Users/gabriel/GS/dev/Microchip_XC32_Compiler/xc32-v4.35-src/pic32m-source/gcc/gmp/gmp-h.in: No such file or directory
   80 | #include "/c/Users/gabriel/GS/dev/Microchip_XC32_Compiler/xc32-v4.35-src/pic32m-source/gcc/gmp/gmp-h.in"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

由于这个不是bug的bug,在Windows上的MSYS2 gcc中,绝对的Linux风格的包含是不允许的

Strange thing is that passing absolute path as command line argument to g++ works, but using it as include does not.

e.g.

g++ -c /c/Users/travis/build/config.cpp

works, i.e. it finds the cpp file, and translates the /c/... path to C:/... path but giving that include error:

C:/Users/travis/build/config.cpp:1:10: fatal error: /c/Users/travis/build/config.hpp: No such file or directory

    1 | #include "/c/Users/travis/build/config.hpp"

      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
所以,通过调用`${gcc_srcdir_RELATIVE}/configure`,在自动生成的`conftest.c`文件中,这个包含现在看起来就像这样,而且它完全正常工作!
#include "../../../pic32m-source/gcc/gmp/gmp-h.in"

注意,在解决这个问题的过程中,我尝试了像这样的Windows风格的包含路径进行测试:
#include "C:\Users\gabriel\GS\dev\Microchip_XC32_Compiler\xc32-v4.35-src\pic32m-source\gcc\gmp\gmp-h.in"

...而且我相当确定那些在MSYS2 UCRT64中运行的gcc也失败了。

我认为这是MSYS2中gcc的绝对路径问题,绝对是一个bug。更新:这不是一个bug。这是我的用户错误和误解。

现在我要解决下一个bug,这个构建过程非常困难。 :/

参考资料

从我的问题底部:

  1. 谷歌搜索“bug:msys2不接受gcc中的绝对路径”
  2. msys2下的gcc和clang无法解析绝对路径的包含文件
  3. gcc/g++无法包含带有绝对路径的文件

另请参阅

一般而言,在构建MSYS2时有一些有用的信息:SourceForge.net: MinGW-w64 - for 32 and 64 bit Windows Wiki2: System Type Triplets - 这篇文章讨论了--build=--host=--target=参数在configure脚本中的用法。 https://www.msys2.org/docs/filesystem-paths/ 我的回答是:在Windows安装的Git Bash中更改~目录的位置 - 特别要注意标题为"More details on paths in Git Bash and MSYS2"的部分。

我正在努力解决的下一个构建错误是:在编译gcc时,在fancy_abort (__FILE__, __LINE__, __FUNCTION__)中的__FILE__之前,C++: error: expected ',' or '...' before string constant - undefined
1
UCRT和MinGW编译器无法识别Unix风格的路径,但msys2编译器可以(x86_64-pc-msys-gcc.exe)。 - undefined
@n.m.couldbeanAI,对我来说很难确定要使用哪个7个MSYS2环境和编译器。我对MSYS非常陌生。根据你对我的了解,你会选择哪个环境,为什么呢?这是环境列表:https://www.msys2.org/docs/environments/。这是我的说明文档:https://stackoverflow.com/a/77407282/4561887。另外,我注意到即使在UCRT64中,只要是相对路径,这个路径也可以使用类Unix的`/`而不是类Windows的`\`:`#include "../../../pic32m-source/gcc/gmp/gmp-h.in"`。 - undefined
1
我不确定,我也不是专家。Msys版本更接近Unix(我认为它是从cygwin派生的),所以这是一个优点。使用Msys版本编译的程序链接到msys-2.0.dll,并且它需要在PATH中,所以这是一个缺点。只有测试才能告诉我们。Windows对斜杠的两种类型都可以接受,但它希望路径以C:/开头而不是/c/。问题不在于绝对路径,而是绝对的Unix风格路径,Windows库不知道如何处理它们。 - undefined
1
还要注意的是,UCRT gcc也不会将Unix风格的文件名作为命令行参数进行理解。Shell会进行路径转换。尝试使用strace gcc /c/temp/foo.c命令,你会看到gcc c:/temp/foo.c是如何被执行的。或者在Shell中运行cmd,然后尝试使用gcc /c/temp/foo.c命令来执行。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接