Permalink
Browse files

Simplify Gurobi install.

Attempts to find path to Gurobi's install location automatically and sets the linking and compile flags accordingly.
  • Loading branch information...
1 parent 6ceda25 commit 086ac0321e566c157191efbdb43e174ac7f4b14b @9thbit 9thbit committed Feb 16, 2014
Showing with 67 additions and 35 deletions.
  1. +9 −11 README.md
  2. +2 −2 available_interfaces/cplex/Makefile
  3. +10 −15 available_interfaces/gurobi/Makefile
  4. +46 −7 tools/solverconfig.py
View
@@ -47,19 +47,17 @@ Numberjack provides an interface to the mathematical programming solver,
[Gurobi][gurobiopt]. To use it in Numberjack, please follow the following steps:
1. [Download and install Gurobi Optimizer][gurobiopt] from their website.
+ Numberjack has been tested against Gurobi versions 5.1, 5.5, and 5.6.
-2. The environment variable `GUROBI_HOME` should point to the Gurobi's install
- directory. This should have been [set during installation][gurobiqs], along
- with appending `$GUROBI_HOME/lib` to the environment variable
- `LD_LIBRARY_PATH`. For example, something like this should have been added to
- your `~/.bash_profile`:
+2. Numberjack will try to find the Gurobi, install location by first checking
+ the `GUROBI_HOME` environment variable which should be set according to the
+ Gurobi install guide. If not, it will try to find the path based on the
+ location of the `gurobi_cl` executable.
- ```bash
- export GUROBI_HOME="/opt/gurobi550/linux64" # Example Linux install dir
- export GUROBI_HOME="/Library/gurobi550/mac64" # Example Mac OSX install dir
- export PATH="${PATH}:${GUROBI_HOME}/bin"
- export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${GUROBI_HOME}/lib"
- ```
+ ```bash
+ export GUROBI_HOME="/opt/gurobi550/linux64" # Example Linux install dir
+ export GUROBI_HOME="/Library/gurobi550/mac64" # Example Mac OSX install dir
+ ```
3. In the Numberjack directory, move the folder `available_interfaces/gurobi` to
`solvers/gurobi`.
@@ -14,8 +14,8 @@ PYLIB = `python-config --cflags`
PYOBJ = `python-config --prefix`
-CPLEXCCFLAGS = `python $(MAINDIR)/tools/solverconfig.py CPLEX cflags` -Wno-unused-private-field
-CPLEXLDFLAGS = `python $(MAINDIR)/tools/solverconfig.py CPLEX lflags`
+CPLEXCCFLAGS = `python $(MAINDIR)/tools/solverconfig.py CPLEX --cflags` -Wno-unused-private-field
+CPLEXLDFLAGS = `python $(MAINDIR)/tools/solverconfig.py CPLEX --lflags`
OPTFLAGS = -O3
@@ -5,8 +5,10 @@ MAINDIR = $(CURDIR)/../..
# paths
#-----------------------------------------------------------------------------
-# GUROBI_HOME environment variable should be set according to install instructions:
-# http://www.gurobi.com/documentation/current/quick-start-guide/
+# Numberjack will try to find the Gurobi, install location. It will first check
+# for the GUROBI_HOME environment variable which should be set accodring to the
+# Gurobi install guide. If not, it will try to find the path based on the
+# location of the gurobi_cl executable.
OBJDIR = ./obj
SRCDIR = ./src
@@ -15,6 +17,9 @@ SWIG = swig
PYLIB = `python-config --cflags`
PYOBJ = `python-config --prefix`
+GRBCCFLAGS = `python $(MAINDIR)/tools/solverconfig.py Gurobi --cflags`
+GRBLDFLAGS = `python $(MAINDIR)/tools/solverconfig.py Gurobi --lflags`
+
#-----------------------------------------------------------------------------
# Main Program
@@ -25,9 +30,6 @@ MAINOBJ = $(MAINNAME).o
MAINSRC = $(addprefix $(SRCDIR)/,$(MAINOBJ:.o=.cpp))
MAINOBJFILES = $(addprefix $(OBJDIR)/,$(MAINOBJ))
-GRBLIBFILES = $(shell find $(GUROBI_HOME)/lib -name "libgurobi??.so")
-GUROBILIB=$(strip $(patsubst $(GUROBI_HOME)/lib/lib%.so, %, $(GRBLIBFILES)))
-
#-----------------------------------------------------------------------------
# Interface
@@ -40,8 +42,8 @@ WOBFILE = $(PYTHON)/$(MAINNAME)_wrap.o
SOFILE = $(PYTHON)/_$(MAINNAME).so
MIPDIR = $(MAINDIR)/solvers/mip
-CFLAGS += -I$(MIPDIR)/src/ -I$(GUROBI_HOME)/include
-LFLAGS = -L$(GUROBI_HOME)/lib -lgurobi_c++ -l$(GUROBILIB)
+CFLAGS += -I$(MIPDIR)/src/ $(GRBCCFLAGS)
+LFLAGS += $(GRBLDFLAGS)
#-----------------------------------------------------------------------------
@@ -51,18 +53,11 @@ LFLAGS = -L$(GUROBI_HOME)/lib -lgurobi_c++ -l$(GUROBILIB)
CXX ?= g++
-wrapper: check-env $(OBJDIR) $(PYTHON) $(IFILE) $(WXXFILE) $(SOFILE) $(OBJDIR)/Gurobi.o $(PYTHON)/Gurobi_wrap.o
+wrapper: $(OBJDIR) $(PYTHON) $(IFILE) $(WXXFILE) $(SOFILE) $(OBJDIR)/Gurobi.o $(PYTHON)/Gurobi_wrap.o
debug: CFLAGS += -D_DEBUGWRAP -g
debug: wrapper
-check-env:
- @if [ "${GUROBI_HOME}" == "" ]; then \
- echo "The environment variable GUROBI_HOME is not set. Please set it according to:"; \
- echo "http://www.gurobi.com/documentation/current/quick-start-guide/"; \
- exit 1; \
- fi
-
install_python: wrapper
cd $(PYTHON); python $(MAINDIR)/tools/setup.py install
View
@@ -7,10 +7,14 @@
"""This script will attempt to find the home directory for a named solver."""
+CPLEX = "CPLEX"
+GUROBI = "Gurobi"
+
+
def get_solver_home(solvername):
from distutils.spawn import find_executable
- if solvername == "CPLEX":
+ if solvername == CPLEX:
# Try for environmental variable first
env_path = os.getenv('CPLEXDIR')
if env_path and len(env_path.strip()) > 0:
@@ -22,6 +26,19 @@ def get_solver_home(solvername):
ex_path = os.path.realpath(ex_path) # Expand symbolic links if any
ex_dir = os.path.dirname(ex_path) # Path to the bin directory
return os.path.abspath(os.path.join(ex_dir, os.pardir, os.pardir))
+
+ elif solvername == GUROBI:
+ # Try for environmental variable first
+ env_path = os.getenv('GUROBI_HOME')
+ if env_path and len(env_path.strip()) > 0:
+ return env_path
+
+ # Try to find the gurobi_cl binary in the PATH
+ ex_path = find_executable('gurobi_cl')
+ if ex_path:
+ ex_path = os.path.realpath(ex_path) # Expand symbolic links if any
+ ex_dir = os.path.dirname(ex_path) # Path to the bin directory
+ return os.path.abspath(os.path.join(ex_dir, os.pardir))
else:
print >> sys.stderr, "Error unknown solver name", solvername
@@ -30,7 +47,7 @@ def get_solver_home(solvername):
def get_cflags(solvername):
solverhome = get_solver_home(solvername)
- if solvername == "CPLEX":
+ if solvername == CPLEX:
concertdir = get_concert_dir(solverhome)
cplexincdir = os.path.join(solverhome, "include")
concertincdir = os.path.join(concertdir, "include")
@@ -43,14 +60,18 @@ def get_cflags(solvername):
else:
print >> sys.stderr, "Error unknown platform", sys.platform
sys.exit(1)
+
+ elif solvername == GUROBI:
+ incdir = os.path.join(solverhome, "include")
+ return "-I%s" % incdir
else:
print >> sys.stderr, "Error unknown solvername", solvername
sys.exit(1)
def get_lflags(solvername):
solverhome = get_solver_home(solvername)
- if solvername == "CPLEX":
+ if solvername == CPLEX:
concertdir = get_concert_dir(solverhome)
cplexlibdir = get_cplex_lib_dir(solverhome)
concertlibdir = get_cplex_lib_dir(concertdir)
@@ -63,11 +84,29 @@ def get_lflags(solvername):
else:
print >> sys.stderr, "Error unknown platform", sys.platform
sys.exit(1)
+
+ elif solvername == GUROBI:
+ libdir = os.path.join(solverhome, "lib")
+ libname = get_gurobi_libname(libdir)
+ return "-L%s -lgurobi_c++ -l%s" % (libdir, libname)
+
else:
print >> sys.stderr, "Error unknown solvername", solvername
sys.exit(1)
+def get_gurobi_libname(libdir):
+ import re
+ libre = re.compile("lib(?P<libname>gurobi\d+)\.so")
+ for dirpath, dirnames, filenames in os.walk(libdir):
+ for f in filenames:
+ match = libre.match(f)
+ if match:
+ return match.groupdict()["libname"]
+ print >> sys.stderr, "Error could not find the Gurobi library in '%s'" % libdir
+ sys.exit(1)
+
+
def get_concert_dir(cplexdir):
return os.path.abspath(os.path.join(cplexdir, os.pardir, "concert"))
@@ -88,7 +127,7 @@ def get_cplex_lib_dir(cplexdir):
def exit_usage():
- print >> sys.stderr, "Usage: %s CPLEX (home|cflags|lflags)" % sys.argv[0]
+ print >> sys.stderr, "Usage: %s CPLEX [--prefix|--cflags|--lflags]" % sys.argv[0]
sys.exit(1)
@@ -99,11 +138,11 @@ def exit_usage():
solvername = sys.argv[1]
query = sys.argv[2]
- if query == "home":
+ if query == "--prefix":
print get_solver_home(solvername)
- elif query == "cflags":
+ elif query == "--cflags":
print get_cflags(solvername)
- elif query == "lflags":
+ elif query == "--lflags":
print get_lflags(solvername)
else:
print >> sys.stderr, "Error unknown query argument:", query

0 comments on commit 086ac03

Please sign in to comment.