3

I've been trying to use glpk-hs in my Haskell project but I'm completely lost on how to do it. I'm using stack to run my program and my confusion most likely comes from my lack of knowledge on how it works.

That being said, I've downloaded glpk-hs-0.7 and put the extracted folder in my project's folder. I'm running my code with stack ghci my_program.hs, with the following dependencies on a stack.yaml file:

"extra-deps: - gasp-1.2.0.0 - glpk-hs-0.7"

It successfully installs gasp but fails the glpk installation with this error: glpk-hs > * Missing (or bad) C library: glpk.
I've also tried installing glpk for Windows by downloading the executables and adding it to the PATH, and when I run glpsol on cmd it gives this message:

GLPSOL: GLPK LP/MIP Solver, v4.65 No input problem file specified; try glpsol --help

What am I missing? I've noticed that in the glpk-hs-0.7/glpk folder there is a glpk.c file. Should I compile and execute this program?

Btw, I'm running on Windows 10 now but I mostly work on a Linux machine, so I would appreciate a solution that works for both systems, if there is one.

Thank you!

ohhisara
  • 67
  • 1
  • 5

1 Answers1

2

The glpk-hs package provides a GHC interface to a separately installed GLPK library, but installing glpk-hs doesn't automatically install that required library. Compiling the package's "glpk.c" file wouldn't help, as that's just some stub C code to help in building the interface. (The vast majority of GHC packages that provide a "bridge" to other libraries are designed this way, so glpk-hs isn't a special case.)

Under Linux, you would need to install the development version of the GLPK package in the "usual" way using your distribution's package manager (e.g., for Debian-based distributions, you'd need to run apt install libglpk-dev) before trying to (re-)install the glpk-hs package.

Under Windows, I guess it's probably easiest to download the zipfile with precompiled binaries from the GLPK for Windows Project Page. Unpack it somewhere convenient and, as per the instructions on that web page, copy either the 32-bit or 64-bit DLLs, as appropriate, to the c:\windows\system32 directory.

In order for stack to build against the library, it needs to have some extra library and include file directories specified. In your project-specific stack.yaml (or in a global config.yaml), you'll want to add lines pointing to the appropriate unpacked paths. For example, something like (assuming a 64-bit environment):

# in stack.yaml or config.yaml
extra-lib-dirs:     ["c:\\users\\XXXXX\\glpk-4.65\\w64"]
extra-include-dirs: ["c:\\users\\XXXXX\\glpk-4.65\\src"]

Also, I ran into a further problem as Cabal was looking for glpk.lib and not glpk_4_65.lib, so I had to copy the library over. I'm not sure if there's a better way to do this.

> cd c:\users\XXXXX\glpk-4.65\w64
> cp glpk_4_65.lib glpk.lib

Now, the latest glpk-hs-0.7 package isn't compatible with the current GHC containers version, so you'll need to use an earlier resolver in your stack.yaml file. The lts-12.26 resolver worked for me:

# in stack.yaml
resolver: lts-12.26

Finally, GLPK only works with the threaded runtime, so add the flags to your .cabal file:

-- in your .cabal file
executable glpktest
  ghc-options: -threaded -O2

You can grab an example from https://github.com/jyp/glpk-hs/blob/master/examples/example1.hs. Delete the import Algebraic.Classes line because it isn't needed, and with the following executable clause in your .cabal file:

-- in your .cabal file
executable glpktest
  hs-source-dirs:    src
  main-is:           Example1.hs
  default-language:  Haskell2010
  build-depends:     base >= 4.7 && < 5
                   , glpk-hs
                   , containers
  ghc-options:       -threaded -O2

and the following stack.yaml:

-- full stack.yaml contents

resolver: lts-12.26

packages:
- .

extra-deps:
- glpk-hs-0.7
- gasp-1.2.0.0

extra-lib-dirs:     ["c:\\users\\XXXXX\\glpk-4.65\\w64"]
extra-include-dirs: ["c:\\users\\XXXXX\\glpk-4.65\\src"]

you should be able to stack build and stack exec glpktest that example. If the executable builds correctly but running it produced no output, it may be because the DLLs aren't being found. Make sure the right set of DLLs have been copied into c:\windows\system32.

To sum up all the steps assuming a 64-bit environment:

  1. Download and unpack the pre-compiled binaries from the winglpk project
  2. Copy the DLLs from the w64 directory to c:\windows\system32
  3. In the w64 directory, copy glpk_4_65.lib to glpk.lib.
  4. Use the stack.yaml above with resolver lts-12.26 and appropriate directory settings.
  5. Try to stack build the Example1.hs linked above (deleting the unnecessary import line first) with the executable clause given above copied into your .cabal file (including the -threaded GHC option)
  6. Use stack exec glpktest, and you'll hopefully see a solution printed (x1=40, x2=50, and x3=0).
K. A. Buhr
  • 45,621
  • 3
  • 45
  • 71
  • Thank you a lot! It is now working on Linux and Windows, I just had to follow the steps you mentioned – ohhisara Jan 26 '20 at 02:05