2

I'm trying to build CGAL for windows to use in my project under Visual Studio 2010. CGAL requires GMP and MPFR libraries and provides them in distribution. However, it provides them as a lib+dll bundle, while I want them to be compiled statically in form of a single .lib file.

So now I'm trying to build GMP and MPFR as a static library under windows. I'm using cygwin for this purpose as suggested here. After call to configure and make I have output libs with .a extension with additional .la file. I don't really know much about static libraries for Unix, so I suggested it is the same as .lib with just different extension. I renamed it to .lib and linked to my project - it fitted well.

The first question: was I correct doing so? Are the .a and .lib files really the same? I saw this question, but didn't find it useful enough.

Then problem arose: I had

error LNK2019: unresolved external symbol ___getreent referenced in function ___gmp_default_reallocate

Seems like some cygwin functions are not linked in resulting gmp.lib. I found here, that getreent may be exported from libcygwin.a. So I copied it to libcygwin.lib and linked to my project. Not surprisingly, I received the following error:

error LNK2005: _strcpy already defined in libcygwin.lib(t-d001719.o) in libcmtd.lib(strcat.obj) 

Of course, I cannot know what functions and how are declared in this library and seems like strcpy is conflicting with one from Visual Studio. What I really want to happen is gmp.lib would be smart enough to link this function statically. So,

The second question: how to force GMP to link library dependencies? or How to properly build GMP for windows without using cygwin?

Community
  • 1
  • 1
Mikhail
  • 20,685
  • 7
  • 70
  • 146

1 Answers1

3

UPDATE: See the MPIR project page for the answer to all your problems (it allows you to build MPIR, a GMP compatible library, and MPFR with Visual Studio). The new MPIR homepage is located here, but lacks the MPFR info as far as I can tell.


You don't want Cygwin.

You need a Bash shell and MinGW(.org/-w64). If you build with the cygwin compiler, you need to link to the Cygwin DLL, which in your case is stupid, as GMP and MPFR both are buildable by MinGW.

The only thing is: I don't believe either library is buildable by MSVC, and MSVC can't link with MinGW libraries (this is exactly the reason your project's authors bundled DLL's and import libraries), so you'll need to build everything with MinGW GCC or use the DLL's.


Below are instructions for building a GCC static library of GMP and MPFR.

In order to build GMP for Windows with MinGW-w64 GCC, you'll need MSYS. Unzip this somewhere like C:\Dev\msys so that C:\Dev\msys\bin\sh.exe is present.

Then you'll need a MinGW-w64 GCC:

(I recommend my "Personal Builds", especially the 4.6.3-1 package. Download the 4.6.3-1-gcc_rubenvb.7z package, but any other MinGW bundle should do for this)

Unzip that to say C:\Dev\mingw64 so that C:\Dev\mingw64\bin\gcc.exe exists.

Double click on C:\Dev\msys\msys.bat. Type:

export PATH=/c/Dev/mingw64/bin:$PATH

And press enter. Unzip the GMP and MPFR source to your /home/USERNAME/* directory, make build directories, and remember to use for configure:

--enable-static --disable-shared --prefix=/easytemplibinstalldir

along with

--host=i686-w64-mingw32

for 32-bit or

--host=x86_64-w64-mingw32

for 64-bit. I believe GMP also requires --build set to the same value. After configure finishes, type make, and then make install, optionally preceded by make check.

You should have libgmp.a in /easytemplibinstalldir/lib. For MPFR, add

--with-gmp=/easytemplibinstalldir

to its configure line.

You will have to manually link both libgmp and libmpfr in the correct order for it to work, no automated dependency linking is possible on Windows for this.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • How can that be that MSVC (or whatever) cannot link .lib built with MinGW (or whoever)? I though .lib is compiler-independent. – Mikhail Feb 24 '12 at 18:00
  • @Mikhail oh no, it's not. MinGW GCC produces an `.a` file, no `.lib` involved. MSVC doesn't care about GCC's output format, why should it be able to link? GCC on the other hand can link to 32-bit `.lib` files produced by MSVC, because some GCC/binutils dev cared enough to make it possible at all. – rubenvb Feb 24 '12 at 18:09
  • So, you mean there is now way to build GMP to static .lib under Windows at all? That's pretty confusing. Why am I able to link gmp.a file produced by cygwin with MSVC? – Mikhail Feb 24 '12 at 18:53
  • @Mikhail I don't know of a way to build GMP with MSVC. There's nothing confusing about that: GMP is a GNU project, uses C99, and MSVC doesn't get along with either of them. I guess there is limited compatibility in the file formats (see [here for example](http://stackoverflow.com/questions/2096519/from-mingw-static-library-a-to-visual-studio-static-library-lib)), but linking Cygwin code with MSVC is asking for trouble. See update for easily googleable information. – rubenvb Feb 25 '12 at 09:22
  • @xamid the triplet `x86_64-w64-mingw64` does not exist. The triplet is built up as architecture-vendor-os. In this case the "os" is mingw32, which due to historical reasons means the Win32 API as GCC sees it. This Win32 API is the same for 64-bit and 32-bit Windows. The w64 comes from MinGW-w64, which provides the C runtime on which this compiler is built. The 32-bit compiler, which is the one you downloaded, has triplet i686-w64-mingw32, where the first bit, i686, means 32-bit. – rubenvb Sep 12 '19 at 18:23
  • @rubenvb Then I wonder why using `x86_64-w64-mingw32` ends up with ` Version: GNU MP 6.1.2 Host type: x86_64-w64-mingw32 ABI: 32 Install prefix: /g/gmp-6.1.2/build_64bit Compiler: gcc Static libraries: yes Shared libraries: no`? (Note the ABI: 32.) – xamid Sep 12 '19 at 18:29
  • @rubenvb The command `./configure --enable-static --disable-shared --prefix=/g/gmp-6.1.2/build_64bit --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32` gave that output in the end. Then I tried `./configure --enable-static --disable-shared --prefix=/g/test2/gmp-6.1.2/build_64bit --host=x86_64-w64-mingw64 --build=x86_64-w64-mingw64`, with result `Version: GNU MP 6.1.2 Host type: x86_64-w64-mingw64 ABI: 64 Install prefix: /g/gmp-6.1.2/build_64bit Compiler: gcc Static libraries: yes Shared libraries: no`. (Now the ABI is 64.) – xamid Sep 12 '19 at 18:40
  • Ah but that's GMP's custom configure script doing it wrong. I'm not kidding. The host/target triplet x86_64-w64-mingw64 does not exist for the GNU compiler and toolchain. You can tell GMP to use the correct ABI by doing `ABI=64 ./configure ...`. Also check what `config.log` contains about all this, probably some other vaguely related check is failing leading to it incorrectly deciding you have a 32-bit compiler. – rubenvb Sep 12 '19 at 18:50
  • @rubenvb Yes, it clearly messed up. Previously I reconfigured after I built 32 bit already in the same folder. Now I tried the same command with `x86_64-w64-mingw32` in a newly extracted folder, and it gave ABI: 64 just fine. Note that, however, in the previous folder building over `x86_64-w64-mingw64` also worked fine (only the `make check` messed up). So I have now successfully built both 32 and 64 bit static libraries. – xamid Sep 12 '19 at 19:05
  • UPDATE: When reconfigured for ABI=64 where previously ABI=32 has been built, the resulting libgmp.a is 64bit-incompatible (visible only from linker error when trying to link towards it; "skipping incompatible [...]\libgmp.a when searching for -lgmp"). When using `./configure --enable-static --disable-shared --prefix=/g/gmp-6.1.2/build_64bit --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32` in a newly extracted gmp folder, the built libgmp.a is suitable for 64bit. SUMMARY: Use different gmp folders for different builds! – xamid Sep 12 '19 at 19:52