Skip to content

Commit

Permalink
Adding Gurobi
Browse files Browse the repository at this point in the history
  • Loading branch information
jgillis committed Feb 27, 2023
1 parent facf9c3 commit de8244a
Show file tree
Hide file tree
Showing 8 changed files with 588 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ add_subdirectory(matlab)
add_subdirectory(octave)
add_subdirectory(knitro)
add_subdirectory(cplex)
add_subdirectory(gurobi)
94 changes: 94 additions & 0 deletions gurobi/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
cmake_minimum_required(VERSION 3.10)

project(gurobi
LANGUAGES C)

set(INSTALL_PREFIX "")

get_directory_property(hasParent PARENT_DIRECTORY)
if(hasParent)
set(INSTALL_PREFIX "${PROJECT_NAME}/")
endif()



set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

set(LIBRARY_NAME gurobi_adaptor)

add_library(${LIBRARY_NAME} SHARED src/gurobi.c include/gurobi.h)

if(WIN32)
set_target_properties(${LIBRARY_NAME} PROPERTIES PREFIX "lib" IMPORT_PREFIX "lib")
endif()

if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(NBITS_TWO "32")
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(NBITS_TWO "64")
endif()

set(ARCHIVE_DIR lib)
set(RUNTIME_DIR bin)

if(${CMAKE_GENERATOR} MATCHES "Visual Studio*")
set(ARCHIVE_DIR extern/lib/win${NBITS_TWO}/microsoft)
set(RUNTIME_DIR bin/win${NBITS_TWO})
elseif(${CMAKE_GENERATOR} MATCHES "MSYS Makefiles")
set(ARCHIVE_DIR extern/lib/win${NBITS_TWO}/mingw${NBITS_TWO})
set(RUNTIME_DIR bin/win${NBITS_TWO})
endif()

install(TARGETS ${LIBRARY_NAME} EXPORT gurobiTargets
LIBRARY DESTINATION ${INSTALL_PREFIX}lib
ARCHIVE DESTINATION ${INSTALL_PREFIX}${ARCHIVE_DIR}
RUNTIME DESTINATION ${INSTALL_PREFIX}${RUNTIME_DIR})


add_library(gurobi INTERFACE)

target_link_libraries(gurobi INTERFACE ${LIBRARY_NAME})

install(TARGETS gurobi EXPORT gurobiTargets
LIBRARY DESTINATION ${INSTALL_PREFIX}lib
ARCHIVE DESTINATION ${INSTALL_PREFIX}lib
RUNTIME DESTINATION ${INSTALL_PREFIX}bin
INCLUDES DESTINATION ${INSTALL_PREFIX}include)

target_include_directories(${LIBRARY_NAME} PUBLIC
$<BUILD_INTERFACE:${gurobi_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${INSTALL_PREFIX}include>
)

target_include_directories(gurobi INTERFACE
$<BUILD_INTERFACE:${gurobi_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${INSTALL_PREFIX}include>
)



install(DIRECTORY include/ DESTINATION ${INSTALL_PREFIX}include)

install(EXPORT gurobiTargets
FILE gurobiTargets.cmake
NAMESPACE gurobi::
DESTINATION cmake
)

include(CMakePackageConfigHelpers)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/gurobiConfigVersion.cmake
VERSION 7.3
COMPATIBILITY SameMajorVersion
)

configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}-config.cmake.in"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
INSTALL_DESTINATION
cmake)



install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/gurobiConfigVersion.cmake"
DESTINATION cmake
)
4 changes: 4 additions & 0 deletions gurobi/cmake/gurobi-config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
check_required_components("@PROJECT_NAME@")
138 changes: 138 additions & 0 deletions gurobi/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@

method_declarations = []

import re

with open("include/gurobi_core.h.in","r") as fin:
for line in fin.readlines():
line = line.strip()
method_declarations.append(line)

preamble = []
postamble = []

with open("include/gurobi.h.in","r") as fin:
target = preamble
for line in fin.readlines():
if "[gurobi_core.h]" in line:
target = postamble
continue
target.append(line)


def get_name(decl):
return decl.split("(")[0].split(" ")[-1]

def function_ptr(decl):
return decl[:-1].replace(get_name(decl),"(*)")

with open("include/gurobi_c.h","w") as fout:
fout.write("".join(preamble))
for decl in method_declarations:
fout.write("#define %s adaptor_%s\n" % (get_name(decl),get_name(decl)))
fout.write("DLLSYMBOL " + decl.replace(get_name(decl),"(__stdcall *%s)" % get_name(decl))+"\n")

fout.write("".join(postamble))

with open("src/gurobi.c","w") as fout:


fout.write("""
#define DLL_IMPLEMENTATION
#include "gurobi_c.h"
#include <stdlib.h>
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#else // _WIN32
#include <dlfcn.h>
#include <stddef.h>
#endif // _WIN32
""")
for decl in method_declarations:
fout.write(decl.replace(get_name(decl),"(*%s)" % get_name(decl))[:-1]+" = NULL;\n")

fout.write("""
#if defined(_WIN32)
static HINSTANCE h;
#else
void * h;
#endif
void gurobi_adaptor_unload() {
if (h) {
#if defined(_WIN32)
FreeLibrary(h);
#elif defined(__APPLE__)
dlclose(h);
#endif
}
}
int gurobi_adaptor_load(char* err_msg, unsigned int err_msg_len) {
const char* suffix = getenv("GUROBI_VERSION");
#if defined(_WIN32)
const char library_suffix[] = "dll";
const char path_env[] = "PATH";
#elif defined(__APPLE__)
const char library_suffix[] = "dylib";
const char path_env[] = "DYLD_LIBRARY_PATH";
#else
const char library_suffix[] = "so";
const char path_env[] = "LD_LIBRARY_PATH";
#endif
if (suffix==NULL) {
snprintf(err_msg, err_msg_len, "Gurobi load adaptor needs an environmental variable <GUROBI_VERSION> "
"such that libgurobi<GUROBI_VERSION>.%s can be found.", library_suffix);
return 1;
}
char buffer[100];
snprintf(buffer, 100, "libgurobi%s.%s", suffix, library_suffix);
#if defined(_WIN32)
h = LoadLibrary(TEXT(buffer));
#elif defined(__APPLE__)
h = dlopen(buffer, RTLD_LAZY | RTLD_LOCAL);
#else
h = dlopen(buffer, RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);
#endif
if (h) {
#ifdef _WIN32
""")

for decl in method_declarations:
fout.write(""" %s = (%s) GetProcAddress(h, "%s");\n""" % (get_name(decl),function_ptr(decl),get_name(decl)))
fout.write(""" if (%s==NULL) { snprintf(err_msg, err_msg_len, "Could not find symbol '%s' in libgurobi%%s.%%s", suffix, library_suffix); return 2; };\n""" % (get_name(decl),get_name(decl).replace("CPXX","CPXL")))

fout.write("""
#else // _WIN32
""")

for decl in method_declarations:
fout.write(""" %s = (%s) dlsym(h, "%s");\n""" % (get_name(decl),function_ptr(decl),get_name(decl)))
fout.write(""" if (%s==NULL) { snprintf(err_msg, err_msg_len, "Could not find symbol '%s' in libgurobi%%s.%%s", suffix, library_suffix); return 2; };\n""" % (get_name(decl),get_name(decl).replace("CPXX","CPXL")))

fout.write("""
#endif // _WIN32
return 0;
} else {
snprintf(err_msg, err_msg_len, "Could not find library '%s'. "
"Consider adding the appropriate gurobi folder to environmental variable '%s'.", buffer, path_env);
return 1;
}
}
""")



48 changes: 48 additions & 0 deletions gurobi/include/gurobi.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef GUROBI_H
#define GUROBI_H

#ifdef __cplusplus
extern "C" {
#endif


#include <stdio.h>

typedef struct _GRBbatch GRBbatch;
typedef struct _GRBmodel GRBmodel;
typedef struct _GRBenv GRBenv;

#if defined(_WIN64) && !defined(WIN64)
#define WIN64
#endif

#if defined(_WIN32) && !defined(_WIN64) && !defined(WIN32)
#define WIN32
#endif

#if !defined(WIN32) && !defined(WIN64)
#define __cdecl
#define __stdcall
#endif

#ifdef _WIN32
#ifdef DLL_IMPLEMENTATION
#define DLLSYMBOL __declspec( dllexport )
#else
#define DLLSYMBOL __declspec( dllimport ) extern
#endif
#else
#ifdef DLL_IMPLEMENTATION
#define DLLSYMBOL
#else
#define DLLSYMBOL extern
#endif
#endif

[gurobi_core.h]

#ifdef __cplusplus
}
#endif

#endif // GUROBI_H
91 changes: 91 additions & 0 deletions gurobi/include/gurobi_c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#ifndef GUROBI_H
#define GUROBI_H

#ifdef __cplusplus
extern "C" {
#endif


#include <stdio.h>

typedef struct _GRBbatch GRBbatch;
typedef struct _GRBmodel GRBmodel;
typedef struct _GRBenv GRBenv;

#if defined(_WIN64) && !defined(WIN64)
#define WIN64
#endif

#if defined(_WIN32) && !defined(_WIN64) && !defined(WIN32)
#define WIN32
#endif

#if !defined(WIN32) && !defined(WIN64)
#define __cdecl
#define __stdcall
#endif

#ifdef _WIN32
#ifdef DLL_IMPLEMENTATION
#define DLLSYMBOL __declspec( dllexport )
#else
#define DLLSYMBOL __declspec( dllimport ) extern
#endif
#else
#ifdef DLL_IMPLEMENTATION
#define DLLSYMBOL
#else
#define DLLSYMBOL extern
#endif
#endif

#define GRBaddconstr adaptor_GRBaddconstr
DLLSYMBOL int (__stdcall *GRBaddconstr)(GRBmodel *, int, int *, double *, char, double, const char *);
#define GRBaddqconstr adaptor_GRBaddqconstr
DLLSYMBOL int (__stdcall *GRBaddqconstr)(GRBmodel *, int, int *, double *, int, int *, int *, double *, char, double, const char *);
#define GRBaddqpterms adaptor_GRBaddqpterms
DLLSYMBOL int (__stdcall *GRBaddqpterms)(GRBmodel *, int, int *, int *, double *);
#define GRBaddrangeconstr adaptor_GRBaddrangeconstr
DLLSYMBOL int (__stdcall *GRBaddrangeconstr)(GRBmodel *, int, int *, double *, double, double, const char *);
#define GRBaddsos adaptor_GRBaddsos
DLLSYMBOL int (__stdcall *GRBaddsos)(GRBmodel *, int, int, int *, int *, int *, double *);
#define GRBaddvar adaptor_GRBaddvar
DLLSYMBOL int (__stdcall *GRBaddvar)(GRBmodel *, int, int *, double *, double, double, double, char, const char *);
#define GRBfreeenv adaptor_GRBfreeenv
DLLSYMBOL void (__stdcall *GRBfreeenv)(GRBenv *);
#define GRBfreemodel adaptor_GRBfreemodel
DLLSYMBOL int (__stdcall *GRBfreemodel)(GRBmodel *);
#define GRBgetdblattr adaptor_GRBgetdblattr
DLLSYMBOL int (__stdcall *GRBgetdblattr)(GRBmodel *, const char *, double *);
#define GRBgetdblattrarray adaptor_GRBgetdblattrarray
DLLSYMBOL int (__stdcall *GRBgetdblattrarray)(GRBmodel *, const char *, int, int, double *);
#define GRBgetenv adaptor_GRBgetenv
DLLSYMBOL GRBenv* (__stdcall *GRBgetenv)(GRBmodel *);
#define GRBgeterrormsg adaptor_GRBgeterrormsg
DLLSYMBOL const char* (__stdcall *GRBgeterrormsg)(GRBenv *);
#define GRBgetintattr adaptor_GRBgetintattr
DLLSYMBOL int (__stdcall *GRBgetintattr)(GRBmodel *, const char *, int *);
#define GRBgetparamtype adaptor_GRBgetparamtype
DLLSYMBOL int (__stdcall *GRBgetparamtype)(GRBenv *, const char *);
#define GRBloadenv adaptor_GRBloadenv
DLLSYMBOL int (__stdcall *GRBloadenv)(GRBenv **, const char *);
#define GRBnewmodel adaptor_GRBnewmodel
DLLSYMBOL int (__stdcall *GRBnewmodel)(GRBenv *, GRBmodel **, const char *, int, double *, double *, double *, char *, char **);
#define GRBoptimize adaptor_GRBoptimize
DLLSYMBOL int (__stdcall *GRBoptimize)(GRBmodel *);
#define GRBsetdblattrelement adaptor_GRBsetdblattrelement
DLLSYMBOL int (__stdcall *GRBsetdblattrelement)(GRBmodel *, const char *, int, double);
#define GRBsetdblparam adaptor_GRBsetdblparam
DLLSYMBOL int (__stdcall *GRBsetdblparam)(GRBenv *, const char *, double);
#define GRBsetintparam adaptor_GRBsetintparam
DLLSYMBOL int (__stdcall *GRBsetintparam)(GRBenv *, const char *, int);
#define GRBsetstrparam adaptor_GRBsetstrparam
DLLSYMBOL int (__stdcall *GRBsetstrparam)(GRBenv *, const char *, const char *);
#define GRBupdatemodel adaptor_GRBupdatemodel
DLLSYMBOL int (__stdcall *GRBupdatemodel)(GRBmodel *);

#ifdef __cplusplus
}
#endif

#endif // GUROBI_H
Loading

0 comments on commit de8244a

Please sign in to comment.