Bug 226959 - devel/cmake: find_package(BLAS REQUIRED) doesn't find blas
Summary: devel/cmake: find_package(BLAS REQUIRED) doesn't find blas
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-kde (Team)
Depends on:
Reported: 2018-03-26 22:45 UTC by Yuri Victorovich
Modified: 2018-04-18 06:55 UTC (History)
2 users (show)

See Also:
bugzilla: maintainer-feedback? (kde)


Note You need to log in before you can comment on or make changes to this bug.
Description Yuri Victorovich freebsd_committer 2018-03-26 22:45:56 UTC
CMake Error at /usr/local/share/cmake/Modules/FindBLAS.cmake:699 (message):
  A required library with BLAS API not found.  Please specify library
Call Stack (most recent call first):
  CMakeLists.txt:1 (find_package)
Comment 1 Yuri Victorovich freebsd_committer 2018-03-26 22:47:01 UTC
FreeBSD 11.1 amd64

> $ pkg info | grep blas
> blas-3.5.0_4                   Basic Linear Algebra Subroutines
> cblas-1.0_8                    Reference implementation of the C interface to the legacy Fortran BLAS
> openblas-0.2.20_2,1            Optimized BLAS library based on GotoBLAS2
Comment 2 Jan Beich freebsd_committer 2018-03-28 09:52:45 UTC
Try MAKE_ENV += BLA_VENDOR=OpenBLAS or CMAKE_ARGS += -DBLA_VENDOR:STRING=OpenBLAS. For example usage see math/ceres-solver or math/superlu.
Comment 3 Yuri Victorovich freebsd_committer 2018-03-28 09:58:13 UTC
(In reply to Jan Beich from comment #2)

> BLA_VENDOR=OpenBLAS cmake .

also fail to find blas.
Comment 4 Jan Beich freebsd_committer 2018-03-28 10:36:17 UTC
I've managed to reproduce. find_package(BLAS) fails because libgfortran loads an old/incorrect libgcc_s version. Only affects ports built by Clang + BFD linker. Possible workarounds: LDFLAGS=-L/usr/local/lib/gcc6 aka USES=fortran, LDFLAGS=-fuse-ld={gold,lld}.

$ pkg install cmake blas
$ echo "find_package(BLAS REQUIRED)" >CMakeLists.txt
$ cmake -Wno-dev
$ cat CMakeFiles/CMakeError.log
Determining if the function sgemm_ exists failed with the following output:
Change Dir: CMakeFiles/CMakeTmp

Run Build Command:"/usr/bin/make" "cmTC_e22cb/fast"
/usr/bin/make -f CMakeFiles/cmTC_e22cb.dir/build.make CMakeFiles/cmTC_e22cb.dir/build
Building C object CMakeFiles/cmTC_e22cb.dir/CheckFunctionExists.c.o
/usr/bin/cc   -DCHECK_FUNCTION_EXISTS=sgemm_ -o CMakeFiles/cmTC_e22cb.dir/CheckFunctionExists.c.o   -c /usr/local/share/cmake/Modules/CheckFunctionExists.c
Linking C executable cmTC_e22cb
/usr/local/bin/cmake -E cmake_link_script CMakeFiles/cmTC_e22cb.dir/link.txt --verbose=1
/usr/bin/cc  -DCHECK_FUNCTION_EXISTS=sgemm_    CMakeFiles/cmTC_e22cb.dir/CheckFunctionExists.c.o  -o cmTC_e22cb -Wl,-rpath,/usr/local/lib /usr/local/lib/libblas.so 
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__getf2@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__floatunditf@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__subtf3@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__multf3@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__unordtf2@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__lttf2@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__addtf3@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__gttf2@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__divtf3@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__letf2@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__netf2@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__floatditf@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__eqtf2@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__floatsitf@GCC_4.6.0'
cc: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error code 1
Comment 5 Jan Beich freebsd_committer 2018-03-28 10:41:36 UTC
Unless you have a patch to fix this in a generic way maybe mark as duplicate of bug 214864.

Comment 6 Yuri Victorovich freebsd_committer 2018-03-28 16:43:23 UTC
(In reply to Jan Beich from comment #4)

> Only affects ports built by Clang + BFD linker.

This can be reproduced with a standalone CMakeLists.txt with this line: "find_package(BLAS REQUIRED)".
Comment 7 Adriaan de Groot freebsd_committer 2018-04-02 22:41:04 UTC
There was another PR filed -- I think by Diane Bruce -- about gfortran and cmake and there was a long discussion there. I can't find it right now, though.

It's not entirely a CMake problem, although find_package(BLAS) shows it shortly and simply. Jan points to "the libgcc problem", which is the underlying thing. Consider this C program:

int main() { return 0; }

Compile it, and link to one of the blas libraries, on amd64 where /usr/bin/cc is Clang:

cc t.c /usr/local/lib/libblas.so

with linker errors (many more than this)

//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__getf2@GCC_4.6.0'
//usr/local/lib/gcc6/libgfortran.so.3: undefined reference to `__floatunditf@GCC_4.6.0'

Throw in the "right" libgcc_s and it links fine:

cc t.c /usr/local/lib/gcc6/libgcc_s.so.1 /usr/local/lib/libblas.so

Using gcc6 instead of Clang does not need this workaround, since it pulls in the right libgcc_s to start with.
Comment 8 Adriaan de Groot freebsd_committer 2018-04-02 23:48:49 UTC
One thing that might be done:

 - if a given BLAS library is found,
 - check it for symbols
 - if not found, then ldd the library, (or readelf, or something) and look for some "special" library names that might need to be added before checking for symbols
 - check it for symbols again

Or, as a gross hack

 - check it for symbols
 - if not found, check it for symbols again, with /usr/local/lib/gcc6/libcss_s.so
Comment 9 Adriaan de Groot freebsd_committer 2018-04-06 13:53:54 UTC
For CMake 3.11 I have added a patch to FindBLAS.cmake that, if it doesn't find the right symbols in the library, and the library links to libgcc_s, re-tries finding the symbols with libgcc_s added to the link line.

That at least makes it *find* BLAS, although more trickery may be needed to get clients to naively use it.
Comment 10 commit-hook freebsd_committer 2018-04-15 21:44:04 UTC
A commit references this bug:

Author: adridg
Date: Sun Apr 15 21:43:58 UTC 2018
New revision: 467437
URL: https://svnweb.freebsd.org/changeset/ports/467437

  Update CMake to 3.11.0. Thanks to antoine@ for the exp-run.

  In the run-up to this commit, many other ports were pre-emptively fixed.
  The only issue still known is math/kig, which had a build failure in
  the exp-run, but which isn't reproducible across multiple 11.1 {i386,amd64}
  machines and poudriere builds. We've decided to forge ahead.

  The new CMake version:
   - drops FreeBSD patches that have been incorporated upstream,
   - re-shuffles patches to FindQt4, since upstream has made some changes
     which break FindQt4 in new ways on FreeBSD (while fixing the old ones),
   - has new patches to make OpenMP and BLAS findable on FreeBSD,
   - drops ports libarchive in favor of the version in base, to avoid
     overlinking for the pkg(8) support in CPack (this makes portlint
     complain, and we have decided to ignore it).

  PR:		227372 226959 223678
  Approved by:	tcberner (mentor)
  Differential Revision:	https://reviews.freebsd.org/D14506

Comment 11 Adriaan de Groot freebsd_committer 2018-04-18 06:55:19 UTC
Plain find_package(BLAS) now works (with the patches introduced with the packaging of CMake 3.11.0).