Compiling simple Fortran program using fpm and local lapack and blas

I am using fpm and locally installed Lapack and Blas libraries to test the Ax=b for a simple case (without fpm the example works perfectly): here is the example

program main
  use example1, only: say_hello  ! calling module example1.f90 from src
  implicit none
    external :: sgesv
    real     :: amat(2, 2)  
    real     :: bvec(2)     
    real     :: pivot(2) 
    integer  :: rcval ,i, j

    amat = reshape([ 2., 3., 2., 2. ], [ 2, 2 ])
    bvec = [ 3., 6. ]

    print*, 'Amat: '
    do j = 1,2
        print*, (amat(i,j),i=1,2)
    enddo


    call sgesv(2, 1, amat, 2, pivot, bvec, 2, rcval)

    if (rcval /= 0) then
        print '(a, i0)', 'Error: ', rcval
        stop
    end if

    print*, "bvec: ", bvec
    print '("solution: x vect  ", f0.6, ", ", f0.6)', bvec
    
    call say_hello()

!
!  using gFortran for this test_example.f90 work fine
! gfortran -L/usr/loca/lib -o example.x example.f90 -llapack -lblas  && ./example.x
!!  Amat: 
!    2.00000000       3.00000000    
!    2.00000000       2.00000000    
!  bvec:    3.00000000      -1.50000012    
! solution: x vect  3.000000, -1.500000
!
end program main

With fpm, I am getting the following error:

fpm build --flag "-L/usr/loca/lib -lblas -llapack"
example1                               failed.
[100%] Compiling...
/usr/bin/ld: build/gfortran_76E40220992853F5/example1/app_main.f90.o: in function `MAIN__':
main.f90:(.text+0x199): undefined reference to `sgesv_'
collect2: error: ld returned 1 exit status
<ERROR> Compilation failed for object " example1 "
<ERROR>stopping due to failed compilation
STOP 1

Any suggestion will be very helpful.

[build]
link = ["blas", "lapack"]

add link in fpm.toml maybe useful

3 Likes

Yes, but I never understood why passing the link flags manually is not sufficient (I’m not aware how fpm passes them to gfortran, or other compilers). Then of course a compiler independent way through the toml is the right and polished way to go.

Apart from the other issues that have been talked about, please check the spelling of the path to the libraries: “/usr/loca/lib” should probably be “/usr/local/lib”, unless you actually have a directory called /usr/loca/lib.

part of fpm.toml:

[build]
link=["blas", "lapack"]

does the job.

Passing
--flag "-L/usr/local/lib -lblas -llapack" does not work. Simply use “fpm build”.

--flag is for compiling and --link-flag is for linking, you can try this:

fpm build --link-flag '-lblas -llapack'

Sorry, I misunderstood :\

In general you should be careful about the order of the linked libraries. The typical linker will attempt to satisfy the dependencies moving from left to right. In that case the correct order would be -llapack -lblas, since LAPACK builds on top of BLAS.

Depending on your LAPACK installation (i.e. whether you have a shared or static library) it could happen the dependencies are embedded/chained automatically. For example ion my Mac, I was able to compile your example with gfortran main.f90 -llapack. By adding -v to to produce verbose output, I was able to infer that I was calling the LAPACK library included in the system-installed Apple Accelerate framework.

Using the the programs otool and dyld_info I could pinpoint the exact dynamic libraries being used:

$ gfortran -o main call_sgesv.f90 -llapack
$ otool -L main
main:
	/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/local/opt/gcc/lib/gcc/current/libgfortran.5.dylib (compatibility version 6.0.0, current version 6.0.0)
	/usr/local/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib (compatibility version 1.0.0, current version 1.1.0)
	/usr/local/opt/gcc/lib/gcc/current/libquadmath.0.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
$ dyld_info -dependents /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib
/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib [x86_64h]:
    -dependents:
        attributes     load path
                       /usr/lib/libc++.1.dylib
                       /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
                       /usr/lib/libSystem.B.dylib
1 Like