Skip to content

Commit

Permalink
hard crash if one Xpress function not found (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
sgatto committed Nov 22, 2023
1 parent 44b6d99 commit e657295
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 27 deletions.
14 changes: 3 additions & 11 deletions ortools/base/dynamic_library.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <functional>
#include <stdexcept>
#include <string>
#include <vector>

#include "ortools/base/logging.h"

Expand All @@ -31,7 +30,6 @@
#endif

class DynamicLibrary {
static constexpr size_t kMaxFunctionsNotFound = 10;
public:
DynamicLibrary() : library_handle_(nullptr) {}

Expand Down Expand Up @@ -59,10 +57,6 @@ static constexpr size_t kMaxFunctionsNotFound = 10;

bool LibraryIsLoaded() const { return library_handle_ != nullptr; }

const std::vector<std::string>& FunctionsNotFound() const {
return functions_not_found_;
}

template <typename T>
std::function<T> GetFunction(const char* function_name) {
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
Expand All @@ -73,10 +67,9 @@ static constexpr size_t kMaxFunctionsNotFound = 10;
const void* function_address = dlsym(library_handle_, function_name);
#endif // MinGW.

// We don't really need the full list of missing functions,
// just a few are enough.
if (!function_address && functions_not_found_.size() < kMaxFunctionsNotFound)
functions_not_found_.push_back(function_name);
CHECK(function_address)
<< "Error: could not find function " << std::string(function_name)
<< " in " << library_name_;

return TypeParser<T>::CreateFunction(function_address);
}
Expand All @@ -100,7 +93,6 @@ static constexpr size_t kMaxFunctionsNotFound = 10;
private:
void* library_handle_ = nullptr;
std::string library_name_;
std::vector<std::string> functions_not_found_;

template <typename T>
struct TypeParser {};
Expand Down
26 changes: 10 additions & 16 deletions ortools/xpress/environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ std::function<int(XPRSprob prob, void (XPRS_CC *f_message)(XPRSprob cbprob, void
std::function<int(XPRSprob prob, const char* flags)> XPRSlpoptimize = nullptr;
std::function<int(XPRSprob prob, const char* flags)> XPRSmipoptimize = nullptr;

absl::Status LoadXpressFunctions(DynamicLibrary* xpress_dynamic_library) {
void LoadXpressFunctions(DynamicLibrary* xpress_dynamic_library) {
// This was generated with the parse_header_xpress.py script.
// See the comment at the top of the script.

Expand Down Expand Up @@ -158,15 +158,6 @@ absl::Status LoadXpressFunctions(DynamicLibrary* xpress_dynamic_library) {
xpress_dynamic_library->GetFunction(&XPRSaddcbmessage, "XPRSaddcbmessage");
xpress_dynamic_library->GetFunction(&XPRSlpoptimize, "XPRSlpoptimize");
xpress_dynamic_library->GetFunction(&XPRSmipoptimize, "XPRSmipoptimize");


auto notFound = xpress_dynamic_library->FunctionsNotFound();
if (!notFound.empty()) {
return absl::NotFoundError(absl::StrCat("Could not find the following functions (list may not be exhaustive). [",
absl::StrJoin(notFound, "', '"),
"]. Please make sure that your XPRESS install is up-to-date (>= 9.0.0)."));
}
return absl::OkStatus();
}

void printXpressBanner(bool error) {
Expand All @@ -184,17 +175,18 @@ std::vector<std::string> XpressDynamicLibraryPotentialPaths() {
std::vector<std::string> potential_paths;

// Look for libraries pointed by XPRESSDIR first.
const char* xpress_home_from_env = getenv("XPRESSDIR");
if (xpress_home_from_env != nullptr) {
const char* xpressdir_from_env = getenv("XPRESSDIR");
if (xpressdir_from_env != nullptr) {
LOG(INFO) << "Environment variable XPRESSDIR = " << xpressdir_from_env;
#if defined(_MSC_VER) // Windows
potential_paths.push_back(
absl::StrCat(xpress_home_from_env, "\\bin\\xprs.dll"));
absl::StrCat(xpressdir_from_env, "\\bin\\xprs.dll"));
#elif defined(__APPLE__) // OS X
potential_paths.push_back(
absl::StrCat(xpress_home_from_env, "/lib/libxprs.dylib"));
absl::StrCat(xpressdir_from_env, "/lib/libxprs.dylib"));
#elif defined(__GNUC__) // Linux
potential_paths.push_back(
absl::StrCat(xpress_home_from_env, "/lib/libxprs.so"));
absl::StrCat(xpressdir_from_env, "/lib/libxprs.so"));
#else
LOG(ERROR) << "OS Not recognized by xpress/environment.cc."
<< " You won't be able to use Xpress.";
Expand Down Expand Up @@ -244,7 +236,9 @@ absl::Status LoadXpressDynamicLibrary(std::string& xpresspath) {
}

if (xpress_library.LibraryIsLoaded()) {
xpress_load_status = LoadXpressFunctions(&xpress_library);
LOG(INFO) << "Loading all Xpress functions";
LoadXpressFunctions(&xpress_library);
xpress_load_status = absl::OkStatus();
} else {
xpress_load_status = absl::NotFoundError(
absl::StrCat("Could not find the Xpress shared library. Looked in: [",
Expand Down

0 comments on commit e657295

Please sign in to comment.