torressa / cspy

A collection of algorithms for the (Resource) Constrained Shortest Path problem in Python / C++ / C#
https://torressa.github.io/cspy/
MIT License
77 stars 24 forks source link

Use cspy as a C++ library #121

Open glanch opened 2 months ago

glanch commented 2 months ago

Hello, I'd like to use cspy as a C++ library in my project. How would I achieve that? It seems that the CMake install targets don't create header files and a correct cspyConfig.cmake:

# CMakeSwig CMake configuration file

include("${CMAKE_CURRENT_LIST_DIR}/CMakeSwigTargets.cmake")

Best, glanch

torressa commented 1 month ago

You are right. This is a mess and needs re-work.

I've managed to get it working using the following:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.28)

project(proj-template CXX)

option(CXX "enable C++ compilation" ON)

if(CXX)
  enable_language(CXX)
endif()

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "Release")
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

# list source files here
set(sources proj.cc)

add_executable(${CMAKE_PROJECT_NAME} ${sources})

include(FetchContent)

FetchContent_Declare(
  cspy
  GIT_REPOSITORY "https://github.com/torressa/cspy"
  GIT_TAG "v1.0.3")
FetchContent_MakeAvailable(cspy)

target_include_directories(
  ${CMAKE_PROJECT_NAME} PUBLIC "$<BUILD_INTERFACE:${cspy_SOURCE_DIR}>/src/cc")

target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE cspy::BiDirectionalCpp
                                                    LEMON::LEMON)

This includes LEMON which is one of cspy's dependencies. I am not sure if there's a neat way of doing this FetchContent — Complex Dependency Hierarchies.

proj.cc:

#include <iostream>

#include "bidirectional.h"

void wrap() {
  // Init
  const std::vector<double> max_res         = {4.0, 20.0};
  const std::vector<double> min_res         = {1.0, 0.0};
  const int                 number_vertices = 5;
  const int                 number_edges    = 5;
  auto bidirectional = std::make_unique<bidirectional::BiDirectional>(
      number_vertices, number_edges, 0, 4, max_res, min_res);

  // Populate graph
  bidirectional->addNodes({0, 1, 2, 3, 4});
  bidirectional->addEdge(0, 1, 0.0, {1, 2});
  bidirectional->addEdge(1, 2, 0.0, {1, 0.3});
  bidirectional->addEdge(2, 3, -10.0, {1, 3});
  bidirectional->addEdge(2, 4, 10.0, {1, 2});
  bidirectional->addEdge(3, 4, 0.0, {1, 10});

  // Run and query attributes
  bidirectional->run();

  std::string s;
  s += "weight = " + std::to_string(bidirectional->getTotalCost());
  s += ", partial_path=[";
  for (const auto& n : bidirectional->getPath())
    s += std::to_string(n) + ",";
  s += "], res=[";
  for (const auto& r : bidirectional->getConsumedResources())
    s += std::to_string(r) + ",";
  s += "]\n";
  std::cout << s;
}

int main() {
  wrap();
}