Include new fortran90 module into existing huge fortran90 model - makefile

I am a beginner of fortran90. What I want to do is to call a new module (also fortran90) from an existing huge model which was written by fortran90. What I knew is that running fortran scripts highly depends on the compilation by gfortran using make or cmake. And make&cmake will compile the Makefile&CMakefile. I checked that, this huge model uses commands make with a large Makefile. The new module I wanted to use contains several .f90 files. So it's impossible to just simply write this module into one existing .f90 file of the model...And one thing is that, I just want to use this new module in ONE subroutine in the existing fortran90 model.
For the new module, it's downloaded from GitHub and the compilation was done by cmake. Firstly I need to run a bash file !sh build_steps.sh (the ! is used for running bash commands in python terminal). And the !sh build_steps.sh simply follows:
rm -rf build
mkdir build
cd build
FC=gfortran cmake .. -DSERIAL=1
# FC='mpif90 -qopenmp' cmake .. -DSERIAL=1
make
cd CMakeFiles/neural.dir/
mv mod_activation.mod.stamp mod_activation.o
mv mod_io.mod.stamp mod_io.o
mv mod_kinds.mod.stamp mod_kinds.o
mv mod_layer.mod.stamp mod_layer.o
mv mod_mnist.mod.stamp mod_mnist.o
mv mod_network.mod.stamp mod_network.o
mv mod_parallel.mod.stamp mod_parallel.o
mv mod_random.mod.stamp mod_random.o
mv mod_ensemble.mod.stamp mod_ensemble.o
mv mod_dense_layer.mod.stamp mod_dense_layer.o
mv mod_batchnorm_layer.mod.stamp mod_batchnorm_layer.o
mv mod_dropout_layer.mod.stamp mod_dropout_layer.o
Then the CMakelists.txt follows:
# cmake version, project name, language
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(neural-fortran Fortran)
# set output paths for modules, archives, and executables
set(CMAKE_Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/include)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# if build type not specified, default to release
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "release")
endif()
# handle integer size
if(INT)
message(STATUS "Configuring build for ${INT}-bit integers")
add_definitions(-DINT${INT})
else()
message(STATUS "Configuring build for 32-bit integers")
add_definitions(-DINT32)
endif()
# handle real size
if(REAL)
message(STATUS "Configuring build for ${REAL}-bit reals")
add_definitions(-DREAL${REAL})
else()
message(STATUS "Configuring build for 32-bit reals")
add_definitions(-DREAL32)
endif()
if(SERIAL)
message(STATUS "Configuring build for serial execution")
else()
message(STATUS "Configuring build for parallel execution")
add_definitions(-DCAF)
endif()
# compiler flags for gfortran
if(CMAKE_Fortran_COMPILER_ID MATCHES GNU)
if(SERIAL)
message(STATUS "Configuring to build with -fcoarray=single")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fcoarray=single")
endif()
if(BLAS)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fexternal-blas ${BLAS}")
set(LIBS "${LIBS} blas")
message(STATUS "Configuring build to use BLAS from ${BLAS}")
endif()
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -cpp -fopenmp")
set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -C -fbacktrace")
set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -ffast-math")
endif()
# compiler flags for ifort
if(CMAKE_Fortran_COMPILER_ID MATCHES Intel)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpp -assume byterecl,realloc_lhs -heap-arrays -qopenmp")
set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -C -traceback")
set(CMAKE_Fortran_FLAGS_RELEASE "-O3")
if(NOT SERIAL)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -coarray=shared")
endif()
endif()
# compiler flags for Cray ftn
if(CMAKE_Fortran_COMPILER_ID MATCHES Cray)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -h noomp")
set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g")
set(CMAKE_Fortran_FLAGS_RELEASE "-O3")
endif()
# library to archive (libneural.a)
add_library(neural src/lib/mod_activation.F90 src/lib/mod_io.F90 src/lib/mod_kinds.F90 src/lib/mod_layer.F90 src/lib/mod_dense_layer.F90 src/lib/mod_dropout_layer.F90 src/lib/mod_batchnorm_layer.F90 src/lib/mod_mnist.F90 src/lib/mod_network.F90 src/lib/mod_ensemble.F90 src/lib/mod_parallel.F90 src/lib/mod_random.F90)
# Remove leading or trailing whitespace
string(REGEX REPLACE "^ | $" "" LIBS "${LIBS}")
# tests
enable_testing()
# mnist network_save network_sync set_activation_function
foreach(execid keras bulk ensembles training save_and_load keras_mymodel)
add_executable(test_${execid} src/tests/test_${execid}.F90)
target_link_libraries(test_${execid} neural ${LIBS})
add_test(test_${execid} bin/test_${execid})
endforeach()
# foreach(execid mnist save_and_load simple sine)
# add_executable(example_${execid} src/tests/example_${execid}.F90)
# target_link_libraries(example_${execid} neural ${LIBS})
# add_test(example_${execid} bin/example_${execid})
# endforeach()
The Makefile is too long, so I keep it in a google doc https://docs.google.com/document/d/10naj1WgE9P4qbILT3n85TosZCd1KISwSzGw2u5FIOwo/edit?usp=sharing. (this model is open-source...)
I knew something about bash, but nothing about Make and Cmake. So I just want to know, is there a simple way to combine this two makefiles? how can I declare the subroutine dependency in the existing makefile? or just simply import the new module in the existing fortran 90 subroutine like import numpy in python. Or do I need to change the dependency one by one?
Thanks a lot!

Related

How to generate a *.so file on AIX with CMake

With gcc the newer CMake V3.14 build a shared library in an archive format with ".a" suffix on AIX platform. But we need a *.so shared file. One solution what I have found is to patch /opt/freeware/share/cmake-3.14/Modules/Platform/AIX-GNU.cmake by adding the line "cp <OBJECT_DIR>/lib<TARGET_NAME>.so <TARGET_BASE>.so".
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# This module is shared by multiple languages; use include blocker.
if(__AIX_COMPILER_GNU)
return()
endif()
set(__AIX_COMPILER_GNU 1)
macro(__aix_compiler_gnu lang)
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-bnoipath -Wl,-blibpath:")
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
set(CMAKE_SHARED_MODULE_${lang}_FLAGS ${CMAKE_SHARED_LIBRARY_${lang}_FLAGS})
set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS})
set(CMAKE_${lang}_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH 1)
if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 7 OR CMAKE_SYSTEM_VERSION VERSION_LESS 7.1)
unset(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY)
endif()
# By default, module are .so and shared libraries .a in AIX.
# As this comportment can be overwritten or misrespected we provides both .a and stripped .so.
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <OBJECT_DIR>/lib<TARGET_NAME>.so <OBJECTS> <LINK_LIBRARIES>"
"<CMAKE_AR> -c -q <TARGET> <OBJECT_DIR>/lib<TARGET_NAME>.so"
"cp <OBJECT_DIR>/lib<TARGET_NAME>.so <TARGET_BASE>.so" # <-- Patched line
"rm <OBJECT_DIR>/lib<TARGET_NAME>.so"
)
set(CMAKE_${lang}_CREATE_SHARED_MODULE
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_MODULE_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
"strip -e -X32_64 <TARGET>"
)
endmacro()
Is there another possibility to switch on the *.so file generation?

How to add the -nodefaultlibs options to an add_executable() command?

I have the CMakeLists.txt for building tests using g++:
file(GLOB sources *.cpp)
foreach(src ${sources})
get_filename_component(src ${src} NAME_WE)
string(REPLACE "our_prefix" "" bin ${src})
add_executable(${bin} ${src})
target_link_libraries(${bin} our options go here)
endforeach()
What I need to do is to add the option -nodefaultlibs to each test. I've tried to do it like this:
file(GLOB sources *.cpp)
foreach(src ${sources})
get_filename_component(src ${src} NAME_WE)
string(REPLACE "our_prefix" "" bin ${src})
add_executable(${bin} ${src})
set_target_properties(${bin} PROPERTIES
INTERFACE_COMPILE_OPTIONS "-nodefaultlibs"
)
target_link_libraries(${bin} our options go here)
endforeach()
But it seems to have no effect. I've also tried to use the command target_compile_options instead of set_target_properties - and it also had no effect.
Cmake generates the link.txt file for each test - I suppose this file describes the building command used for the test. This file doesn't contain my option -nodefaultlibs.
Could you please explain me what is the right way to add the -nodefaultlibs option?
-nodefaultlibs is a linker flag so use set_target_properties(${bin} PROPERTIES LINK_OPTIONS -nodefaultlibs) or target_link_libraries(${bin} PRIVATE -nodefaultlibs) or for CMake 3.2 set_target_properties(${bin} PROPERTIES LINK_FLAGS -nodefaultlibs).
INTERFACE_COMPILE_OPTIONS is used for something else and target_compile_options won't show up on the link line.
The link.txt file isn't always generated. When using MSYS Makefiles the linker flags show up in linklibs.rsp.

How do I evaluate a command in CMakeLists.txt on Windows?

I want to set some variables in CMakeLists.txt, like CMAKE_CXX__FLAGS.
Unfortunately, I don't want to copy paste from terminal into set().
Instead, I want to evaluate commands in CMakeLists.txt and set variables to their output.
An example is the following attempt:
set(x ${llvm-config --libs core})
message("${x}")
I want to bind the output of llvm-config --libs core to x. But evaluating this CMakeLists.txt results in output: ${llvm-config;--libs;core}.
What is the proper way to evaluate commands in CMakeLists.txt?
The current platform is Windows 10.
Your problem is that Cmake cannot locate llvm-config. To fix this, one must point Cmake to the location of the program.
You will need to write a CMakeLists.txt like:
cmake_minimum_required(VERSION 3.7)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
execute_process(COMMAND llvm-config --libs core WORKING_DIRECTORY ${LLVM_TOOLS_BINARY_DIR} OUTPUT_VARIABLE x)
message(${x})
The find_package(LLVM REQUIRED CONFIG) makes LLVM specific Cmake variables available.
To use llvm-config it is necessary to set the working directory to${LLVM_TOOLS_BINARY_DIR}.
I think you are looking for the execute_process function.
In your case :
execute_process(COMMAND llvm-config --libs core OUTPUT_VARIABLE x)
message(${x})
execute_process have a lot of useful options, take a look at the doc.

How to stop CMake appending C compiler flags

I converted an old style makefile to a CMake CMakeLists.txt file so that I can load a project into JetBrain's new CLion IDE.
I thought it would be easy, but I'm stuck at the point of CMake appending some custom compiler flags to the compilation command which cause a compilation error. I don't have enough knowledge of CMake to solve this issue.
Here is the original makefile.
# makefile
# Main Filename to be compiled
MAINFILE = TestProgram
# Paths
DRIVE := C:
COMPILERROOT := $(DRIVE)/GNUHC11
COMPILERPATH := $(COMPILERROOT)/bin
GELROOT := $(DRIVE)/library/gel-hc1x-1.6.1
GELINCLUDESDIR := $(GELROOT)/include
# Compiler, Linker, Object Copy, and Object Dump path
CC := $(COMPILERPATH)/m6811-elf-gcc # compiler
OC := $(COMPILERPATH)/m6811-elf-objcopy # object copy
OD := $(COMPILERPATH)/m6811-elf-objdump # object dump
# Includes
GELINCLUDES += -I$(GELINCLUDESDIR) -I$(GELINCLUDESDIR)/asm-m68hc11/arch-32k
# Compiler Flags
CFLAGS += -Os # turn on optimizer
CFLAGS += -mshort # consider type int to be 16 bits
CFLAGS += -Wl,-m,m68hc11elfb # build for elf file and use memory.x for memory map
CFLAGS += -I. $(GELINCLUDES) # Add current dir and gel library for includes
CFLAGS += -Dmc6811 # Add define to define the processor architecture for gel includes
# C Source codes to be compiled
SRC1 = $(MAINFILE).c
SRC2 = Interrupts.c
SRC3 = Utilities.c
# C Header files dependencies
HDR1 = $(MAINFILE).h
HDR2 = Interrupts.h
HDR3 = Utilities.h
SRCS = $(SRC1) $(SRC2) $(SRC3)
HDRS = $(HDR1) $(HDR2) $(HDR3)
# Elf file to be generated
ELF1 = $(SRC1:.c=.elf)
# Generate Bin file for programming & Assembly dump
$(MAINFILE).bin : $(ELF1)
$(OC) -O binary $(ELF1) $(MAINFILE).bin
$(OD) -xDC --section=.text --section=.vectors $(ELF1) >$(MAINFILE).dump
# Full compile and link
$(ELF1) : $(SRCS) $(HDRS)
$(CC) $(CFLAGS) -o $(ELF1) $(SRCS)
clean ::
del *.dump
del *.elf
del *.bin
And here is my attempt at the CMakeLists.txt file.
cmake_minimum_required(VERSION 2.8.4)
# program names
set(HC11C m6811-elf-gcc.exe)
set(OBJCOPY m6811-elf-objcopy.exe)
set(OBJDUMP m6811-elf-objdump.exe)
# Important project paths
set(LIB_INC_PATH "C:/library/gel-hc1x-1.6.1/include"
"C:/library/gel-hc1x-1.6.1/include/asm-m68hc11/arch-32k")
set(HC11C_PATH "C:/GNUHC11/bin")
# Sets the compiler
# Needs to come before the project function
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER "${HC11C_PATH}/${HC11C}")
set(MAIN_FILE "TestProgram")
project(${MAIN_FILE})
# Files to be compiled
set(BASE_PATH "${${PROJECT_NAME}_SOURCE_DIR}")
set(INC_PATH "${BASE_PATH}")
set(SRC_PATH "${BASE_PATH}")
set(SRC_FILES "${SRC_PATH}/${MAIN_FILE}.c"
"${SRC_PATH}/Interrupts.c"
"${SRC_PATH}/Utilities.c")
# Attempt to clear the other spurious compiler flags that I don't want,
# and which cause a compiler arguments error.
# This doesn't seem to work - the defaults still appear.
set(CMAKE_C_FLAGS_DEBUG "")
set(CMAKE_C_FLAGS_RELEASE "")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "")
set(CMAKE_C_FLAGS_MINSIZEREL "")
# Compiler flags
set(CWARN "-Wl,-m,m68hc11elfb") # build for elf file and use memory.x for memory map
set(CTUNING "-mshort") # consider type int to be 16 bits
set(COPT "-Os") # turn on optimizer
set(CDEFS "-Dmc6811") # Add define to define the processor architecture for gel includes
set(CFILES "${MAIN_FILE}.c Interrupts.c Utilities.c")
set(CFLAGS "${CDEFS} ${COPT} ${CWARN} ${CTUNING} ${CFILES}")
set(CMAKE_C_FLAGS "${CFLAGS}")
# Project setup
include_directories(${INC_PATH} ${LIB_INC_PATH})
add_executable(${MAIN_FILE} ${SRC_FILES})
set_target_properties(${MAIN_FILE} PROPERTIES OUTPUT_NAME "${MAIN_FILE}.elf")
# Compiling targets
add_custom_target(main ALL ${OBJCOPY} -O binary "${MAIN_FILE}.elf" "${MAIN_FILE}.bin" DEPENDS ${MAIN_FILE})
add_custom_target(dump ALL ${OBJDUMP} -xDC --section=.text --section=.vectors "${MAIN_FILE}.elf" > "${MAIN_FILE}.dump" DEPENDS main)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${MAIN_FILE}.dump;${MAIN_FILE}.elf;${MAIN_FILE}.bin")
# Config logging
message("* ")
message("* Project Name:\t${PROJECT_NAME}")
message("* Project Source:\t${SRC_PATH}")
message("* Project Include:\t${INC_PATH}")
message("* Library Include:\t${LIB_INC_PATH}")
message("* ")
message("* Project Source Files:\t${SRC_FILES}")
message("* MAIN_FILE variable:\t${MAIN_FILE}")
message("* ")
message("* C Flags:\t${CMAKE_C_FLAGS}")
message("* ")
Here is the generated compilation command:
C:\GNUHC11\bin\m6811-elf-gcc.exe "-xc" "-Dmc6811" "-Os" "-Wl,-m,m68hc11elfb" "-mshort" "TestProgram.c" "Interrupts.c" "Utilities.c" "-IC:\\DEVELO~1\\source" "-IC:\\library\\gel-hc1x-1.6.1\\include" "-IC:\\library\\gel-hc1x-1.6.1\\include\\asm-m68hc11\\arch-32k" "-v" "-dD" "-E" "-D___CIDR_IGNORE_DEFINITIONS_START"
It would work but for the auto appended "-E" compiler flag at the end which I don't want. The other appended flags "-v" "-dD" and '-D___CIDR..." are also unwanted but do not cause a compilation error like "-E" does. How can I turn these appended flags off?
Thanks in advance for any help.
It seems you are cross-compiling, so the preferred cmake configuration is a bit different than normal.
See http://www.vtk.org/Wiki/CMake_Cross_Compiling for details, pay attention to the "toolchain file".
I have no idea regarding the auto-appended flags.
You can also have a look at the generated CMakeCache.txt file, either with any editor, from CLion itself, or with cmake-gui.
Remember that CLion copies your CMakeLists.txt in a funky temporary directory and runs cmake off the temporary directory, if you want to look at CMakeCache.txt by hand.
What I suggest is to put aside CLion while you are debugging the CMakeLists.txt, and just use cmake or cmake-gui directly from the shell.
Don't give up, both cmake and CLion are two very good programs IMHO :-)
There doesn't seem to be too much information on this one, but I also ran into this issue. In cmake if you do something like
target_compile_options(game PRIVATE /W4 /WX /wd4100 /wd4200 /wd4201 /FAs /EHsc /Gh /GH)
this will add those options for all compilers in that target.
You can use a generator if you want to add language specific options, so I changed it to:
target_compile_options(game PRIVATE
$<$<COMPILE_LANGUAGE:C>:/W4 /WX /wd4100 /wd4200 /wd4201 /FAs /EHsc /Gh /GH>)
which works.

how to compile lapack so that it can be used correctly during installation of octave?

I'm trying to install the latest octave 3.8.1 from source in a cluster running redhat+IBM LSF. I don't have write access to anywhere else except my own home dir, that's why I have to install octave from source. The blas and lapack provided by the cluster does not work so I have to build them by myself. I have now finished compiling both blas and lapack and passed the ./configure, but when I run make, an error is reported as follows:
These are steps I used to build my own BLAS and LAPACK. The source of BLAS is in ~/src/BLAS while the source of LAPACK is in ~/src/lapack-3.5.0 and the source of octave 3.8.1 is in ~/src/octave-3.8.1.
With only two module, 1) pcre/8.33 2) acml/5.3.1/gfortran64, loaded, I compiled BLAS shared library using
gfortran -shared -O2 *.f -o libblas.so -fPIC
and static library using
gfortran -O2 -c *.f -fPIC
ar cr libblas.a *.o
Then I copy the shared library libblas.so to ~/src/octave-3.8.1. The contents of make.inc file in lapack's dir is:
####################################################################
# LAPACK make include file. #
# LAPACK, Version 3.5.0 #
# November 2013 #
####################################################################
#
SHELL = /bin/sh
#
# Modify the FORTRAN and OPTS definitions to refer to the
# compiler and desired compiler options for your machine. NOOPT
# refers to the compiler options desired when NO OPTIMIZATION is
# selected. Define LOADER and LOADOPTS to refer to the loader and
# desired load options for your machine.
#
FORTRAN = gfortran
OPTS = -shared -O2 -fPIC
DRVOPTS = $(OPTS)
NOOPT = -O0 -frecursive
LOADER = gfortran
LOADOPTS =
#
# Timer for the SECOND and DSECND routines
#
# Default : SECOND and DSECND will use a call to the EXTERNAL FUNCTION ETIME
#TIMER = EXT_ETIME
# For RS6K : SECOND and DSECND will use a call to the EXTERNAL FUNCTION ETIME_
# TIMER = EXT_ETIME_
# For gfortran compiler: SECOND and DSECND will use a call to the INTERNAL FUNCTION ETIME
TIMER = INT_ETIME
# If your Fortran compiler does not provide etime (like Nag Fortran Compiler, etc...)
# SECOND and DSECND will use a call to the INTERNAL FUNCTION CPU_TIME
# TIMER = INT_CPU_TIME
# If neither of this works...you can use the NONE value... In that case, SECOND and DSECND will always return 0
# TIMER = NONE
#
# Configuration LAPACKE: Native C interface to LAPACK
# To generate LAPACKE library: type 'make lapackelib'
# Configuration file: turned off (default)
# Complex types: C99 (default)
# Name pattern: mixed case (default)
# (64-bit) Data model: LP64 (default)
#
# CC is the C compiler, normally invoked with options CFLAGS.
#
CC = gcc
CFLAGS = -O3
#
# The archiver and the flag(s) to use when building archive (library)
# If you system has no ranlib, set RANLIB = echo.
#
ARCH = ar
ARCHFLAGS= cr
RANLIB = ranlib
#
# Location of the extended-precision BLAS (XBLAS) Fortran library
# used for building and testing extended-precision routines. The
# relevant routines will be compiled and XBLAS will be linked only if
# USEXBLAS is defined.
#
# USEXBLAS = Yes
XBLASLIB =
# XBLASLIB = -lxblas
#
# The location of the libraries to which you will link. (The
# machine-specific, optimized BLAS library should be used whenever
# possible.)
#
#BLASLIB = ../../librefblas.a
BLASLIB = ~/src/BLAS/libblas.a
LAPACKLIB = liblapack.a
TMGLIB = libtmglib.a
LAPACKELIB = liblapacke.a
Then I type make to compile LAPACK. After compilation, I copied the output liblapack.a to ~/src/octave-3.8.1.
The ./configure command line is:
./configure --prefix=$HOME/bin/octave --with-blas=./libblas.so --with-lapack=$HOME/src/octave-3.8.1/liblapack.a --disable-readline --enable-64
I can pass the ./configure. Then I type make to try to build octave 3.8.1 and I got the above error.
From the make.inc file it can be seen that I have followed the suggestion of the compiler "recompile with -fPIC" and modified the make.inc accordingly. I also add -shared switch in the OPTS variable. In addition, I have tried using old LAPACK version but not working. I really have no idea why the error still comes out. So I wonder if you could please tell me how to compile the LAPACK library so that it can be correctly used during installation of octave 3.8.1. The following two points may be worth considering. (1) should I compile lapack as a static library or a shared library? (2) should -fPIC switch be applied to lapack compilation or octave's make? If the latter, how to apply -fPIC to make? You don't have to get restricted to the above two points since there may be other reasons for the error. Any advice to solve this problem is welcomed. If you need any other information please tell me. Thank you.
Just compiled the lapack shared lib on my boss's beast... Here's a link which almost did it right.
I made some changes:
(1) Adding -fPIC to
OPTS & NOOPT in make.inc
(2) Change the names in make.inc to .so
BLASLIB = ../../libblas.so
LAPACKLIB = ../liblapack.so
(3) In ./SRC, change the Makefile from
../$(LAPACKLIB): $(ALLOBJ)
$(ARCH) $(ARCHFLAGS) $# $(ALLOBJ)
$(RANLIB) $#
to
../$(LAPACKLIB): $(ALLOBJ)
$(LOADER) $(LOADOPTS) -shared -Wl,-soname,liblapack.so -o $# $(ALLOBJ) ../libblas.so
Cuz lapack is calling blas, if you miss the very last part, your liblapack.so will fail! You need to LINK liblapack.so against libblas.so ( libatlas.so is also OK). You can use "ldd liblapack.so" to check its dependency. If you see libblas.so in there, pretty much you did it right.
(4) In ./BLAS/SRC, change the Makefile from
$(BLASLIB): $(ALLOBJ)
$(ARCH) $(ARCHFLAGS) $# $(ALLOBJ)
$(RANLIB) $#
to
$(BLASLIB): $(ALLOBJ)
$(LOADER) $(LOADOPTS) -z muldefs -shared -Wl,-soname,libblas.so -o $# $(ALLOBJ)
(5) I don't need libtmg.so so that I didn't change it...
Run
make blaslib
Then
make lapacklib
You will have both of them compiled. I check the liblapack.so with building a numpy on it and Python ctypes.cdll loading. All work for me to solve eigenvalues and eigenvectors... So it should be fine...
(6) YOU MAY NEED TO SET UP LD_LIBRARY_PATH to where you keep your library files.
google it... If not set by admin, then
export LD_LIBRARY_PATH=path-to-lib
If already set, then
export LD_LIBRARY_PATH=path-to-lib:$LD_LIBRARY_PATH
to overwrite your default libs.
So that you won't have ld linking errors. Good luck!!
In lapack-3.7.0, there are redundant lines in the SRC/Makefile. Simply deleting them will solve your error.
I would suggest using OpenBLAS.
> git clone https://github.com/xianyi/OpenBLAS.git
> make
> make make --PREFIX=INSTALL_DIR install
move the librabries from OpenBLAS to /usr/lib64
> cp /path/to/OpenBLAS/lib/* /usr/lib64/
then go to the octave installation path and run
> "your specific flags" ./configure "your specific arguments" --with-blas="-lopenblas"

Resources