2
votes

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.

1

1 Answers

3
votes

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.