I am having an issue with the LAPACK/BLAS libraries when compiling a C code that needs them.
The issues are, when I run "make", I get:
file.c:(.text+0x1c41): undefined reference to `zgesvd_'
file.c:(.text+0x1c9c): undefined reference to `zgetrf_'
../file.a(SpatialOrientation.o): In function `myfunction.c':myfunction.c:(.text+0x7be): undefined reference to `dsyev_'
And several other such lines, all referring to similar missing references.
I have chased this error down to being something to do with BLAS. I followed the directions given at this excellent link for installing BLAS and put the relevant directory on the path. I also changed my Makefile accordingly to find these libraries.
Any help on this issue would be really appreciated!
Just to update, I recently installed itpp as well, also following the instructional here, since it seemed my missing references were linked to that. No changes so far...
Thanks for your help!
The problem is solved! Hooray! I just danced around my office...
For those who have the same problem, here is what I did:
1) Follow the instructions given here to make the lapack and blas libraries. To paraphrase, for a scientific Linux 6 machine, they are:
wget http://www.netlib.org/lapack/lapack.tgz
tar xvzf lapack.tgz
cd lapack-3.3.0 //if version number changes, change here to the right directory
mv make.inc.example make.inc
2) Then (important bit, also recommended here):
edit make.inc and add -m64 -fPIC flag to fortran compiler options: FORTRAN, OPTS, NOOPT, LOADER
Then
make blaslib
make
Now, what you have is, in /lapack-3.6.1 (or whatever your directory is called after this process), two files:
librefblas.a , and liblapack.a.
3) The next thing I did was to copy librefblas.a and liblapack.a into some subdirectories - i.e. /lib/liblapack for liblapack.a and /lib/libblas for librefblas.a
4) Then, put those directories in your makefile, like this:
LIBDIR1 = /path/lib/lapack
LIBDIR2 = /path/lib/blas
LIBS = -L$(LIBDIR1) -llapack -L$(LIBDIR2) -lblas $(SYSLIBS)
LIBSMPI = -L$(LIBDIR1) -llapack -L$(LIBDIR2) -lblas $(MPILIBS) $(SYSLIBS)
I also added /path/lib/lapack and /path/lib/blas onto my LD_LIBRARY_PATH (and PATH, just-in-case...)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/lib/lapack:/path/lib/blas
export PATH=$PATH:/path/lib/lapack:/path/lib/blas
Then, go to wherever you Makefile is, and type
make
Yay yay yay!
By the way, with the latest version of lapack and blas, obtained in step 1), I compiled with gcc version 5.1.0 and the corresponding mpicc (openmpi 1.10.2).
Hope this helps someone else and shares the absolute delight.
Related
I'm still fairly new to CMAKE, but I'm using find_package(Protobuf Requried) to compile my .proto files as part of the build, and I'm having trouble getting imports to work, and I'm well and truly stumped.
I have 2 .proto files in the same direcotry, "protobuf" named "A.proto" and "B.proto"
Without an import, they compile fine.
If I change A.proto to have an import to B:
syntax = "proto3";
import "B.proto";
message MyMessage
{}
With a CMakeLists.txt file that sets the Protobuf_IMPORT_DIRS variable correctly (I think):
find_package(Protobuf REQUIRED)
set(Protobuf_IMPORT_DIRS ${Protobuf_IMPORT_DIRS} ${CMAKE_SOURCE_DIR}/protobuf)
...
protobuf_generate(TARGET ${MY_PROJECT_NAME})
I get this on build:
Running cpp protocol buffer compiler on protobuf/A.proto
B.proto: File not found.
protobuf/A.proto:3:1: Import "B.proto" was not found or had errors.
Any help would be much appreciated, as I feel like i'm taking crazy pills! :)
So i found the answer, although it took some hacking. Bascially I just read all the CMAKE files associated with Protobuf until I figured it out. There's probably better docs out there but I couldn't find.
Short Story:
if you call PROTOBUF_GENERATE_CPP, it respects setting a Protobuf_IMPORT_DIRS variable.
However if you directly call the protobuf_generate for a target as I do, the variable is ignored.
The answer is to call protobuf_generate with an argument of IMPORT_DIRS, such as:
protobuf_generate(TARGET ${MY_PROJECT_NAME} IMPORT_DIRS protobuf)
IMPORT_DIRS is a multi argument, you can supply several.
Here's the relevant code:
function(protobuf_generate)
include(CMakeParseArguments)
set(_options APPEND_PATH)
set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN)
if(COMMAND target_sources)
list(APPEND _singleargs TARGET)
endif()
set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS)
cmake_parse_arguments(protobuf_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}")
I hope this will save someone headache in the future!
I am learning CMake with CMake Tutorial and found something which is not clear for me:
include(CheckSymbolExists)
set(CMAKE_REQUIRED_LIBRARIES "m")
So what is the CheckSymbolExists? Is it a function or a lib?
What's meaning of the "m"? Does it mean a lib name or some flag?
I had tried to read through cmake documents, but I just don't understand.
Please somebody help me to understand these.
First, set(CMAKE_REQUIRED_LIBRARIES "m") includes the math library. You do the same on the command-line like this: gcc test.c -lm which includes the library libm.so/.dll
CheckSymbolExists is a CMake Module which provides more functionality. You can include it with include(CheckSymbolExists)
After this you can use the function check_symbol_exists(...) in CMake to check the availability of symbols in header files.
The exact example from the tutorial:
check_symbol_exists(log "math.h" HAVE_LOG) checks if the header file math.h has a symbol (can be a function, constant or whatever) which is called log. If there is one, the CMake Variable HAVE_LOG is set to 1, otherwise set to 0.
The document said, if my understanding is correct, this module will check if a symbol can be correctly linked when it saw a symbol that is not a enum, type or intrinsic.
So in that snippet, when the first runs of check_symbol_exists didn't define the two cache variable, it will check if it had missed an required lib, and retry.
I have managed to build the Kicad 4.0.6 in Linux Mageia 5.1 with gcc version 4.9.2. I first manually fixed two wxWidgets 3.0.2 header files in the /usr/include/wx-3.0/wx/ directory: regex.h and features.h. Kicad then compiled successfully. With the native wx-3.0 headers, the compiler generated the error in pcbnew/netlist_reader.cpp due to the undefined variable wxRE_ADVANCED.
The features.h header checks if the macro WX_NO_REGEX_ADVANCED is defined. If yes, features.h UNdefines wxHAS_REGEX_ADVANCED macro, and defines it, if no. The macro wxHAS_REGEX_ADVANCED, in turn, is used in regex.h to determine if among the enum constants wxRE_ADVANCED = 1 is present. The standard prebuilt Mageia 5 packages wxgtku3.0_0 and lib64wxgtku3.0-devel that I installed with the use of Mageia's software manager urpmi from Mageia repository WX_NO_REGEX_ADVANCED is defined, therefore wxHAS_REGEX_ADVANCED is undefined, and, hence, wxRE_ADVANCED is undefined either. Kicad 4.0.6 source package assumes wxRE_ADVANCED = 1, therefore the build process stops with the error.
Then I reverted /usr/include/wx-3.0/wx/regex.h and features.h to their original state and learned how to add the definition of wxRE_ADVANCED to CMakeLists.txt. However, I still have a question.
The recommended format of adding the definition to CMakeLists.txt I found at CMake command line for C++ #define is this:
if (NOT DEFINED wxRE_ADVANCED)
set(wxRE_ADVANCED 1)
endif()
add_definitions(-DwxRE_ADVANCED=$(wxRE_ADVANCED))
However, it did not work! The macro expansion for wxRE_ADVANCED in pcbnew/netlist_reader.cpp was empty. I printed it at compile time inserting the following lines into the netlist_reader.cpp file (this was hard to find, most of the recommended formats did not work. The correct one is in C preprocessor: expand macro in a #warning):
#define __STRINGIFY(TEXT) #TEXT
#define __WARNING(TEXT) __STRINGIFY(GCC warning TEXT)
#define WARNING(VALUE) __WARNING(__STRINGIFY(wxRE_ADVANCED = VALUE))
Pragma (WARNING(wxRE_ADVANCED))
Finally, I simplified the CMakeLists.txt definition down to this, and it was a success:
if (NOT DEFINED wxRE_ADVANCED)
set(wxRE_ADVANCED 1)
endif()
add_definitions(-DwxRE_ADVANCED=1)
My question: what is the meaning of "-DwxRE_ADVANCED=$(wxRE_ADVANCED)" if it does not work? Is it possible not to use set(wxRE_ADVANCED 1), and simply write add_definitions(-DwxRE_ADVANCED=1)? Thank you.
P.S. Yes, the Kicad 4.0.6 build process successfully finished with only one line added to the top level CMakeLists.txt file:
add_definitions(-DwxRE_ADVANCED=1)
A variable is called via $variable or ${variable}. Note the curly brackets, not parentheses.
Also, it is recommended to use:
target_compile_definitions(mytarget PUBLIC wxRE_ADVANCED=1)
on a target directly, rather than the general add_definitions() command.
When I try to compile nettle-2.7.1, I get the following:
root#tcx2270-19:~/nettle-2.7.1# make
make: Warning: Can't find aes-decrypt-internal.o.d': No such file or directory
make: Fatal error in reader: Makefile, line 594: Read of include fileaes-decrypt-internal.o.d' failed
Has anyone seen this issue? Thanks.
I also had the exact same problem. It has nothing to do with gmp. The ./configure script generates a broken Makefile. After doing some analyzation of the generated Makefile I figured out a solution.
On the very bottom of the generated Makefile search for the line that looks like the following:
DEP_FILES = $(SOURCES:.c=.$(OBJEXT).d) $(SOURCES:.c=.p$(OBJEXT).d) asm.d
You can fix the build by changing it to the following line:
DEP_FILES = $(SOURCES:.c=.c.$(OBJEXT).d) $(SOURCES:.c=.c.p$(OBJEXT).d) asm.d
Additionally, we have to fix the Makefiles in all sub-directories.
For ./tools/Makefile, on the very bottom, find the line that looks like:
include $(SOURCES:.c=.$(OBJEXT).d)
and change it to
include $(SOURCES:.c=.c.$(OBJEXT).d)
Furthermore, you need to add the following two build-targets:
../libnettle.a:
$(MAKE) -C .. libnettle.a
../libhogweed.a:
$(MAKE) -C .. libhogweed.a
For ./testsuite/Makefile, on the very bottom, find the line that looks like this:
DEP_FILES = $(SOURCES:.c=.$(OBJEXT).d) $(CXX_SOURCES:.cxx=.$(OBJEXT).d)
and change it to:
DEP_FILES = $(SOURCES:.c=.c.$(OBJEXT).d) $(CXX_SOURCES:.cxx=.cxx.$(OBJEXT).d)
Finally, in ./examples/Makefile, again on the very bottom, search for the line that looks like:
include $(SOURCES:.c=.$(OBJEXT).d)
and change it to
include $(SOURCES:.c=.c.$(OBJEXT).d)
Phew, at least for me, that makes the build work. Of course, this is an ugly solution but it gets the job done. A better solution would be to fix the configure-script but I did not have the time to do it yet. It is also worth noting that nettle 3.0 does not have this issue. Too bad gnutls does not work with that newer version.
UPDATE: I created a patch which does all the above fixes in the Makefile.in files. As a result, you don't have to fix them yourselfs. Optimally, just unpack the source, apply the patch and proceed the way you normally would by continuing with the ./configure.
Get it from here: http://pastebin.com/36M5LHK3
Note: This is my first time using CMake. I don't know much about it, so I'm just posting a bunch of information to see if anyone can see my problem.
I would like the ability to automatically determine which c++11 flag is appropriate, given my compiler. There are many examples of this line. Here is my CMakeLists.txt following such an example:
cmake_minimum_required (VERSION 2.8)
#Add the c++11 flag, whatever it is
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG(-std=c++0x COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
project(AnalyzeGames)
set(AnalyzeGames_SRCS AnalyzeGames.cpp)
add_executable(AnalyzeGames ${AnalyzeGames_SRCS})
Here is my cmake output when trying to use this file: http://pastebin.com/3AUwqffD
Here is CMakeError.log: http://pastebin.com/EbNKvGt8
Here is CMakeOutput.log: http://pastebin.com/kVJ0enJC
echo $CC: /usr/bin/gcc
echo $CXX: /usr/bin/g++
I can compile a simple test executable with g++ using either flag manually.
cmake --version: cmake version 2.8.12.2
For some reason CMake is not recognizing that my compiler does support both of those flags.
The cmake output tells you that it does not recognize the '.cxx' extension because it doesn't know that your project is a C++ project. To fix this, you should enable C++ in the project command. Try to change the following line:
project(AnalyzeGames)
to:
project(AnalyzeGames CXX)
and then move it to the 2nd line of the CMakeLists.txt, right under cmake_minimum_required. The configuration should work as expected after this.
TLDR
Compiler checks are only performed in the variable passed is not previously defined, which includes in the cache from previous failed attempts. Use unset(my_var CACHE) to force checking to always occur, or just be aware of this behaviour and clear the cache manually when needed.
Detail
I too had this problem (with cmake 2.8.12.2) and I had to turn on trace output, and step through the code to get a similar toy build to work I had make sure the variables I used (COMPILER_SUPPORTS_CXX11_*) in these calls:
CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG(-std=c++0x COMPILER_SUPPORTS_CXX0X)
Were set such that they named themselves:
set(COMPILER_SUPPORTS_CXX11 "COMPILER_SUPPORTS_CXX11")
The other posters solution didn't work for me, it mainly just seemed to limit the detecting of compilers to just CXX and ignored the C compiler.
The issue appears to be with this line of code in the cmake module:
if("${VAR}" MATCHES "^${VAR}$")
Which in the trace output is:
/usr/share/cmake/Modules/CheckCXXSourceCompiles.cmake(30): if(COMPILER_SUPPORTS_CXX0X MATCHES ^COMPILER_SUPPORTS_CXX0X$ )
It looks as if the expression on the left of the MATCHES is replaced with the variables value, but the expression on the right is assumed to be plain text.
If the MATCH fails then the main part of the macro is skipped and according the to the log the check fails.
Looking at later versions of this macro online it looks as if this line has changed to only perform the compile check if the variable is undefined.
It as at this point that I realise that this is the intent / hack of the original code; if the X is undefined then "X" MATCHES "^X$" will be true, but then the compile check can be performed, fail for some other reason and then never be performed again.
So the solution is either force unset of variable in cache before calling the macro using:
unset(COMPILER_SUPPORTS_CXX0X CACHE)
Or clear the cache manually and be prepared for this behaviour.