Этот ветка создана для всех желающих помочь получить СТАТИЧЕСКИ скомпилированную библиотеку Libtorrent.
Зачем это нужно?
На текущий момент эту библиотеку используют многие плагины, представленные на нашем форуме. Используют для организации потокового скачивания торрент-раздач (реализация торрент-плееров).
Однако есть небольшая засада. Установка этой библиотеки для обычного пользователя не так тривиальна в случае, если она используется в связки с XBMC. В добавок к этому, кучу “головняков” имеют и разработчики плагинов, пытаясь разобраться в “зоопарке” железа пользователей.
Все эти проблемы можно решить, если скомпилировать библиотеку для всех платформ в статическом режиме.
В этом случае, все зависимости (OpenSSL, GeoIP и др.) и сам libtorrent будут собраны в ОДИН файл. Точнее – по одному файлу на каждую платформу (linux32, linux64 и т.д.). Если библиотека собрана в статическом режиме, то ей безразлично где она находится, какой python-интерпретатор ее использует (системный или встроеный в XBMC) и т.д.
Полученные файлы можно просто закидывать в свои плагины и пользователь даже не заметит, что используется libtorrent. Все «портянки» с описанием установки библиотеки уйдут в прошлое.
Как компилировать?
Чтобы не загрязнять собственную систему, а также быть полностью уверенными в том, что все зависимости собираются внутрь библиотеки (и она будет работать поверх чистой ОС) вся компиляция происходит в виртуальной машине. На основе VirtualBox. Для упрощения передачи друг-другу наработок используется Vagrant.
Как поставить Vagrant?
Vagrant хорошо работает в Linux и MacOS. Про Windows ничего не могу сказать. Имеется в виду сам Vagrant, а не виртуальные машины с целевыми системами.
Vagrant имеет две зависимости: Ruby и VirtualBox. Если у вас MacOS, то Ruby уже стоит. Если Linux свежий, то Ruby также скорее всего установлен. VirtaulBox ставится элементарно. Если вы используете GUI в Linux или MacOS, то ставьте VirtualBox с помощью графического установщика. Просто ответьте на все вопросы положительно.
С установкой Vagrant также справится любая домохозяйка. На официальном сайте скачайте графический установщик и также ответьте на все вопросы положительно.
Как использовать Vagrant?
Создайте директорию где будет происходить ваша сборка (например: ~/build).
Скачайте туда один из файлов, представленных ниже.
Переименуйте его в Vagrantfile
Создайте поддиректорию vm
В консоле перейдите в директорию ~/build и выполните команду vagrant up
На этом все. Нужная виртуальная машина скачается из интернет и в ней запустится компиляция libtorrent.
После того, как все скомпилируется, файл будет находиться по адресу ~/build/vm. Просто скопируйте его куда-нибудь и после этого виртуальную машину можно уничтожить.
Уничтожение виртуальной машины происходит при помощи консольной команды vagrant destroy выполненной из той-же директории, где лежит Vagrantfile.
Для повторной компиляции (например, в случае ошибки), вначале надо уничтожить виртуальную машину (выполните vagrant destroy) и затем заново выполните vagrant up.
Если вам надо войти внутрь виртуальной машины, то в той же директории выполните vagrant ssh.
Как редактировать Vagrantfile для сборки под другую систему?
Найдите в Vagrantfile внизу строчку config.vm.box = "бла-бла-бла"
В этой строчке указывается целевая операционная система под которую вы хотите скомпилировать libtorrent. Например, кодовое имя для «пустой» 64-битной Убунты будет hashicorp/precise64. Весь список доступных ОС вы можете найти на сайте VagrantCloud.
Далее.
Выбранная система будет установлена «голой». Весь процесс компиляции запрограммирован в строках, которые начинаются с $script = SCRIPT и заканчиваются строкой SCRIPT. Все что между этими строками – это обычный shell. Вот в нем вы и можете «играться» сколько захотите.
Какая помощь необходима от сообщества?
Если вы умеете статически компилировать libtorrent под какую-то конкретную систему (на которой работает XBMC) создайте такой же Vagrantfile и скиньте его в эту ветку. Я размещу его в этом заглавном посте.
Также, если у вас есть какие-то полезные ссылки по теме, то также их скидывайте в эту ветку. Я размещу их в заглавном посте.
Будущее.
Как только мы «научимся» компилировать под большинство требуемых нами платформ, можно будет создать какой-нибудь проектик где-нибудь на github`е и уже как-то все это причесать в виде отдельного плагина для XBMC.
Имея такой плагин, создать уже к нему качественный торрент-плеер будет делом небольшого времени.
Полезные ссылки:
Страница сборки Си-шной части библиотеки на официальном сайте - http://libtorrent.org/building.html. Особое внимание обращайте там на все, что связано со static.
Есть проект go-libtorrent (используется в проекте Pulsar). Это статически скомпилированный libtorrent почти для всех платформ, но там обвязка для языка Go, а не для Python. Тем не менее, можно подчерпнуть очень много информации из файлов этого проекта. А именно – README.md, а также из файлов Docerfile, которые расположены в соответствующих папках этого проекта (linux-64, android-arm и т.д.)
Страница wiki с мануалом по сборке libtorrent на сайте торрент-клиента Deluge - http://dev.deluge-torrent.org/wiki/Building/libtorrent. У libtorrent и Deluge сейчас одни и те же авторы. Будте осторожны – там иструкция по сборке shared-версии libtorrent. Поэтому не забывайте добавлять соответствующие флаги static.
Наработки от ребят, нарезающих qBittorrent (сделан на базе libtorrent). У них на Github есть страничка c WiKi: https://github.com/qbittorrent/qBittorrent/wiki. Там в самом низу есть раздел Compilation и в нем ссылки на текст по компиляции для трех основных ОС (Win, Mac, Linux).
Бакалаврская работа голландских студентов, в конце которой описывается процедура компиляции под Андроид boost и libtorrent с питоновской-обвязкой.
Есть проект BitTorrent.bundle (это клон Pulsar). До версии 0.8 в нем использовался libtorrent-go под управлением cherrytorrent. Уже собранные библиотеки для Linux (32bit и 64bit), Windows и MacOSX можно взять здесь. Сейчас (начиная с версии 0.8) он работает на собственной сборки libtorrent-go - scrapmagnet. Уже собранные библиотеки под Linux (32bit, 64bit и ARM), Windows и MacOSX можно взять здесь.
Есть софтина для скачки торрентов с Рутрекер в фоновом режиме на Андроид: страница проекта (исходники).
Инструкция для компиляции в Windows (автор - Roman_V_M):
Компиляцию лучше проводить на чистой винде ХР/7 под виртуалкой.
Выполняете инструкцию отсюда до п. 5 включительно. В качестве компилятора устанавливаете VC++ 2008 Express (можно скачать с сайта Майкрософта).
После установки всех компонентов и компиляции Буста у вас должны быть следующие папки:
c:\OpenSSL-Win32\
C:\boost
C:\libtorrent-rasterbar
Далее выполняете следующий батник:
PHP код:
@echo off
copy "c:\OpenSSL-Win32\lib\VC\static\libeay32MT.lib" "C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\libeay32.lib" /y
copy "c:\OpenSSL-Win32\lib\VC\static\ssleay32MT.lib" "C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\ssleay32.lib" /y
xcopy "C:\OpenSSL-Win32\include\openssl" "C:\Program Files\Microsoft Visual Studio 9.0\VC\include\openssl" /y /i
call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86
set BOOST_ROOT=C:\boost
set BOOST_BUILD_PATH=%BOOST_ROOT%
set PATH=%BOOST_ROOT%;%PATH%
#********************************************
#* patch_bjam *
#********************************************
function patch_bjam {
local PATCH="been patched"
local JAM_CONFIG_DIR="$1"
local XBMC_JAM="$2/user-config.jam"
local CONFIG_JAM="$JAM_CONFIG_DIR/user-config.jam"
if [ -e $CONFIG_JAM ]; then
if grep -Fq "$PATCH" $CONFIG_JAM; then
echo "BOOST.BUILD configuration has been already patched."
return
fi
fi
echo "Patching BOOST.BUILD configuration file at $CONFIG_JAM..."
\cp -f $XBMC_JAM $CONFIG_JAM
echo "#This file has been patched by build-libtorrent.bash script!">> $CONFIG_JAM
#********************************************
#* setup_build_env *
#********************************************
function setup_build_env {
local CONFIG_JAM="$1/user-config.jam"
local JAM_CFLAG_PATTERN="<cflags>"
local JAM_CXXFLAG_PATTERN="<cxxflags>"
while IFS='' read -r line || [[ -n $line ]]; do
if [[ $line == *"$JAM_CFLAG_PATTERN"* ]]; then
line=${line/$JAM_CFLAG_PATTERN/}
line="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
line="${line%\"}"
line="${line#\"}"
export CFLAGS="$line -I$XBMC_DEPENDS_DIRECTORY/include/python2.6"
fi
if [[ $line == *"$JAM_CXXFLAG_PATTERN"* ]]; then
line=${line/$JAM_CXXFLAG_PATTERN/}
line="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
line="${line%\"}"
line="${line#\"}"
export CXXFLAGS="$line -I$XBMC_DEPENDS_DIRECTORY/include/python2.6 -Wno-sign-compare -Wno-unused-variable -Wno-literal-suffix -Wno-unused-local-typedefs"
fi
function build_libtorrent {
local LIBTORRENT_ROOT="$1"
local XBMC_ROOT="$2"
if [ -e "$LIBTORRENT_ROOT/libtorrent.so" ]; then
echo "Skip libtorrent building. $LIBTORRENT_ROOT/libtorrent.so exists"
return
fi
echo "Buildin libtorrent core..."
cd "$LIBTORRENT_ROOT"
#--debug-configuration --debug-building
$BOOST_ROOT/bjam toolset=gcc target-os=android boost=source release boost-link=static link=static runtime-link=shared encryption=tommath cxxflags="$CXXFLAGS" linkflags="$LDFLAGS"
# Sometimes previous line will fail for libtorrent 0.16.19. For some reason bjam fails to construct right command for mpi.cpp...
# Please copy failed command from terminal and edit it like following sample. After that just run in terminal a fixed command and re-run script once again. Sudo may be needed.
#"/opt/arm-linux-androideabi-4.8-vanilla/android-17/bin/arm-linux-androideabi-gcc" -x c -DANDROID -DBOOST_PTHREAD_NO_LIB -DBOOST_PYTHON2.6_NO_LIB -DBOOST_PYTHON_STATIC_LIB -Os -fexceptions -march=armv7-a -mtune=cortex-a9 -mfloat-abi=softfp -mfpu=neon -I/opt/xbmc-depends/arm-linux-androideabi-android-17/include/android-17 -isystem /opt/xbmc-depends/arm-linux-androideabi-android-17/include --sysroot=/opt/arm-linux-androideabi-4.8-vanilla/android-17/sysroot/ -Wl,--verbose -DANDROID -O3 -finline-functions -Wno-inline -Wall -Wno-missing-braces -fno-strict-aliasing -DBOOST_ALL_NO_LIB -DBOOST_ASIO_ENABLE_CANCELIO -DBOOST_ASIO_HASH_MAP_BUCKETS=1021 -DBOOST_ASIO_SEPARATE_COMPILATION -DBOOST_EXCEPTION_DISABLE -DBOOST_SYSTEM_STATIC_LINK=1 -DNDEBUG -DTORRENT_DISABLE_GEO_IP -DTORRENT_USE_I2P=1 -DTORRENT_USE_TOMMATH -DUNICODE -D_FILE_OFFSET_BITS=64 -D_UNICODE -D_WIN32_WINNT=0x0500 -I"/home/sergey/boost_1_57_0" -I"/usr/local/include" -I"/usr/sfw/include" -I"include" -I"include/libtorrent" -c -o "bin/gcc-4.8/release/boost-source/link-static/target-os-android/threading-multi/src/mpi.o" "src/mpi.c"
#export LDFLAGS="$LDFLAGS -undefined dynamic_lookup -Z"
#--debug-configuration --debug-building
$BOOST_ROOT/bjam toolset=gcc target-os=android boost=source release boost-link=static link=static runtime-link=shared encryption=tommath cxxflags="$CXXFLAGS" linkflags="$LDFLAGS" | tee build-log.txt
# Sometimes previous line will fail for libtorrent 0.16.19. For some reason bjam fails to construct right command for mpi.cpp...
# Please copy failed command from terminal and edit it like following sample. After that just run in terminal a fixed command and re-run script once again. Sudo may be needed.
#"/opt/arm-linux-androideabi-4.8-vanilla/android-17/bin/arm-linux-androideabi-gcc" -x c -DANDROID -DBOOST_PTHREAD_NO_LIB -DBOOST_PYTHON2.6_NO_LIB -DBOOST_PYTHON_STATIC_LIB -Os -fexceptions -march=armv7-a -mtune=cortex-a9 -mfloat-abi=softfp -mfpu=neon -I/opt/xbmc-depends/arm-linux-androideabi-android-17/include/android-17 -isystem /opt/xbmc-depends/arm-linux-androideabi-android-17/include --sysroot=/opt/arm-linux-androideabi-4.8-vanilla/android-17/sysroot/ -Wl,--verbose -DANDROID -O3 -finline-functions -Wno-inline -Wall -Wno-missing-braces -fPIC -fno-strict-aliasing -DBOOST_ALL_NO_LIB -DBOOST_ASIO_ENABLE_CANCELIO -DBOOST_ASIO_HASH_MAP_BUCKETS=1021 -DBOOST_ASIO_SEPARATE_COMPILATION -DBOOST_EXCEPTION_DISABLE -DBOOST_SYSTEM_STATIC_LINK=1 -DNDEBUG -DTORRENT_DISABLE_GEO_IP -DTORRENT_USE_I2P=1 -DTORRENT_USE_TOMMATH -DUNICODE -D_FILE_OFFSET_BITS=64 -D_UNICODE -D_WIN32_WINNT=0x0500 -I"../../include" -I"../../include/libtorrent" -I"/home/sergey/boost_1_57_0" -I"/usr/local/include" -I"/usr/sfw/include" -c -o "../../bin/gcc-4.8/release/boost-source/fpic-on/link-static/target-os-android/threading-multi/src/mpi.o" "../../src/mpi.c"
# if ! grep -q "ld: library not found for -lpython2.6" build-log.txt
# then
# echo Check link errors. Expected only missing libpython2.6.a
# exit 1
# fi
if [ -e $FINAL_LIB_PATH ]; then
cp $FINAL_LIB_PATH$LIBTORRENT_ROOT "$ANDROID_TOOLCHAIN_ROOT/bin/$SRTIP_TOOL" -g $LIBTORRENT_ROOT/libtorrent.so
echo "Done"
echo
echo "Final result been copied to $LIBTORRENT_ROOT"
else
echo
echo "Build of libtorrent binding FAILED."
return 1
fi
}
#********************************************
#* MAIN *
#********************************************
Скрипт компиляции для Mac OS X [версия - 0.16.19] (автор - srg70):
Запускать можно со следующими параметрами:
Код:
./build-libtorrent [-r | --rebuild all | libtorrent] [-t | --libtorrent-version ...]
-r or --rebuild - will build from scratch (takes a while).
-t or --libtorrent-version - version of libtorrent source to build. Default 0.16.19
PHP код:
#!/bin/bash
set -e
# build_order.bash
#
# Created by Sergey Shramchenko on 15.08.13.
# Copyright (c) 2013 Sergey Shramchenko. All rights reserved.
function usage {
echo "Usage ./build-libtorrent [-r | --rebuild all | libtorrent] [-t | --libtorrent-version ...]"
echo " -r or --rebuild - will build from scratch (takes a while)."
echo " -t | --libtorrent-version - version of libtorrent source to build. Default 0.16.19"
}
case $key in
-r|--rebuild)
if [ "$2" == "all" ]; then
SHOULD_REBUILD_ALL=1
else
if [ "$2" == "libtorrent" ]; then
SHOULD_REBUILD_LIBTORRENT=1
fi
fi
shift # past argument
;;
-t|--libtorrent-version)
LIBTORRENT_VERSION="$2"
shift # past argument
;;
# -l|--lib)
# LIBPATH="$2"
# shift # past argument
# ;;
# --default)
# DEFAULT=YES
# ;;
*)
usage
exit
;;
esac
shift # past argument or value
done
#********************************************
#* contains_element *
#********************************************
function contains_element () {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}
#********************************************
#* check_components *
#********************************************
function check_components {
local test=""
echo "Checking components..."
# brew
if [ $(which brew) != "/usr/local/bin/brew" ]; then
echo "Home Brew not found. Tring to install..."
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
if [ $(which brew) != "/usr/local/bin/brew" ]; then
echo "FAILED to install Home Brew. Please visit [url]http://brew.sh[/url] and install Home Brew manually"
exit 1
fi
fi
echo "Brew: Ok"
installed_libs=( $(brew list) )
requested_libs=("autoconf" "automake" "binutils" "cmake" "cppunit" "libtool" "openssl" "pkg-config")
for i in "${requested_libs[@]}"; do
if ! contains_element "$i" "${installed_libs[@]}"; then
echo "Tring to installing $i..."
brew install openssl
echo "$i: Ok"
else
echo "$i: Ok"
fi
done
}
#********************************************
#* download *
#********************************************
function download {
local REMOTE="$1"
local LOCAL="$3/$2"
if [ -e $LOCAL ]; then
echo "Skip downloading of $REMOTE. Found local copy at $LOCAL"
return
fi
#********************************************
#* extract *
#********************************************
function extract {
local ARCHIVE="$1"
local TARGET="$2"
if [ -d $TARGET ] && [ $SHOULD_REBUILD_ALL -ne 1 ]; then
echo "Skip extracting of $ARCHIVE. $TARGET exists"
return
fi
echo "Exracting $ARCHIVE to $TARGET ..."
rm -rf $TARGET; mkdir $TARGET
tar -xf $ARCHIVE -C $TARGET
echo "Done"
}
#********************************************
#* build_xbmc *
#********************************************
function build_xbmc {
local XBMC_HOME="$1"
local XBMC_DEPENDS="$2"
cd $XBMC_HOME
if [ -d $XBMC_DEPENDS ] && [ $SHOULD_REBUILD_ALL -ne 1 ]; then
echo "Skip XBMC building. $XBMC_DEPENDS exists"
return
fi
echo "Building XBMC/Kodi ..."
rm -rf $XBMC_DEPENDS
cd "$XBMC_HOME/tools/depends"
./bootstrap
./configure --host=x86_64-apple-darwin
# NOTE: do NOT use -j to speed up make. Building may fail
make
cd "$XBMC_HOME"
make -C tools/depends/target/xbmc
make clean
make xcode_depends
}
#********************************************
#* patch_bjam *
#********************************************
function patch_bjam {
local PATTERN="using gcc"
local PATCH="using darwin"
local JAM_CONFIG_DIR="$1"
local CONFIG_JAM="$JAM_CONFIG_DIR/user-config.jam"
if grep -Fq "$PATCH" $CONFIG_JAM; then
echo "BOOST.BUILD configuration has been already patched."
return
fi
echo "Patching BOOST.BUILD configuration file at $CONFIG_JAM..."
CONFIG_JAM_BACKUP="$JAM_CONFIG_DIR/user-config.original"
\cp $CONFIG_JAM $CONFIG_JAM_BACKUP
echo "#This file has been patched by build-libtorrent.bash script!"> $CONFIG_JAM
while IFS='' read -r line || [[ -n $line ]]; do
line=${line/$PATTERN/$PATCH}
echo "$line" >> $CONFIG_JAM
done < $CONFIG_JAM_BACKUP
#********************************************
#* setup_build_env *
#********************************************
function setup_build_env {
local CONFIG_JAM="$1/user-config.jam"
local JAM_CFLAG_PATTERN="<cflags>"
local JAM_CXXFLAG_PATTERN="<cxxflags>"
while IFS='' read -r line || [[ -n $line ]]; do
if [[ $line == *"$JAM_CFLAG_PATTERN"* ]]; then
line=${line/$JAM_CFLAG_PATTERN/}
line="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
line="${line%\"}"
line="${line#\"}"
export CFLAGS="$line -I$XBMC_DEPENDS_DIRECTORY/include/python2.6"
fi
if [[ $line == *"$JAM_CXXFLAG_PATTERN"* ]]; then
line=${line/$JAM_CXXFLAG_PATTERN/}
line="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
line="${line%\"}"
line="${line#\"}"
export CXXFLAGS="$line -I$XBMC_DEPENDS_DIRECTORY/include/python2.6 -stdlib=libstdc++ -Wno-parentheses-equality -Wno-unused-private-field -Wno-unused-function -Wno-unused-variable -Wno-deprecated-declarations"
fi
if [ -e $FINAL_LIB_PATH ]; then
cp $FINAL_LIB_PATH$LIBTORRENT_ROOT echo "Done"
echo
echo "Final result been copied to $LIBTORRENT_ROOT"
else
echo "Build of libtorrent binding FAILED."
return 1
fi
}
#********************************************
#* MAIN *
#********************************************
check_components
# XBMC archive has subdirectory with branch name
XBMC_SOURCES_DIRECTORY="$XBMC_SOURCES_DIRECTORY/$(ls $XBMC_SOURCES_DIRECTORY )"
echo XBMC_SOURCES_DIRECTORY = $XBMC_SOURCES_DIRECTORY