Search code examples
c++cygwinmingwstatic-linkinggsl

MinGW on Cygwin. Some issues on linking the GNU Scientific Library


I have a couple of issues when linking the GNU Scientific Library with MinGW on Cygwin. Let me explain the situation.

I have installed both MinGW and GSL from the Cygwin setup utility. The path /usr/i686-w64-mingw32/sys-root/mingw/bin/ contains:

gsl-config           libgfortran-3.dll                 libssp-0.dll
libatomic-1.dll      libgomp-1.dll                     libstdc++-6.dll
libblas.dll          libgomp-plugin-host_nonshm-1.dll  libvtv_stubs-0.dll
libcblas.dll         libgsl-19.dll                     libvtv-0.dll
libgcc_s_sjlj-1.dll  libquadmath-0.dll                 libwinpthread-1.dll

The path /usr/i686-w64-mingw32/sys-root/mingw/include/contains all the GSL headers.

The path /usr/i686-w64-mingw32/sys-root/mingw/lib/contains, among many other libraries, the files libgsl.dll.a and libgslcblas.dll.a

If I compile using

i686-w64-mingw32-g++.exe -std=c++11 -s someGSLapp.cpp -lgsl -static-libgcc -Wl,-Bstatic -lstdc++ -lpthread -lm

it compiles without any problem, and the executable can be run provided /usr/i686-w64-mingw32/sys-root/mingw/bin/ is properly added to PATH environment variable.

Let me point out the first strange issue. If I do not set the PATH variable, in order to run my program, I have to copy all files in /usr/i686-w64-mingw32/sys-root/mingw/bin/ into the path where my executable is located. Be careful, ALL files, not only the GSL DLLs. This is strange, because other libraries are linked statically. Indeed, I have other programs that do not use GSL, and when I compile them statically linking the standard library in the same way as I do for my someGSLapp above, they can be run without setting PATH, nor copying any DLLs.

The second issue happens when I try to statically link the GSL. If I try:

i686-w64-mingw32-g++.exe -std=c++11 -s someGSLapp.cpp -static-libgcc -Wl,-Bstatic -lstdc++ -lpthread -lm -lgsl

the GNU linker returns the error cannot find -lgsl. I tried to add

-I/usr/i686-w64-mingw32/sys-root/mingw/include/
-L/usr/i686-w64-mingw32/sys-root/mingw/lib/

but it does not change anything, I still get the same error.

So, concerning the first issue, could anyone explain why I need to copy ALL the DLLs? My tentative explanation is that the GSL DLL needs the others, but I cannot understand why even the fortran DLL is needed.

Concerning the second issue, could anyone tell me how to link the GSL statically?

UPDATE on the second issue

If I link statically using

i686-w64-mingw32-g++.exe -std=c++11 -s someGSLapp.cpp -static-libgcc -Wl,-Bstatic -lstdc++ -lpthread -lm -lgsl.dll

I do not get the error cannot find -lgsl anymore, compilation and linking terminate without any error or warning, but the executable still do not run if I do not set PATH or copy all the DLLs as seen above. It seems that static linking is not working for the GSL.


Solution

  • I solved the problem. It seems that precompiled GSL packages currently available through the Cygwin setup utility does not allow to statically link the library. Indeed, as noticed by @ssbssa in a comment, they do not install libgsl.a

    This is what I did. First I completely removed all GSL packages previously installed. From the main GSL repository ftp://ftp.gnu.org/gnu/gsl/ I downloaded the latest version of the library into a local path.

    GNU make has to be already installed. I used

    ./configure CC=x86_64-w64-mingw32-gcc --prefix=/usr/gsl/mingw64/
    

    CC sets the compiler to be used. --prefix sets the path the library will be installed into. Then I called make and, as soon it finished compiling, make install.

    Since I need to compile programs also for 32 bit systems, I called make clean to start a new installation, then I set

    ./configure CC=i686-w64-mingw32-gcc --prefix=/usr/gsl/mingw32/
    

    and then again make and make install. Now I can cross-compile programs using GSL for both 32 and 64 bits, and I can statically link the library simply adding the -static flag