Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 115 additions & 14 deletions cmake/modules/FindGUROBI.cmake
Original file line number Diff line number Diff line change
@@ -1,20 +1,121 @@
set(GUROBI_ROOT_DIR "" CACHE PATH "GUROBI root directory.")
# - Find Gurobi Optimizer
#
# This module finds an installed Gurobi Optimizer library.
# It is an independent implementation that is not based on the script
# provided by Gurobi GmbH.
#
# USAGE:
# In your CMakeLists.txt, add the following:
# 1. list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") # Path to this file
# 2. find_package(GUROBI REQUIRED)
# 3. target_link_libraries(your_target PRIVATE Gurobi::gurobi)
#
# This module will define the following IMPORTED target:
# Gurobi::gurobi - An interface library that links to Gurobi's C and C++
# libraries and includes its headers.
#
# It also defines these variables, though using the target is preferred:
# GUROBI_FOUND - True if Gurobi was found.
# GUROBI_INCLUDE_DIRS - The Gurobi include directories.
# GUROBI_LIBRARIES - A list of the Gurobi C and C++ libraries.
#
# The search for Gurobi is controlled by the following variables:
# GUROBI_HOME - An environment variable pointing to the Gurobi
# installation root (e.g., /opt/gurobi1003/linux64).
# GUROBI_ROOT_DIR - A CMake variable that can be set to the Gurobi
# installation root. Overrides GUROBI_HOME.

STRING(REGEX MATCH "^[0-9]+" GUROBI_VERSION "${GUROBI_ROOT_DIR}")
# Step 1: Find the Gurobi Root Directory
# --------------------------------------------------------------------
if(DEFINED ENV{GUROBI_HOME})
set(GUROBI_ROOT_DIR "$ENV{GUROBI_HOME}")
endif()

find_path(GUROBI_INCLUDE_DIR gurobi_c++.h HINTS "${GUROBI_ROOT_DIR}/include")
find_library(GUROBI_LIBRARY libgurobi70.so HINTS ${GUROBI_ROOT_DIR}/lib)
find_library(GUROBI_CPP_LIBRARY libgurobi_c++.a HINTS ${GUROBI_ROOT_DIR}/lib)
# Allow the user to override the environment variable with a CMake variable
set(GUROBI_ROOT_DIR "${GUROBI_ROOT_DIR}" CACHE PATH "Gurobi installation root directory")

if(NOT EXISTS "${GUROBI_ROOT_DIR}")
message(FATAL_ERROR "Gurobi root directory not found. Please set GUROBI_HOME in your environment or GUROBI_ROOT_DIR in your CMake configuration.")
endif()


# Step 2: Extract the Gurobi Version from the Path
# --------------------------------------------------------------------
# This regex looks for "gurobi" followed by a sequence of digits (e.g., 1003)
# in the path and captures the digits.
string(REGEX MATCH "gurobi([0-9]+)" _ "${GUROBI_ROOT_DIR}")
if(NOT CMAKE_MATCH_1)
message(WARNING "Could not determine Gurobi version from path: ${GUROBI_ROOT_DIR}. Assuming version 90 for library search.")
set(GUROBI_VERSION "90") # Fallback to a common older version
else()
set(GUROBI_VERSION "${CMAKE_MATCH_1}")
# Gurobi library names don't use the patch number, e.g. 10.0.3 -> 100
string(SUBSTRING "${GUROBI_VERSION}" 0 3 GUROBI_VERSION_MAJOR_MINOR)
set(GUROBI_VERSION ${GUROBI_VERSION_MAJOR_MINOR})
endif()


# Step 3: Find the Required Components (Include directory and Libraries)
# --------------------------------------------------------------------
find_path(GUROBI_INCLUDE_DIR
NAMES gurobi_c++.h
HINTS "${GUROBI_ROOT_DIR}/include"
DOC "Path to the Gurobi C++ header file"
)

find_library(GUROBI_LIBRARY
NAMES gurobi${GUROBI_VERSION} # e.g., searches for libgurobi100.so
HINTS "${GUROBI_ROOT_DIR}/lib"
DOC "Gurobi C library"
)

find_library(GUROBI_CPP_LIBRARY
NAMES gurobi_c++
HINTS "${GUROBI_ROOT_DIR}/lib"
DOC "Gurobi C++ library"
)


# Step 4: Handle standard arguments and report result
# --------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GUROBI DEFAULT_MSG GUROBI_LIBRARY GUROBI_CPP_LIBRARY GUROBI_INCLUDE_DIR)
find_package_handle_standard_args(GUROBI
FOUND_VAR GUROBI_FOUND
REQUIRED_VARS GUROBI_LIBRARY GUROBI_CPP_LIBRARY GUROBI_INCLUDE_DIR
VERSION_VAR GUROBI_VERSION
)


# Step 5: Create Imported Target and set variables if found
# --------------------------------------------------------------------
if(GUROBI_FOUND)
set(GUROBI_INCLUDE_DIRS ${GUROBI_INCLUDE_DIR})
set(GUROBI_LIBRARIES ${GUROBI_CPP_LIBRARY} ${GUROBI_LIBRARY})
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(GUROBI_LIBRARIES "${GUROBI_LIBRARIES};m;pthread")
endif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
endif(GUROBI_FOUND)

mark_as_advanced(GUROBI_LIBRARY GUROBI_CPP_LIBRARY GUROBI_INCLUDE_DIR)
# --- Create the modern IMPORTED target ---
if(NOT TARGET Gurobi::gurobi)
add_library(Gurobi::gurobi INTERFACE IMPORTED)
set_property(TARGET Gurobi::gurobi PROPERTY
INTERFACE_INCLUDE_DIRECTORIES "${GUROBI_INCLUDE_DIR}")

# Set system-specific libraries
set(GUROBI_SYSTEM_LIBS "")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(GUROBI_SYSTEM_LIBS m pthread)
endif()

set_property(TARGET Gurobi::gurobi PROPERTY
INTERFACE_LINK_LIBRARIES "${GUROBI_CPP_LIBRARY};${GUROBI_LIBRARY};${GUROBI_SYSTEM_LIBS}")
endif()

# --- Set classic variables for compatibility ---
set(GUROBI_INCLUDE_DIRS "${GUROBI_INCLUDE_DIR}")
set(GUROBI_LIBRARIES "${GUROBI_CPP_LIBRARY}" "${GUROBI_LIBRARY}")

if(NOT GUROBI_FIND_QUIETLY)
message(STATUS "Found Gurobi: ${GUROBI_ROOT_DIR} (version ${GUROBI_VERSION})")
message(STATUS " - Gurobi C++ Library: ${GUROBI_CPP_LIBRARY}")
message(STATUS " - Gurobi C Library: ${GUROBI_LIBRARY}")
endif()

endif()

# Mark internal variables as advanced so they don't show up in the default CMake GUI
mark_as_advanced(GUROBI_ROOT_DIR GUROBI_INCLUDE_DIR GUROBI_LIBRARY GUROBI_CPP_LIBRARY)
1 change: 1 addition & 0 deletions include/andres/graph/minimum-spanning-tree.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <queue>
#include <stdexcept>
#include <vector>
#include <limits>

#include "andres/functional.hxx"
#include "subgraph.hxx"
Expand Down
1 change: 1 addition & 0 deletions include/andres/graph/multicut-lifted/greedy-additive.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <algorithm>
#include <map>
#include <queue>
#include <limits>

#include "andres/partition.hxx"

Expand Down
1 change: 1 addition & 0 deletions include/andres/graph/multicut-lifted/kernighan-lin.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <set>
#include <vector>
#include <stack>
#include <limits>



Expand Down
1 change: 1 addition & 0 deletions include/andres/graph/multicut/kernighan-lin.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <stdexcept>
#include <set>
#include <vector>
#include <limits>

#include "../complete-graph.hxx"

Expand Down
4 changes: 3 additions & 1 deletion include/andres/graph/multicut/preprocessing.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#define ANDRES_GRAPH_MULTICUT_PREPROCESSING_HXX

#include <cmath>
#include <limits>

#include "andres/graph/components.hxx"
#include "andres/graph/bridges.hxx"
Expand All @@ -15,7 +16,8 @@ namespace multicut {
// Edge contraction operation by masking
// First vertex of given node pair stays in the graph, the other one is removed (masked)
// Flags affected vertices in optional flag pointer
void contract(andres::graph::Graph<> & graph, std::vector<double> & edge_costs,
template <typename T>
void contract(andres::graph::Graph<T> & graph, std::vector<double> & edge_costs,
std::vector<char> & emask, std::vector<char> & vmask, std::vector<size_t> pair,
std::vector<std::pair<std::pair<size_t,size_t>, char>> & constr, std::vector<char> * flag = NULL)
{
Expand Down