From 937b96c01c391692a7ec0bd4628d25d8efaf1ce5 Mon Sep 17 00:00:00 2001 From: Laurent Perron Date: Wed, 22 Jul 2020 17:08:17 +0200 Subject: [PATCH] add make based support for xpress on MAC OS X --- examples/cpp/integer_programming.cc | 1 + makefiles/Makefile.third_party.unix.mk | 12 +++++++ makefiles/Makefile.unix.mk | 25 +++++++------- ortools/linear_solver/xpress_interface.cc | 42 ++++++++++++++--------- 4 files changed, 51 insertions(+), 29 deletions(-) diff --git a/examples/cpp/integer_programming.cc b/examples/cpp/integer_programming.cc index b1747c23b6..cc433326ea 100644 --- a/examples/cpp/integer_programming.cc +++ b/examples/cpp/integer_programming.cc @@ -80,6 +80,7 @@ void RunAllExamples() { RunIntegerProgrammingExample("GUROBI"); RunIntegerProgrammingExample("GLPK"); RunIntegerProgrammingExample("CPLEX"); + RunIntegerProgrammingExample("XPRESS"); } } // namespace operations_research diff --git a/makefiles/Makefile.third_party.unix.mk b/makefiles/Makefile.third_party.unix.mk index 8cb43eddfa..4ce9a8295d 100644 --- a/makefiles/Makefile.third_party.unix.mk +++ b/makefiles/Makefile.third_party.unix.mk @@ -101,6 +101,9 @@ ifndef UNIX_CPLEX_DIR endif ifndef UNIX_GLPK_DIR $(info GLPK: not found) +endif +ifndef UNIX_XPRESS_DIR + $(info XPRESS: not found) endif $(TOUCH) $@ @@ -161,6 +164,10 @@ Makefile.local: makefiles/Makefile.third_party.$(SYSTEM).mk @echo "# Define UNIX_GLPK_DIR to point to a compiled version of GLPK to use it" >> Makefile.local @echo "# e.g. UNIX_GLPK_DIR = /opt/glpk-x.y.z" >> Makefile.local @echo >> Makefile.local + @echo "# Define UNIX_XPRESS_DIR to use XPRESS MP" >> Makefile.local + @echo "# e.g. UNIX_XPRESS_DIR = /Applications/FICO\ Xpress/xpressmp on Mac OS X" >> Makefile.local + @echo "# e.g. UNIX_XPRESS_DIR = /opt/xpressmp on linux" >> Makefile.local + @echo >> Makefile.local @echo "## REQUIRED DEPENDENCIES ##" >> Makefile.local @echo "# By default they will be automatically built -> nothing to define" >> Makefile.local @echo "# Define UNIX_GFLAGS_DIR to depend on external Gflags dynamic library" >> Makefile.local @@ -933,6 +940,11 @@ ifdef UNIX_CPLEX_DIR @echo UNIX_CPLEX_DIR = $(UNIX_CPLEX_DIR) @echo CPLEX_INC = $(CPLEX_INC) @echo CPLEX_LNK = $(CPLEX_LNK) +endif +ifdef UNIX_XPRESS_DIR + @echo UNIX_XPRESS_DIR = $(UNIX_XPRESS_DIR) + @echo XPRESS_INC = $(XPRESS_INC) + @echo XPRESS_LNK = $(XPRESS_LNK) endif @echo SWIG_VERSION = $(SWIG_VERSION) @echo diff --git a/makefiles/Makefile.unix.mk b/makefiles/Makefile.unix.mk index d710f501f4..cdcd62d0de 100644 --- a/makefiles/Makefile.unix.mk +++ b/makefiles/Makefile.unix.mk @@ -97,6 +97,10 @@ ifdef UNIX_CPLEX_DIR CPLEX_INC = -I$(UNIX_CPLEX_DIR)/cplex/include -DUSE_CPLEX CPLEX_SWIG = $(CPLEX_INC) endif +ifdef UNIX_XPRESS_DIR + XPRESS_INC = -I$(UNIX_XPRESS_DIR)/include -DUSE_XPRESS -DXPRESS_PATH="$(UNIX_XPRESS_DIR)" + XPRESS_SWIG = $(XPRESS_INC) +endif ifeq ($(PLATFORM),LINUX) SWIG_INC = -DSWIGWORDSIZE64 @@ -105,7 +109,7 @@ else endif SWIG_INC += \ -DUSE_GLOP -DUSE_BOP -DABSL_MUST_USE_RESULT \ - $(GLPK_SWIG) $(CPLEX_SWIG) + $(GLPK_SWIG) $(CPLEX_SWIG) $(XPRESS_INC) # Compilation flags DEBUG = -O4 -DNDEBUG @@ -122,15 +126,9 @@ ifeq ($(PLATFORM),LINUX) GLPK_LNK = $(UNIX_GLPK_DIR)/lib/libglpk.a endif ifdef UNIX_CPLEX_DIR - ifeq ($(PTRLENGTH),64) - CPLEX_LNK = \ - -L$(UNIX_CPLEX_DIR)/cplex/lib/x86-64_linux/static_pic -lcplex \ - -lm -lpthread -ldl - else - CPLEX_LNK = \ - -L$(UNIX_CPLEX_DIR)/cplex/lib/x86_linux/static_pic -lcplex \ - -lm -lpthread -ldl - endif + CPLEX_LNK = \ + -L$(UNIX_CPLEX_DIR)/cplex/lib/x86-64_linux/static_pic -lcplex \ + -lm -lpthread -ldl endif SYS_LNK = -lrt -lpthread -Wl,--no-as-needed -ldl JAVA_INC = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux @@ -176,6 +174,9 @@ ifeq ($(PLATFORM),MACOSX) -force_load $(UNIX_CPLEX_DIR)/cplex/lib/x86-64_osx/static_pic/libcplex.a \ -lm -lpthread -framework CoreFoundation -framework IOKit endif + ifdef UNIX_XPRESS_DIR + XPRESS_LNK = -Wl,-rpath,$(UNIX_XPRESS_DIR)/lib -L$(UNIX_XPRESS_DIR)/lib -lxprs -lxprl + endif SYS_LNK = SET_COMPILER = CXX="$(CCC)" JAVA_INC = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/darwin @@ -209,12 +210,12 @@ endif # ifeq ($(PLATFORM),MACOSX) DEPENDENCIES_INC = -I$(INC_DIR) -I$(GEN_DIR) \ -Wno-deprecated -DUSE_GLOP -DUSE_BOP \ - $(GLPK_INC) $(CPLEX_INC) + $(GLPK_INC) $(CPLEX_INC) $(XPRESS_INC) CFLAGS = $(DEBUG) $(DEPENDENCIES_INC) -DOR_TOOLS_MAJOR=$(OR_TOOLS_MAJOR) -DOR_TOOLS_MINOR=$(OR_TOOLS_MINOR) JNIFLAGS = $(JNIDEBUG) $(DEPENDENCIES_INC) LDFLAGS += $(ZLIB_LNK) $(SYS_LNK) $(LINK_FLAGS) -DEPENDENCIES_LNK = $(GLPK_LNK) $(CPLEX_LNK) +DEPENDENCIES_LNK = $(GLPK_LNK) $(CPLEX_LNK) $(XPRESS_LNK) OR_TOOLS_LNK = $(PRE_LIB)ortools$(POST_LIB) OR_TOOLS_LDFLAGS = $(ZLIB_LNK) $(SYS_LNK) $(LINK_FLAGS) diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index 9e2a9d9a9f..a1815ff57d 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -30,6 +30,8 @@ extern "C" { #define XPRS_INTEGER 'I' #define XPRS_CONTINUOUS 'C' +#define STRINGIFY2(X) #X +#define STRINGIFY(X) STRINGIFY2(X) void printError(const XPRSprob &mLp, int line) { char errmsg[512]; @@ -252,35 +254,41 @@ class XpressInterface : public MPSolverInterface { }; /** init XPRESS environment */ -int init_xpress_env(int xpress_oem_license_key = 0); -int init_xpress_env(int xpress_oem_license_key) { +int init_xpress_env(int xpress_oem_license_key = 0) { int code; - char *xpresspath; - xpresspath = getenv("XPRESS"); + const char *xpress_from_env = getenv("XPRESS"); + std::string xpresspath; - google::InitGoogleLogging("Xpress"); - - if (!xpresspath) { - VLOG(0) - << "XpressInterface Error : Environment variable XPRESS undefined.\n"; - return -1; +#if defined(XPRESS_PATH) + if (xpress_from_env == nullptr) { + LOG(WARNING) + << "Environment variable XPRESS undefined. Trying compile path " + << "'" << STRINGIFY(XPRESS_PATH) << "'"; + xpresspath = STRINGIFY(XPRESS_PATH) "/bin"; +#else + LOG(WARNING) + << "XpressInterface Error : Environment variable XPRESS undefined.\n"; + return -1; +#endif + } else { + xpresspath = xpress_from_env; } /** if not an OEM key */ if (xpress_oem_license_key == 0) { - VLOG(0) << "XpressInterface : Initialising xpress-MP with parameter " - << xpresspath << std::endl; + LOG(WARNING) << "XpressInterface : Initialising xpress-MP with parameter " + << xpresspath << std::endl; - code = XPRSinit(xpresspath); + code = XPRSinit(xpresspath.c_str()); if (!code) { /** XPRSbanner informs about Xpress version, options and error messages */ char banner[1000]; XPRSgetbanner(banner); - VLOG(0) << "XpressInterface : Xpress banner :\n" << banner << std::endl; - + LOG(WARNING) << "XpressInterface : Xpress banner :\n" + << banner << std::endl; return 0; } else { char errmsg[256]; @@ -297,8 +305,8 @@ int init_xpress_env(int xpress_oem_license_key) { } } else { /** if OEM key */ - VLOG(0) << "XpressInterface : Initialising xpress-MP with OEM key " - << xpress_oem_license_key << "\n"; + LOG(WARNING) << "XpressInterface : Initialising xpress-MP with OEM key " + << xpress_oem_license_key << "\n"; int nvalue = 0; int ierr;