1
votes

I am trying to create a program which will be pretty heavily dependant on BLAS. I have never made an executable that is dependant on static libraries before though. So far I understand that I need to make the BLAS static library using the following:

gfortran -O2 -c *.f
ar cr libblas.a *.o

Apparently after this you can link programs with BLAS using -lblas on command-line.

My make file looks like the following and has just basically been copied from online:

# ======================================================================
# Declarations
# ======================================================================

# The compiler
FCOMP = gfortran

# flags for debugging or for maximum performance, comment as necessary
FCFLAGS = -g -O2

# libraries needed for linking 
LDFLAGS = -lblas

# List of executables to be built within the package
PROGRAM = prog_name_here 

# List of subroutines to be built within the package
OBJECTS = foo1.f08 foo2.f08 foo3.f08 ....

# "make" builds all
all: $(PROGRAM)


# ======================================================================
# General Rules
# ======================================================================

# General rule for building prog from prog.o; $^ (GNU extension) is
# used in order to list additional object files on which the
# executable depends

%: %.o
    $(FCOMP) $(FCFLAGS) -o $@ $^ $(LDFLAGS)

# General rules for building prog.o from prog.f90 or prog.F90; $< is
# used in order to list only the first prerequisite (the source file)
# and not the additional prerequisites such as module or include files

%.o: %.f08
    $(FCOMP) $(FCFLAGS) -c $<

%.o: %.F08
    $(FCOMP) $(FCFLAGS) -c $<

%.o: %.f90
    $(FCOMP) $(FCFLAGS) -c $<

%.o: %.F90
    $(FCOMP) $(FCFLAGS) -c $<

# Utility targets
.PHONY: clean veryclean

clean:
    rm -f *.o *.mod *.MOD

veryclean: clean
    rm -f *~ $(PROGRAMS)

I am clearly linking the libraries incorrectly as I get the error:

gfortran -g -O2 -c Consistency_Check.f08
gfortran -g -O2 -o Consistency_Check Consistency_Check.o -lblas
Undefined symbols for architecture x86_64:
  "_direct_find_", referenced from:
      _MAIN__ in Consistency_Check.o
  "_kernel_correction_", referenced from:
      _MAIN__ in Consistency_Check.o
  "_output_", referenced from:
      _MAIN__ in Consistency_Check.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [Consistency_Check] Error 1
rm Consistency_Check.o

Could someone highlight how to correctly link static libraries?

** EDIT 1 ** I have placed libblas.a in the same directory as the .f08 / makefile on the off chance that this is a relevant point

** EDIT 2 ** I noticed that removing libblas.a from the working directory makes no difference. I get the same error. I don't think it is being called / used by the makefile.

2
Are _direct_find_, _kernel_correction_, etc. symbols from BLAS? - Etan Reisner
Those are subroutines in the program Consistency_Check - 1QuickQuestion
If those are symbols in Consistency_Check then have to first look into why those symbols are not available after you compile Consistency_Check.f08. - deepak
As deepak said if those are your symbols then you need to figure out why they are missing from your build. Can you see them in Consistency_Check.o? - Etan Reisner

2 Answers

2
votes

As others have said, the link errors you are seeing not related to libblas but to your own code.

I doubt that your makefile looks like the one you have posted as that one defines no rule for making $(PROGRAM) at all, so it would not even get as far as linkage errors.

Try one like this:

FCOMP = gfortran
FCFLAGS = -g -O2
LDFLAGS = -lblas
PROGRAM =  prog_name_here 
SRCS = foo1.f08 foo2.f08 foo3.f08 ...
OBJECTS = $(SRCS:.f08=.o)

all: $(PROGRAM)

$(PROGRAM): $(OBJECTS)
    $(FCOMP) $(FCFLAGS) -o $@ $^ $(LDFLAGS)

%.o: %.f08
    $(FCOMP) $(FCFLAGS) -c $<

.PHONY: clean veryclean

clean:
    rm -f *.o *.mod *.MOD

veryclean: clean
    rm -f *~ $(PROGRAM)

(Take care to correct the typo $(PROGRAMS) to $(PROGRAM) in the veryclean rule).

As for linking libblas as a static library it is unclear where or why you are doing that, as a) your makefile does not build it and b) your linux distribution will almost certainly provide it as a shared library package that you could install. However, if you want to build it and link it statically then (having done so), your makefile must tell the linker what directory to search for libblas.a using the L linker option. So change your LDFLAGS to:

LDFLAGS = -L/path/to/your/liblas/build -lblas

If you build libblas.a in the directory where you run your make then:

LDFLAGS = -L. -lblas
2
votes

You have to run ranlib on the blas archive (library) first before you can use it.

gfortran -O2 -c *.f
ar cr libblas.a *.o
ranlib libblas.a

Useful link: https://superuser.com/questions/404603/what-is-ranlib