diff --git a/docs/building.html b/docs/building.html new file mode 100644 index 000000000..ff42ea32f --- /dev/null +++ b/docs/building.html @@ -0,0 +1,377 @@ + + + +
+ + +Author: | +Arvid Norberg, arvid@rasterbar.com |
---|
To acquire the latest version of libtorrent, you'll have to grab it from CVS. +You'll find instructions on how to do this here (see Anonymous CVS access).
+The build systems supported "out of the box" in libtorrent are boost-build v2 +(BBv2) and autotools (for unix-like systems). If you still can't build after +following these instructions, you can usually get help in the #libtorrent +IRC channel on irc.freenode.net.
+The primary reason to use boost-build is that it will automatically build the +dependent boost libraries with the correct compiler settings, in order to +ensure that the build targets are link compatible (see boost guidelines +for some details on this issue).
+Since BBv2 will build the boost libraries for you, you need the full boost +source package. Having boost installed via some package system is usually not +enough (and even if it is enough, the necessary environment variables are +usually not set by the package installer).
+You'll find boost here.
+Extract the archive to some directory where you want it. For the sake of this +guide, let's assume you extract the package to c:\boost_1_33_1 (I'm using +a windows path in this example since if you're on linux/unix you're more likely +to use the autotools). You'll need at least version 1.32 of the boost library +in order to build libtorrent.
+If you use 1.32, you need to download BBv2 separately, so for now, let's +assume you will use version 1.33.1.
+First you need to build bjam. You do this by opening a terminal (In +windows, run cmd). Change directory to +c:\boost_1_33_1\tools\build\jam_src. Then run the script called +build.bat or build.sh on a unix system. This will build bjam and +place it in a directory starting with bin. and then have the name of your +platform. Copy the bjam.exe (or bjam on a unix system) to a place +that's in you shell's PATH. On linux systems a place commonly used may be +/usr/local/bin or on windows c:\windows (you can also add directories +to the search paths by modifying the environment variable called PATH).
+Now you have bjam installed. bjam can be considered an interpreter +that the boost-build system is implemented on. So boost-build uses bjam. +So, to complete the installation you need to make two more things. You need to +set the environment variable BOOST_BUILD_PATH. This is the path that tells +bjam where it can find boost-build, your configuration file and all the +toolsets (descriptions used by boost-build to know how to use different +compilers on different platforms). Assuming the boost install path above, set +it to c:\boost_1_33_1\tools\build\v2.
+To set an environment variable in windows, type for example:
++set BOOST_BUILD_PATH=c:\boost_1_33_1\tools\build\v2 ++
In a terminal window.
+The last thing to do to complete the setup of BBv2 is to modify your +user-config.jam file. It is located in c:\boost_1_33_1\tools\build\v2. +Depending on your platform and which compiler you're using, you should add a +line for each compiler and compiler version you have installed on your system +that you want to be able to use with BBv2. For example, if you're using +Microsoft Visual Studio 7.1 (2003), just add a line:
++using msvc : 7.1 ; ++
If you use GCC, add the line:
++using gcc ; ++
If you have more than one version of GCC installed, you can add the +commandline used to invoke g++ after the version number, like this:
++using gcc : 3.3 : g++-3.3 ; +using gcc : 4.0 : g++-4.0 ; ++
Another toolset worth mentioning is the darwin toolset (For MacOS X). +From Tiger (10.4) MacOS X comes with both GCC 3.3 and GCC 4.0. Then you can +use the following toolsets:
++using darwin : 3.3 : g++-3.3 ; +using darwin : 4.0 : g++-4.0 ; ++
Note that the spaces around the semi-colons and colons are important!
+When building libtorrent, the Jamfile expects the environment variable +BOOST_ROOT to be set to the boost installation directory. It uses this to +find the boost libraries it depends on, so they can be built and their headers +files found. So, set this to c:\boost_1_33_1.
+Then the only thing left is simply to invoke bjam. If you want to specify +a specific toolset to use (compiler) you can just add that to the commandline. +For example:
++bjam msvc-7.1 link=static +bjam gcc-3.3 link=static +bjam darwin-4.0 link=static ++
To build different versions you can also just add the name of the build +variant. Some default build variants in BBv2 are release, debug, +profile.
+You can build libtorrent as a dll too, by typing link=shared, or +link=static to build a static library. link=shared is the default.
+If you want to explicitly say how to link against the runtime library, you +can set the runtime-link feature on the commandline, either to shared +or static. Most operating systems will only allow linking shared against +the runtime, but on windows you can do both. Example:
++bjam msvc-7.1 link=static runtime-link=static ++
Warning
+If you link statically to the runtime library, you cannot build libtorrent +as a shared library (DLL), since you will get separate heaps in the library +and in the client application. It will result in crashes.
+The build targets are put in a directory called bin, and under it they are +sorted in directories depending on the toolset and build variant used.
+To build the examples, just change directory to the examples directory and +invoke bjam from there. To build and run the tests, go to the test +directory and run bjam.
+Note that if you're building on windows using the msvc toolset, you cannot run it +from a cygwin terminal, you'll have to run it from a cmd terminal. The same goes for +cygwin, if you're building with gcc in cygwin you'll have to run it from a cygwin terminal. +Also, make sure the paths are correct in the different environments. In cygwin, the paths +(BOOST_BUILD_PATH and BOOST_ROOT) should be in the typical unix-format (e.g. +/cygdrive/c/boost_1_33_1). In the windows environment, they should have the typical +windows format (c:/boost_1_33_1).
+The Jamfile will define NDEBUG when it's building a release build. +There are two other build variants available in the Jamfile. debug_log +and release_log, these two variants inherits from the debug and release +variants respectively, but adds extra logging (TORRENT_VERBOSE_LOGGING). +For more build configuration flags see Build configurations.
+The Jamfile has the following build variants:
+The logs created when building vlog or log mode are put in a directory called +libtorrent_logs in the current working directory.
+When building the example client on windows, you need to build with +link=static otherwise you may get unresolved external symbols for some +boost.program-options symbols.
+For more information, see the Boost build v2 documentation.
+First of all, you need to install automake and autoconf. Many +unix/linux systems comes with these preinstalled.
+No build system is present if libtorrent is checked out from CVS - it +needs to be generated first. If you're building from a released tarball, +you may skip directly to Step 2: Running configure.
+Execute the following commands, in the given order, to generate +the build system:
+In your shell, change directory to the libtorrent directory and run +./configure. This will look for libraries and C++ features that libtorrent +is dependent on. If something is missing or can't be found it will print an +error telling you what failed.
+The most likely problem you may encounter is that the configure script won't +find the boost libraries. Make sure you have boost installed on your system. +The easiest way to install boost is usually to use the preferred package +system on your platform. Usually libraries and headers are installed in +standard directories where the compiler will find them, but sometimes that +may not be the case. For example when installing boost on darwin using +darwinports (the package system based on BSD ports) all libraries are +installed to /opt/local/lib and headers are installed to +/opt/local/include. By default the compiler will not look in these +directories. You have to set the enviornment variables LDFLAGS and +CXXFLAGS in order to make the compiler find those libs. In this example +you'd set them like this:
++export LDFLAGS=-L/opt/local/lib +export CXXFLAGS=-I/opt/local/include ++
It was observed on FreeBSD (release 6.0) that one needs to add '-lpthread' to +LDFLAGS, as Boost::Thread detection will fail without it, even if +Boost::Thread is installed.
+If you need to set these variables, it may be a good idea to add those lines +to your ~/.profile or ~/.tcshrc depending on your shell.
+You know that the boost libraries were found if you see the following output +from the configure script:
++checking whether the Boost::DateTime library is available... yes +checking for main in -lboost_date_time... yes +checking whether the Boost::Filesystem library is available... yes +checking for main in -lboost_filesystem... yes +checking whether the Boost::Thread library is available... yes +checking for main in -lboost_thread... yes ++
Another possible source of problems may be if the path to your libtorrent +directory contains spaces. Make sure you either rename the directories with +spaces in their names to remove the spaces or move the libtorrent directory.
+To tell configure to build a debug version (with debug info, asserts +and invariant checks enabled), you have to run the configure script +with the following option:
++./configure --enable-debug=yes ++
To tell the configure to build a release version (without debug info, +asserts and invariant checks), you have to run the configure script +with the following option:
++./configure --enable-debug=no ++
The above option make use of -DNDEBUG, which is used throughout libtorrent.
+Once the configure script is run successfully, you just type make and +libtorrent, the examples and the tests will be built.
+When libtorrent is built it may be a good idea to run the tests, you do this +by running make check.
+If you want to build a release version (without debug info, asserts and +invariant checks), you have to rerun the configure script and rebuild, like this:
++./configure --disable-debug +make clean +make ++
If you're making your own project file, note that there are two versions of +the file abstraction. There's one file_win.cpp which relies on windows +file API that supports files larger than 2 Gigabytes. This does not work in +vc6 for some reason, possibly because it may require windows NT and above. +The other file, file.cpp is the default implementation that simply relies +on the standard low level io routines (read(), write(), open() +etc.), this implementation doesn't do anything special to support unicode +filenames, so if your target is Windows 2000 and up, you may want to use +file_win.cpp which supports unicode filenames.
+If you're building in MS Visual Studio, you may have to set the compiler +options "force conformance in for loop scope", "treat wchar_t as built-in +type" and "Enable Run-Time Type Info" to Yes. For a detailed description +on how to build libtorrent with VS 2005, see this document.
+By default libtorrent is built In debug mode, and will have pretty expensive +invariant checks and asserts built into it. If you want to disable such checks +(you want to do that in a release build) you can see the table below for which +defines you can use to control the build.
+macro | +description | +
---|---|
NDEBUG | +If you define this macro, all asserts, +invariant checks and general debug code will be +removed. This option takes precedence over +other debug settings. | +
TORRENT_LOGGING | +This macro will enable logging of the session +events, such as tracker announces and incoming +connections (as well as blocked connections). | +
TORRENT_VERBOSE_LOGGING | +If you define this macro, every peer connection +will log its traffic to a log file as well as +the session log. | +
TORRENT_STORAGE_DEBUG | +This will enable extra expensive invariant +checks in the storage, including logging of +piece sorting. | +
UNICODE | +If building on windows this will make sure the +UTF-8 strings in pathnames are converted into +UTF-16 before they are passed to the file +operations. | +
LITTLE_ENDIAN | +This will use the little endian version of the +sha-1 code. If defined on a big-endian system +the sha-1 hashes will be incorrect and fail. +If it is not defined and __BIG_ENDIAN__ +isn't defined either (it is defined by Apple's +GCC) both little-endian and big-endian versions +will be built and the correct code will be +chosen at run-time. | +
TORRENT_LINKING_SHARED | +If this is defined when including the +libtorrent headers, the classes and functions +will be tagged with __declspec(dllimport) +on msvc and default visibility on GCC 4 and +later. Set this in your project if you're +linking against libtorrent as a shared library. +(This is set by the Jamfile when +link=shared is set). | +
TORRENT_BUILDING_SHARED | +If this is defined, the functions and classes +in libtorrent are marked with +__declspec(dllexport) on msvc, or with +default visibility on GCC 4 and later. This +should be defined when building libtorrent as +a shared library. (This is set by the Jamfile +when link=shared is set). | +
TORRENT_DISABLE_DHT | +If this is defined, the support for trackerless +torrents will be disabled. | +
If you experience that libtorrent uses unreasonable amounts of cpu, it will +definitely help to define NDEBUG, since it will remove the invariant checks +within the library.
+Author: | +Arvid Norberg, arvid@rasterbar.com |
---|
Except for the example programs in this manual, there's also a bigger example +of a (little bit) more complete client, client_test. There are separate +instructions for how to use it here if you'd like to try it.
+This is an example of a program that will take a torrent-file as a parameter and +print information about it to std out:
++#include <iostream> +#include <fstream> +#include <iterator> +#include <iomanip> + +#include "libtorrent/entry.hpp" +#include "libtorrent/bencode.hpp" +#include "libtorrent/torrent_info.hpp" + + +int main(int argc, char* argv[]) +{ + using namespace libtorrent; + + if (argc != 2) + { + std::cerr << "usage: dump_torrent torrent-file\n"; + return 1; + } + + try + { + std::ifstream in(argv[1], std::ios_base::binary); + in.unsetf(std::ios_base::skipws); + entry e = bdecode(std::istream_iterator<char>(in) + , std::istream_iterator<char>()); + + std::cout << "\n\n----- raw info -----\n\n"; + e.print(std::cout); + + torrent_info t(e); + + // print info about torrent + std::cout << "\n\n----- torrent file info -----\n\n"; + std::cout << "trackers:\n"; + for (std::vector<announce_entry>::const_iterator i + = t.trackers().begin(); i != t.trackers().end(); ++i) + { + std::cout << i->tier << ": " << i->url << "\n"; + } + + std::cout << "number of pieces: " << t.num_pieces() << "\n"; + std::cout << "piece length: " << t.piece_length() << "\n"; + std::cout << "info hash: " << t.info_hash() << "\n"; + std::cout << "comment: " << t.comment() << "\n"; + std::cout << "created by: " << t.creator() << "\n"; + std::cout << "files:\n"; + for (torrent_info::file_iterator i = t.begin_files(); + i != t.end_files(); ++i) + { + std::cout << " " << std::setw(11) << i->size + << " " << i->path.string() << "\n"; + } + + } + catch (std::exception& e) + { + std::cout << e.what() << "\n"; + } + + return 0; +} ++
This is a simple client. It doesn't have much output to keep it simple:
++#include <iostream> +#include <fstream> +#include <iterator> +#include <exception> + +#include <boost/format.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> + +#include "libtorrent/entry.hpp" +#include "libtorrent/bencode.hpp" +#include "libtorrent/session.hpp" + +int main(int argc, char* argv[]) +{ + using namespace libtorrent; + + if (argc != 2) + { + std::cerr << "usage: ./simple_cient torrent-file\n" + "to stop the client, press return.\n"; + return 1; + } + + try + { + session s; + s.listen_on(std::make_pair(6881, 6889)); + + std::ifstream in(argv[1], std::ios_base::binary); + in.unsetf(std::ios_base::skipws); + entry e = bdecode(std::istream_iterator<char>(in) + , std::istream_iterator<char>()); + s.add_torrent(torrent_info(e), ""); + + // wait for the user to end + char a; + std::cin.unsetf(std::ios_base::skipws); + std::cin >> a; + } + catch (std::exception& e) + { + std::cout << e.what() << "\n"; + } + return 0; +} ++
Shows how to create a torrent from a directory tree:
++#include <iostream> +#include <fstream> +#include <iterator> +#include <iomanip> + +#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 <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> +#include <boost/filesystem/fstream.hpp> + +using namespace boost::filesystem; +using namespace libtorrent; + +void add_files(torrent_info& t, path const& p, path const& l) +{ + path f(p / l); + if (is_directory(f)) + { + for (directory_iterator i(f), end; i != end; ++i) + add_files(t, p, l / i->leaf()); + } + else + { + std::cerr << "adding \"" << l.string() << "\"\n"; + file fi(f, file::in); + fi.seek(0, file::end); + libtorrent::size_type size = fi.tell(); + t.add_file(l, size); + } +} + +int main(int argc, char* argv[]) +{ + using namespace libtorrent; + using namespace boost::filesystem; + + if (argc != 4) + { + std::cerr << "usage: make_torrent <output torrent-file> " + "<announce url> <file or directory to create torrent from>\n"; + return 1; + } + + boost::filesystem::path::default_name_check(native); + + try + { + torrent_info t; + path full_path = initial_path() / path(argv[3]); + ofstream out(initial_path() / path(argv[1]), std::ios_base::binary); + + int piece_size = 256 * 1024; + char const* creator_str = "libtorrent"; + + add_files(t, full_path.branch_path(), full_path.leaf()); + t.set_piece_size(piece_size); + + storage st(t, full_path.branch_path()); + t.add_tracker(argv[2]); + + // calculate the hash for all pieces + int num = t.num_pieces(); + std::vector<char> buf(piece_size); + for (int i = 0; i < num; ++i) + { + st.read(&buf[0], i, 0, t.piece_size(i)); + hasher h(&buf[0], t.piece_size(i)); + t.set_hash(i, h.final()); + std::cerr << (i+1) << "/" << num << "\r"; + } + + t.set_creator(creator_str); + + // create the torrent and print it to out + entry e = t.create_torrent(); + libtorrent::bencode(std::ostream_iterator<char>(out), e); + } + catch (std::exception& e) + { + std::cerr << e.what() << "\n"; + } + + return 0; +} ++