kyonifer / koma

A scientific computing library for Kotlin. https://kyonifer.github.io/koma
Other
270 stars 23 forks source link

Unable to build native on Mac - Missing cblas.h #61

Closed quenio closed 6 years ago

quenio commented 6 years ago

I got the following error trying to build for Kotlin Native:

Exception in thread "main" java.lang.Error: /var/folders/y7/qnnjc1q143q39hwttm_rs4gm0000gn/T/tmp7387811828594230022.c:1:10: fatal error: 'cblas.h' file not found
        at org.jetbrains.kotlin.native.interop.indexer.UtilsKt.ensureNoCompileErrors(Utils.kt:137)
        at org.jetbrains.kotlin.native.interop.indexer.IndexerKt.indexDeclarations(Indexer.kt:898)
        at org.jetbrains.kotlin.native.interop.indexer.IndexerKt.buildNativeIndexImpl(Indexer.kt:888)
        at org.jetbrains.kotlin.native.interop.indexer.NativeIndexKt.buildNativeIndex(NativeIndex.kt:56)
        at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:307)
        at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.interop(main.kt:38)
        at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:100)
        at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:29)

I installed openblas but it didn't help.

kyonifer commented 6 years ago

Unfortunately I don't have access to a Mac to help test. In general though, you'll want to find the location of cblas.h as installed by your blas provider, and then make sure the path is in the list of locations specified in cblas.def. See #53 for an example of someone else getting it to work on OS X.

quenio commented 6 years ago

Thanks for the tip. I was able to change the .def files (both cblas.def and lapacke.def) to point to the right paths on my system, and the build went further, but stopped here:

> Task :koma-core-cblas:compileKonanKomaMacbook
Produced dynamic library API in libkoma_api.h
/var/folders/y7/qnnjc1q143q39hwttm_rs4gm0000gn/T/konan_temp6107933151178018820/api.cpp:1168:13: warning: empty struct has size 0 in C, size 1 in C++ [-Wextern-c-compat]
            struct {
            ^
/var/folders/y7/qnnjc1q143q39hwttm_rs4gm0000gn/T/konan_temp6107933151178018820/api.cpp:1215:11: warning: empty struct has size 0 in C, size 1 in C++ [-Wextern-c-compat]
          struct {
          ^
2 warnings generated.
Undefined symbols for architecture x86_64:
  "_LAPACKE_dlange", referenced from:
      _lapacke_kniBridge430 in combined.o
  "_LAPACKE_dgetri", referenced from:
      _lapacke_kniBridge206 in combined.o
  "_LAPACKE_dpotrf", referenced from:
      _lapacke_kniBridge606 in combined.o
  "_LAPACKE_dgetrf", referenced from:
      _lapacke_kniBridge198 in combined.o
  "_LAPACKE_dgesv", referenced from:
      _lapacke_kniBridge168 in combined.o
ld: symbol(s) not found for architecture x86_64
error: /Library/Developer/CommandLineTools/usr/bin/ld invocation reported errors
kyonifer commented 6 years ago

From the error, it seems it has found the lapacke header file, but whatever lapacke lib you are linking against doesn't have the x64 symbols defined. Where did you get your lapacke lib from? Does the lapacke.dylib you're linking against actually have those symbols in it? If so, perhaps another lapacke is getting picked up from the linker path.

For example, on linux with liblapacke-dev installed I can run

$ objdump -T /usr/lib/x86_64-linux-gnu/liblapacke.so | grep LAPACKE_dlange

which returns

00000000000c8970 g    DF .text  0000000000000122  Base        LAPACKE_dlange

I believe an equivalent inspection can be made on OS X using otool, but its been awhile.

quenio commented 6 years ago

It worked now!

The problem is that I had not installed lapack on my system, and the build was picking up lapack from /usr/lib instead, which apparently didn't have all the symbols needed.

Once I installed lapack with Homebrew and changed the lapacke.defs file accordingly, it all compiled correctly.

Summarizing, these are the commands I had to execute on my Mac in order to get Koma building:

$ brew install lapack
$ brew install openblas

Then change cblas.def and lapacke.def with the locations provided by the brew install commands. Also removed -L/usr/lib in order to make sure it didn't pick anything up from that directory.

Then, executed the build: gradle clean compileKonanKoma -Ptarget=native

kyonifer commented 6 years ago

Glad to hear it. Would you mind listing here (or making a PR containing) the default paths homebrew installs the libs and headers into? Perhaps to make the process easier for people in the future if they are building against homebrew blas/lapacke.

quenio commented 6 years ago

Created PR #63 but I'm not sure these changes would work on Linux.

Probably requires some changes like the following to the build.gradle file:

cinterop('cblas') {
            target('linux') {
                includeDirs.headerFilterOnly '/linux/path/...'
            }

            target('macbook') {
                includeDirs.headerFilterOnly '/macos/path/...'
            }
        }
kyonifer commented 6 years ago

Closed in #63. Native is building successfully in CI on both mac and linux now, so hopefully it also works for you.