'检查mp_limb_t的大小......从源代码编译 Microchip XC32 编译器时出现 0“和”配置:错误:哎呀,mp_limb_t似乎不起作用”

`checking size of mp_limb_t... 0` and `configure: error: Oops, mp_limb_t doesn't seem to work` when compiling the Microchip XC32 compiler from source

提问人:Gabriel Staples 提问时间:11/3/2023 最后编辑:Gabriel Staples 更新时间:11/9/2023 访问量:200

问:

我无法弄清楚这一点。我正在尝试构建 Microchip XC32 PIC32 微控制器 GCC 交叉编译器。

自己尝试一下(这就是我遇到错误的方式):

  1. 在 Windows 10 或 Windows 11 上:启用“开发人员模式”以允许符号链接。Windows 键 - >搜索“使用开发人员功能”,请单击按钮(下图中现在是蓝色的)将其打开:enter image description here

  2. 在这里克隆我的存储库:https://github.com/ElectricRCAircraftGuy/Microchip_XC32_Compiler

  3. 安装 MSYS2,然后打开 MSYS2 UCRT64 shell。或者,请按照我的完整 MSYS2 设置说明进行操作

  4. 通过 pacman 安装依赖,如下所示: 将整个 blob 复制并粘贴到终端中:

    # ============= 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"
    
  5. 运行构建脚本:build-xc32-v4.35m.sh

    time ./build-xc32-v4.35m.sh
    
  6. 大约 20 分钟后,在配置 GMP 时编译 gcc 时失败。请注意,要获得干净的错误,您必须修改构建脚本以在第一行中代替 ,否则您将在终端中得到多线程输出乱码:-j1-j$(nproc)

    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社区使用GCC进行构建,而无需从Microchip购买许可证。交叉编译器是 GPL 许可的。

我也在这里留言,更详细一点:https://github.com/JuliaLang/julia/issues/13206#issuecomment-1791823912。我不再认为符号链接是问题所在,因为我尝试将数据直接复制到它们上面而没有更改。

我在这里提供了自动生成的文件:https://github.com/ElectricRCAircraftGuy/Microchip_XC32_Compiler/tree/main/temp_debug_files。我已经在该目录的 README.md 文件中描述了它们。Makefilegcc/gmp/config.log

被困了好几天。可以使用一些社区支持。


如果有人想在 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+doesn't+accept+absolute+paths+in+gcc&oq=bug%3A+msys2+doesn't+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

注意:我认为包含中的前导可能会被 MSYS GCC 解释为 ,这意味着它被视为而不是 .然而,这与 MSYS 终端的处理方式相反。真是PITA。研究上面的来源。/C:\/c/my/pathC:\c\my\pathC:\my\path

在构建脚本中转换为相对路径,使用 .也更新了我的 Stack Overflow 答案:https://stackoverflow.com/a/60157372/4561887realpath --relative-to

C++ GCC、 MINGW-W64 GMP 、MSYS2

评论

1赞 HolyBlackCat 11/3/2023
这是可疑的,因为我认为 MinGW GCC(除了 Cygwin-ish ,您不也不应该使用它)不理解 Linux 风格的路径。可能需要修补配置脚本,以便不生成绝对路径,或将其转换为 Windows 样式。#include "/c/Users/<...>/gcc/gmp/gmp-h.in"/usr/bin/gcc
0赞 HolyBlackCat 11/3/2023
此外,我认为这应该被标记为 C 或 C++ 以提高可见性。
0赞 Gabriel Staples 11/3/2023
@HolyBlackCat,我没有标签了。我应该删除哪个标签来添加 C++?随意编辑。至于路径,我知道我可以在 MSYS2 终端本身中使用 Linux 风格的路径。但这和你的意思不同吗?另外,我不明白该路径是如何创建的,也不明白该文件位于何处。如果您足够感兴趣,请尝试克隆和构建。
0赞 Gabriel Staples 11/3/2023
@HolyBlackCat,不错的标签选择来删除:)。我得上床睡觉了。被困了好几天。我明天再来看看。
1赞 HolyBlackCat 11/3/2023
在终端中,每次调用非 msys(非基于 Cygwin)的应用程序时,路径转换都会变魔术。编译器不会自己这样做。“请尝试克隆和构建”我没有 Windows 计算机,在 VM 中可能需要很长时间。我也不知道是什么产生了这条路径......bash

答:

2赞 Gabriel Staples 11/7/2023 #1

解决。非常感谢@HolyBlackCat的评论和帮助,包括这个,这让我开始寻找解决方案。

修复:在 Windows 的 MSYS2 终端中编译时,C 和 C++ 中不允许使用绝对 #include 路径!

事实证明,这是一个 MSYS2 gcc 绝对路径问题/错误。不能使用绝对路径调用脚本,因为它使用调用路径在生成过程中生成 C include。而且,绝对路径在 C 或 C++ 包含在 Windows 上的 MSYS2 中被破坏。configure

因此,更改 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_RELATIVEconfigure

# 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 脚本会导致该相对路径插入到主 gcc 中,然后传递给 gmp 脚本,在 gmp 脚本中将其作为 include 语句注入到自动生成的 C 文件中。因此,使用绝对路径调用 gcc 脚本会将绝对路径放入内部,而使用相对路径调用 gcc 脚本会将相对路径放入该语句中。但是,在 MSYS2 UCRT64 gcc 编译器中,由于(在 Windows 样式路径中)或(在 Windows 上的 Unix 样式路径中)部分的路径转换问题,只允许使用相对路径,这与绝对路径的开头有关。configureMakefileconfigureconftest.cconfigure#includeconftest.cconfigure#includeC:\/c/

详:

通过执行此操作,文件顶部的变量将从此处的以下绝对路径更改:srcdirMicrochip_XC32_Compiler/xc32-v4.35-src/pic32m-build/gcc/Makefile

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_srcdirconfiguregmp

.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 脚本使用该参数来设置这个 include,如 Microchip_XC32_Compiler/xc32-v4.35-src/pic32m-build/gcc/gmp/config 所示.log这里:configure--srcdir

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 的错误,不允许在 Windows 上的 MSYS2 gcc 中使用绝对 Linux 风格的包含:

奇怪的是,将绝对路径作为命令行参数传递给有效,但将其用作包含则不行。g++

例如

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

有效,即它找到文件,并将路径转换为路径,但给出包含错误:cpp/c/...C:/...

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,该 include 现在在自动生成的 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 中的这个绝对路径问题是一个明确的错误。更新:这不是一个错误。这是我的用户错误和误解。

现在,我将在这个非常困难的构建过程中处理我的下一个错误。:/

引用

从我问题的底部:

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

另请参阅

  1. 一般的、有用的信息。在 MSYS2 中构建时: SourceForge.net:MinGW-w64 - 适用于 32 位和 64 位 Windows Wiki2:系统类型三元组 - 讨论脚本的参数。--build=--host=--target=configure
  2. https://www.msys2.org/docs/filesystem-paths/
  3. 我的回答是:在 Windows 安装的 Git Bash 中更改 ~ 目录的位置 - 特别请参阅标题为“有关 Git Bash 和 MSYS2 中路径的更多详细信息”的部分

评论

1赞 n. m. could be an AI 11/7/2023
UCRT 和 MinGW 编译器无法识别 Unix 样式的路径,但 msys2 编译器可以 (x86_64-pc-msys-gcc.exe)。
0赞 Gabriel Staples 11/7/2023
@n.m.couldbeanAI,我很难知道使用 7 个 MSYS2 环境和编译器中的哪一个。我是 MSYS 的新手。鉴于你对我在做什么的了解,你会选择哪一个,为什么?这是列表:msys2.org/docs/environments。这是我的文章:stackoverflow.com/a/77407282/4561887。另外,我注意到即使在 UCRT64 中,此路径也适用于类 Unix 而不是类 Windows ,只要它是相对路径: ./\ #include "../../../pic32m-source/gcc/gmp/gmp-h.in"
1赞 n. m. could be an AI 11/7/2023
我不确定,我也不是大师。msys 版本更接近 Unix(我认为它源自 cygwin),所以这是一个加分项。使用 msys 版本编译的程序与 msys-2.0.dll 链接,它需要在 PATH 中,所以这是一个减号。只有测试才能说明问题。Windows 对任何一种斜杠都感到满意,但它想要而不是在开始时。问题不在于绝对路径,而在于绝对 Unix 风格的路径,Windows 库不知道如何处理它们。C://c/
1赞 n. m. could be an AI 11/7/2023
另请注意,UCRT gcc 也不理解 Unix 样式的文件名作为命令行参数。shell 执行路径转换。尝试一下,你会看到是如何执行的。或者只是在 shell 中运行并尝试从 .strace gcc /c/temp/foo.cgcc c:/temp/foo.ccmdgcc /c/temp/foo.ccmd