4

I am making use of OpenBLAS for both my BLAS and LAPACK routine calls. I do not want the user base of my C++ library to have to install the dependency on their machine. So I want to supply the OpenBLAS library in my third_party and have CMake link to it locally.

The tree

This is the tree of this minimal example project.

OBLASCmake/
├─ third_party/
│  ├─ OpenBLAS-0.3.15
├─ CMakeLists.txt
├─ main.cpp

main.cpp

#include <iostream>
#include <vector>

using namespace std;

extern "C" double ddot_(int *n, double *x, int *incx, double *y, int * incy);

int main() {
    int n = 3;  // n elements
    vector<double> x = {1.2, 2.4, 3.8};
    vector<double> y = {4.8, 5.5, 6.2};
    int incx = 1;  // increments
    int incy = 1;

    double dot_product = ddot_(&n, &*x.begin(), &incx, &*y.begin(), &incy);

    std::cout << dot_product << std::endl;
    return 0;
}

CMakeLists (currently)

This goes into the system and looks for the OpenBLAS installation on the users machine. This is not what I want, but it works for me because I have it installed on my machine.

cmake_minimum_required(VERSION 3.19)
project(OBLASCMake)

set(CMAKE_CXX_STANDARD 11)

add_library(OBLASCMake SHARED main.cpp)
set(BLA_VENDOR OpenBLAS)
find_package(BLAS)
if (BLAS_FOUND)
    target_link_libraries(OBLASCMake ${BLAS_LIBRARIES})
else()
    # ERROR
endif()

add_executable(test1 main.cpp)
target_link_libraries(test1 OBLASCMake)
enable_testing()
add_test(NAME RunTest COMMAND ${CMAKE_BINARY_DIR}/test1)

The result of running the test with this cmake is an output of 42.52 as the dot product of the two vectors.

CMakeLists (what I want)

This method of defining the local installation is not working properly.

cmake_minimum_required(VERSION 3.19)
project(OBLASCMake)

set(CMAKE_CXX_STANDARD 11)

add_library(OBLASCMake SHARED main.cpp)
# cant use add_subdirectory and find_package
# add_subdirectory(third_party/OpenBLAS-0.3.15)
set(OpenBLAS_DIR ${CMAKE_SOURCE_DIR}/third_party/OpenBLAS-0.3.15)
find_package(OpenBLAS REQUIRED HINTS ${CMAKE_SOURCE_DIR}/third_party/OpenBLAS-0.3.15)

add_executable(test1 main.cpp)
target_link_libraries(test1 OBLASCMake)
enable_testing()
add_test(NAME RunTest COMMAND ${CMAKE_BINARY_DIR}/test1)

Building with CMake results in the following error message:

CMake Error at CMakeLists.txt:12 (find_package):
  Could not find a package configuration file provided by "OpenBLAS" with any
  of the following names:

    OpenBLASConfig.cmake
    openblas-config.cmake

  Add the installation prefix of "OpenBLAS" to CMAKE_PREFIX_PATH or set
  "OpenBLAS_DIR" to a directory containing one of the above files.  If
  "OpenBLAS" provides a separate development package or SDK, be sure it has
  been installed.

There is an OpenBLASConfig.cmake file in the third_party/OpenBLAS-0.3.15/, but CMake isn't seeing it. Does anyone know why cmake is unable to see the config file?

Thank you for your time.

starball
  • 20,030
  • 7
  • 43
  • 238
GeneralCode
  • 794
  • 1
  • 11
  • 26
  • I am not cmake expert, but maybe you have to use the absolute path, like `set(OpenBLAS_DIR "${CMAKE_SOURCE_DIR_ALWAYS_FORGET_EXACT_NAME}/third_party/OpenBLAS-0.3.15")` – alfC May 23 '21 at 04:46
  • 1
    You don't use `add_subdirectory` _and_ `find_package` for the same dependency. Pick one. – Alex Reinking May 23 '21 at 07:57
  • I have updated based on the previous two comments. Still getting the same error message @AlexReinking – GeneralCode May 23 '21 at 14:16
  • @GeneralCode well, do what you did also for the hint. – alfC May 24 '21 at 00:43

1 Answers1

0

Seems to me that you are defining OpenBLAS_DIR without actually using it in the find_package call (which probably takes an absolute PATH or HINT).