Skip to content

Commit 80aeb4f

Browse files
committed
Fix libtorrent+boost (update to latest versions and add python3 compatibility)
Since the openssl and ndk update the boost and libtorrent recipes weren't working. The old version for boost libraries does not support openssl 1.1, so we must update it. The old libtorrent recipe is strongly dependant on boost so we also update it. Also, before this commit, the compiler used to make those builds were gcc, now we use clang (the default compiler for the latest android ndk). Note: We use the latest release candidate version for libtorrent because still not released the final version (and it is more prepared to be build with clang compiler). To make it work with python3 we need to apply a patch to it, which will be not necessary when released the final version (the changes made by this patch are already merged into libtorrent's master branch). Those recipes were tested for both python versions with a slight modification of the test apps and importing the libtorrent at runtime without problems, plus the generated libraries are linked with our versions of openssl and python (using the readelf command).
1 parent 8493d5e commit 80aeb4f

File tree

7 files changed

+346
-125
lines changed

7 files changed

+346
-125
lines changed

pythonforandroid/recipes/boost/__init__.py

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from pythonforandroid.toolchain import Recipe, shprint, shutil, current_directory
22
from os.path import join, exists
3+
from os import environ
34
import sh
45

56
"""
@@ -9,11 +10,36 @@
910

1011

1112
class BoostRecipe(Recipe):
12-
version = '1.60.0'
13-
# Don't forget to change the URL when changing the version
14-
url = 'http://downloads.sourceforge.net/project/boost/boost/{version}/boost_1_60_0.tar.bz2'
15-
depends = ['python2']
16-
patches = ['disable-so-version.patch', 'use-android-libs.patch']
13+
# Todo: make recipe compatible with all p4a architectures
14+
'''
15+
.. note:: This recipe can be built only against API 21+ and arch armeabi-v7a
16+
17+
.. versionchanged:: 0.6.0
18+
Rewrote recipe to support clang's build. The following changes has
19+
been made:
20+
21+
- Bumped version number to 1.68.0
22+
- Better version handling for url
23+
- Added python 3 compatibility
24+
- Default compiler for ndk's toolchain set to clang
25+
- Python version will be detected via user-config.jam
26+
- Changed stl's lib from ``gnustl_shared`` to ``c++_shared``
27+
'''
28+
version = '1.68.0'
29+
url = 'http://downloads.sourceforge.net/project/boost/' \
30+
'boost/{version}/boost_{version_underscore}.tar.bz2'
31+
depends = [('python2', 'python3')]
32+
patches = ['disable-so-version.patch',
33+
'use-android-libs.patch',
34+
'fix-android-issues.patch']
35+
36+
@property
37+
def versioned_url(self):
38+
if self.url is None:
39+
return None
40+
return self.url.format(
41+
version=self.version,
42+
version_underscore=self.version.replace('.', '_'))
1743

1844
def should_build(self, arch):
1945
return not exists(join(self.get_build_dir(arch.arch), 'b2'))
@@ -28,41 +54,50 @@ def prebuild_arch(self, arch):
2854
shprint(bash, join(self.ctx.ndk_dir, 'build/tools/make-standalone-toolchain.sh'),
2955
'--arch=' + env['ARCH'],
3056
'--platform=android-' + str(self.ctx.android_api),
31-
'--toolchain=' + env['CROSSHOST'] + '-' + env['TOOLCHAIN_VERSION'],
57+
'--toolchain=' + env['CROSSHOST'] + '-' + self.ctx.toolchain_version + ':-llvm',
58+
'--use-llvm',
59+
'--stl=libc++',
3260
'--install-dir=' + env['CROSSHOME']
33-
)
61+
)
3462
# Set custom configuration
3563
shutil.copyfile(join(self.get_recipe_dir(), 'user-config.jam'),
3664
join(env['BOOST_BUILD_PATH'], 'user-config.jam'))
3765

3866
def build_arch(self, arch):
3967
super(BoostRecipe, self).build_arch(arch)
4068
env = self.get_recipe_env(arch)
69+
env['PYTHON_HOST'] = self.ctx.hostpython
4170
with current_directory(self.get_build_dir(arch.arch)):
4271
# Compile Boost.Build engine with this custom toolchain
4372
bash = sh.Command('bash')
44-
shprint(bash, 'bootstrap.sh',
45-
'--with-python=' + join(env['PYTHON_ROOT'], 'bin/python.host'),
46-
'--with-python-version=2.7',
47-
'--with-python-root=' + env['PYTHON_ROOT']
48-
) # Do not pass env
73+
shprint(bash, 'bootstrap.sh') # Do not pass env
4974
# Install app stl
50-
shutil.copyfile(join(env['CROSSHOME'], env['CROSSHOST'], 'lib/libgnustl_shared.so'),
51-
join(self.ctx.get_libs_dir(arch.arch), 'libgnustl_shared.so'))
75+
shutil.copyfile(
76+
join(self.ctx.ndk_dir, 'sources/cxx-stl/llvm-libc++/libs/'
77+
'armeabi-v7a/libc++_shared.so'),
78+
join(self.ctx.get_libs_dir(arch.arch), 'libc++_shared.so'))
5279

5380
def select_build_arch(self, arch):
5481
return arch.arch.replace('eabi-v7a', '').replace('eabi', '')
5582

5683
def get_recipe_env(self, arch):
57-
env = super(BoostRecipe, self).get_recipe_env(arch)
84+
# We don't use the normal env because we
85+
# are building with a standalone toolchain
86+
env = environ.copy()
87+
5888
env['BOOST_BUILD_PATH'] = self.get_build_dir(arch.arch) # find user-config.jam
5989
env['BOOST_ROOT'] = env['BOOST_BUILD_PATH'] # find boost source
60-
env['PYTHON_ROOT'] = self.ctx.get_python_install_dir()
90+
91+
env['PYTHON_ROOT'] = self.ctx.python_recipe.link_root(arch.arch)
92+
env['PYTHON_INCLUDE'] = self.ctx.python_recipe.include_root(arch.arch)
93+
env['PYTHON_MAJOR_MINOR'] = self.ctx.python_recipe.version[:3]
94+
env['PYTHON_LINK_VERSION'] = self.ctx.python_recipe.major_minor_version_string
95+
if 'python3' in self.ctx.python_recipe.name:
96+
env['PYTHON_LINK_VERSION'] += 'm'
97+
6198
env['ARCH'] = self.select_build_arch(arch)
62-
env['ANDROIDAPI'] = str(self.ctx.android_api)
6399
env['CROSSHOST'] = env['ARCH'] + '-linux-androideabi'
64100
env['CROSSHOME'] = join(env['BOOST_ROOT'], 'standalone-' + env['ARCH'] + '-toolchain')
65-
env['TOOLCHAIN_PREFIX'] = join(env['CROSSHOME'], 'bin', env['CROSSHOST'])
66101
return env
67102

68103

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
diff -u -r boost_1_68_0.orig/boost/config/user.hpp boost_1_68_0/boost/config/user.hpp
2+
--- boost_1_68_0.orig/boost/config/user.hpp 2018-08-01 22:50:46.000000000 +0200
3+
+++ boost_1_68_0/boost/config/user.hpp 2018-08-27 15:43:38.000000000 +0200
4+
@@ -13,6 +13,12 @@
5+
// configuration policy:
6+
//
7+
8+
+// Android defines
9+
+// There is problem with std::atomic on android (and some other platforms).
10+
+// See this link for more info:
11+
+// https://code.google.com/p/android/issues/detail?id=42735#makechanges
12+
+#define BOOST_ASIO_DISABLE_STD_ATOMIC 1
13+
+
14+
// define this to locate a compiler config file:
15+
// #define BOOST_COMPILER_CONFIG <myheader>
16+
17+
diff -u -r boost_1_68_0.orig/boost/asio/detail/config.hpp boost_1_68_0/boost/asio/detail/config.hpp
18+
--- boost_1_68_0.orig/boost/asio/detail/config.hpp 2018-08-01 22:50:46.000000000 +0200
19+
+++ boost_1_68_0/boost/asio/detail/config.hpp 2018-09-19 12:39:56.000000000 +0200
20+
@@ -804,7 +804,11 @@
21+
# if defined(__clang__)
22+
# if (__cplusplus >= 201402)
23+
# if __has_include(<experimental/string_view>)
24+
-# define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
25+
+# if __clang_major__ >= 7
26+
+# undef BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW
27+
+# else
28+
+# define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
29+
+# endif // __clang_major__ >= 7
30+
# endif // __has_include(<experimental/string_view>)
31+
# endif // (__cplusplus >= 201402)
32+
# endif // defined(__clang__)
33+
diff -u -r boost_1_68_0.orig/boost/system/error_code.hpp boost_1_68_0/boost/system/error_code.hpp
34+
--- boost_1_68_0.orig/boost/system/error_code.hpp 2018-08-01 22:50:53.000000000 +0200
35+
+++ boost_1_68_0/boost/system/error_code.hpp 2018-08-27 15:44:29.000000000 +0200
36+
@@ -17,6 +17,7 @@
37+
#include <boost/assert.hpp>
38+
#include <boost/noncopyable.hpp>
39+
#include <boost/utility/enable_if.hpp>
40+
+#include <stdio.h>
41+
#include <ostream>
42+
#include <string>
43+
#include <stdexcept>
44+
diff -u -r boost_1_68_0.orig/libs/filesystem/src/operations.cpp boost_1_68_0/libs/filesystem/src/operations.cpp
45+
--- boost_1_68_0.orig/libs/filesystem/src/operations.cpp 2018-08-01 22:50:47.000000000 +0200
46+
+++ boost_1_68_0/libs/filesystem/src/operations.cpp 2018-08-27 15:47:15.000000000 +0200
47+
@@ -232,6 +232,21 @@
48+
49+
# if defined(BOOST_POSIX_API)
50+
51+
+# if defined(__ANDROID__)
52+
+# define truncate libboost_truncate_wrapper
53+
+// truncate() is present in Android libc only starting from ABI 21, so here's a simple wrapper
54+
+static int libboost_truncate_wrapper(const char *path, off_t length)
55+
+{
56+
+ int fd = open(path, O_WRONLY);
57+
+ if (fd == -1) {
58+
+ return -1;
59+
+ }
60+
+ int status = ftruncate(fd, length);
61+
+ close(fd);
62+
+ return status;
63+
+}
64+
+# endif
65+
+
66+
typedef int err_t;
67+
68+
// POSIX uses a 0 return to indicate success
Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,61 @@
11
import os ;
22

3-
local ANDROIDNDK = [ os.environ ANDROIDNDK ] ;
4-
local ANDROIDAPI = [ os.environ ANDROIDAPI ] ;
5-
local TOOLCHAIN_VERSION = [ os.environ TOOLCHAIN_VERSION ] ;
6-
local TOOLCHAIN_PREFIX = [ os.environ TOOLCHAIN_PREFIX ] ;
73
local ARCH = [ os.environ ARCH ] ;
4+
local CROSSHOME = [ os.environ CROSSHOME ] ;
5+
local PYTHON_HOST = [ os.environ PYTHON_HOST ] ;
86
local PYTHON_ROOT = [ os.environ PYTHON_ROOT ] ;
7+
local PYTHON_INCLUDE = [ os.environ PYTHON_INCLUDE ] ;
8+
local PYTHON_LINK_VERSION = [ os.environ PYTHON_LINK_VERSION ] ;
9+
local PYTHON_MAJOR_MINOR = [ os.environ PYTHON_MAJOR_MINOR ] ;
910

10-
using gcc : $(ARCH) : $(TOOLCHAIN_PREFIX)-g++ :
11+
using clang : $(ARCH) : $(CROSSHOME)/bin/arm-linux-androideabi-clang++ :
12+
<archiver>$(CROSSHOME)/bin/arm-linux-androideabi-ar
13+
<root>$(CROSSHOME)/sysroot
1114
<architecture>$(ARCH)
12-
<archiver>$(TOOLCHAIN_PREFIX)-ar
13-
<compileflags>-DBOOST_SP_USE_PTHREADS
14-
<compileflags>-DBOOST_AC_USE_PTHREADS
15-
<cxxflags>-DBOOST_SP_USE_PTHREADS
16-
<cxxflags>-DBOOST_AC_USE_PTHREADS
17-
<cxxflags>-frtti
18-
<cxxflags>-fexceptions
19-
<compileflags>-I$(ANDROIDNDK)/platforms/android-$(ANDROIDAPI)/arch-$(ARCH)/usr/include
20-
<compileflags>-I$(ANDROIDNDK)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/include
21-
<compileflags>-I$(ANDROIDNDK)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/libs/$(ARCH)/include
22-
<compileflags>-I$(PYTHON_ROOT)/include/python2.7
23-
<linkflags>--sysroot=$(ANDROIDNDK)/platforms/android-$(ANDROIDAPI)/arch-$(ARCH)
24-
<linkflags>-L$(ANDROIDNDK)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/libs/$(ARCH)
25-
<linkflags>-L$(PYTHON_ROOT)/lib
26-
<linkflags>-lgnustl_shared
27-
<linkflags>-lpython2.7
15+
<compileflags>-fexceptions
16+
<compileflags>-frtti
17+
<compileflags>-fpic
18+
<compileflags>-ffunction-sections
19+
<compileflags>-funwind-tables
20+
<compileflags>-march=armv7-a
21+
<compileflags>-msoft-float
22+
<compileflags>-mfpu=neon
23+
<compileflags>-mthumb
24+
<linkflags>-march=armv7-a
25+
<linkflags>-Wl,--fix-cortex-a8
26+
<compileflags>-Os
27+
<compileflags>-fomit-frame-pointer
28+
<compileflag>-fno-strict-aliasing
29+
<compileflags>-DANDROID
30+
<compileflags>-D__ANDROID__
31+
<compileflags>-DANDROID_TOOLCHAIN=clang
32+
<compileflags>-DANDROID_ABI=armv7-a
33+
<compileflags>-DANDROID_STL=c++_shared
34+
<compileflags>-DBOOST_ALL_NO_LIB
35+
#<compileflags>-DNDEBUG
36+
<compileflags>-O2
37+
<compileflags>-g
38+
<compileflags>-fvisibility=hidden
39+
<compileflags>-fvisibility-inlines-hidden
40+
<compileflags>-fdata-sections
41+
<cxxflags>-D__arm__
42+
<cxxflags>-D_REENTRANT
43+
<cxxflags>-D_GLIBCXX__PTHREADS
44+
<compileflags>-Wno-long-long
45+
<compileflags>-Wno-missing-field-initializers
46+
<compileflags>-Wno-unused-variable
47+
<linkflags>-Wl,-z,relro
48+
<linkflags>-Wl,-z,now
49+
<linkflags>-lc++_shared
50+
<linkflags>-L$(PYTHON_ROOT)
51+
<linkflags>-lpython$(PYTHON_LINK_VERSION)
52+
<linkflags>-Wl,-O1
53+
<linkflags>-Wl,-Bsymbolic-functions
2854
;
55+
56+
using python : $(PYTHON_MAJOR_MINOR)
57+
: $(PYTHON_host)
58+
: $(PYTHON_ROOT) $(PYTHON_INCLUDE)
59+
: $(PYTHON_ROOT)/libpython$(PYTHON_LINK_VERSION).so
60+
: #<define>BOOST_ALL_DYN_LINK
61+
;

0 commit comments

Comments
 (0)