12

I have installed MinGW and MSYS on Microsoft Windows (64bit), inside directory C:\MinGW (MSYS directory is C:\MinGW\msys\1.0). I have downloaded the latest GNU Scientific Library (GNU GSL) package from the official ftp.

I have used MSYS to perform configure and make successfully as described in the INSTALL file in the GSL package. That means, in the MSYS command-line interface, in the MSYS home directory, I have inserted:

$ ./configure
$ make
$ make install

This produces a local directory under the MSYS directory (C:\MinGW\msys\1.0) including the directories bin, include, lib, and share.

I have successfully compiled the example program (which computes the value of the Bessel function $J_0 (x)$ at $x = 5$) according to the instructions in the GSL manual, by

$ gcc -Wall -I/usr/local/include -c example.c

This results in an object file example.o, as expected, without any error messages.

The object file is linked, according to the instructions by

$ gcc -L/usr/local/lib example.o -lgsl -lgslcblas -lm

This produces an executable a.exe which can be executed in the MSYS environment. However, in a Windows command-line interface, cmd.exe, trying to run the executable gives the following error message:

The program can't start because libgsl-0.dll is missing from your computer. Try reinstalling the program to fix this problem.

I wonder what is missing? What should one do to produce the executable file?

AlQuemist
  • 1,110
  • 3
  • 12
  • 22

5 Answers5

10

When you build projects for MinGW, under MSYS, you should always specify a --prefix argument to ./configure; (the /usr/local default specifies an MSYS specific path, which is entirely unsuitable for MinGW application development). In your case, you should have configured GSL thus:

./configure --prefix=C:/MinGW

or, better still, segregate the build files from the sources, (e.g. as a subdirectory of the GSL top source directory):

mkdir build
cd build
../configure --prefix=C:/MinGW

This ensures that all libraries and headers installed by the package are located in appropriate directories, where MinGW can find them, and more importantly, where installed DLLs are found by a %PATH% search, when running outside of MSYS.

By configuring as you did, when you subsequently ran

make
make install

you've installed MinGW libraries and headers for use by MSYS, (which is wrong), and in particular libgsl-0.dll will have been installed into C:/MinGW/msys/1.0/local/bin, whereas it should be in C:/MinGW/bin, (which is where the latter command would have installed it, following configuration with the appropriate --prefix=C:/MinGW specification).

Important Footnote

You should note that the preceding procedure will correctly prepare GSL, (or any other library prepared in similar fashion), for use with MinGW, and will allow you to run applications which you've linked with such libraries on your development host, (or on any other host with a similar MinGW installation). However, if you wish to distribute such applications, (and provided you comply with any licensing conditions), so that they may be run as free-standing applications, (i.e. without a requirement that MinGW be installed on the end user's machine), you must take care that run time dependencies will be properly satisfied in your distribution. To achieve this, you must choose either to:

  1. Link the application statically. This may be appropriate, if your distribution is limited to one, or maybe two executables, but will quickly lead to "executable bloat" as the number of executables with a common core library dependency increases, within a distributable application suite. In the latter case, a better choice would be to
  2. Link the application dynamically, and distribute copies of any necessary DLLs, (other than system DLLs), along with the application suite; in this case, you should make no assumptions regarding directory layout or %PATH% settings which may or may not apply on the end user's machine; you should simply package your distribution such that all delivered executables and their accompanying DLLs will be installed into one and the same directory.
Keith Marshall
  • 1,980
  • 15
  • 19
  • 1
    Thanks for the detailed answer, @Keith Marshall. With your suggested configuration, I can now compile easily in Windows `cmd`, with `g++ -c example.c -o example.o` and then, link with `g++ example.o -lgsl -lgslcblas -lm`. No error messages appears. – AlQuemist May 05 '15 at 18:58
5

For reference, let me note that all previous answers are outdated. For Win64, MinGW and MSYS have been replaced by the independent projects Mingw-w64 and MSys2. And it is no longer necessary to compile GSL on your own: Use the binaries from https://packages.msys2.org/package/mingw-w64-x86_64-gsl.

Joachim W
  • 7,290
  • 5
  • 31
  • 59
1

I found also a partial solution; yet I don't know exactly why it works!

With the same procedure and configuration which I mentioned originally in the question, if one uses Windows cmd (CLI) and one compiles and links the C code (example.c) with

gcc -c example.c -I"C:\MinGW\msys\1.0\local\include" -Wall
gcc -static example.o -L"C:\MinGW\msys\1.0\local\lib" -lgsl -lgslcblas -lm

or a C++ code (equivalent to example.c) with

g++ -c example.cpp -I"C:\MinGW\msys\1.0\local\include" -Wall
g++ -static example.o -L"C:\MinGW\msys\1.0\local\lib" -lgsl -lgslcblas -lm

i.e., using the -static option in linking, then everything works perfect and the final executable runs without any error messages. So, it seems the problem has to do with dynamic linking of libraries.

Please correct me if I am wrong.

AlQuemist
  • 1,110
  • 3
  • 12
  • 22
  • This works, after a fashion, by mitigating *symptoms* of the problem, rather than tackling its *cause*; as such, it is more of a (fundamentally unsatisfactory) work-around, than an actual solution. – Keith Marshall May 06 '15 at 00:57
  • 1
    To clarify: the fundamental problem *cause* is that the libraries and headers have been installed in an inappropriate location. This gives rise to the *symptoms* that these libraries and headers are less readily found at build time, and that shared objects (DLLs) are not found at run time.You mitigated the first symptom by specifying explicit `-I path/to/headers` and `-L path/to/libraries` at build time. You mitigated the second by linking statically, so there is now no DLL dependency at run time, but your executable has become unnecessarily bloated as a result. – Keith Marshall May 06 '15 at 05:15
  • 1
    As a final clarification: the problem is *not* so much with dynamic linking as simply that you can mitigate the symptom of the fundamental problem at build time, but, if you continue to link dynamically, you cannot *mitigate* the placement of the requisite DLL in a directory where no native (MinGW) application should ever look for it; you can *correct* this, by installing into an appropriate prefix, such as `C:/MinGW`, whereas `/usr/local` (the normal GNU package default) is *inappropriate* for MinGW built applications and their supporting libraries. – Keith Marshall May 06 '15 at 05:31
0

The executable doesn't run under windows cmd because the library libgsl-0.dll you compiled is not on the system or user path. Windows does not know where to look for it. The immediate solution is to tell the system where to find it by editing the environment variable PATH to include the location of libgsl-0.dll. This can be done using cmd by entering

PATH=PATH;path-to-libgsl-0.dll

on the command line. (I don't exactly remember where the library winds up so please forgive me for not being specific.) This will only last for the session, though, and to make the change permanent one must edit the PATH variable by going through the Control Panel. One way of accessing the environment variables is by clicking on "Advanced system settings" which can be found to the left in the window resulting by clicking through Control Panel->System and Security ->System or by right-clicking on Computer in the Start Menu and choosing Properties. Clicking on "Advanced system settings" opens a window where the button "Environment Variables" shows up and the environment variables become accessible by clicking on that button. To edit the PATH, though, I would recommend using the freeware utility "PathEditor.exe" which can be found here. This utility makes the process far easier.

Your build setup is far from optimal, though. Using the .configure step without any options means that the generated files will be installed under C:\MinGW\msys\1.0\local and spread over several directories. It will be hard to remove the files in case you want to install a newer version of GSL after having installed also other development libraries. I would recommend adding the option --prefix=C:/MinGW/gsl to the .configure step. (For a complete set of options run .configure --help.) This makes it very easy to get the installation out of the way if need be, simply by deleting or renaming C:\MinGW\gsl. Furthermore, the purpose of MSYS is to facilitate building of software targeted for GNU systems which is not the Windows way. The software once built should not reside under MSYS but rather somewhere under C:\MinGW and made accessible to the build tools in C:\MinGW\bin which are used to build native Windows programs using cmd or other suitable Windows tools. In practice this means that --prefix=C:/MinGW should always be used if MSYS is needed to build software to be used in MinGW as in this case the GSL header files and libraries. Preferably, though, for the reasons given choose --prefix=C:/MinGW/software.

Once the software is installed do not forget to edit PATH so that the system can find any needed libraries.

gostal
  • 71
  • 1
  • 5
0

It's not that simple. gcc runs from a LINUX command prompt in a bash shell. MinGW32-gcc runs from a DOS command prompt in a cmd.exe shell. The dynamic linking required to execute a program that needs a dynamic link library (.dll in DOS or .so .la in Linux) is also OS dependent. Linux dynamic libraries and Windows dynamic libraries are not interchangeable. This much is expected; however, static libraries created by gcc and ld in Linux' bash shell seems to be incompatible with MinGW32-gcc in Windows' cmd.exe shell and this surprises me. I cannot get MinGW32-gcc to link to libgsl.a; I keep getting unresolved references from ld. I also cannot figure out how to get GSL to build in the cmd.exe shell.

Byron
  • 1
  • 1