如何使用Visual Studio为windows编译GMP

How to compile GMP for windows using Visual Studio

本文关键字:windows 编译 GMP Studio 何使用 Visual      更新时间:2023-10-16

我正在尝试在windows上安装gmp。我找到了在windows上从源代码进行编译的好方法。但无法从gmp 6.1.2或visualstudio项目中找到二进制文件以便从源代码进行编译。所以问题是:我在哪里可以下载gmp 6.1.2二进制文件,或者使用Visual Studio从源代码进行编译。

我将描述在Windows中编译GMP的三种方法。

第一个

从此页面安装Visual Studio 2022社区。

按照这里的描述安装VCPKG包管理器,基本上只需执行两个步骤:

git clone https://github.com/Microsoft/vcpkg --depth=1

vcpkg目录内运行

cmd /c bootstrap-vcpkg.bat

设置系统环境变量VCPKG_DEFAULT_TRIPLET=x64-windows-static,为此按下WinKey+Pause,然后单击";高级系统设置";,那么";"环境变量";,内部";系统变量";点击";新的";并且将CCD_ 5的值设置为CCD_。

不用执行上面的步骤(设置变量),您只需将triple直接传递给所有vcpkg命令,如vcpkg install gmp --triplet=x64-windows-static

在vcpkg的git目录中运行以下命令:

vcpkg install gmp --triplet=x64-windows-static

(如果你像我上面说的那样设置环境变量,你可以省略--triplet=x64-windows-static)

这将花费相当多的时间,它将从源代码编译许多包。

完整编译完成后,它将在控制台中显示带有已编译GMP库的ZIP文件的路径。在我的系统上,ZIP文件是在C:UsersuserAppDataLocalvcpkgarchives8d8d1c08fabf677187083dedd12d6accf7114d91580e75611c065f1674b600bee9.zip创建的。

解压缩这个ZIP文件,然后你就可以像下面这样编译你的C++程序:

cl program.cpp /O2 /GL /EHsc /std:c++latest /Ipath_to_unpacked_zip/include/ path_to_unpacked_zip/lib/gmp.lib

正如您可能知道的,CCD_;x64本机命令提示符";命令外壳,可以在";Windows「开始」菜单/View Studio 2022/";。

您也可以安装MPIR而不是GMP,这是GMP的分支,具有相同的接口,但更受Windows用户的青睐。只需执行vcpkg install mpir,但只有先删除GMP包,才能执行此操作,并且只能安装MPIR或GMP中的一个。


第二次

此步骤不编译GMP,而是使用MinGW安装中预先编译的二进制文件。

按照第一步安装Visual Studio。

转到MSYS2的主页。下载安装程序,链接位于";1.下载安装程序:";短语将其安装到任何位置,例如c:binmsys

在Windows「开始」菜单中安装后,转到应用程序";MSYS2 64位";并且在其内部启动程序";MSYS2-MSYS";,它将运行类似Unix的shell,从它开始:

pacman -S msys/binutils msys/gcc msys/mingw-w64-cross-crt-git clang64/mingw-w64-clang-x86_64-gmp

上面的这个命令将安装使用GMP所需的所有软件包。如果您需要更多使用pacman -Ss clang-Ss选项的软件包,这将搜索CLang,因此-Ss会进行搜索并安装-S

如果稍后需要一段时间,pacmans -Syu命令会更新所有已安装的程序包,运行此命令两次,一次更新基本系统文件,第二次更新所有其他程序包(第一次之后需要再次关闭并打开MSYS shell)。

现在您需要一个调整,重命名库libmingwex.a中的两个符号,因为它们与Visual Studio的libucrt.lib库发生冲突。

在下面的两个命令中,我假设您的MSYS安装文件夹是c:devmsys,您可以更改为安装到的文件夹。

c:binmsysusrbinobjcopy.exe --redefine-sym wcsnlen=wcsnlen_renamed --redefine-sym strnlen=strnlen_renamed c:binmsysoptx86_64-w64-mingw32liblibmingwex.a c:binmsysoptx86_64-w64-mingw32liblibmingwex_renamed.a

(这将从libmingwex.a库中创建具有重命名的两个符号的文件libmingwex_renamed.a)

现在一切都准备好了,你可以编译你的C++程序如下:

cl program.cpp /O2 /GL /EHsc /std:c++latest /Ic:binmsysclang64include c:binmsysclang64liblibgmp.a c:binmsysusrlibgccx86_64-pc-msys11.3.0libgcc.a c:binmsysoptx86_64-w64-mingw32liblibmingwex_renamed.a

请看,在上面的命令中,我使用了3个库libgmp.alibgcc.alibmingwex_renamed.a。另外请注意,libgcc.a取自子文件夹11.3.0,它是已安装GCC的当前版本,但随着时间的推移,MSYS2会将GCC更新到更高的版本,因此此版本的子文件夹应相应更改。


第三次

像第一步和第二步一样安装Visual Studio。

在这一步我们将使用MPIR,它是GMP的一个分支,真正好的分支更适合Windows。

克隆存储库:

git clone https://github.com/BrianGladman/mpir --depth=1

文件夹内部.mpirmsvcvs22运行:

cmd /c msbuild.bat gc LIB x64 Release

上面的命令构建了适用于任何CPU的通用版本。之后做

cmd /c msbuild.bat skylake_avx LIB x64 Release

它构建了非常优化的版本,比普通版本更快。

非常重要。如果第二个(skylake)构建失败,那么可以使用Generic(gc)版本,但速度可能会慢5倍。如果快速Skylake版本失败了,那么最好不要使用这种第三种编译GMP的方式,除非你不能执行其他操作,或者如果慢速版本对你来说已经足够了。

上面的这个命令应该像往常一样从";x64本机命令提示符";"开始"菜单中Visual Studio的shell。

在构建完成GMP(实际上是MPIR)后,您可以将程序编译为:

cl program.cpp /O2 /GL /EHsc /std:c++latest /Ipath_to_mpir_repomsvcvs22lib_mpir_skylake_avxx64Release path_to_mpir_repomsvcvs22lib_mpir_skylake_avxx64Releasempir.lib

注意,在上面的命令中,我使用了优化AVX版本的lib_mpir_skylake_avx子文件夹,如果只有Generic版本可用,请使用lib_mpir_gc子文件夹。

使用VisualStudio在Windows上编译GMP可能很棘手,但已经有一些SO问题,可能会对您有所帮助(取决于您的确切用例):

  • 用Visual Studio构建GMP库
  • 如何在visual studio上安装针对C++的MPFR和GMP
  • 视觉工作室的GMP++

简单的答案是,没有可以直接使用VisualStudio编译的GMP源,因为GMP是在考虑UNIX的情况下开发的。

您的选择总结:

  1. 使用MinGW分销中提供的GMP版本
  2. 使用MinGW/Cygwin编写自己的GMP
  3. 使用Visual Studio使用GMP compilable的MPIR fork
  4. 尝试自己解决所有的编译问题,这里有一些关于旧GMP版本的提示:
    • https://cs.nyu.edu/exact/core/gmp/
    • http://www.blizzhackers.cc/viewtopic.php?t=393933

多亏了@Arty,我在Windows 11中遇到了同样的问题,当时我需要gmp和gmpxx,只有第一个选项可以使用。唯一需要添加的是,vcpkg install gmp --triplet=x64-windows-static命令应该在具有管理员权限的终端中运行,否则将出现以下错误:

文件RENAME无法重命名

C:/Users/Desktop/polycut/vcpkg/packages/gmp_x64-windows-static

C:/Users/Desktop/polycut/vcpkg/packages/gmp_x64-windows-static_tmp

因为:访问被拒绝。