Linking with BLAS OS X - c++

I am currently trying to compile a program using a library that I'm not very familiar with. When I run the compiler, I get the following output/error:
Undefined symbols for architecture x86_64:
"_cblas_ddot", referenced from:
shark::LDA::train(shark::LinearClassifier<shark::blas::vector<double> >&, shark::LabeledData<shark::blas::vector<double>, unsigned int> const&) in libshark.a(LDA.cpp.o)
shark::LDA::train(shark::LinearClassifier<shark::blas::vector<double> >&, shark::WeightedLabeledData<shark::blas::vector<double>, unsigned int> const&) in libshark.a(LDA.cpp.o)
My current idea is that this is from missing BLAS library, which I just downloaded and compiled (from fortran code?).
The command-line arg for compiling looks like thsi
g++ -o example -I/to/boost/include -I/to/shark/include -L/to/boost/lib -L/to/shark/lib -L/to/BLAS -lshark -lblas -l(boost_flags)
In /to/BLAS have a libblas.a, and I ran nm libblas.a which gives a line
libblas.a(ddot.o):
00000000000001c0 s EH_frame1
0000000000000000 T _ddot_
Without being too secure abut this, I assume that this means that the library does have the symbol, but without the _cblas_ prefix.
What can I do from this point? Can I change the symbols name? Or do I need to link this library with something else?
I use OS X Mavericks
Thanks in advance : )

OS X ships with BLAS (including cblas) already installed (it's part of the Accelerate.framework). There's no need to download and build your own. Just link with -lcblas.

Solution was as suggested by Logicrat, that I needed other files, I downloaded te source code from here and build it with cmake/make very seamless. Linking with the libraries that came from this resolved the issue.

Related

gcc ignores the explicitly specified linked libraries to be linked

I use CMake/vcpkg to manage my C++ programs dependencies, and ran into a linking issue on Linux.
My program depends on library X (arrow more specifically), and library X depends on another library Y internally (RE2 in this case). When I linked my program to library X, the linking worked on macOS X (Apple clang 11) while didn't work on debian (g++ 9.3), reporting symbols in library Y cannot be found, and symbol missing were still reported by linker under Linux even if I explicitly linked library Y to my program directly.
Currently the only workaround I found is writing a useless function in my program using library Y, so that the linker will link the library Y. It seems to me the linker tries to be smart and avoid linking the library Y because it is not directly used by my program but reporting error when linking to library X due to it cannot find symbols in library Y used by X.
This doesn't seem to be a problem for this particular library since I had another library with the same case on Linux as well. One of the possible cause is I tried to make my program a shared library, but I don't know if it is relevant or not. Could some one shed some light on how this happens and how I may fix it?
Here is the error message reported:
/usr/bin/ld: /vcpkg/installed/x64-linux/debug/lib/libarrow.a(gdv_function_stubs.cc.o): in function `bool re2::RE2::FullMatch<>(re2::StringPiece const&, re2::RE2 const&)':
/vcpkg/installed/x64-linux/include/re2/re2.h:368: undefined reference to `re2::RE2::FullMatchN(re2::StringPiece const&, re2::RE2 const&, re2::RE2::Arg const* const*, int)'

compiling against libstdc++.so.5 is not finding symbols #GLIBCPP_3.2

I am building an application which makes use of a third party library which requires libstdc++.so.5. Until recently I was compiling my application with libstdc++.so.6 which worked fine, however it had some portability issues.
Therefore I decided installing g++ version 3.3.4 in order to be capable of compiling my application with libstdc++.so.5. However now I cannot compile my application at all. Neither with my old g++ nor with the 3.3.4 Version of it... Building the application reports the following error message:
/opt/ExPansion/lib/libexpansion.so: undefined reference to `std::basic_istream<char, std::char_traits<char> >::basic_istream(std::basic_streambuf<char, std::char_traits<char> >*)#GLIBCPP_3.2'
EDIT:
Interesting might also be the output of the following commands:
$ strings /usr/lib/libstdc++.so.5 | grep 'LIB'
GLIBCPP_3.2
GLIBCPP_3.2.1
GLIBCPP_3.2.2
GLIBCPP_3.2.3
GLIBCPP_3.2.4
GLIBC_2.0
GLIBC_2.3
GLIBC_2.1.3
GLIBC_2.1
GLIBC_2.2
GLIBCPP_FORCE_NEW
The only thing that makes me wonder is the following:
$ nm /usr/lib/libstdc++.so.5
nm: /usr/lib/libstdc++.so.5: no symbols
Is that "normal"? Is it possible that my lib is not containing the needed symbols? I downloaded this lib through:
yum install compat-libstdc++-33
..so it shouldn't be causing any problems..
From my understanding #GLIBCPP_3.2 is provided by my libstdc++.so.5. So what could be going wrong here?
I have no idea what causes my linker not finding the lib on its own...
The following question helped me however find a "workaround" to my problem: how to force linker to use shared library instead of static library?
Simply forcing my linker to link against the library helped..
gcc -o app app.o {other libs} /usr/lib/libstdc++.so.5

Linking with gmock libs generated using GCC 3.4.6 (libstdc++.so.6.0.13) gives "undefined reference to... #GLIBCXX_3.4.9" errors

Linking with gmock(1.4+svn281) libs generated on a Linux machine "A", having GCC 3.4.6 using libstdc++.so.6.0.13 gives me the following linking error:
libgmock.so: undefined reference to `std::basic_ostream >& std::__ostream_insert >(std::basic_ostream >&, char const*, long)#GLIBCXX_3.4.9'
...
I tried also with the latest gmock release version and also got the undefined reference to... #GLIBCXX_3.4.9 errors (this time with other symbols).
Building gmock using the same build procedure, however on another machine "B" (retired machine now, but previously used to generate the older binaries) I was able to link successfully. The machine uses GCC 3.4.6, with a different libstdc++ version: libstdc++.so.6.0.3.
Grepping on libstdc++.so.6.0.13 for GLIBCXX_3.4.9 shows that it contains such symbol patterns:
_ZNSt13basic_ostreamIwSt1##GLIBCXX_3.4.9 (referencing GLIBCXX_3.4.9, hence the error). I verified that this is not the case for libstdc++.so.6.0.3
To understand the linking error and what are my options, I read about libstdc++ and glibcxx to get some perspective, but couldn't conclude the relation between the libs: Does libstdc++ need glibcxx or is it the other way around (the error message makes it seem that the problem is: at glibcxx there is an undefined reference to a symbol in libstdc++)?
Does libstdc++ implicitly link with glibcxx (knowing that libstdc++ can reference multiple glibcxx versions at a time)?
I don't want to go back to the old machine to build gmock whenever I want to update the libs, am I constrained to building gmock with specific libstdc++ versions that work?
Appreciate any help on the issue
EDIT:
I built gmock libs on machine "A" and specified the version of libstdc++: libstdc++.so.6.0.3 and got the same errors as before, but this time without the #GLIBCXX_3.4.9 appended at the end of the symbol:
libgmock.so: undefined reference to `std::basic_ostream >& std::__ostream_insert >(std::basic_ostream >&, char const*, long)'
...
I also verified that libstdc++.so.6.0.3 was actually taken, by launching the command: "readelf -a libgmock.so" and verifying that GLIBCXX_3.4.9 was not referenced.
To understand the linking error and what are my options, I read about libstdc++ and glibcxx to get some perspective, but couldn't conclude the relation between the libs: Does libstdc++ need glibcxx
There is no such thing as glibcxx library. The libstdc++.so uses GNU symbol versioning, and uses GLIBCXX symbol prefix. The whole GLIBCXX is implementation detail of libstdc++ itself.
Your actual problem, and possible solutions, is explained here.
Effectively, you can not expect a binary linked on a newer Linux system to work on an older one.

How can I resolve single symbol link error when dynamically linking XCode project to lib4cxx library?

I'm writing in C++ under XCode 4.6 on Mountain Lion. I'm trying to add and use the Apache log4cxx library. I installed the library this morning via Brew. I'm linking against liblog4cxx.dylib. I'm getting a link error that just one symbol can't be found:
Undefined symbols for architecture x86_64:
"log4cxx::Logger::forcedLog(log4cxx::helpers::ObjectPtrT
const&, std::__1::basic_string,
std::__1::allocator > const&, log4cxx::spi::LocationInfo const&)
const", referenced from:
I know it's finding the library file because if I remove it, I get lots more undefined symbol errors relating to log4cxx.
relevant code is basically:
#include <log4cxx/logger.h>
static LoggerPtr logger(log4cxx::Logger::getLogger("foo.bar.Baz"));
void foo(int p1, int p2)
{
LOG4CXX_WARN(logger, "blah blah blah");
}
Creating the logger object inside the function, either as static or not, doesn't change the behavior. Also, linking with the static library, with or without defining LOG4CXX_STATIC in my project, does not change the behavior.
Looking at the macro I'm calling, I see that this symbol is the actual method that performs the log operation. If take out the logging call but leave in the code that defines the logger object, the code links fine as you might expect.
What do I need to do to have this last symbol resolve?
TIA!
I traced my issue down to compiling the library in a non C++11 compiler, but then my target project was a C++11 compiler.
I was able to compile log4cxx in a C+11 compiler by viewing the changes to log4cxx in the development git repo, which mainly consisted of inserting static_casts, as in this update:
http://apache-logging.6191.n7.nabble.com/C-11-does-not-allow-char-literals-with-highest-bit-set-unless-cast-td34908.html
I suppose the few incompatible routines came up undefined, which is why we were getting confused with only a few seemingly random undefines. (Or I was anyway)

Adding Boost.Log to boost libraries using CMake

I am trying to add Boost.Log to the Boost libraries using CMake, but I am having trouble when trying to link into my program.
I've added a wrapper around the Boost.Log and generated a shared library called libcls_utils.so. The Boost libraries (along with Boost.Log) appear to be built and generate all the .so files properly in the correct location, and so does libcls_utils.so.
When I try to link my file, I get the following error:
/media/data/workspace/mdxdev/tmp/staging/i686-mv-linux/usr/lib/libcls_utils.so: undefined reference to `boost::log_mt_posix::sinks::basic_text_file_backend::construct(boost::fil‌​esystem2::basic_path, std::allocator >, boost::filesystem2::path_traits> const&, std::_Ios_Openmode, unsigned long long, boost::function0 const&, bool)
As far as I can tell, I'm linking against all the correct libraries. Has anyone tried this before successfully? What am I doing wrong?
I am using CMake 2.8.8, Boost-1.49.0 and Boost.Log from the svn trunk.
You might need to define BOOST_LOG_DYN_LINK:
g++ -DBOOST_LOG_DYN_LINK blog.cpp -lboost_log -lpthread