Linking C++ library (libtorrent) from Objective-C - c++

I'm trying to use libtorrent library from Xcode 5.0 Objective-C Project without success.
I've built boost 1.54 and libtorrent-rasterbar (latest) from sources using LLVM 5.0, no problems with that. Also, via MacPorts I obtained pkg-config to get the proper cflags for libtorrent-rasterbar library. From my build settings, the output for pkgconfig libs and cflags were:
-DTORRENT_USE_OPENSSL -DWITH_SHIPPED_GEOIP_H
-DBOOST_ASIO_HASH_MAP_BUCKETS=1021
-DBOOST_EXCEPTION_DISABLE -DBOOST_ASIO_ENABLE_CANCELIO
-DBOOST_ASIO_DYN_LINK -DTORRENT_LINKING_SHARED -I/usr/local/include
-I/usr/local/include/libtorrent
-L/usr/local/lib -ltorrent-rasterbar
Naturally, I added those parameters to Xcode "Linker Flags" and "C/C++ Flags" settings.
Unfortunately, I cannot get my called functions to link right. This is a sample class I wrote in a testclass.cpp file:
#include "libtorrent/entry.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/torrent_info.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/create_torrent.hpp"
void testclass::addFilesFromPath(const char* path)
{
libtorrent::file_storage fs;
libtorrent::add_files(fs, path);
}
Tried to get called from a createpackage.mm file:
testclass* pPackage = new testclass();
testclass->addFilesFromPath([_sessionDir UTF8String]);
The linker cannot found the symbols, output is:
Undefined symbols for architecture x86_64:
"libtorrent::parent_path(std::__1::basic_string, std::__1::allocator > const&)",
referenced from:
libtorrent::add_files(libtorrent::file_storage&, std::__1::basic_string,
std::__1::allocator > const&, unsigned int) in
createpackage.o
"libtorrent::detail::add_files_impl(libtorrent::file_storage&,
std::__1::basic_string,
std::__1::allocator > const&, std::__1::basic_string, std::__1::allocator > const&,
boost::function, std::__1::allocator >)>, unsigned
int)", referenced from:
libtorrent::add_files(libtorrent::file_storage&, std::__1::basic_string,
std::__1::allocator > const&, unsigned int) in
createpackage.o
"libtorrent::complete(std::__1::basic_string, std::__1::allocator > const&)",
referenced from:
libtorrent::add_files(libtorrent::file_storage&, std::__1::basic_string,
std::__1::allocator > const&, unsigned int) in
createpackage.o
"libtorrent::filename(std::__1::basic_string, std::__1::allocator > const&)",
referenced from:
libtorrent::add_files(libtorrent::file_storage&, std::__1::basic_string,
std::__1::allocator > const&, unsigned int) in
createpackage.o ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
I'm pretty puzzled. Checked that libtorrent-raster bar architecture is x86_64. Also, boost is built OK. I'm new to this C++ / Objetive-C code mixing approach.
Thanks.
EDIT 1:
I've resorted to a minimal sample. Made the following CPP file:
#include "libtorrent/file.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/create_torrent.hpp"
int main()
{
libtorrent::file_storage fs;
libtorrent::add_files(fs, ".");
}
At command line, tried:
c++ test.cpp $(pkg-config /usr/local/lib/pkgconfig/libtorrent-rasterbar.pc --cflags --libs) -lboost_system
Build is successful. So I wonder how to put all that pkg-config data into the proper target configurations in OSX.

Finally, problem was solved.
Let's check symbols comparing the produced object file and the symbols contained in libtorrent library.
nm createpackage.o|grep 'add_files'
U __ZN10libtorrent6detail14add_files_implERNS_12file_storageERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESB_N5boost8functionIFbS9_EEEj
00000000000002a0 S __ZN10libtorrent9add_filesERNS_12file_storageERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEj
00000000000018e0 S __ZN10libtorrent9add_filesERNS_12file_storageERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEj.eh
Compare with:
$ nm libtorrent-rasterbar.a | grep 'add_files'
00000000000002f0 T __ZN10libtorrent6detail14add_files_implERNS_12file_storageERKSsS4_N5boost8functionIFbSsEEEj
0000000000006e68 S __ZN10libtorrent6detail14add_files_implERNS_12file_storageERKSsS4_N5boost8functionIFbSsEEEj.eh
The difference as many could imagine seeing that output, it's that i'm using the LLVM Standard C++ library for my .mm files while libtorrent was compiled with GCC Stdlib, that's the reason of different symbols referring to char_traits, basic_string, etc.
So, changing in XCode Build Settings > Standard C++ Library to libstdc++ fixed the problem.

Related

Errors using OpenCV with opencv_contrib on Xcode

For my application running on iPhone I am using OpenCV using opencv2.framework in Xcode with objective-c and C++ as languages. My development worked well until I wanted to introduce cv::Tracker that is not included in opencv2.framework but part of opencv_contrib.
I rebuilt and installed from the source opencv-3.4.0 with opencv_contrib-master using CMake and terminal commands make and install.
In Xcode I have set
HEADER_SEARCH_PATHS = /usr/local/include and
LIBRARY_SEARCH_PATHS = /usr/local/lib
When compiling I get a long list of errors of the style:
Undefined symbols for architecture x86_64:
"cv::error(int, cv::String const&, char const*, char const*, int)",
referenced from:
cv::Mat::Mat(int, int, int, void*, unsigned long) in OpenCVRenderer.o
"cv::Mat::operator=(cv::Scalar_<double> const&)", referenced from:
cv::Mat::Mat(int, int, int, cv::Scalar_<double> const&) in
OpenCVRenderer.o
cv::Mat::Mat(cv::Size_<int>, int, cv::Scalar_<double> const&) in
OpenCVRenderer.o
"cv::Mat::deallocate()", referenced from:
cv::Mat::release() in OpenCVRenderer.o
"cv::polylines(cv::_InputOutputArray const&, cv::_InputArray const&,
bool, cv::Scalar_<double> const&, int, int, int)", referenced from:
.
.
.
I set OTHER_LDFLAGS = (list of opencv dylibs) preceeded by a "-" sign
Now I get errors as if the libraries are not found while there are in fact in /usr/local/lib
For example I get:
ld: library not found for -libopencv_core.3.4.0.dylib
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
Any help?
Thank you.
There are a couples of problems with your settings.
You only specified where to find the libraries, not opencv2.framework. You should either specify framework_search_path (and link your framework to the project) or link the corresponding libraries.
You said you were building an iPhone app, yet the error says Undefined symbols for architecture x86_64:. That is, either you built your app for phone simulator or for mac. Yet, your framework is most likely built for iPhone architecture (armv7 and arm64). This case, you need to rebuild the framework. If you build iPhone app, do not link any dylib libraries in /usr/local/lib/.
Note that libopencv_core.3.4.0.dylib is part of normal opencv so the error has nothing to do with opencv_contrib (yet).

When I install Caffe on Mac, there is a fault "clang: warning: argument unused during compilation: '-pthread' "

I feel that all dependences are installed, and I want to install Caffe without GPU, but when I do make all, there is an error:
CXX src/caffe/util/upgrade_proto.cpp
AR -o .build_release/lib/libcaffe.a
/Applications/Xcode.app/Contents/Developer/Toolchain/XcodeDefault.xctoolch ain/usr/bin/ranlib: file: .build_release/lib/libcaffe.a(cudnn_conv_layer.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchain/XcodeDefault.xctoolchain/usr/bin/ranlib: file: .build_release/lib/libcaffe.a(cudnn_lcn_layer.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchain/XcodeDefault.xctoolchain/usr/bin/ranlib: file: .build_release/lib/libcaffe.a(cudnn_lrn_layer.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchain/XcodeDefault.xctoolchain/usr/bin/ranlib: file: .build_release/lib/libcaffe.a(cudnn_pooling_layer.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchain/XcodeDefault.xctoolchain/usr/bin/ranlib: file: .build_release/lib/libcaffe.a(cudnn_relu_layer.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchain/XcodeDefault.xctoolchain/usr/bin/ranlib: file: .build_release/lib/libcaffe.a(cudnn_sigmoid_layer.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchain/XcodeDefault.xctoolchain/usr/bin/ranlib: file: .build_release/lib/libcaffe.a(cudnn_softmax_layer.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchain/XcodeDefault.xctoolchain/usr/bin/ranlib: file: .build_release/lib/libcaffe.a(cudnn_tanh_layer.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchain/XcodeDefault.xctoolchain/usr/bin/ranlib: file: .build_release/lib/libcaffe.a(cudnn.o) has no symbols
LD -o .build_release/lib/libcaffe.so.1.0.0-rc3
clang: warning: argument unused during compilation: '-pthread'
Undefined symbols for architecture x86_64:
"cv::imread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
caffe::WindowDataLayer<float>::load_batch(caffe::Batch<float>*) in window_data_layer.o
caffe::WindowDataLayer<double>::load_batch(caffe::Batch<double>*) in window_data_layer.o
caffe::ReadImageToCVMat(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, int, bool) in io.o
"cv::imencode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::_InputArray const&, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, std::__1::vector<int, std::__1::allocator<int> > const&)", referenced from:
caffe::ReadImageToDatum(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, int, int, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, caffe::Datum*) in io.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [.build_release/lib/libcaffe.so.1.0.0-rc3] Error 1
I do not understand why this happens and it seems like my Xcode may have some problems? Could someone help me?
There are two separate things here:
"clang: warning: argument unused during compilation: '-pthread'" is an ignoreable (although annoying) compiler warning (not error) that you often get with MacOS clang, these days it has pthreads support builtin. Ignore it, or suppress it with -Wno-error=unused-command-line-argument
whereas "Undefined symbols for architecture x86_64: ... clang: error: linker command failed with exit code " is an actual error. Fix that. (Looks like a missing header file to me, so check your -I... include paths. I don't know Caffe so I can't comment more on that.)
make sure you install openCV before building caffe.
brew install -vd snappy leveldb gflags glog szip lmdb
# need the homebrew science source for OpenCV and hdf5
brew tap homebrew/science
brew install hdf5 opencv
please go threw caffe OS X Installation.
I had a similar problem as well. It could be the Makefile.config. Please check the paths you provided for PYTHON_INCLUDE and PYTHON_LIB.
I had given the brew python path to PYTHON_INCLUDE and system path to PYTHON_LIB. I also made sure that the caffe python was added to the python path before compiling.Hope this information is of help.

Xcode 5.1.1 and Boost

Problem was solved by adding .dylib files (boost) to project.
I'm trying connect Boost 1.55 to Xcode 5 through Homebrew.
Brew installed it as it should. In /usr/local/include && /usr/local/lib appeared aliases on Boost headers and libraries.
Xcode "Search Path" settings:
http://i.imgur.com/j5GJ0sh.png
http://i.imgur.com/DXRxiyA.png
But when I tried compile simple example:
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <boost/regex.hpp>
using namespace std;
using namespace boost;
int main()
{
const regex expression( "How to re" );
string string1 = "How to re";
bool match=regex_match(string1,expression);
if (match){
cout<<"Yes"<<endl;
}
return 0;
}
Errors:
Undefined symbols for architecture x86_64: "boost::basic_regex >
::do_assign(char const*, char const*, unsigned int)", referenced from:
boost::basic_regex > >::assign(char const*, char const*,
unsigned int) in main.o "boost::re_detail::get_mem_block()",
referenced from:
boost::re_detail::perl_matcher,
std::__1::allocator > >, boost::regex_traits >
::extend_stack() in main.o
boost::re_detail::save_state_init::save_state_init(boost::re_detail::saved_state**,
boost::re_detail::saved_state**) in main.o
"boost::re_detail::put_mem_block(void*)", referenced from:
boost::re_detail::save_state_init::~save_state_init() in main.o
boost::re_detail::perl_matcher,
std::__1::allocator > >, boost::regex_traits >
::unwind_extra_block(bool) in main.o "boost::re_detail::verify_options(unsigned int,
boost::regex_constants::_match_flags)", referenced from:
boost::re_detail::perl_matcher,
std::__1::allocator > >, boost::regex_traits >
::match_imp() in main.o "boost::re_detail::raise_runtime_error(std::runtime_error const&)",
referenced from:
void boost::re_detail::raise_error > >
(boost::regex_traits_wrapper > > const&,
boost::regex_constants::error_type) in main.o
"boost::re_detail::get_default_error_string(boost::regex_constants::error_type)",
referenced from:
boost::re_detail::cpp_regex_traits_implementation::error_string(boost::regex_constants::error_type)
const in main.o
"boost::re_detail::cpp_regex_traits_implementation::transform_primary(char const*, char const*) const", referenced from:
boost::cpp_regex_traits::transform_primary(char const*, char const*) const in main.o
"boost::re_detail::cpp_regex_traits_implementation::transform(char
const*, char const*) const", referenced from:
boost::cpp_regex_traits::transform(char const*, char const*) const in main.o ld: symbol(s) not found for architecture
x86_64 clang: error: linker command failed with exit code 1 (use -v to
see invocation)
Really tired with it, so, ask for your help.
Thank you,
- Philipp
You have a few options but all of them involve adding the library libboost_regex to your project to resolve the link errors. Even though you installed boost using homebrew, you still need to add the library to your project because boost's regex code contains a compiled portion. If you don't add the library there is no way for the linker to resolve the symbols.
The first option is to add /usr/local/lib to Library Search Paths, and add -lboost_regex to Other Linker Flags. If you choose this option you may need to add /usr/local/lib to Runpath Search Paths also. This method will link against the dynamic library in /usr/local/lib.
If you want your program to be self-contained you can link against the static (.a) version of boost_regex. To do this add libboost_regex.a to your project in Build Settings - Link Binary With Libraries.

g++ ld: symbol(s) not found for architecture x86_64

I'm trying to compile the Sam Hare's Struck code.
I'm using mac OSX10.9, opencv 2.4.6 and Eigen 2.0.17.
Eigen and opencv headers are stored in /opt/local/include while opencv dylib in /opt/local/lib.
I modified the Hare's Makefile to work on this folder. When I type make on the terminal:
g++ -L/opt/local/lib -lopencv_core -lopencv_highgui -lopencv_imgproc src/Config.o src/Features.o src/HaarFeature.o src/HaarFeatures.o src/HistogramFeatures.o src/ImageRep.o src/LaRank.o src/MultiFeatures.o src/RawFeatures.o src/Sampler.o src/Tracker.o src/main.o src/GraphUtils/GraphUtils.o -o struck
I get these errors:
Undefined symbols for architecture x86_64:
"cv::namedWindow(std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > const&,
int)", referenced from:
_main in main.o "cv::split(cv::Mat const&, std::__1::vector<cv::Mat, std::__1::allocator<cv::Mat> >&)",
referenced from:
ImageRep::ImageRep(cv::Mat const&, bool, bool, bool) in ImageRep.o "cv::imread(std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> > const&,
int)", referenced from:
_main in main.o "cv::imshow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&,
cv::_InputArray const&)", referenced from:
LaRank::Debug() in LaRank.o
Tracker::Debug() in Tracker.o
_main in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see
invocation)
Any ideas? Thanks!
I had a similar warning/error/failure when I was simply trying to make an executable from two different object files (main.o and add.o). I was using the command:
gcc -o exec main.o add.o
But my program is a C++ program. Using the g++ compiler solved my issue:
g++ -o exec main.o add.o
I was always under the impression that gcc could figure these things out on its own. Apparently not. I hope this helps someone else searching for this error.
finally solved my problem.
I created a new project in XCode with the sources and changed the C++ Standard Library from the default libc++ to libstdc++ as in this and this.
I am getting the same error. I don't think it is a "fix", but my work-around is to also include the cpp file. So instead of just putting
#include "MyClass.h"
I have to put
#include "MyClass.h"
#include "MyClass.cpp"
I wrote my declarition in the .h file
class String
{
String (const char * cstr = 0);
};
and I used inline in another .cpp file (implementation)
inline String::String(const char * cstr)
{
//code ...
}
then I use g++ and get this:
Undefined symbols for architecture x86_64:
"String::String(char const*)", referenced from:
_main in test-d389f3.o
ld: symbol(s) not found for architecture x86_64
solution: do not write inline when declarition and implementation is independent.
When I using clang to compile a C++ program, I have the similar error.
But after I changing to use chang++, the compilation worked.

Error when using imshow on OS X

I have setup OpenCV2 in XCode but unfortunately imshow does not work:
Undefined symbols for architecture x86_64:
"cv::imshow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::_InputArray const&)", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I am running OS X 10.8.4 with latest XCode.
I have attached a few images below to show the setup in XCode and the libraries.
So far it seems that other functions work fine with OpenCV, except this.
I'm going to go out on a limb and say that you compiled OpenCV2 with libstdc++, and are now compiling your application with libc++ support.
You need to compile OpenCV2 with the same C++ library, otherwise it will not be able to link.
if you do an nm of the OpenCV2 library, if it was compiled with libstdc++, it will look like:
cv::imshow(std::string const&, cv::_InputArray const&)
while if it was compiled with libc++, it would look like:
cv::imshow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::_InputArray const&)
to get the demangled symbol do:
nm library | c++filt | grep cv::imshow