I'working on a project that uses SAF (Spatial Audio Framework) which has OpenBlas and LAPACK as Dependecies. (The Project includes a lot of libraries so I only show the code that relates to my problem: BLAS)
I'm trying to figure out how I can link the project with OpenBlas, but nothing worked. I use cmake's FETCHCONTENT to get LAPACK which also contains BLAS. I tried:
target_link_libraries(dev_example PUBLIC openblas) # or libopenblas or cblas or libblas
which resulted in cannot find -lopenblas
.
Now I tried to specify the library directly
SET(OPENBLAS_LIBRARY ${lapack_BINARY_DIR}/lib/libblas.a)
and get a lot of undefined references like undefined reference to 'cblas_sgemm'
I also tried linking against libopenblas.a
from the precompiled binaries from the OpenBlas Repo - same as above.
My CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(dev_example VERSION 1.0 LANGUAGES C CXX)
include(FetchContent)
FETCHCONTENT_DECLARE(
lapack
GIT_REPOSITORY https://github.com/Reference-lapack/lapack
GIT_TAG master
)
FetchContent_MakeAvailable(lapack)
FetchContent_GetProperties(lapack)
if(NOT lapack_POPULATED)
FetchContent_Populate(lapack)
endif()
set(OPENBLAS_HEADER_PATH ${lapack_SOURCE_DIR}/CBLAS/include)
set(LAPACKE_HEADER_PATH ${lapack_SOURCE_DIR}/LAPACKE/include ${lapack_BINARY_DIR}/include)
SET(LAPACKE_LIBRARY ${lapack_BINARY_DIR}/lib/liblapack.a)
SET(OPENBLAS_LIBRARY ${lapack_BINARY_DIR}/lib/libblas.a)
add_executable(dev_example WIN32
main.cpp
)
target_include_directories(dev_example PUBLIC
${lapack_SOURCE_DIR}/CBLAS/include
${lapack_BINARY_DIR}/include
)
target_link_libraries(dev_example PUBLIC
${OPENBLAS_LIBRARY}
)
How can I link Blas correctly?
I made sure that libblas.a
is located in the given directory.
I was also wondering if I'm even using the correct BLAS library because all the undefined refences are prefixed with cblas_
like cblas_sgemm
while libblas.a
only contains Symbols like sgemm
without the prefix.
Compiler: gcc.exe (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
In your own answer:
I assume that LAPACK on Github contains a different implementation of BLAS and not OpenBLAS.
The libblas.a
that is built along with liblapack.a
with repo https://github.com/Reference-lapack/lapack
is a Fortran BLAS library. That is why all its symbols lack the CBLAS prefix cblas_
. As per the repo's README
,
it does contain a CBLAS source tree but it does not tell you that this is not built by default. Or that you have to configure the CMake build with
-DCBLAS=ON
, and then, instead of (or after) running make
you
must run make cblas
. The build will then output a libcblas.a
.
As you found, OpenBLAS builds a CBLAS library
libopenblas.a
by default with header files equipped for linkage with C++. Regarding
that repo:
FetchContent didn't set any library variable for BLAS, unlike find_package usually would.
It doesn't, but it does set:
openblas_SOURCE_DIR
openblas_BINARY_DIR
So just as far as linking against libopenblas
is concerned, you can have a CMakeLists.txt
on the lines:
cmake_minimum_required(VERSION 3.16)
project(dev_example VERSION 1.0 LANGUAGES C CXX)
include(FetchContent)
FetchContent_Declare(
openblas
GIT_REPOSITORY https://github.com/OpenMathLib/OpenBLAS.git
GIT_TAG v0.3.28
)
FetchContent_MakeAvailable(openblas)
FetchContent_GetProperties(openblas)
set(openblas_HDR_DIRS ${openblas_SOURCE_DIR} ${openblas_BINARY_DIR})
set(openblas_LIB_DIRS ${openblas_BINARY_DIR}/lib)
add_executable(dev_example
main.cpp
)
target_include_directories(dev_example PRIVATE
${openblas_HDR_DIRS}
)
target_link_directories(dev_example PRIVATE
${openblas_LIB_DIRS}
)
target_link_libraries(dev_example PRIVATE
openblas
)
The reason for the inclusion of ${openblas_BINARY_DIR}
in target_include_directories
is
the fact that an autotools-style header config.h
is generated in the build directory.