opencv: Building against OpenBLAS complains about missing lapacke.h

System information (version)
  • OpenCV => 3.3.1
  • Operating System / Platform => Ubuntu 16.04. (xenial)
Detailed description

It is not possible to build openCV against libOpenBLAS unless one also installs an additional LAPACK implementation that includes the lapacke.h header, e.g. liblapacke-dev on Ubuntu.

To me that does not look like the intended behavior and it might be explained by the fact, that OpenBLAS on Ubuntu only include cblas.h and f77blas.h as an header.

On the other hand OpenCVFindOpenBLAS.cmake does not check for lapacke.h, so it might just be the case that ocv_lapack_check() is too strict when it comes to OpenBLAS.

@alalek You seem to have some experience with this. Any thoughts on this?

Steps to reproduce

If I only install libopenblas-dev, I get the following cmake output once ocv_lapack_check() inside OpenCVFindLAPACK.cmake is called:

-- LAPACK(OpenBLAS): LAPACK_LIBRARIES: /usr/lib/libopenblas.so
CMake Warning at cmake/OpenCVFindLAPACK.cmake:29 (message):
  LAPACK(OpenBLAS): CBLAS/LAPACK headers are not found in '/usr/include'
Call Stack (most recent call first):
  cmake/OpenCVFindLAPACK.cmake:155 (ocv_lapack_check)
  CMakeLists.txt:596 (include)

If I now install any LAPACK implementation that includes a lapacke.h, e.g.: liblapacke-dev, everything passes and OpenBLAS will be used:

-- LAPACK(OpenBLAS): LAPACK_LIBRARIES: /usr/lib/libopenblas.so
-- LAPACK(OpenBLAS): Support is enabled.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 8
  • Comments: 23 (3 by maintainers)

Most upvoted comments

Even installing of liblapacke-dev from the repository did not work for me (Opencv 3.4)

liblapacke-dev Installed lapacke.h to /usr/include/lapacke.h OpenCVFindLAPACK.cmake complains not found it in ‘/usr/include/openblas

My current workaround is to copy /usr/include/lapacke*.h to ‘/usr/include/openblas’, then verything works fine

CMake Warning at cmake/OpenCVFindLAPACK.cmake:29 (message):
   LAPACK(OpenBLAS): CBLAS/LAPACK headers are not found in
   '/usr/include/openblas'
 Call Stack (most recent call first):
   cmake/OpenCVFindLAPACK.cmake:97 (ocv_lapack_check)
   CMakeLists.txt:604 (include)

On Linux mint 18, equal to ubuntu 16.04

Kernel: 4.4.0-104-generic x86_64 (64 bit) Desktop: Cinnamon 3.0.7
           Distro: Linux Mint 18 Sarah 
$ ldconfig -p | grep libopenblas
	libopenblas.so.0 (libc6,x86-64) => /usr/lib/libopenblas.so.0
	libopenblas.so (libc6,x86-64) => /usr/lib/libopenblas.so

BLAS is API with functions for low-level matrix/vector operations (like gemm). OpenCV requires LAPACK API too (high-level functionality, like matrix factorization, eigenvalues, etc): http://www.netlib.org/lapack/

For some reason, CMake’s FindLAPACK module doesn’t provide any information about header files (they are required for C/C++ programs compilation).

Ubuntu’s OpenBLAS binaries support LAPACK API symbols.

$ nm -D /usr/lib/liblapack.so | grep cheev
000000000008db80 T cheev_
000000000008e0e0 T cheevd_
000000000008e860 T cheevr_
000000000008fbc0 T cheevx_

But headers are not provided for LAPACK routines via “-dev” package (only BLAS headers are available). (update: new link on Ubuntu 18.04 because 16.04 is EOL)

/usr/include/x86_64-linux-gnu/cblas-openblas.h
/usr/include/x86_64-linux-gnu/f77blas.h
/usr/include/x86_64-linux-gnu/openblas_config.h
/usr/lib/x86_64-linux-gnu/libopenblas.a
/usr/lib/x86_64-linux-gnu/libopenblas.so
/usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.a
/usr/lib/x86_64-linux-gnu/openblas/libblas.a
/usr/lib/x86_64-linux-gnu/openblas/libblas.so
/usr/lib/x86_64-linux-gnu/openblas/liblapack.a
/usr/lib/x86_64-linux-gnu/openblas/liblapack.so
/usr/lib/x86_64-linux-gnu/pkgconfig/blas-openblas.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/lapack-openblas.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/openblas.pc
/usr/share/doc/libopenblas-dev/changelog.Debian.gz
/usr/share/doc/libopenblas-dev/copyright

BTW, Fedora provides “openblas-devel” package with lapacke.h header:

...
* Tue Jan 15 2013 Susi Lehtola <jussilehtola@fedoraproject.org> - 0.2.5-8
  - Added LAPACKE include files.
...
/usr/include/openblas
/usr/include/openblas/cblas.h
/usr/include/openblas/f77blas.h
/usr/include/openblas/lapacke.h
/usr/include/openblas/lapacke_config.h
/usr/include/openblas/lapacke_mangling.h
/usr/include/openblas/lapacke_utils.h
/usr/include/openblas/openblas_config.h
/usr/lib64/libopenblas.so
...

OpenCV detects OpenBLAS on Fedora (if there is no other conflicted BLAS/LAPACK libraries):

-- Found OpenBLAS libraries: /lib64/libopenblas.so
-- Found OpenBLAS include: /usr/include/openblas
-- LAPACK(OpenBLAS): LAPACK_LIBRARIES: /lib64/libopenblas.so
-- LAPACK(OpenBLAS): Support is enabled.

OpenBLAS source repository has LAPACK files internally. I have no idea why LAPACK headers are not packaged on Ubuntu. We use liblapacke-dev workaround at this moment on our Ubuntu builders.

I ran into this issue as well, and I have developed a solution.

The fix involves three steps:

  • Copy the lapack-netlib/LAPACKE/include/*.h files into the include directory where OpenBLAS is installed (location of cblas.h, f77blas.h, openblas_config.h, i.e. CMake OpenBLAS_INCLUDE_DIR)
  • Copy liblapacke.a into the lib directory where OpenBLAS is installed (location of libopenblas.so, etc, i.e. CMake OpenBLAS_LIB)
  • Specify the full path the the LAPACK library: -D LAPACK_LIBRARIES=/path/path/to/liblapacke.a, where /path/path/to/ should match OpenBLAS_LIB

In case they are useful to anyone, here are my scripts for a custom install from source using custom compilers.

# OpenBLAS
cd $DIR/
git clone https://github.com/xianyi/OpenBLAS.git
cd OpenBLAS/
git checkout v0.3.7
make -j$(nproc) FC=$FCPATH CC=$CCPATH CFLAGS="-std=c17 -fPIC" \
 CXX=$CXXPATH CXXFLAGS="-std=c++17 -fPIC" BINARY=64 NOFORTRAN=1
mkdir install
make install PREFIX=$(pwd)/install
cp lapack-netlib/LAPACKE/include/*.h install/include/
cd lapack-netlib/
cp make.inc.example make.inc
sed -i "s,gcc,$CCPATH," make.inc
sed -i "s,CFLAGS = -O3,CFLAGS = -std=c17 -fPIC -O3," make.inc
sed -i "s,= gfortran,= $FCPATH," make.inc
cd LAPACKE/
make -j$(nproc)
cp ../liblapacke.a $DIR/OpenBLAS/install/lib/

#OpenCV
cd $DIR/
git clone https://github.com/opencv/opencv.git
cd opencv/
git checkout 3.4.7
mkdir install
mkdir build
cd build/
FC=$FCPATH CC=$CCPATH CXX=$CXXPATH cmake \
 -D CMAKE_C_FLAGS="${CMAKE_C_FLAGS} -std=c17 -fPIC" \
 -D CMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -std=c++17 -fPIC" \
 -D WITH_PROTOBUF=OFF -D WITH_JASPER=OFF \
 -D BUILD_opencv_java=OFF -D BUILD_JAVA=OFF \
 -D BUILD_opencv_java_bindings_generator=OFF \
 -D BUILD_opencv_python2=OFF -D BUILD_opencv_python3=OFF \
 -D BUILD_opencv_python_bindings_generator=OFF \
 -D BUILD_opencv_python_tests=OFF \
 -D OpenBLAS_INCLUDE_DIR=$DIR/OpenBLAS/install/include \
 -D OpenBLAS_LIB=$DIR/OpenBLAS/install/lib \
 -D LAPACK_LIBRARIES=$DIR/OpenBLAS/install/lib/liblapacke.a \
 -D CMAKE_INSTALL_PREFIX=$DIR/opencv/install ../
make FC=$FCPATH CC=$CCPATH CFLAGS="-std=c17 -fPIC" \
 CXX=$CXXPATH CXXFLAGS="-std=c++17 -fPIC" -j$(nproc)
make install

As a side note, OpenCV should really focus some resources on fixing its ridiculous dependencies situation. I’ve probably spent more time over the years compiling and configuring the latest version than writing OpenCV code. As far as I can tell, there isn’t even an install readme or dependency doc anymore. If you look at the CMake statement above, I have to turn off Python and Java like seven different times and CMake still lists the path to the Python interpreter in the output.

Perhaps we should drop OpenCVFindAtlas.cmake OpenCVFindOpenBLAS.cmake scripts and use CMake official instead (available since CMake 2.6.0): https://gitlab.kitware.com/cmake/cmake/blob/v3.11.3/Modules/FindBLAS.cmake

To me this currently looks more like a packaging bug in Ubuntu. That is why I submitted the problem to their Launchpad bug tracker. Please feel free to mark yourself as affected, to increase visibility:

https://bugs.launchpad.net/ubuntu/+source/openblas/+bug/1728068

I’m trying to build on an aarch64 machine on Ubuntu, and just installing liblapacke-dev didn’t work for me.

The problem seems to be that liblapacke-dev puts lapacke.h at /usr/include/lapacke.h, but cmake is searching in /usr/include/aarch64-linux-gnu.

I tried passing -DLAPACKE_INCLUDE_DIR=/usr/include, but that didn’t help because on line 98 that gets overwritten with the OpenBLAS include directory.

My solution was to pass -DOpenBLAS_INCLUDE_DIR='/usr/include/aarch64-linux-gnu;/usr/include' instead of -DOpenBLAS_INCLUDE_DIR=/usr/include/aarch64-linux-gnu.

The workaround didn’t entirely do it for me (I’m on Ubuntu 17.10, installing OpenCV 3.4.1). I did the workaround and added cblas header cblas.h:

sudo ln -s /usr/include/x86_64-linux-gnu/cblas.h /usr/include/openblas/cblas.h

I edited cmake/OpenCVFindOpenBLAS.cmake and added the line

/usr/lib/x86_64-linux-gnu

to the Open_BLAS_LIB_SEARCH_PATHS list. This solved the issue!

I think there are three problems:

  1. The lapacke header files are in a different location than cblas header files but the OpenCVFindLAPACK.cmake module looks under only one folder where OpenCVFindOpenBLAS.cmake found cblas.h.
  2. The header file search path cannot find cblas.h on Ubuntu 17.x. (It’s in /usr/include/x86_64-linux-gnu)
  3. The library search path cannot find libopenblas.so on Ubuntu 17.x (It’s in /usr/lib/x86_64-linux-gnu)

Using ubuntu 17.10:

-- Could not find OpenBLAS include. Turning OpenBLAS_FOUND off
-- Could not find OpenBLAS lib. Turning OpenBLAS_FOUND of
ldconfig -p | grep libopenblas
	libopenblas.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libopenblas.so.0
	libopenblas.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libopenblas.so

Installed packages

ii  libopenblas-base:amd64                       0.2.20+ds-4                 amd64
ii  libopenblas-dev:amd64                        0.2.20+ds-4                 amd64